diff --git a/Android.bp b/Android.bp
index c47b747..9493733 100644
--- a/Android.bp
+++ b/Android.bp
@@ -916,6 +916,7 @@
         ":ipconnectivity-proto-src",
         ":libstats_atom_enum_protos",
         ":libstats_internal_protos",
+        ":statsd_internal_protos",
         "cmds/am/proto/instrumentation_data.proto",
         "cmds/statsd/src/**/*.proto",
         "core/proto/**/*.proto",
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..4f89f7d
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,24 @@
+# This top-level list should remain narrowly defined as team leads; individual
+# teams are strongly encouraged to define narrower OWNERS files at deeper
+# levels within the source tree; see OWNERS.md for more details
+dsandler@android.com
+dsandler@google.com
+hackbod@android.com
+hackbod@google.com
+jsharkey@android.com
+jsharkey@google.com
+michaelwr@google.com
+nandana@google.com
+narayan@google.com
+ogunwale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
+yamasani@google.com
+
+# Support bulk translation updates
+per-file */res*/values*/*.xml = byi@google.com
+
+per-file Android.bp = file:platform/build/soong:/OWNERS
+per-file Android.mk = file:platform/build/soong:/OWNERS
+per-file ApiDocs.bp = file:platform/build/soong:/OWNERS
+per-file StubLibraries.bp = file:platform/build/soong:/OWNERS
diff --git a/OWNERS.md b/OWNERS.md
new file mode 100644
index 0000000..6428c59
--- /dev/null
+++ b/OWNERS.md
@@ -0,0 +1,34 @@
+As general background, `OWNERS` files expedite code reviews by helping code
+authors quickly find relevant reviewers, and they also ensure that stakeholders
+are involved in code changes in their areas.
+
+The structure of `frameworks/base/` is unique among Android repositories, and
+it's evolved into a complex interleaved structure over the years.  Because of
+this structure, the best place to authoritatively define `OWNERS` can vary
+wildly, but here are some common patterns:
+
+* `core/java/` contains source that is included in the base classpath, and as
+such it's where most APIs are defined:
+  * `core/java/android/app/`
+  * `core/java/android/content/`
+* `services/core/` contains most system services, and these directories
+typically have more granularity than `core/java/`, since they can be refactored
+without API changes:
+  * `services/core/java/com/android/server/net/`
+  * `services/core/java/com/android/server/wm/`
+* `services/` contains several system services that have been isolated from the
+main `services/core/` project:
+  * `services/appwidget/`
+  * `services/midi/`
+* `apex/` contains Mainline modules:
+  * `apex/jobscheduler/`
+  * `apex/permission/`
+* Finally, some teams may have dedicated top-level directories:
+  * `media/`
+  * `wifi/`
+
+Area maintainers are strongly encouraged to list people in a single
+authoritative `OWNERS` file in **exactly one** location.  Then, other paths
+should reference that single authoritative `OWNERS` file using an include
+directive.  This approach ensures that updates are applied consistently across
+the tree, reducing maintenance burden.
diff --git a/ZYGOTE_OWNERS b/ZYGOTE_OWNERS
new file mode 100644
index 0000000..90a185b
--- /dev/null
+++ b/ZYGOTE_OWNERS
@@ -0,0 +1,5 @@
+calin@google.com
+chriswailes@google.com
+maco@google.com
+narayan@google.com
+ngeoffray@google.com
diff --git a/apct-tests/perftests/OWNERS b/apct-tests/perftests/OWNERS
new file mode 100644
index 0000000..a060ad9
--- /dev/null
+++ b/apct-tests/perftests/OWNERS
@@ -0,0 +1,2 @@
+timmurray@google.com
+philipcuadra@google.com
diff --git a/apct-tests/perftests/autofill/OWNERS b/apct-tests/perftests/autofill/OWNERS
new file mode 100644
index 0000000..c52751d
--- /dev/null
+++ b/apct-tests/perftests/autofill/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/autofill/OWNERS
diff --git a/apct-tests/perftests/blobstore/OWNERS b/apct-tests/perftests/blobstore/OWNERS
new file mode 100644
index 0000000..65bb6b8
--- /dev/null
+++ b/apct-tests/perftests/blobstore/OWNERS
@@ -0,0 +1 @@
+include /apex/blobstore/OWNERS
diff --git a/apct-tests/perftests/contentcapture/OWNERS b/apct-tests/perftests/contentcapture/OWNERS
new file mode 100644
index 0000000..a28e00a
--- /dev/null
+++ b/apct-tests/perftests/contentcapture/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/contentcapture/OWNERS
diff --git a/apct-tests/perftests/core/apps/overlay/OWNERS b/apct-tests/perftests/core/apps/overlay/OWNERS
new file mode 100644
index 0000000..afb98d4
--- /dev/null
+++ b/apct-tests/perftests/core/apps/overlay/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/content/om/OWNERS
diff --git a/apct-tests/perftests/core/src/android/accounts/OWNERS b/apct-tests/perftests/core/src/android/accounts/OWNERS
new file mode 100644
index 0000000..df1b4f4
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/accounts/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/accounts/OWNERS
diff --git a/apct-tests/perftests/core/src/android/database/OWNERS b/apct-tests/perftests/core/src/android/database/OWNERS
new file mode 100644
index 0000000..bb9a2ca
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/database/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/database/OWNERS
diff --git a/apct-tests/perftests/inputmethod/OWNERS b/apct-tests/perftests/inputmethod/OWNERS
new file mode 100644
index 0000000..5deb2ce
--- /dev/null
+++ b/apct-tests/perftests/inputmethod/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/inputmethod/OWNERS
diff --git a/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfRunPrecondition.java b/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfRunPrecondition.java
index fc48fd5..4bfcade 100644
--- a/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfRunPrecondition.java
+++ b/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfRunPrecondition.java
@@ -16,134 +16,8 @@
 
 package android.inputmethod;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.inputmethod.ImePerfTestBase.executeShellCommand;
-import static android.inputmethod.ImePerfTestBase.runWithShellPermissionIdentity;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningAppProcessInfo;
-import android.app.ActivityTaskManager;
-import android.content.Context;
-import android.inputmethod.ImePerfTestBase.SettingsSession;
-import android.os.BatteryManager;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.WindowManagerPolicyConstants;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.internal.policy.PhoneWindow;
-
-import org.junit.runner.Description;
-import org.junit.runner.Result;
-import org.junit.runner.notification.RunListener;
-
-import java.util.List;
+import android.perftests.utils.WindowPerfRunPreconditionBase;
 
 /** Prepare the preconditions before running performance test. */
-public class ImePerfRunPrecondition extends RunListener {
-    private static final String TAG = ImePerfRunPrecondition.class.getSimpleName();
-
-    private static final String ARGUMENT_LOG_ONLY = "log";
-    private static final String ARGUMENT_KILL_BACKGROUND = "kill-bg";
-    private static final String ARGUMENT_PROFILING_ITERATIONS = "profiling-iterations";
-    private static final String ARGUMENT_PROFILING_SAMPLING = "profiling-sampling";
-    private static final String DEFAULT_PROFILING_ITERATIONS = "10";
-    private static final String DEFAULT_PROFILING_SAMPLING_US = "10";
-    private static final long KILL_BACKGROUND_WAIT_MS = 3000;
-
-    /** The requested iterations to run with method profiling. */
-    static int sProfilingIterations;
-
-    /** The interval of sample profiling in microseconds. */
-    static int sSamplingIntervalUs;
-
-    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
-    private long mWaitPreconditionDoneMs = 500;
-
-    private final SettingsSession<Integer> mStayOnWhilePluggedInSetting = new SettingsSession<>(
-            Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0),
-            value -> executeShellCommand(String.format("settings put global %s %d",
-                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN, value)));
-
-    private final SettingsSession<Integer> mNavigationModeSetting = new SettingsSession<>(
-            mContext.getResources().getInteger(
-                    com.android.internal.R.integer.config_navBarInteractionMode),
-            value -> {
-                final String navOverlay;
-                switch (value) {
-                    case WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL:
-                    default:
-                        navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
-                        break;
-                }
-                executeShellCommand("cmd overlay enable-exclusive " + navOverlay);
-            });
-
-    /** It only executes once before all tests. */
-    @Override
-    public void testRunStarted(Description description) {
-        final Bundle arguments = InstrumentationRegistry.getArguments();
-        // If true, it only logs the method names without running.
-        final boolean skip = Boolean.parseBoolean(arguments.getString(ARGUMENT_LOG_ONLY, "false"));
-        Log.i(TAG, "arguments=" + arguments);
-        if (skip) {
-            return;
-        }
-        sProfilingIterations = Integer.parseInt(
-                arguments.getString(ARGUMENT_PROFILING_ITERATIONS, DEFAULT_PROFILING_ITERATIONS));
-        sSamplingIntervalUs = Integer.parseInt(
-                arguments.getString(ARGUMENT_PROFILING_SAMPLING, DEFAULT_PROFILING_SAMPLING_US));
-
-        // Use same navigation mode (gesture navigation) across all devices and tests
-        // for consistency.
-        mNavigationModeSetting.set(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL);
-        // Keep the device awake during testing.
-        mStayOnWhilePluggedInSetting.set(BatteryManager.BATTERY_PLUGGED_ANY);
-
-        runWithShellPermissionIdentity(() -> {
-            final ActivityTaskManager atm = mContext.getSystemService(ActivityTaskManager.class);
-            atm.removeAllVisibleRecentTasks();
-            atm.removeRootTasksWithActivityTypes(new int[] { ACTIVITY_TYPE_STANDARD,
-                    ACTIVITY_TYPE_ASSISTANT, ACTIVITY_TYPE_RECENTS, ACTIVITY_TYPE_UNDEFINED });
-        });
-        PhoneWindow.sendCloseSystemWindows(mContext, "ImePerfTests");
-
-        if (Boolean.parseBoolean(arguments.getString(ARGUMENT_KILL_BACKGROUND))) {
-            runWithShellPermissionIdentity(this::killBackgroundProcesses);
-            mWaitPreconditionDoneMs = KILL_BACKGROUND_WAIT_MS;
-        }
-        // Wait a while for the precondition setup to complete.
-        SystemClock.sleep(mWaitPreconditionDoneMs);
-    }
-
-    private void killBackgroundProcesses() {
-        Log.i(TAG, "Killing background processes...");
-        final ActivityManager am = mContext.getSystemService(ActivityManager.class);
-        final List<RunningAppProcessInfo> processes = am.getRunningAppProcesses();
-        if (processes == null) {
-            return;
-        }
-        for (RunningAppProcessInfo processInfo : processes) {
-            if (processInfo.importanceReasonCode == RunningAppProcessInfo.REASON_UNKNOWN
-                    && processInfo.importance > RunningAppProcessInfo.IMPORTANCE_SERVICE) {
-                for (String pkg : processInfo.pkgList) {
-                    am.forceStopPackage(pkg);
-                }
-            }
-        }
-    }
-
-    /** It only executes once after all tests. */
-    @Override
-    public void testRunFinished(Result result) {
-        mNavigationModeSetting.close();
-        mStayOnWhilePluggedInSetting.close();
-    }
+public class ImePerfRunPrecondition extends WindowPerfRunPreconditionBase {
 }
diff --git a/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTest.java b/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTest.java
index 2b7af2f..689fb36 100644
--- a/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTest.java
+++ b/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTest.java
@@ -29,7 +29,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.inputmethodservice.InputMethodService;
-import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.SystemClock;
 import android.perftests.utils.ManualBenchmarkState;
@@ -420,23 +419,20 @@
                 });
     }
 
-    private void startAsyncAtrace() throws IOException {
+    private void startAsyncAtrace() {
         mIsTraceStarted = true;
         // IMF uses 'wm' component for trace in InputMethodService, InputMethodManagerService,
         // WindowManagerService and 'view' for client window (InsetsController).
         // TODO(b/167947940): Consider a separate input_method atrace
-        UI_AUTOMATION.executeShellCommand("atrace -b 32768 --async_start wm view");
-        // Avoid atrace isn't ready immediately.
-        SystemClock.sleep(TimeUnit.NANOSECONDS.toMillis(TIME_1_S_IN_NS));
+        startAsyncAtrace("wm view");
     }
 
     private void stopAsyncAtrace() {
         if (!mIsTraceStarted) {
             return;
         }
-        final ParcelFileDescriptor pfd = UI_AUTOMATION.executeShellCommand("atrace --async_stop");
         mIsTraceStarted = false;
-        final InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+        final InputStream inputStream = stopAsyncAtraceWithStream();
         try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
             String line;
             while ((line = reader.readLine()) != null) {
diff --git a/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTestBase.java b/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTestBase.java
index 1a861d7..f70d79c 100644
--- a/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTestBase.java
+++ b/apct-tests/perftests/inputmethod/src/android/inputmethod/ImePerfTestBase.java
@@ -18,135 +18,21 @@
 
 import static android.perftests.utils.PerfTestActivity.INTENT_EXTRA_ADD_EDIT_TEXT;
 
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import android.app.KeyguardManager;
-import android.app.UiAutomation;
-import android.content.Context;
 import android.content.Intent;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
 import android.perftests.utils.PerfTestActivity;
+import android.perftests.utils.WindowPerfTestBase;
 
-
-import androidx.test.rule.ActivityTestRule;
-
-import org.junit.BeforeClass;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Objects;
-import java.util.function.Consumer;
-
-public class ImePerfTestBase {
-    static final UiAutomation UI_AUTOMATION = getInstrumentation().getUiAutomation();
-    static final long NANOS_PER_S = 1000L * 1000 * 1000;
-    static final long TIME_1_S_IN_NS = 1 * NANOS_PER_S;
+public class ImePerfTestBase extends WindowPerfTestBase {
     static final long TIMEOUT_1_S_IN_MS = 1 * 1000L;
 
-    @BeforeClass
-    public static void setUpOnce() {
-        final Context context = getInstrumentation().getContext();
-
-        if (!context.getSystemService(PowerManager.class).isInteractive()
-                || context.getSystemService(KeyguardManager.class).isKeyguardLocked()) {
-            executeShellCommand("input keyevent KEYCODE_WAKEUP");
-            executeShellCommand("wm dismiss-keyguard");
-        }
-        context.startActivity(new Intent(Intent.ACTION_MAIN)
-                .addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
-    }
-
-    /**
-     * Executes shell command with reading the output. It may also used to block until the current
-     * command is completed.
-     */
-    static ByteArrayOutputStream executeShellCommand(String command) {
-        final ParcelFileDescriptor pfd = UI_AUTOMATION.executeShellCommand(command);
-        final byte[] buf = new byte[512];
-        final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-        int bytesRead;
-        try (FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
-            while ((bytesRead = fis.read(buf)) != -1) {
-                bytes.write(buf, 0, bytesRead);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-        return bytes;
-    }
-
-    /** Returns how many iterations should run with method tracing. */
-    static int getProfilingIterations() {
-        return ImePerfRunPrecondition.sProfilingIterations;
-    }
-
-    static void runWithShellPermissionIdentity(Runnable runnable) {
-        UI_AUTOMATION.adoptShellPermissionIdentity();
-        try {
-            runnable.run();
-        } finally {
-            UI_AUTOMATION.dropShellPermissionIdentity();
-        }
-    }
-
-    static class SettingsSession<T> implements AutoCloseable {
-        private final Consumer<T> mSetter;
-        private final T mOriginalValue;
-        private boolean mChanged;
-
-        SettingsSession(T originalValue, Consumer<T> setter) {
-            mOriginalValue = originalValue;
-            mSetter = setter;
-        }
-
-        void set(T value) {
-            if (Objects.equals(value, mOriginalValue)) {
-                mChanged = false;
-                return;
-            }
-            mSetter.accept(value);
-            mChanged = true;
-        }
-
-        @Override
-        public void close() {
-            if (mChanged) {
-                mSetter.accept(mOriginalValue);
-            }
-        }
-    }
-
-    /**
-     * Provides an activity that keeps screen on and is able to wait for a stable lifecycle stage.
-     */
-    static class PerfTestActivityRule extends ActivityTestRule<PerfTestActivity> {
-        private final Intent mStartIntent =
-                new Intent(getInstrumentation().getTargetContext(), PerfTestActivity.class);
-
-        PerfTestActivityRule() {
-            this(false /* launchActivity */);
-        }
-
-        PerfTestActivityRule(boolean launchActivity) {
-            super(PerfTestActivity.class, false /* initialTouchMode */, launchActivity);
-        }
-
-        @Override
-        protected Intent getActivityIntent() {
-            return mStartIntent;
-        }
+    /** Provides an activity that contains an edit text view.*/
+    static class PerfTestActivityRule extends PerfTestActivityRuleBase {
 
         @Override
         public PerfTestActivity launchActivity(Intent intent) {
             intent.putExtra(INTENT_EXTRA_ADD_EDIT_TEXT, true);
             return super.launchActivity(intent);
         }
-
-        PerfTestActivity launchActivity() {
-            return launchActivity(mStartIntent);
-        }
     }
 
     static String[] buildArray(String[]... arrays) {
diff --git a/apct-tests/perftests/packagemanager/OWNERS b/apct-tests/perftests/packagemanager/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/apct-tests/perftests/packagemanager/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/apct-tests/perftests/textclassifier/OWNERS b/apct-tests/perftests/textclassifier/OWNERS
new file mode 100644
index 0000000..46b3cb8
--- /dev/null
+++ b/apct-tests/perftests/textclassifier/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/textclassifier/OWNERS
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfRunPreconditionBase.java b/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfRunPreconditionBase.java
new file mode 100644
index 0000000..8d2ac02
--- /dev/null
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfRunPreconditionBase.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2020 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.perftests.utils;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.perftests.utils.WindowPerfTestBase.executeShellCommand;
+import static android.perftests.utils.WindowPerfTestBase.runWithShellPermissionIdentity;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.ActivityTaskManager;
+import android.content.Context;
+import android.os.BatteryManager;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.perftests.utils.WindowPerfTestBase.SettingsSession;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.WindowManagerPolicyConstants;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.internal.policy.PhoneWindow;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.RunListener;
+
+import java.util.List;
+
+/** Prepare the preconditions before running performance test. */
+public class WindowPerfRunPreconditionBase extends RunListener {
+    protected final String mTag = getClass().getSimpleName();
+
+    private static final String ARGUMENT_LOG_ONLY = "log";
+    private static final String ARGUMENT_KILL_BACKGROUND = "kill-bg";
+    private static final String ARGUMENT_PROFILING_ITERATIONS = "profiling-iterations";
+    private static final String ARGUMENT_PROFILING_SAMPLING = "profiling-sampling";
+    private static final String DEFAULT_PROFILING_ITERATIONS = "0";
+    private static final String DEFAULT_PROFILING_SAMPLING_US = "10";
+    private static final long KILL_BACKGROUND_WAIT_MS = 3000;
+
+    /** The requested iterations to run with method profiling. */
+    static int sProfilingIterations;
+
+    /** The interval of sample profiling in microseconds. */
+    static int sSamplingIntervalUs;
+
+    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
+    private long mWaitPreconditionDoneMs = 500;
+
+    private final SettingsSession<Integer> mStayOnWhilePluggedInSetting = new SettingsSession<>(
+            Settings.Global.getInt(mContext.getContentResolver(),
+                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0),
+            value -> executeShellCommand(String.format("settings put global %s %d",
+                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN, value)));
+
+    private final SettingsSession<Integer> mNavigationModeSetting = new SettingsSession<>(
+            mContext.getResources().getInteger(
+                    com.android.internal.R.integer.config_navBarInteractionMode),
+            value -> {
+                final String navOverlay;
+                switch (value) {
+                    case WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON:
+                        navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
+                        break;
+                    case WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON:
+                        navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
+                        break;
+                    case WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL:
+                    default:
+                        navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
+                        break;
+                }
+                executeShellCommand("cmd overlay enable-exclusive " + navOverlay);
+            });
+
+    /** It only executes once before all tests. */
+    @Override
+    public void testRunStarted(Description description) {
+        final Bundle arguments = InstrumentationRegistry.getArguments();
+        // If true, it only logs the method names without running.
+        final boolean skip = Boolean.parseBoolean(arguments.getString(ARGUMENT_LOG_ONLY, "false"));
+        Log.i(mTag, "arguments=" + arguments);
+        if (skip) {
+            return;
+        }
+        sProfilingIterations = Integer.parseInt(
+                arguments.getString(ARGUMENT_PROFILING_ITERATIONS, DEFAULT_PROFILING_ITERATIONS));
+        sSamplingIntervalUs = Integer.parseInt(
+                arguments.getString(ARGUMENT_PROFILING_SAMPLING, DEFAULT_PROFILING_SAMPLING_US));
+
+        // Use same navigation mode (gesture navigation) across all devices and tests
+        // for consistency.
+        mNavigationModeSetting.set(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL);
+        // Keep the device awake during testing.
+        mStayOnWhilePluggedInSetting.set(BatteryManager.BATTERY_PLUGGED_ANY);
+
+        runWithShellPermissionIdentity(() -> {
+            final ActivityTaskManager atm = mContext.getSystemService(ActivityTaskManager.class);
+            atm.removeAllVisibleRecentTasks();
+            atm.removeRootTasksWithActivityTypes(new int[] { ACTIVITY_TYPE_STANDARD,
+                    ACTIVITY_TYPE_ASSISTANT, ACTIVITY_TYPE_RECENTS, ACTIVITY_TYPE_UNDEFINED });
+        });
+        PhoneWindow.sendCloseSystemWindows(mContext, mTag);
+
+        if (Boolean.parseBoolean(arguments.getString(ARGUMENT_KILL_BACKGROUND))) {
+            runWithShellPermissionIdentity(this::killBackgroundProcesses);
+            mWaitPreconditionDoneMs = KILL_BACKGROUND_WAIT_MS;
+        }
+        // Wait a while for the precondition setup to complete.
+        SystemClock.sleep(mWaitPreconditionDoneMs);
+    }
+
+    private void killBackgroundProcesses() {
+        Log.i(mTag, "Killing background processes...");
+        final ActivityManager am = mContext.getSystemService(ActivityManager.class);
+        final List<RunningAppProcessInfo> processes = am.getRunningAppProcesses();
+        if (processes == null) {
+            return;
+        }
+        for (RunningAppProcessInfo processInfo : processes) {
+            if (processInfo.importanceReasonCode == RunningAppProcessInfo.REASON_UNKNOWN
+                    && processInfo.importance > RunningAppProcessInfo.IMPORTANCE_SERVICE) {
+                for (String pkg : processInfo.pkgList) {
+                    am.forceStopPackage(pkg);
+                }
+            }
+        }
+    }
+
+    /** It only executes once after all tests. */
+    @Override
+    public void testRunFinished(Result result) {
+        mNavigationModeSetting.close();
+        mStayOnWhilePluggedInSetting.close();
+    }
+}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfTestBase.java b/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfTestBase.java
new file mode 100644
index 0000000..ca59137
--- /dev/null
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/WindowPerfTestBase.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2020 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.perftests.utils;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.app.KeyguardManager;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.Intent;
+import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
+import android.os.SystemClock;
+
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.After;
+import org.junit.BeforeClass;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/** The base class for window related performance tests. */
+public class WindowPerfTestBase {
+    public static final long NANOS_PER_S = 1000L * 1000 * 1000;
+    public static final long TIME_1_S_IN_NS = 1 * NANOS_PER_S;
+
+    static boolean sIsProfilingMethod;
+
+    @BeforeClass
+    public static void setUpOnce() {
+        final Context context = getInstrumentation().getContext();
+
+        if (!context.getSystemService(PowerManager.class).isInteractive()
+                || context.getSystemService(KeyguardManager.class).isKeyguardLocked()) {
+            executeShellCommand("input keyevent KEYCODE_WAKEUP");
+            executeShellCommand("wm dismiss-keyguard");
+        }
+        context.startActivity(new Intent(Intent.ACTION_MAIN)
+                .addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+    }
+
+    @After
+    public void tearDown() {
+        // Make sure that profiling is stopped if test fails.
+        if (sIsProfilingMethod) {
+            stopProfiling();
+        }
+    }
+
+    public static UiAutomation getUiAutomation() {
+        return getInstrumentation().getUiAutomation();
+    }
+
+    public static void startAsyncAtrace(String tags) {
+        getUiAutomation().executeShellCommand("atrace -b 32768 --async_start " + tags);
+        // Avoid atrace isn't ready immediately.
+        SystemClock.sleep(TimeUnit.NANOSECONDS.toMillis(TIME_1_S_IN_NS));
+    }
+
+    public static InputStream stopAsyncAtraceWithStream() {
+        return new ParcelFileDescriptor.AutoCloseInputStream(
+                getUiAutomation().executeShellCommand("atrace --async_stop"));
+    }
+
+    /** Starts method tracing on system server. */
+    public static void startProfiling(File basePath, String outFileName) {
+        if (!basePath.exists()) {
+            executeShellCommand("mkdir -p " + basePath);
+        }
+        final String samplingArg = WindowPerfRunPreconditionBase.sSamplingIntervalUs > 0
+                ? ("--sampling " + WindowPerfRunPreconditionBase.sSamplingIntervalUs)
+                : "";
+        executeShellCommand("am profile start " + samplingArg + " system "
+                + new File(basePath, outFileName));
+        sIsProfilingMethod = true;
+    }
+
+    /** Stops method tracing of system server. */
+    public static void stopProfiling() {
+        executeShellCommand("am profile stop system");
+        sIsProfilingMethod = false;
+    }
+
+    public static boolean sIsProfilingMethod() {
+        return sIsProfilingMethod;
+    }
+
+    /** Returns how many iterations should run with method tracing. */
+    public static int getProfilingIterations() {
+        return WindowPerfRunPreconditionBase.sProfilingIterations;
+    }
+
+    /**
+     * Executes shell command with reading the output. It may also used to block until the current
+     * command is completed.
+     */
+    public static ByteArrayOutputStream executeShellCommand(String command) {
+        final ParcelFileDescriptor pfd = getUiAutomation().executeShellCommand(command);
+        final byte[] buf = new byte[512];
+        final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+        int bytesRead;
+        try (FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
+            while ((bytesRead = fis.read(buf)) != -1) {
+                bytes.write(buf, 0, bytesRead);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return bytes;
+    }
+
+    public static void runWithShellPermissionIdentity(Runnable runnable) {
+        getUiAutomation().adoptShellPermissionIdentity();
+        try {
+            runnable.run();
+        } finally {
+            getUiAutomation().dropShellPermissionIdentity();
+        }
+    }
+
+    public static class SettingsSession<T> implements AutoCloseable {
+        private final Consumer<T> mSetter;
+        private final T mOriginalValue;
+        private boolean mChanged;
+
+        public SettingsSession(T originalValue, Consumer<T> setter) {
+            mOriginalValue = originalValue;
+            mSetter = setter;
+        }
+
+        public void set(T value) {
+            if (Objects.equals(value, mOriginalValue)) {
+                mChanged = false;
+                return;
+            }
+            mSetter.accept(value);
+            mChanged = true;
+        }
+
+        @Override
+        public void close() {
+            if (mChanged) {
+                mSetter.accept(mOriginalValue);
+            }
+        }
+    }
+
+    /**
+     * Provides the {@link PerfTestActivity} with an associated customizable intent.
+     */
+    public static class PerfTestActivityRuleBase extends ActivityTestRule<PerfTestActivity> {
+        protected final Intent mStartIntent =
+                new Intent(getInstrumentation().getTargetContext(), PerfTestActivity.class);
+
+        public PerfTestActivityRuleBase() {
+            this(false /* launchActivity */);
+        }
+
+        public PerfTestActivityRuleBase(boolean launchActivity) {
+            super(PerfTestActivity.class, false /* initialTouchMode */, launchActivity);
+        }
+
+        @Override
+        public Intent getActivityIntent() {
+            return mStartIntent;
+        }
+
+        public PerfTestActivity launchActivity() {
+            return launchActivity(mStartIntent);
+        }
+    }
+}
diff --git a/apct-tests/perftests/windowmanager/OWNERS b/apct-tests/perftests/windowmanager/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/apct-tests/perftests/windowmanager/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/InternalWindowOperationPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/InternalWindowOperationPerfTest.java
index 5c09ec2..bccef53 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/InternalWindowOperationPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/InternalWindowOperationPerfTest.java
@@ -18,7 +18,6 @@
 
 import static android.perftests.utils.ManualBenchmarkState.StatsReport;
 
-import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
 import android.perftests.utils.ManualBenchmarkState;
 import android.perftests.utils.ManualBenchmarkState.ManualBenchmarkTest;
@@ -37,7 +36,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.util.concurrent.TimeUnit;
 
 /** Measure the performance of internal methods in window manager service by trace tag. */
 @LargeTest
@@ -85,7 +83,7 @@
 
         while (state.keepRunning(measuredTimeNs)) {
             if (!mIsTraceStarted && !mIsProfiling && !state.isWarmingUp()) {
-                startAsyncAtrace();
+                startAsyncAtrace("wm");
                 mIsTraceStarted = true;
             }
             final long startTime = SystemClock.elapsedRealtimeNanos();
@@ -108,15 +106,8 @@
         Log.i(TAG, String.valueOf(mTraceMarkParser));
     }
 
-    private void startAsyncAtrace() throws IOException {
-        sUiAutomation.executeShellCommand("atrace -b 32768 --async_start wm");
-        // Avoid atrace isn't ready immediately.
-        SystemClock.sleep(TimeUnit.NANOSECONDS.toMillis(TIME_1_S_IN_NS));
-    }
-
     private void stopAsyncAtrace() {
-        final ParcelFileDescriptor pfd = sUiAutomation.executeShellCommand("atrace --async_stop");
-        final InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+        final InputStream inputStream = stopAsyncAtraceWithStream();
         try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
             String line;
             while ((line = reader.readLine()) != null) {
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java
index 833cc0f..2aea61f 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/RecentsAnimationPerfTest.java
@@ -96,7 +96,7 @@
     @BeforeClass
     public static void setUpClass() {
         // Get the permission to invoke startRecentsActivity.
-        sUiAutomation.adoptShellPermissionIdentity();
+        getUiAutomation().adoptShellPermissionIdentity();
 
         final Context context = getInstrumentation().getContext();
         final PackageManager pm = context.getPackageManager();
@@ -129,7 +129,7 @@
             ActivityManager.resumeAppSwitches();
         } catch (RemoteException ignored) {
         }
-        sUiAutomation.dropShellPermissionIdentity();
+        getUiAutomation().dropShellPermissionIdentity();
     }
 
     @Before
@@ -233,7 +233,7 @@
 
             // Ensure the animation callback is done.
             Assume.assumeTrue(recentsSemaphore.tryAcquire(
-                    sIsProfilingMethod ? 10 * TIME_5_S_IN_NS : TIME_5_S_IN_NS,
+                    sIsProfilingMethod() ? 10 * TIME_5_S_IN_NS : TIME_5_S_IN_NS,
                     TimeUnit.NANOSECONDS));
         }
     }
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java
index 2960603..9403e8b 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java
@@ -54,12 +54,12 @@
     @BeforeClass
     public static void setUpClass() {
         // Get the permission to use most window types.
-        sUiAutomation.adoptShellPermissionIdentity();
+        getUiAutomation().adoptShellPermissionIdentity();
     }
 
     @AfterClass
     public static void tearDownClass() {
-        sUiAutomation.dropShellPermissionIdentity();
+        getUiAutomation().dropShellPermissionIdentity();
     }
 
     /** The last customized iterations will provide the information of method profiling. */
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
index b51a9a8..4b1982f 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
@@ -19,36 +19,21 @@
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import android.app.Activity;
-import android.app.KeyguardManager;
-import android.app.UiAutomation;
-import android.content.Context;
 import android.content.Intent;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
 import android.perftests.utils.PerfTestActivity;
+import android.perftests.utils.WindowPerfTestBase;
 
-import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.lifecycle.ActivityLifecycleCallback;
 import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
 import androidx.test.runner.lifecycle.Stage;
 
-import org.junit.After;
-import org.junit.BeforeClass;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Objects;
 import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
 
-public class WindowManagerPerfTestBase {
-    static final UiAutomation sUiAutomation = getInstrumentation().getUiAutomation();
-    static final long NANOS_PER_S = 1000L * 1000 * 1000;
-    static final long TIME_1_S_IN_NS = 1 * NANOS_PER_S;
+public class WindowManagerPerfTestBase extends WindowPerfTestBase {
     static final long TIME_5_S_IN_NS = 5 * NANOS_PER_S;
 
     /**
@@ -58,121 +43,21 @@
      */
     static final File BASE_OUT_PATH = new File("/data/local/tmp/WmPerfTests");
 
-    static boolean sIsProfilingMethod;
-
-    @BeforeClass
-    public static void setUpOnce() {
-        final Context context = getInstrumentation().getContext();
-
-        if (!context.getSystemService(PowerManager.class).isInteractive()
-                || context.getSystemService(KeyguardManager.class).isKeyguardLocked()) {
-            executeShellCommand("input keyevent KEYCODE_WAKEUP");
-            executeShellCommand("wm dismiss-keyguard");
-        }
-        context.startActivity(new Intent(Intent.ACTION_MAIN)
-                .addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
-    }
-
-    @After
-    public void tearDown() {
-        // Make sure that profiling is stopped if test fails.
-        if (sIsProfilingMethod) {
-            stopProfiling();
-        }
+    static void startProfiling(String outFileName) {
+        startProfiling(BASE_OUT_PATH, outFileName);
     }
 
     /**
-     * Executes shell command with reading the output. It may also used to block until the current
-     * command is completed.
+     * Provides an activity that is able to wait for a stable lifecycle stage.
      */
-    static ByteArrayOutputStream executeShellCommand(String command) {
-        final ParcelFileDescriptor pfd = sUiAutomation.executeShellCommand(command);
-        final byte[] buf = new byte[512];
-        final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-        int bytesRead;
-        try (FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
-            while ((bytesRead = fis.read(buf)) != -1) {
-                bytes.write(buf, 0, bytesRead);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-        return bytes;
-    }
-
-    /** Starts method tracing on system server. */
-    static void startProfiling(String subPath) {
-        if (!BASE_OUT_PATH.exists()) {
-            executeShellCommand("mkdir -p " + BASE_OUT_PATH);
-        }
-        final String samplingArg = WmPerfRunListener.sSamplingIntervalUs > 0
-                ? ("--sampling " + WmPerfRunListener.sSamplingIntervalUs)
-                : "";
-        executeShellCommand("am profile start " + samplingArg + " system "
-                + new File(BASE_OUT_PATH, subPath));
-        sIsProfilingMethod = true;
-    }
-
-    static void stopProfiling() {
-        executeShellCommand("am profile stop system");
-        sIsProfilingMethod = false;
-    }
-
-    /** Returns how many iterations should run with method tracing. */
-    static int getProfilingIterations() {
-        return WmPerfRunListener.sProfilingIterations;
-    }
-
-    static void runWithShellPermissionIdentity(Runnable runnable) {
-        sUiAutomation.adoptShellPermissionIdentity();
-        try {
-            runnable.run();
-        } finally {
-            sUiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    static class SettingsSession<T> implements AutoCloseable {
-        private final Consumer<T> mSetter;
-        private final T mOriginalValue;
-        private boolean mChanged;
-
-        SettingsSession(T originalValue, Consumer<T> setter) {
-            mOriginalValue = originalValue;
-            mSetter = setter;
-        }
-
-        void set(T value) {
-            if (Objects.equals(value, mOriginalValue)) {
-                mChanged = false;
-                return;
-            }
-            mSetter.accept(value);
-            mChanged = true;
-        }
-
-        @Override
-        public void close() {
-            if (mChanged) {
-                mSetter.accept(mOriginalValue);
-            }
-        }
-    }
-
-    /**
-     * Provides an activity that keeps screen on and is able to wait for a stable lifecycle stage.
-     */
-    static class PerfTestActivityRule extends ActivityTestRule<PerfTestActivity> {
-        private final Intent mStartIntent =
-                new Intent(getInstrumentation().getTargetContext(), PerfTestActivity.class);
+    static class PerfTestActivityRule extends PerfTestActivityRuleBase {
         private final LifecycleListener mLifecycleListener = new LifecycleListener();
 
         PerfTestActivityRule() {
-            this(false /* launchActivity */);
         }
 
         PerfTestActivityRule(boolean launchActivity) {
-            super(PerfTestActivity.class, false /* initialTouchMode */, launchActivity);
+            super(launchActivity);
         }
 
         @Override
@@ -191,21 +76,12 @@
         }
 
         @Override
-        protected Intent getActivityIntent() {
-            return mStartIntent;
-        }
-
-        @Override
         public PerfTestActivity launchActivity(Intent intent) {
             final PerfTestActivity activity = super.launchActivity(intent);
             mLifecycleListener.setTargetActivity(activity);
             return activity;
         }
 
-        PerfTestActivity launchActivity() {
-            return launchActivity(mStartIntent);
-        }
-
         void waitForIdleSync(Stage state) {
             mLifecycleListener.waitForIdleSync(state);
         }
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java b/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java
index a9d5716..2b0801a 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/WmPerfRunListener.java
@@ -16,138 +16,8 @@
 
 package android.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.wm.WindowManagerPerfTestBase.executeShellCommand;
-import static android.wm.WindowManagerPerfTestBase.runWithShellPermissionIdentity;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningAppProcessInfo;
-import android.app.ActivityTaskManager;
-import android.content.Context;
-import android.os.BatteryManager;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.WindowManagerPolicyConstants;
-import android.wm.WindowManagerPerfTestBase.SettingsSession;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.internal.policy.PhoneWindow;
-
-import org.junit.runner.Description;
-import org.junit.runner.Result;
-import org.junit.runner.notification.RunListener;
-
-import java.util.List;
+import android.perftests.utils.WindowPerfRunPreconditionBase;
 
 /** Prepare the preconditions before running performance test. */
-public class WmPerfRunListener extends RunListener {
-    private static final String TAG = WmPerfRunListener.class.getSimpleName();
-
-    private static final String ARGUMENT_LOG_ONLY = "log";
-    private static final String ARGUMENT_KILL_BACKGROUND = "kill-bg";
-    private static final String ARGUMENT_PROFILING_ITERATIONS = "profiling-iterations";
-    private static final String ARGUMENT_PROFILING_SAMPLING = "profiling-sampling";
-    private static final String DEFAULT_PROFILING_ITERATIONS = "0";
-    private static final String DEFAULT_PROFILING_SAMPLING_US = "10";
-    private static final long KILL_BACKGROUND_WAIT_MS = 3000;
-
-    /** The requested iterations to run with method profiling. */
-    static int sProfilingIterations;
-
-    /** The interval of sample profiling in microseconds. */
-    static int sSamplingIntervalUs;
-
-    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
-    private long mWaitPreconditionDoneMs = 500;
-
-    private final SettingsSession<Integer> mStayOnWhilePluggedInSetting = new SettingsSession<>(
-            Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0),
-            value -> executeShellCommand(String.format("settings put global %s %d",
-                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN, value)));
-
-    private final SettingsSession<Integer> mNavigationModeSetting = new SettingsSession<>(
-            mContext.getResources().getInteger(
-                    com.android.internal.R.integer.config_navBarInteractionMode),
-            value -> {
-                final String navOverlay;
-                switch (value) {
-                    case WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON:
-                        navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
-                        break;
-                    case WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON:
-                        navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
-                        break;
-                    case WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL:
-                    default:
-                        navOverlay = WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
-                        break;
-                }
-                executeShellCommand("cmd overlay enable-exclusive " + navOverlay);
-            });
-
-    /** It only executes once before all tests. */
-    @Override
-    public void testRunStarted(Description description) {
-        final Bundle arguments = InstrumentationRegistry.getArguments();
-        // If true, it only logs the method names without running.
-        final boolean skip = Boolean.parseBoolean(arguments.getString(ARGUMENT_LOG_ONLY, "false"));
-        Log.i(TAG, "arguments=" + arguments);
-        if (skip) {
-            return;
-        }
-        sProfilingIterations = Integer.parseInt(
-                arguments.getString(ARGUMENT_PROFILING_ITERATIONS, DEFAULT_PROFILING_ITERATIONS));
-        sSamplingIntervalUs = Integer.parseInt(
-                arguments.getString(ARGUMENT_PROFILING_SAMPLING, DEFAULT_PROFILING_SAMPLING_US));
-
-        // Use gesture navigation for consistency.
-        mNavigationModeSetting.set(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL);
-        // Keep the device awake during testing.
-        mStayOnWhilePluggedInSetting.set(BatteryManager.BATTERY_PLUGGED_ANY);
-
-        runWithShellPermissionIdentity(() -> {
-            final ActivityTaskManager atm = mContext.getSystemService(ActivityTaskManager.class);
-            atm.removeAllVisibleRecentTasks();
-            atm.removeRootTasksWithActivityTypes(new int[] { ACTIVITY_TYPE_STANDARD,
-                    ACTIVITY_TYPE_ASSISTANT, ACTIVITY_TYPE_RECENTS, ACTIVITY_TYPE_UNDEFINED });
-        });
-        PhoneWindow.sendCloseSystemWindows(mContext, "WmPerfTests");
-
-        if (Boolean.parseBoolean(arguments.getString(ARGUMENT_KILL_BACKGROUND))) {
-            runWithShellPermissionIdentity(this::killBackgroundProcesses);
-            mWaitPreconditionDoneMs = KILL_BACKGROUND_WAIT_MS;
-        }
-        // Wait a while for the precondition setup to complete.
-        SystemClock.sleep(mWaitPreconditionDoneMs);
-    }
-
-    private void killBackgroundProcesses() {
-        final ActivityManager am = mContext.getSystemService(ActivityManager.class);
-        final List<RunningAppProcessInfo> processes = am.getRunningAppProcesses();
-        if (processes == null) {
-            return;
-        }
-        for (RunningAppProcessInfo processInfo : processes) {
-            if (processInfo.importanceReasonCode == RunningAppProcessInfo.REASON_UNKNOWN
-                    && processInfo.importance > RunningAppProcessInfo.IMPORTANCE_SERVICE) {
-                for (String pkg : processInfo.pkgList) {
-                    am.forceStopPackage(pkg);
-                }
-            }
-        }
-    }
-
-    /** It only executes once after all tests. */
-    @Override
-    public void testRunFinished(Result result) {
-        mNavigationModeSetting.close();
-        mStayOnWhilePluggedInSetting.close();
-    }
+public class WmPerfRunListener extends WindowPerfRunPreconditionBase {
 }
diff --git a/apex/Android.bp b/apex/Android.bp
index 0a535a8..4e80acb 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -15,6 +15,7 @@
 mainline_stubs_args =
     "--error UnhiddenSystemApi " +
     "--hide BroadcastBehavior " +
+    "--hide CallbackInterface " +
     "--hide DeprecationMismatch " +
     "--hide HiddenSuperclass " +
     "--hide HiddenTypedefConstant " +
diff --git a/apex/appsearch/OWNERS b/apex/appsearch/OWNERS
new file mode 100644
index 0000000..ce0c212
--- /dev/null
+++ b/apex/appsearch/OWNERS
@@ -0,0 +1 @@
+sudheersai@google.com
diff --git a/apex/appsearch/framework/api/current.txt b/apex/appsearch/framework/api/current.txt
index 2be873c..380c646 100644
--- a/apex/appsearch/framework/api/current.txt
+++ b/apex/appsearch/framework/api/current.txt
@@ -1,6 +1,27 @@
 // Signature format: 2.0
 package android.app.appsearch {
 
+  public final class AppSearchBatchResult<KeyType, ValueType> {
+    method @NonNull public java.util.Map<KeyType,android.app.appsearch.AppSearchResult<ValueType>> getFailures();
+    method @NonNull public java.util.Map<KeyType,ValueType> getSuccesses();
+    method public boolean isSuccess();
+  }
+
+  public final class AppSearchResult<ValueType> {
+    method @Nullable public String getErrorMessage();
+    method public int getResultCode();
+    method @Nullable public ValueType getResultValue();
+    method public boolean isSuccess();
+    field public static final int RESULT_INTERNAL_ERROR = 2; // 0x2
+    field public static final int RESULT_INVALID_ARGUMENT = 3; // 0x3
+    field public static final int RESULT_INVALID_SCHEMA = 7; // 0x7
+    field public static final int RESULT_IO_ERROR = 4; // 0x4
+    field public static final int RESULT_NOT_FOUND = 6; // 0x6
+    field public static final int RESULT_OK = 0; // 0x0
+    field public static final int RESULT_OUT_OF_SPACE = 5; // 0x5
+    field public static final int RESULT_UNKNOWN_ERROR = 1; // 0x1
+  }
+
   public final class AppSearchSchema {
     method @NonNull public java.util.List<android.app.appsearch.AppSearchSchema.PropertyConfig> getProperties();
     method @NonNull public String getSchemaType();
@@ -85,6 +106,43 @@
     method @NonNull public BuilderType setTtlMillis(long);
   }
 
+  public final class GetByUriRequest {
+    method @NonNull public String getNamespace();
+    method @NonNull public java.util.Set<java.lang.String> getUris();
+  }
+
+  public static final class GetByUriRequest.Builder {
+    ctor public GetByUriRequest.Builder();
+    method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUri(@NonNull java.lang.String...);
+    method @NonNull public android.app.appsearch.GetByUriRequest.Builder addUri(@NonNull java.util.Collection<java.lang.String>);
+    method @NonNull public android.app.appsearch.GetByUriRequest build();
+    method @NonNull public android.app.appsearch.GetByUriRequest.Builder setNamespace(@NonNull String);
+  }
+
+  public final class PutDocumentsRequest {
+    method @NonNull public java.util.List<android.app.appsearch.GenericDocument> getDocuments();
+  }
+
+  public static final class PutDocumentsRequest.Builder {
+    ctor public PutDocumentsRequest.Builder();
+    method @NonNull public android.app.appsearch.PutDocumentsRequest.Builder addGenericDocument(@NonNull android.app.appsearch.GenericDocument...);
+    method @NonNull public android.app.appsearch.PutDocumentsRequest.Builder addGenericDocument(@NonNull java.util.Collection<android.app.appsearch.GenericDocument>);
+    method @NonNull public android.app.appsearch.PutDocumentsRequest build();
+  }
+
+  public final class RemoveByUriRequest {
+    method @NonNull public String getNamespace();
+    method @NonNull public java.util.Set<java.lang.String> getUris();
+  }
+
+  public static final class RemoveByUriRequest.Builder {
+    ctor public RemoveByUriRequest.Builder();
+    method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder addUri(@NonNull java.lang.String...);
+    method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder addUri(@NonNull java.util.Collection<java.lang.String>);
+    method @NonNull public android.app.appsearch.RemoveByUriRequest build();
+    method @NonNull public android.app.appsearch.RemoveByUriRequest.Builder setNamespace(@NonNull String);
+  }
+
   public final class SearchResult {
     method @NonNull public android.app.appsearch.GenericDocument getDocument();
     method @NonNull public java.util.List<android.app.appsearch.SearchResult.MatchInfo> getMatches();
@@ -139,5 +197,18 @@
     method @NonNull public android.app.appsearch.SearchSpec.Builder setTermMatch(int);
   }
 
+  public final class SetSchemaRequest {
+    method @NonNull public java.util.Set<android.app.appsearch.AppSearchSchema> getSchemas();
+    method public boolean isForceOverride();
+  }
+
+  public static final class SetSchemaRequest.Builder {
+    ctor public SetSchemaRequest.Builder();
+    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchema(@NonNull android.app.appsearch.AppSearchSchema...);
+    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder addSchema(@NonNull java.util.Collection<android.app.appsearch.AppSearchSchema>);
+    method @NonNull public android.app.appsearch.SetSchemaRequest build();
+    method @NonNull public android.app.appsearch.SetSchemaRequest.Builder setForceOverride(boolean);
+  }
+
 }
 
diff --git a/apex/appsearch/framework/java/android/app/TEST_MAPPING b/apex/appsearch/framework/java/TEST_MAPPING
similarity index 100%
rename from apex/appsearch/framework/java/android/app/TEST_MAPPING
rename to apex/appsearch/framework/java/TEST_MAPPING
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
index 98daa66..97cfe36 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java
@@ -33,7 +33,6 @@
  *
  * @param <KeyType> The type of the keys for {@link #getSuccesses} and {@link #getFailures}.
  * @param <ValueType> The type of result objects associated with the keys.
- * @hide
  */
 public final class AppSearchBatchResult<KeyType, ValueType> implements Parcelable {
     @NonNull private final Map<KeyType, ValueType> mSuccesses;
@@ -51,6 +50,7 @@
         mFailures = Collections.unmodifiableMap(in.readHashMap(/*loader=*/ null));
     }
 
+    /** @hide */
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeMap(mSuccesses);
@@ -100,11 +100,14 @@
         return "{\n  successes: " + mSuccesses + "\n  failures: " + mFailures + "\n}";
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /** @hide */
+    @NonNull
     public static final Creator<AppSearchBatchResult> CREATOR =
             new Creator<AppSearchBatchResult>() {
         @NonNull
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
index 5fd45ea..442ca7b 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java
@@ -224,7 +224,11 @@
         }
         AndroidFuture<AppSearchResult> future = new AndroidFuture<>();
         try {
-            mService.setSchema(DEFAULT_DATABASE_NAME, schemaBundles, request.isForceOverride(),
+            mService.setSchema(
+                    DEFAULT_DATABASE_NAME,
+                    schemaBundles,
+                    new ArrayList<>(request.getSchemasNotPlatformSurfaceable()),
+                    request.isForceOverride(),
                     new IAppSearchResultCallback.Stub() {
                         public void onResult(AppSearchResult result) {
                             future.complete(result);
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
index 6e2ed70..76225e4 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchResult.java
@@ -32,7 +32,6 @@
  * Information about the success or failure of an AppSearch call.
  *
  * @param <ValueType> The type of result object for successful calls.
- * @hide
  */
 public final class AppSearchResult<ValueType> implements Parcelable {
     /**
@@ -107,6 +106,7 @@
         mErrorMessage = in.readString();
     }
 
+    /** @hide */
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(mResultCode);
@@ -181,13 +181,15 @@
         return "[FAILURE(" + mResultCode + ")]: " + mErrorMessage;
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
     }
 
-    public static final Creator<AppSearchResult> CREATOR =
-            new Creator<AppSearchResult>() {
+    /** @hide */
+    @NonNull
+    public static final Creator<AppSearchResult> CREATOR = new Creator<AppSearchResult>() {
         @NonNull
         @Override
         public AppSearchResult createFromParcel(@NonNull Parcel in) {
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java
deleted file mode 100644
index 2db74a8..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright 2020 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.app.appsearch;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.app.appsearch.exceptions.IllegalSchemaException;
-import android.os.Bundle;
-import android.util.ArraySet;
-
-import com.android.internal.util.Preconditions;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * The AppSearch Schema for a particular type of document.
- *
- * <p>For example, an e-mail message or a music recording could be a schema type.
- *
- * <p>The schema consists of type information, properties, and config (like tokenization type).
- *
- * @see AppSearchManager#setSchema
- */
-public final class AppSearchSchema {
-    private static final String SCHEMA_TYPE_FIELD = "schemaType";
-    private static final String PROPERTIES_FIELD = "properties";
-
-    private final Bundle mBundle;
-
-    /** @hide */
-    public AppSearchSchema(@NonNull Bundle bundle) {
-        Preconditions.checkNotNull(bundle);
-        mBundle = bundle;
-    }
-
-    /**
-     * Returns the {@link Bundle} populated by this builder.
-     *
-     * @hide
-     */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    @Override
-    public String toString() {
-        return mBundle.toString();
-    }
-
-    /** Returns the name of this schema type, e.g. Email. */
-    @NonNull
-    public String getSchemaType() {
-        return mBundle.getString(SCHEMA_TYPE_FIELD, "");
-    }
-
-    /**
-     * Returns the list of {@link PropertyConfig}s that are part of this schema.
-     *
-     * <p>This method creates a new list when called.
-     */
-    @NonNull
-    public List<PropertyConfig> getProperties() {
-        ArrayList<Bundle> propertyBundles =
-                mBundle.getParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD);
-        if (propertyBundles.isEmpty()) {
-            return Collections.emptyList();
-        }
-        List<PropertyConfig> ret = new ArrayList<>(propertyBundles.size());
-        for (int i = 0; i < propertyBundles.size(); i++) {
-            ret.add(new PropertyConfig(propertyBundles.get(i)));
-        }
-        return ret;
-    }
-
-    /** Builder for {@link AppSearchSchema objects}. */
-    public static final class Builder {
-        private final String mTypeName;
-        private final ArrayList<Bundle> mPropertyBundles = new ArrayList<>();
-        private final Set<String> mPropertyNames = new ArraySet<>();
-        private boolean mBuilt = false;
-
-        /** Creates a new {@link AppSearchSchema.Builder}. */
-        public Builder(@NonNull String typeName) {
-            Preconditions.checkNotNull(typeName);
-            mTypeName = typeName;
-        }
-
-        /** Adds a property to the given type. */
-        // TODO(b/171360120): MissingGetterMatchingBuilder expects a method called getPropertys, but
-        //  we provide the (correct) method getProperties. Once the bug referenced in this TODO is
-        //  fixed, remove this SuppressLint.
-        @SuppressLint("MissingGetterMatchingBuilder")
-        @NonNull
-        public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(propertyConfig);
-            String name = propertyConfig.getName();
-            if (!mPropertyNames.add(name)) {
-                throw new IllegalSchemaException("Property defined more than once: " + name);
-            }
-            mPropertyBundles.add(propertyConfig.mBundle);
-            return this;
-        }
-
-        /**
-         * Constructs a new {@link AppSearchSchema} from the contents of this builder.
-         *
-         * <p>After calling this method, the builder must no longer be used.
-         */
-        @NonNull
-        public AppSearchSchema build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Bundle bundle = new Bundle();
-            bundle.putString(AppSearchSchema.SCHEMA_TYPE_FIELD, mTypeName);
-            bundle.putParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD, mPropertyBundles);
-            mBuilt = true;
-            return new AppSearchSchema(bundle);
-        }
-    }
-
-    /**
-     * Configuration for a single property (field) of a document type.
-     *
-     * <p>For example, an {@code EmailMessage} would be a type and the {@code subject} would be a
-     * property.
-     */
-    public static final class PropertyConfig {
-        private static final String NAME_FIELD = "name";
-        private static final String DATA_TYPE_FIELD = "dataType";
-        private static final String SCHEMA_TYPE_FIELD = "schemaType";
-        private static final String CARDINALITY_FIELD = "cardinality";
-        private static final String INDEXING_TYPE_FIELD = "indexingType";
-        private static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
-
-        /**
-         * Physical data-types of the contents of the property.
-         *
-         * @hide
-         */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.PropertyConfigProto.DataType.Code.
-        @IntDef(
-                value = {
-                    DATA_TYPE_STRING,
-                    DATA_TYPE_INT64,
-                    DATA_TYPE_DOUBLE,
-                    DATA_TYPE_BOOLEAN,
-                    DATA_TYPE_BYTES,
-                    DATA_TYPE_DOCUMENT,
-                })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface DataType {}
-
-        public static final int DATA_TYPE_STRING = 1;
-        public static final int DATA_TYPE_INT64 = 2;
-        public static final int DATA_TYPE_DOUBLE = 3;
-        public static final int DATA_TYPE_BOOLEAN = 4;
-
-        /** Unstructured BLOB. */
-        public static final int DATA_TYPE_BYTES = 5;
-
-        /**
-         * Indicates that the property is itself a {@link GenericDocument}, making it part of a
-         * hierarchical schema. Any property using this DataType MUST have a valid {@link
-         * PropertyConfig#getSchemaType}.
-         */
-        public static final int DATA_TYPE_DOCUMENT = 6;
-
-        /**
-         * The cardinality of the property (whether it is required, optional or repeated).
-         *
-         * @hide
-         */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.PropertyConfigProto.Cardinality.Code.
-        @IntDef(
-                value = {
-                    CARDINALITY_REPEATED,
-                    CARDINALITY_OPTIONAL,
-                    CARDINALITY_REQUIRED,
-                })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface Cardinality {}
-
-        /** Any number of items (including zero) [0...*]. */
-        public static final int CARDINALITY_REPEATED = 1;
-
-        /** Zero or one value [0,1]. */
-        public static final int CARDINALITY_OPTIONAL = 2;
-
-        /** Exactly one value [1]. */
-        public static final int CARDINALITY_REQUIRED = 3;
-
-        /**
-         * Encapsulates the configurations on how AppSearch should query/index these terms.
-         *
-         * @hide
-         */
-        @IntDef(
-                value = {
-                    INDEXING_TYPE_NONE,
-                    INDEXING_TYPE_EXACT_TERMS,
-                    INDEXING_TYPE_PREFIXES,
-                })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface IndexingType {}
-
-        /**
-         * Content in this property will not be tokenized or indexed.
-         *
-         * <p>Useful if the data type is not made up of terms (e.g. {@link
-         * PropertyConfig#DATA_TYPE_DOCUMENT} or {@link PropertyConfig#DATA_TYPE_BYTES} type). None
-         * of the properties inside the nested property will be indexed regardless of the value of
-         * {@code indexingType} for the nested properties.
-         */
-        public static final int INDEXING_TYPE_NONE = 0;
-
-        /**
-         * Content in this property should only be returned for queries matching the exact tokens
-         * appearing in this property.
-         *
-         * <p>Ex. A property with "fool" should NOT match a query for "foo".
-         */
-        public static final int INDEXING_TYPE_EXACT_TERMS = 1;
-
-        /**
-         * Content in this property should be returned for queries that are either exact matches or
-         * query matches of the tokens appearing in this property.
-         *
-         * <p>Ex. A property with "fool" <b>should</b> match a query for "foo".
-         */
-        public static final int INDEXING_TYPE_PREFIXES = 2;
-
-        /**
-         * Configures how tokens should be extracted from this property.
-         *
-         * @hide
-         */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.IndexingConfig.TokenizerType.Code.
-        @IntDef(
-                value = {
-                    TOKENIZER_TYPE_NONE,
-                    TOKENIZER_TYPE_PLAIN,
-                })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface TokenizerType {}
-
-        /**
-         * It is only valid for tokenizer_type to be 'NONE' if the data type is {@link
-         * PropertyConfig#DATA_TYPE_DOCUMENT}.
-         */
-        public static final int TOKENIZER_TYPE_NONE = 0;
-
-        /** Tokenization for plain text. */
-        public static final int TOKENIZER_TYPE_PLAIN = 1;
-
-        final Bundle mBundle;
-
-        PropertyConfig(@NonNull Bundle bundle) {
-            mBundle = Preconditions.checkNotNull(bundle);
-        }
-
-        @Override
-        public String toString() {
-            return mBundle.toString();
-        }
-
-        /** Returns the name of this property. */
-        @NonNull
-        public String getName() {
-            return mBundle.getString(NAME_FIELD, "");
-        }
-
-        /** Returns the type of data the property contains (e.g. string, int, bytes, etc). */
-        public @DataType int getDataType() {
-            return mBundle.getInt(DATA_TYPE_FIELD, -1);
-        }
-
-        /**
-         * Returns the logical schema-type of the contents of this property.
-         *
-         * <p>Only set when {@link #getDataType} is set to {@link #DATA_TYPE_DOCUMENT}. Otherwise,
-         * it is {@code null}.
-         */
-        @Nullable
-        public String getSchemaType() {
-            return mBundle.getString(SCHEMA_TYPE_FIELD);
-        }
-
-        /**
-         * Returns the cardinality of the property (whether it is optional, required or repeated).
-         */
-        public @Cardinality int getCardinality() {
-            return mBundle.getInt(CARDINALITY_FIELD, -1);
-        }
-
-        /** Returns how the property is indexed. */
-        public @IndexingType int getIndexingType() {
-            return mBundle.getInt(INDEXING_TYPE_FIELD);
-        }
-
-        /** Returns how this property is tokenized (split into words). */
-        public @TokenizerType int getTokenizerType() {
-            return mBundle.getInt(TOKENIZER_TYPE_FIELD);
-        }
-
-        /**
-         * Builder for {@link PropertyConfig}.
-         *
-         * <p>The following properties must be set, or {@link PropertyConfig} construction will
-         * fail:
-         *
-         * <ul>
-         *   <li>dataType
-         *   <li>cardinality
-         * </ul>
-         *
-         * <p>In addition, if {@code schemaType} is {@link #DATA_TYPE_DOCUMENT}, {@code schemaType}
-         * is also required.
-         */
-        public static final class Builder {
-            private final Bundle mBundle = new Bundle();
-            private boolean mBuilt = false;
-
-            /** Creates a new {@link PropertyConfig.Builder}. */
-            public Builder(@NonNull String propertyName) {
-                mBundle.putString(NAME_FIELD, propertyName);
-            }
-
-            /**
-             * Type of data the property contains (e.g. string, int, bytes, etc).
-             *
-             * <p>This property must be set.
-             */
-            @NonNull
-            public PropertyConfig.Builder setDataType(@DataType int dataType) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                Preconditions.checkArgumentInRange(
-                        dataType, DATA_TYPE_STRING, DATA_TYPE_DOCUMENT, "dataType");
-                mBundle.putInt(DATA_TYPE_FIELD, dataType);
-                return this;
-            }
-
-            /**
-             * The logical schema-type of the contents of this property.
-             *
-             * <p>Only required when {@link #setDataType} is set to {@link #DATA_TYPE_DOCUMENT}.
-             * Otherwise, it is ignored.
-             */
-            @NonNull
-            public PropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                Preconditions.checkNotNull(schemaType);
-                mBundle.putString(SCHEMA_TYPE_FIELD, schemaType);
-                return this;
-            }
-
-            /**
-             * The cardinality of the property (whether it is optional, required or repeated).
-             *
-             * <p>This property must be set.
-             */
-            @NonNull
-            public PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                Preconditions.checkArgumentInRange(
-                        cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
-                mBundle.putInt(CARDINALITY_FIELD, cardinality);
-                return this;
-            }
-
-            /**
-             * Configures how a property should be indexed so that it can be retrieved by queries.
-             */
-            @NonNull
-            public PropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                Preconditions.checkArgumentInRange(
-                        indexingType, INDEXING_TYPE_NONE, INDEXING_TYPE_PREFIXES, "indexingType");
-                mBundle.putInt(INDEXING_TYPE_FIELD, indexingType);
-                return this;
-            }
-
-            /** Configures how this property should be tokenized (split into words). */
-            @NonNull
-            public PropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                Preconditions.checkArgumentInRange(
-                        tokenizerType, TOKENIZER_TYPE_NONE, TOKENIZER_TYPE_PLAIN, "tokenizerType");
-                mBundle.putInt(TOKENIZER_TYPE_FIELD, tokenizerType);
-                return this;
-            }
-
-            /**
-             * Constructs a new {@link PropertyConfig} from the contents of this builder.
-             *
-             * <p>After calling this method, the builder must no longer be used.
-             *
-             * @throws IllegalSchemaException If the property is not correctly populated (e.g.
-             *     missing {@code dataType}).
-             */
-            @NonNull
-            public PropertyConfig build() {
-                Preconditions.checkState(!mBuilt, "Builder has already been used");
-                // TODO(b/147692920): Send the schema to Icing Lib for official validation, instead
-                //     of partially reimplementing some of the validation Icing does here.
-                if (!mBundle.containsKey(DATA_TYPE_FIELD)) {
-                    throw new IllegalSchemaException("Missing field: dataType");
-                }
-                if (mBundle.getString(SCHEMA_TYPE_FIELD, "").isEmpty()
-                        && mBundle.getInt(DATA_TYPE_FIELD) == DATA_TYPE_DOCUMENT) {
-                    throw new IllegalSchemaException(
-                            "Missing field: schemaType (required for configs with "
-                                    + "dataType = DOCUMENT)");
-                }
-                if (!mBundle.containsKey(CARDINALITY_FIELD)) {
-                    throw new IllegalSchemaException("Missing field: cardinality");
-                }
-                mBuilt = true;
-                return new PropertyConfig(mBundle);
-            }
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
index 9c7ccea..b7cd4f5 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java
@@ -140,7 +140,11 @@
             schemaBundles.add(schema.getBundle());
         }
         try {
-            mService.setSchema(mDatabaseName, schemaBundles, request.isForceOverride(),
+            mService.setSchema(
+                    mDatabaseName,
+                    schemaBundles,
+                    new ArrayList<>(request.getSchemasNotPlatformSurfaceable()),
+                    request.isForceOverride(),
                     new IAppSearchResultCallback.Stub() {
                         public void onResult(AppSearchResult result) {
                             executor.execute(() -> callback.accept(result));
diff --git a/apex/appsearch/framework/java/android/app/appsearch/GenericDocument.java b/apex/appsearch/framework/java/android/app/appsearch/GenericDocument.java
deleted file mode 100644
index 0056377..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/GenericDocument.java
+++ /dev/null
@@ -1,963 +0,0 @@
-/*
- * Copyright 2020 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.app.appsearch;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.internal.util.Preconditions;
-
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Represents a document unit.
- *
- * <p>Documents are constructed via {@link GenericDocument.Builder}.
- *
- * @see AppSearchManager#putDocuments
- * @see AppSearchManager#getByUri
- * @see AppSearchManager#query
- */
-public class GenericDocument {
-    private static final String TAG = "GenericDocument";
-
-    /** The default empty namespace. */
-    public static final String DEFAULT_NAMESPACE = "";
-
-    /**
-     * The maximum number of elements in a repeatable field. Will reject the request if exceed this
-     * limit.
-     */
-    private static final int MAX_REPEATED_PROPERTY_LENGTH = 100;
-
-    /**
-     * The maximum {@link String#length} of a {@link String} field. Will reject the request if
-     * {@link String}s longer than this.
-     */
-    private static final int MAX_STRING_LENGTH = 20_000;
-
-    /** The maximum number of indexed properties a document can have. */
-    private static final int MAX_INDEXED_PROPERTIES = 16;
-
-    /** The default score of document. */
-    private static final int DEFAULT_SCORE = 0;
-
-    /** The default time-to-live in millisecond of a document, which is infinity. */
-    private static final long DEFAULT_TTL_MILLIS = 0L;
-
-    private static final String PROPERTIES_FIELD = "properties";
-    private static final String BYTE_ARRAY_FIELD = "byteArray";
-    private static final String SCHEMA_TYPE_FIELD = "schemaType";
-    private static final String URI_FIELD = "uri";
-    private static final String SCORE_FIELD = "score";
-    private static final String TTL_MILLIS_FIELD = "ttlMillis";
-    private static final String CREATION_TIMESTAMP_MILLIS_FIELD = "creationTimestampMillis";
-    private static final String NAMESPACE_FIELD = "namespace";
-
-    /**
-     * The maximum number of indexed properties a document can have.
-     *
-     * <p>Indexed properties are properties where the {@link
-     * AppSearchSchema.PropertyConfig#getIndexingType()} constant is anything other than {@link
-     * AppSearchSchema.PropertyConfig.IndexingType#INDEXING_TYPE_NONE}.
-     */
-    public static int getMaxIndexedProperties() {
-        return MAX_INDEXED_PROPERTIES;
-    }
-
-    /** Contains {@link GenericDocument} basic information (uri, schemaType etc). */
-    @NonNull final Bundle mBundle;
-
-    /**
-     * Contains all properties in {@link GenericDocument} to support getting properties via keys.
-     */
-    @NonNull private final Bundle mProperties;
-
-    @NonNull private final String mUri;
-    @NonNull private final String mSchemaType;
-    private final long mCreationTimestampMillis;
-    @Nullable private Integer mHashCode;
-
-    /**
-     * Rebuilds a {@link GenericDocument} by the a bundle.
-     *
-     * @param bundle Contains {@link GenericDocument} basic information (uri, schemaType etc) and a
-     *     properties bundle contains all properties in {@link GenericDocument} to support getting
-     *     properties via keys.
-     * @hide
-     */
-    public GenericDocument(@NonNull Bundle bundle) {
-        Preconditions.checkNotNull(bundle);
-        mBundle = bundle;
-        mProperties = Preconditions.checkNotNull(bundle.getParcelable(PROPERTIES_FIELD));
-        mUri = Preconditions.checkNotNull(mBundle.getString(URI_FIELD));
-        mSchemaType = Preconditions.checkNotNull(mBundle.getString(SCHEMA_TYPE_FIELD));
-        mCreationTimestampMillis =
-                mBundle.getLong(CREATION_TIMESTAMP_MILLIS_FIELD, System.currentTimeMillis());
-    }
-
-    /**
-     * Creates a new {@link GenericDocument} from an existing instance.
-     *
-     * <p>This method should be only used by constructor of a subclass.
-     */
-    protected GenericDocument(@NonNull GenericDocument document) {
-        this(document.mBundle);
-    }
-
-    /**
-     * Returns the {@link Bundle} populated by this builder.
-     *
-     * @hide
-     */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
-    /** Returns the URI of the {@link GenericDocument}. */
-    @NonNull
-    public String getUri() {
-        return mUri;
-    }
-
-    /** Returns the namespace of the {@link GenericDocument}. */
-    @NonNull
-    public String getNamespace() {
-        return mBundle.getString(NAMESPACE_FIELD, DEFAULT_NAMESPACE);
-    }
-
-    /** Returns the schema type of the {@link GenericDocument}. */
-    @NonNull
-    public String getSchemaType() {
-        return mSchemaType;
-    }
-
-    /**
-     * Returns the creation timestamp of the {@link GenericDocument}, in milliseconds.
-     *
-     * <p>The value is in the {@link System#currentTimeMillis} time base.
-     */
-    public long getCreationTimestampMillis() {
-        return mCreationTimestampMillis;
-    }
-
-    /**
-     * Returns the TTL (Time To Live) of the {@link GenericDocument}, in milliseconds.
-     *
-     * <p>The TTL is measured against {@link #getCreationTimestampMillis}. At the timestamp of
-     * {@code creationTimestampMillis + ttlMillis}, measured in the {@link System#currentTimeMillis}
-     * time base, the document will be auto-deleted.
-     *
-     * <p>The default value is 0, which means the document is permanent and won't be auto-deleted
-     * until the app is uninstalled.
-     */
-    public long getTtlMillis() {
-        return mBundle.getLong(TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
-    }
-
-    /**
-     * Returns the score of the {@link GenericDocument}.
-     *
-     * <p>The score is a query-independent measure of the document's quality, relative to other
-     * {@link GenericDocument}s of the same type.
-     *
-     * <p>Results may be sorted by score using {@link SearchSpec.Builder#setRankingStrategy}.
-     * Documents with higher scores are considered better than documents with lower scores.
-     *
-     * <p>Any nonnegative integer can be used a score.
-     */
-    public int getScore() {
-        return mBundle.getInt(SCORE_FIELD, DEFAULT_SCORE);
-    }
-
-    /** Returns the names of all properties defined in this document. */
-    @NonNull
-    public Set<String> getPropertyNames() {
-        return Collections.unmodifiableSet(mProperties.keySet());
-    }
-
-    /**
-     * Retrieves a {@link String} value by key.
-     *
-     * @param key The key to look for.
-     * @return The first {@link String} associated with the given key or {@code null} if there is no
-     *     such key or the value is of a different type.
-     */
-    @Nullable
-    public String getPropertyString(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        String[] propertyArray = getPropertyStringArray(key);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return null;
-        }
-        warnIfSinglePropertyTooLong("String", key, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@code long} value by key.
-     *
-     * @param key The key to look for.
-     * @return The first {@code long} associated with the given key or default value {@code 0} if
-     *     there is no such key or the value is of a different type.
-     */
-    public long getPropertyLong(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        long[] propertyArray = getPropertyLongArray(key);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return 0;
-        }
-        warnIfSinglePropertyTooLong("Long", key, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@code double} value by key.
-     *
-     * @param key The key to look for.
-     * @return The first {@code double} associated with the given key or default value {@code 0.0}
-     *     if there is no such key or the value is of a different type.
-     */
-    public double getPropertyDouble(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        double[] propertyArray = getPropertyDoubleArray(key);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return 0.0;
-        }
-        warnIfSinglePropertyTooLong("Double", key, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@code boolean} value by key.
-     *
-     * @param key The key to look for.
-     * @return The first {@code boolean} associated with the given key or default value {@code
-     *     false} if there is no such key or the value is of a different type.
-     */
-    public boolean getPropertyBoolean(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        boolean[] propertyArray = getPropertyBooleanArray(key);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return false;
-        }
-        warnIfSinglePropertyTooLong("Boolean", key, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@code byte[]} value by key.
-     *
-     * @param key The key to look for.
-     * @return The first {@code byte[]} associated with the given key or {@code null} if there is no
-     *     such key or the value is of a different type.
-     */
-    @Nullable
-    public byte[] getPropertyBytes(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        byte[][] propertyArray = getPropertyBytesArray(key);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return null;
-        }
-        warnIfSinglePropertyTooLong("ByteArray", key, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /**
-     * Retrieves a {@link GenericDocument} value by key.
-     *
-     * @param key The key to look for.
-     * @return The first {@link GenericDocument} associated with the given key or {@code null} if
-     *     there is no such key or the value is of a different type.
-     */
-    @Nullable
-    public GenericDocument getPropertyDocument(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        GenericDocument[] propertyArray = getPropertyDocumentArray(key);
-        if (propertyArray == null || propertyArray.length == 0) {
-            return null;
-        }
-        warnIfSinglePropertyTooLong("Document", key, propertyArray.length);
-        return propertyArray[0];
-    }
-
-    /** Prints a warning to logcat if the given propertyLength is greater than 1. */
-    private static void warnIfSinglePropertyTooLong(
-            @NonNull String propertyType, @NonNull String key, int propertyLength) {
-        if (propertyLength > 1) {
-            Log.w(
-                    TAG,
-                    "The value for \""
-                            + key
-                            + "\" contains "
-                            + propertyLength
-                            + " elements. Only the first one will be returned from "
-                            + "getProperty"
-                            + propertyType
-                            + "(). Try getProperty"
-                            + propertyType
-                            + "Array().");
-        }
-    }
-
-    /**
-     * Retrieves a repeated {@code String} property by key.
-     *
-     * @param key The key to look for.
-     * @return The {@code String[]} associated with the given key, or {@code null} if no value is
-     *     set or the value is of a different type.
-     */
-    @Nullable
-    public String[] getPropertyStringArray(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        return getAndCastPropertyArray(key, String[].class);
-    }
-
-    /**
-     * Retrieves a repeated {@link String} property by key.
-     *
-     * @param key The key to look for.
-     * @return The {@code long[]} associated with the given key, or {@code null} if no value is set
-     *     or the value is of a different type.
-     */
-    @Nullable
-    public long[] getPropertyLongArray(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        return getAndCastPropertyArray(key, long[].class);
-    }
-
-    /**
-     * Retrieves a repeated {@code double} property by key.
-     *
-     * @param key The key to look for.
-     * @return The {@code double[]} associated with the given key, or {@code null} if no value is
-     *     set or the value is of a different type.
-     */
-    @Nullable
-    public double[] getPropertyDoubleArray(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        return getAndCastPropertyArray(key, double[].class);
-    }
-
-    /**
-     * Retrieves a repeated {@code boolean} property by key.
-     *
-     * @param key The key to look for.
-     * @return The {@code boolean[]} associated with the given key, or {@code null} if no value is
-     *     set or the value is of a different type.
-     */
-    @Nullable
-    public boolean[] getPropertyBooleanArray(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        return getAndCastPropertyArray(key, boolean[].class);
-    }
-
-    /**
-     * Retrieves a {@code byte[][]} property by key.
-     *
-     * @param key The key to look for.
-     * @return The {@code byte[][]} associated with the given key, or {@code null} if no value is
-     *     set or the value is of a different type.
-     */
-    @SuppressLint("ArrayReturn")
-    @Nullable
-    @SuppressWarnings("unchecked")
-    public byte[][] getPropertyBytesArray(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        ArrayList<Bundle> bundles = getAndCastPropertyArray(key, ArrayList.class);
-        if (bundles == null || bundles.size() == 0) {
-            return null;
-        }
-        byte[][] bytes = new byte[bundles.size()][];
-        for (int i = 0; i < bundles.size(); i++) {
-            Bundle bundle = bundles.get(i);
-            if (bundle == null) {
-                Log.e(TAG, "The inner bundle is null at " + i + ", for key: " + key);
-                continue;
-            }
-            byte[] innerBytes = bundle.getByteArray(BYTE_ARRAY_FIELD);
-            if (innerBytes == null) {
-                Log.e(TAG, "The bundle at " + i + " contains a null byte[].");
-                continue;
-            }
-            bytes[i] = innerBytes;
-        }
-        return bytes;
-    }
-
-    /**
-     * Retrieves a repeated {@link GenericDocument} property by key.
-     *
-     * @param key The key to look for.
-     * @return The {@link GenericDocument}[] associated with the given key, or {@code null} if no
-     *     value is set or the value is of a different type.
-     */
-    @SuppressLint("ArrayReturn")
-    @Nullable
-    public GenericDocument[] getPropertyDocumentArray(@NonNull String key) {
-        Preconditions.checkNotNull(key);
-        Bundle[] bundles = getAndCastPropertyArray(key, Bundle[].class);
-        if (bundles == null || bundles.length == 0) {
-            return null;
-        }
-        GenericDocument[] documents = new GenericDocument[bundles.length];
-        for (int i = 0; i < bundles.length; i++) {
-            if (bundles[i] == null) {
-                Log.e(TAG, "The inner bundle is null at " + i + ", for key: " + key);
-                continue;
-            }
-            documents[i] = new GenericDocument(bundles[i]);
-        }
-        return documents;
-    }
-
-    /**
-     * Gets a repeated property of the given key, and casts it to the given class type, which must
-     * be an array class type.
-     */
-    @Nullable
-    private <T> T getAndCastPropertyArray(@NonNull String key, @NonNull Class<T> tClass) {
-        Object value = mProperties.get(key);
-        if (value == null) {
-            return null;
-        }
-        try {
-            return tClass.cast(value);
-        } catch (ClassCastException e) {
-            Log.w(TAG, "Error casting to requested type for key \"" + key + "\"", e);
-            return null;
-        }
-    }
-
-    @Override
-    public boolean equals(@Nullable Object other) {
-        if (this == other) {
-            return true;
-        }
-        if (!(other instanceof GenericDocument)) {
-            return false;
-        }
-        GenericDocument otherDocument = (GenericDocument) other;
-        return bundleEquals(this.mBundle, otherDocument.mBundle);
-    }
-
-    /**
-     * Deeply checks whether two bundles are equal.
-     *
-     * <p>Two bundles will be considered equal if they contain the same content.
-     */
-    @SuppressWarnings("unchecked")
-    private static boolean bundleEquals(Bundle one, Bundle two) {
-        if (one.size() != two.size()) {
-            return false;
-        }
-        Set<String> keySetOne = one.keySet();
-        Object valueOne;
-        Object valueTwo;
-        // Bundle inherit its equals() from Object.java, which only compare their memory address.
-        // We should iterate all keys and check their presents and values in both bundle.
-        for (String key : keySetOne) {
-            valueOne = one.get(key);
-            valueTwo = two.get(key);
-            if (valueOne instanceof Bundle
-                    && valueTwo instanceof Bundle
-                    && !bundleEquals((Bundle) valueOne, (Bundle) valueTwo)) {
-                return false;
-            } else if (valueOne == null && (valueTwo != null || !two.containsKey(key))) {
-                // If we call bundle.get(key) when the 'key' doesn't actually exist in the
-                // bundle, we'll get back a null. So make sure that both values are null and
-                // both keys exist in the bundle.
-                return false;
-            } else if (valueOne instanceof boolean[]) {
-                if (!(valueTwo instanceof boolean[])
-                        || !Arrays.equals((boolean[]) valueOne, (boolean[]) valueTwo)) {
-                    return false;
-                }
-            } else if (valueOne instanceof long[]) {
-                if (!(valueTwo instanceof long[])
-                        || !Arrays.equals((long[]) valueOne, (long[]) valueTwo)) {
-                    return false;
-                }
-            } else if (valueOne instanceof double[]) {
-                if (!(valueTwo instanceof double[])
-                        || !Arrays.equals((double[]) valueOne, (double[]) valueTwo)) {
-                    return false;
-                }
-            } else if (valueOne instanceof Bundle[]) {
-                if (!(valueTwo instanceof Bundle[])) {
-                    return false;
-                }
-                Bundle[] bundlesOne = (Bundle[]) valueOne;
-                Bundle[] bundlesTwo = (Bundle[]) valueTwo;
-                if (bundlesOne.length != bundlesTwo.length) {
-                    return false;
-                }
-                for (int i = 0; i < bundlesOne.length; i++) {
-                    if (!bundleEquals(bundlesOne[i], bundlesTwo[i])) {
-                        return false;
-                    }
-                }
-            } else if (valueOne instanceof ArrayList) {
-                if (!(valueTwo instanceof ArrayList)) {
-                    return false;
-                }
-                ArrayList<Bundle> bundlesOne = (ArrayList<Bundle>) valueOne;
-                ArrayList<Bundle> bundlesTwo = (ArrayList<Bundle>) valueTwo;
-                if (bundlesOne.size() != bundlesTwo.size()) {
-                    return false;
-                }
-                for (int i = 0; i < bundlesOne.size(); i++) {
-                    if (!bundleEquals(bundlesOne.get(i), bundlesTwo.get(i))) {
-                        return false;
-                    }
-                }
-            } else if (valueOne instanceof Object[]) {
-                if (!(valueTwo instanceof Object[])
-                        || !Arrays.equals((Object[]) valueOne, (Object[]) valueTwo)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mHashCode == null) {
-            mHashCode = bundleHashCode(mBundle);
-        }
-        return mHashCode;
-    }
-
-    /**
-     * Calculates the hash code for a bundle.
-     *
-     * <p>The hash code is only effected by the contents in the bundle. Bundles will get consistent
-     * hash code if they have same contents.
-     */
-    @SuppressWarnings("unchecked")
-    private static int bundleHashCode(Bundle bundle) {
-        int[] hashCodes = new int[bundle.size()];
-        int i = 0;
-        // Bundle inherit its hashCode() from Object.java, which only relative to their memory
-        // address. Bundle doesn't have an order, so we should iterate all keys and combine
-        // their value's hashcode into an array. And use the hashcode of the array to be
-        // the hashcode of the bundle.
-        for (String key : bundle.keySet()) {
-            Object value = bundle.get(key);
-            if (value instanceof boolean[]) {
-                hashCodes[i++] = Arrays.hashCode((boolean[]) value);
-            } else if (value instanceof long[]) {
-                hashCodes[i++] = Arrays.hashCode((long[]) value);
-            } else if (value instanceof double[]) {
-                hashCodes[i++] = Arrays.hashCode((double[]) value);
-            } else if (value instanceof String[]) {
-                hashCodes[i++] = Arrays.hashCode((Object[]) value);
-            } else if (value instanceof Bundle) {
-                hashCodes[i++] = bundleHashCode((Bundle) value);
-            } else if (value instanceof Bundle[]) {
-                Bundle[] bundles = (Bundle[]) value;
-                int[] innerHashCodes = new int[bundles.length];
-                for (int j = 0; j < innerHashCodes.length; j++) {
-                    innerHashCodes[j] = bundleHashCode(bundles[j]);
-                }
-                hashCodes[i++] = Arrays.hashCode(innerHashCodes);
-            } else if (value instanceof ArrayList) {
-                ArrayList<Bundle> bundles = (ArrayList<Bundle>) value;
-                int[] innerHashCodes = new int[bundles.size()];
-                for (int j = 0; j < innerHashCodes.length; j++) {
-                    innerHashCodes[j] = bundleHashCode(bundles.get(j));
-                }
-                hashCodes[i++] = Arrays.hashCode(innerHashCodes);
-            } else {
-                hashCodes[i++] = value.hashCode();
-            }
-        }
-        return Arrays.hashCode(hashCodes);
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-        return bundleToString(mBundle).toString();
-    }
-
-    @SuppressWarnings("unchecked")
-    private static StringBuilder bundleToString(Bundle bundle) {
-        StringBuilder stringBuilder = new StringBuilder();
-        try {
-            final Set<String> keySet = bundle.keySet();
-            String[] keys = keySet.toArray(new String[0]);
-            // Sort keys to make output deterministic. We need a custom comparator to handle
-            // nulls (arbitrarily putting them first, similar to Comparator.nullsFirst, which is
-            // only available since N).
-            Arrays.sort(
-                    keys,
-                    (@Nullable String s1, @Nullable String s2) -> {
-                        if (s1 == null) {
-                            return s2 == null ? 0 : -1;
-                        } else if (s2 == null) {
-                            return 1;
-                        } else {
-                            return s1.compareTo(s2);
-                        }
-                    });
-            for (String key : keys) {
-                stringBuilder.append("{ key: '").append(key).append("' value: ");
-                Object valueObject = bundle.get(key);
-                if (valueObject == null) {
-                    stringBuilder.append("<null>");
-                } else if (valueObject instanceof Bundle) {
-                    stringBuilder.append(bundleToString((Bundle) valueObject));
-                } else if (valueObject.getClass().isArray()) {
-                    stringBuilder.append("[ ");
-                    for (int i = 0; i < Array.getLength(valueObject); i++) {
-                        Object element = Array.get(valueObject, i);
-                        stringBuilder.append("'");
-                        if (element instanceof Bundle) {
-                            stringBuilder.append(bundleToString((Bundle) element));
-                        } else {
-                            stringBuilder.append(Array.get(valueObject, i));
-                        }
-                        stringBuilder.append("' ");
-                    }
-                    stringBuilder.append("]");
-                } else if (valueObject instanceof ArrayList) {
-                    for (Bundle innerBundle : (ArrayList<Bundle>) valueObject) {
-                        stringBuilder.append(bundleToString(innerBundle));
-                    }
-                } else {
-                    stringBuilder.append(valueObject.toString());
-                }
-                stringBuilder.append(" } ");
-            }
-        } catch (RuntimeException e) {
-            // Catch any exceptions here since corrupt Bundles can throw different types of
-            // exceptions (e.g. b/38445840 & b/68937025).
-            stringBuilder.append("<error>");
-        }
-        return stringBuilder;
-    }
-
-    /**
-     * The builder class for {@link GenericDocument}.
-     *
-     * @param <BuilderType> Type of subclass who extends this.
-     */
-    // This builder is specifically designed to be extended by classes deriving from
-    // GenericDocument.
-    @SuppressLint("StaticFinalBuilder")
-    public static class Builder<BuilderType extends Builder> {
-
-        private final Bundle mProperties = new Bundle();
-        private final Bundle mBundle = new Bundle();
-        private final BuilderType mBuilderTypeInstance;
-        private boolean mBuilt = false;
-
-        /**
-         * Create a new {@link GenericDocument.Builder}.
-         *
-         * @param uri The uri of {@link GenericDocument}.
-         * @param schemaType The schema type of the {@link GenericDocument}. The passed-in {@code
-         *     schemaType} must be defined using {@link AppSearchManager#setSchema} prior to
-         *     inserting a document of this {@code schemaType} into the AppSearch index using {@link
-         *     AppSearchManager#putDocuments}. Otherwise, the document will be rejected by {@link
-         *     AppSearchManager#putDocuments}.
-         */
-        @SuppressWarnings("unchecked")
-        public Builder(@NonNull String uri, @NonNull String schemaType) {
-            Preconditions.checkNotNull(uri);
-            Preconditions.checkNotNull(schemaType);
-            mBuilderTypeInstance = (BuilderType) this;
-            mBundle.putString(GenericDocument.URI_FIELD, uri);
-            mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
-            mBundle.putString(GenericDocument.NAMESPACE_FIELD, DEFAULT_NAMESPACE);
-            // Set current timestamp for creation timestamp by default.
-            mBundle.putLong(
-                    GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, System.currentTimeMillis());
-            mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
-            mBundle.putInt(GenericDocument.SCORE_FIELD, DEFAULT_SCORE);
-            mBundle.putBundle(PROPERTIES_FIELD, mProperties);
-        }
-
-        /**
-         * Sets the app-defined namespace this Document resides in. No special values are reserved
-         * or understood by the infrastructure.
-         *
-         * <p>URIs are unique within a namespace.
-         *
-         * <p>The number of namespaces per app should be kept small for efficiency reasons.
-         */
-        @NonNull
-        public BuilderType setNamespace(@NonNull String namespace) {
-            mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets the score of the {@link GenericDocument}.
-         *
-         * <p>The score is a query-independent measure of the document's quality, relative to other
-         * {@link GenericDocument}s of the same type.
-         *
-         * <p>Results may be sorted by score using {@link SearchSpec.Builder#setRankingStrategy}.
-         * Documents with higher scores are considered better than documents with lower scores.
-         *
-         * <p>Any nonnegative integer can be used a score.
-         *
-         * @throws IllegalArgumentException If the provided value is negative.
-         */
-        @NonNull
-        public BuilderType setScore(@IntRange(from = 0, to = Integer.MAX_VALUE) int score) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            if (score < 0) {
-                throw new IllegalArgumentException("Document score cannot be negative.");
-            }
-            mBundle.putInt(GenericDocument.SCORE_FIELD, score);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets the creation timestamp of the {@link GenericDocument}, in milliseconds.
-         *
-         * <p>Should be set using a value obtained from the {@link System#currentTimeMillis} time
-         * base.
-         */
-        @NonNull
-        public BuilderType setCreationTimestampMillis(long creationTimestampMillis) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putLong(
-                    GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, creationTimestampMillis);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets the TTL (Time To Live) of the {@link GenericDocument}, in milliseconds.
-         *
-         * <p>The TTL is measured against {@link #getCreationTimestampMillis}. At the timestamp of
-         * {@code creationTimestampMillis + ttlMillis}, measured in the {@link
-         * System#currentTimeMillis} time base, the document will be auto-deleted.
-         *
-         * <p>The default value is 0, which means the document is permanent and won't be
-         * auto-deleted until the app is uninstalled.
-         *
-         * @param ttlMillis A non-negative duration in milliseconds.
-         * @throws IllegalArgumentException If the provided value is negative.
-         */
-        @NonNull
-        public BuilderType setTtlMillis(long ttlMillis) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            if (ttlMillis < 0) {
-                throw new IllegalArgumentException("Document ttlMillis cannot be negative.");
-            }
-            mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, ttlMillis);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code String} values for a property, replacing its previous values.
-         *
-         * @param key The key associated with the {@code values}.
-         * @param values The {@code String} values of the property.
-         */
-        @NonNull
-        public BuilderType setPropertyString(@NonNull String key, @NonNull String... values) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(key);
-            Preconditions.checkNotNull(values);
-            putInPropertyBundle(key, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code boolean} values for a property, replacing its previous
-         * values.
-         *
-         * @param key The key associated with the {@code values}.
-         * @param values The {@code boolean} values of the property.
-         */
-        @NonNull
-        public BuilderType setPropertyBoolean(@NonNull String key, @NonNull boolean... values) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(key);
-            Preconditions.checkNotNull(values);
-            putInPropertyBundle(key, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code long} values for a property, replacing its previous values.
-         *
-         * @param key The key associated with the {@code values}.
-         * @param values The {@code long} values of the property.
-         */
-        @NonNull
-        public BuilderType setPropertyLong(@NonNull String key, @NonNull long... values) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(key);
-            Preconditions.checkNotNull(values);
-            putInPropertyBundle(key, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code double} values for a property, replacing its previous values.
-         *
-         * @param key The key associated with the {@code values}.
-         * @param values The {@code double} values of the property.
-         */
-        @NonNull
-        public BuilderType setPropertyDouble(@NonNull String key, @NonNull double... values) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(key);
-            Preconditions.checkNotNull(values);
-            putInPropertyBundle(key, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@code byte[]} for a property, replacing its previous values.
-         *
-         * @param key The key associated with the {@code values}.
-         * @param values The {@code byte[]} of the property.
-         */
-        @NonNull
-        public BuilderType setPropertyBytes(@NonNull String key, @NonNull byte[]... values) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(key);
-            Preconditions.checkNotNull(values);
-            putInPropertyBundle(key, values);
-            return mBuilderTypeInstance;
-        }
-
-        /**
-         * Sets one or multiple {@link GenericDocument} values for a property, replacing its
-         * previous values.
-         *
-         * @param key The key associated with the {@code values}.
-         * @param values The {@link GenericDocument} values of the property.
-         */
-        @NonNull
-        public BuilderType setPropertyDocument(
-                @NonNull String key, @NonNull GenericDocument... values) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(key);
-            Preconditions.checkNotNull(values);
-            putInPropertyBundle(key, values);
-            return mBuilderTypeInstance;
-        }
-
-        private void putInPropertyBundle(@NonNull String key, @NonNull String[] values)
-                throws IllegalArgumentException {
-            validateRepeatedPropertyLength(key, values.length);
-            for (int i = 0; i < values.length; i++) {
-                if (values[i] == null) {
-                    throw new IllegalArgumentException("The String at " + i + " is null.");
-                } else if (values[i].length() > MAX_STRING_LENGTH) {
-                    throw new IllegalArgumentException(
-                            "The String at "
-                                    + i
-                                    + " length is: "
-                                    + values[i].length()
-                                    + ", which exceeds length limit: "
-                                    + MAX_STRING_LENGTH
-                                    + ".");
-                }
-            }
-            mProperties.putStringArray(key, values);
-        }
-
-        private void putInPropertyBundle(@NonNull String key, @NonNull boolean[] values) {
-            validateRepeatedPropertyLength(key, values.length);
-            mProperties.putBooleanArray(key, values);
-        }
-
-        private void putInPropertyBundle(@NonNull String key, @NonNull double[] values) {
-            validateRepeatedPropertyLength(key, values.length);
-            mProperties.putDoubleArray(key, values);
-        }
-
-        private void putInPropertyBundle(@NonNull String key, @NonNull long[] values) {
-            validateRepeatedPropertyLength(key, values.length);
-            mProperties.putLongArray(key, values);
-        }
-
-        /**
-         * Converts and saves a byte[][] into {@link #mProperties}.
-         *
-         * <p>Bundle doesn't support for two dimension array byte[][], we are converting byte[][]
-         * into ArrayList<Bundle>, and each elements will contain a one dimension byte[].
-         */
-        private void putInPropertyBundle(@NonNull String key, @NonNull byte[][] values) {
-            validateRepeatedPropertyLength(key, values.length);
-            ArrayList<Bundle> bundles = new ArrayList<>(values.length);
-            for (int i = 0; i < values.length; i++) {
-                if (values[i] == null) {
-                    throw new IllegalArgumentException("The byte[] at " + i + " is null.");
-                }
-                Bundle bundle = new Bundle();
-                bundle.putByteArray(BYTE_ARRAY_FIELD, values[i]);
-                bundles.add(bundle);
-            }
-            mProperties.putParcelableArrayList(key, bundles);
-        }
-
-        private void putInPropertyBundle(@NonNull String key, @NonNull GenericDocument[] values) {
-            validateRepeatedPropertyLength(key, values.length);
-            Bundle[] documentBundles = new Bundle[values.length];
-            for (int i = 0; i < values.length; i++) {
-                if (values[i] == null) {
-                    throw new IllegalArgumentException("The document at " + i + " is null.");
-                }
-                documentBundles[i] = values[i].mBundle;
-            }
-            mProperties.putParcelableArray(key, documentBundles);
-        }
-
-        private static void validateRepeatedPropertyLength(@NonNull String key, int length) {
-            if (length == 0) {
-                throw new IllegalArgumentException("The input array is empty.");
-            } else if (length > MAX_REPEATED_PROPERTY_LENGTH) {
-                throw new IllegalArgumentException(
-                        "Repeated property \""
-                                + key
-                                + "\" has length "
-                                + length
-                                + ", which exceeds the limit of "
-                                + MAX_REPEATED_PROPERTY_LENGTH);
-            }
-        }
-
-        /** Builds the {@link GenericDocument} object. */
-        @NonNull
-        public GenericDocument build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBuilt = true;
-            return new GenericDocument(mBundle);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/GetByUriRequest.java b/apex/appsearch/framework/java/android/app/appsearch/GetByUriRequest.java
deleted file mode 100644
index 053d401..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/GetByUriRequest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2020 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.app.appsearch;
-
-import android.annotation.NonNull;
-import android.util.ArraySet;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Encapsulates a request to retrieve documents by namespace and URI.
- *
- * @see AppSearchSession#getByUri
- * @hide
- */
-public final class GetByUriRequest {
-    private final String mNamespace;
-    private final Set<String> mUris;
-
-    GetByUriRequest(@NonNull String namespace, @NonNull Set<String> uris) {
-        mNamespace = namespace;
-        mUris = uris;
-    }
-
-    /** Returns the namespace to get documents from. */
-    @NonNull
-    public String getNamespace() {
-        return mNamespace;
-    }
-
-    /** Returns the URIs to get from the namespace. */
-    @NonNull
-    public Set<String> getUris() {
-        return Collections.unmodifiableSet(mUris);
-    }
-
-    /** Builder for {@link GetByUriRequest} objects. */
-    public static final class Builder {
-        private String mNamespace = GenericDocument.DEFAULT_NAMESPACE;
-        private final Set<String> mUris = new ArraySet<>();
-        private boolean mBuilt = false;
-
-        /**
-         * Sets which namespace these documents will be retrieved from.
-         *
-         * <p>If this is not set, it defaults to {@link GenericDocument#DEFAULT_NAMESPACE}.
-         */
-        @NonNull
-        public Builder setNamespace(@NonNull String namespace) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(namespace);
-            mNamespace = namespace;
-            return this;
-        }
-
-        /** Adds one or more URIs to the request. */
-        @NonNull
-        public Builder addUri(@NonNull String... uris) {
-            Preconditions.checkNotNull(uris);
-            return addUri(Arrays.asList(uris));
-        }
-
-        /** Adds one or more URIs to the request. */
-        @NonNull
-        public Builder addUri(@NonNull Collection<String> uris) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(uris);
-            mUris.addAll(uris);
-            return this;
-        }
-
-        /** Builds a new {@link GetByUriRequest}. */
-        @NonNull
-        public GetByUriRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBuilt = true;
-            return new GetByUriRequest(mNamespace, mUris);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
index 22e00f2..1d7cb87 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
+++ b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl
@@ -32,6 +32,8 @@
      *
      * @param databaseName  The databaseName this document resides in.
      * @param schemaBundles List of AppSearchSchema bundles.
+     * @param schemasNotPlatformSurfaceable Schema types that should not be surfaced on platform
+     *     surfaces.
      * @param forceOverride Whether to apply the new schema even if it is incompatible. All
      *     incompatible documents will be deleted.
      * @param callback {@link IAppSearchResultCallback#onResult} will be called with an
@@ -40,6 +42,7 @@
     void setSchema(
         in String databaseName,
         in List<Bundle> schemaBundles,
+        in List<String> schemasNotPlatformSurfaceable,
         boolean forceOverride,
         in IAppSearchResultCallback callback);
 
diff --git a/apex/appsearch/framework/java/android/app/appsearch/PutDocumentsRequest.java b/apex/appsearch/framework/java/android/app/appsearch/PutDocumentsRequest.java
deleted file mode 100644
index 42f1ff2..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/PutDocumentsRequest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2020 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.app.appsearch;
-
-import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.app.appsearch.exceptions.AppSearchException;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Encapsulates a request to index a document into an {@link AppSearchSession} database.
- *
- * @see AppSearchSession#putDocuments
- * @hide
- */
-public final class PutDocumentsRequest {
-    private final List<GenericDocument> mDocuments;
-
-    PutDocumentsRequest(List<GenericDocument> documents) {
-        mDocuments = documents;
-    }
-
-    /** Returns the documents that are part of this request. */
-    @NonNull
-    public List<GenericDocument> getDocuments() {
-        return Collections.unmodifiableList(mDocuments);
-    }
-
-    /** Builder for {@link PutDocumentsRequest} objects. */
-    public static final class Builder {
-        private final List<GenericDocument> mDocuments = new ArrayList<>();
-        private boolean mBuilt = false;
-
-        /** Adds one or more documents to the request. */
-        @SuppressLint("MissingGetterMatchingBuilder") // Merged list available from getDocuments()
-        @NonNull
-        public Builder addGenericDocument(@NonNull GenericDocument... documents) {
-            Preconditions.checkNotNull(documents);
-            return addGenericDocument(Arrays.asList(documents));
-        }
-
-        /** Adds one or more documents to the request. */
-        @SuppressLint("MissingGetterMatchingBuilder") // Merged list available from getDocuments()
-        @NonNull
-        public Builder addGenericDocument(@NonNull Collection<GenericDocument> documents) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(documents);
-            mDocuments.addAll(documents);
-            return this;
-        }
-
-        /** Builds a new {@link PutDocumentsRequest}. */
-        @NonNull
-        public PutDocumentsRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBuilt = true;
-            return new PutDocumentsRequest(mDocuments);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/RemoveByUriRequest.java b/apex/appsearch/framework/java/android/app/appsearch/RemoveByUriRequest.java
deleted file mode 100644
index 3d83c39..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/RemoveByUriRequest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2020 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.app.appsearch;
-
-import android.annotation.NonNull;
-import android.util.ArraySet;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Encapsulates a request to remove documents by namespace and URI.
- *
- * @see AppSearchSession#removeByUri
- * @hide
- */
-public final class RemoveByUriRequest {
-    private final String mNamespace;
-    private final Set<String> mUris;
-
-    RemoveByUriRequest(String namespace, Set<String> uris) {
-        mNamespace = namespace;
-        mUris = uris;
-    }
-
-    /** Returns the namespace to remove documents from. */
-    @NonNull
-    public String getNamespace() {
-        return mNamespace;
-    }
-
-    /** Returns the URIs to remove from the namespace. */
-    @NonNull
-    public Set<String> getUris() {
-        return Collections.unmodifiableSet(mUris);
-    }
-
-    /** Builder for {@link RemoveByUriRequest} objects. */
-    public static final class Builder {
-        private String mNamespace = GenericDocument.DEFAULT_NAMESPACE;
-        private final Set<String> mUris = new ArraySet<>();
-        private boolean mBuilt = false;
-
-        /**
-         * Sets which namespace these documents will be removed from.
-         *
-         * <p>If this is not set, it defaults to {@link GenericDocument#DEFAULT_NAMESPACE}.
-         */
-        @NonNull
-        public Builder setNamespace(@NonNull String namespace) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(namespace);
-            mNamespace = namespace;
-            return this;
-        }
-
-        /** Adds one or more URIs to the request. */
-        @NonNull
-        public Builder addUri(@NonNull String... uris) {
-            Preconditions.checkNotNull(uris);
-            return addUri(Arrays.asList(uris));
-        }
-
-        /** Adds one or more URIs to the request. */
-        @NonNull
-        public Builder addUri(@NonNull Collection<String> uris) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(uris);
-            mUris.addAll(uris);
-            return this;
-        }
-
-        /** Builds a new {@link RemoveByUriRequest}. */
-        @NonNull
-        public RemoveByUriRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBuilt = true;
-            return new RemoveByUriRequest(mNamespace, mUris);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SetSchemaRequest.java b/apex/appsearch/framework/java/android/app/appsearch/SetSchemaRequest.java
deleted file mode 100644
index 3e472fd..0000000
--- a/apex/appsearch/framework/java/android/app/appsearch/SetSchemaRequest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2020 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.app.appsearch;
-
-import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.app.appsearch.exceptions.AppSearchException;
-import android.util.ArraySet;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Encapsulates a request to update the schema of an {@link AppSearchSession} database.
- *
- * @see AppSearchSession#setSchema
- * @hide
- */
-public final class SetSchemaRequest {
-    private final Set<AppSearchSchema> mSchemas;
-    private final boolean mForceOverride;
-
-    SetSchemaRequest(Set<AppSearchSchema> schemas, boolean forceOverride) {
-        mSchemas = schemas;
-        mForceOverride = forceOverride;
-    }
-
-    /** Returns the schemas that are part of this request. */
-    @NonNull
-    public Set<AppSearchSchema> getSchemas() {
-        return mSchemas;
-    }
-
-    /** Returns whether this request will force the schema to be overridden. */
-    public boolean isForceOverride() {
-        return mForceOverride;
-    }
-
-    /** Builder for {@link SetSchemaRequest} objects. */
-    public static final class Builder {
-        private final Set<AppSearchSchema> mSchemas = new ArraySet<>();
-        private boolean mForceOverride = false;
-        private boolean mBuilt = false;
-
-        /** Adds one or more types to the schema. */
-        @NonNull
-        public Builder addSchema(@NonNull AppSearchSchema... schemas) {
-            Preconditions.checkNotNull(schemas);
-            return addSchema(Arrays.asList(schemas));
-        }
-
-        /** Adds one or more types to the schema. */
-        @NonNull
-        public Builder addSchema(@NonNull Collection<AppSearchSchema> schemas) {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            Preconditions.checkNotNull(schemas);
-            mSchemas.addAll(schemas);
-            return this;
-        }
-
-        /**
-         * Configures the {@link SetSchemaRequest} to delete any existing documents that don't
-         * follow the new schema.
-         *
-         * <p>By default, this is {@code false} and schema incompatibility causes the {@link
-         * AppSearchSession#setSchema} call to fail.
-         *
-         * @see AppSearchSession#setSchema
-         */
-        @NonNull
-        public Builder setForceOverride(boolean forceOverride) {
-            mForceOverride = forceOverride;
-            return this;
-        }
-
-        /** Builds a new {@link SetSchemaRequest}. */
-        @NonNull
-        public SetSchemaRequest build() {
-            Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBuilt = true;
-            return new SetSchemaRequest(mSchemas, mForceOverride);
-        }
-    }
-}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchEmail.java
similarity index 100%
rename from apex/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java
rename to apex/appsearch/framework/java/external/android/app/appsearch/AppSearchEmail.java
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
new file mode 100644
index 0000000..62cf38b
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/AppSearchSchema.java
@@ -0,0 +1,491 @@
+/*
+ * Copyright 2020 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.app.appsearch;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.appsearch.exceptions.IllegalSchemaException;
+import android.app.appsearch.util.BundleUtil;
+import android.os.Bundle;
+import android.util.ArraySet;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * The AppSearch Schema for a particular type of document.
+ *
+ * <p>For example, an e-mail message or a music recording could be a schema type.
+ *
+ * <p>The schema consists of type information, properties, and config (like tokenization type).
+ *
+ * @see AppSearchSession#setSchema
+ */
+public final class AppSearchSchema {
+    private static final String SCHEMA_TYPE_FIELD = "schemaType";
+    private static final String PROPERTIES_FIELD = "properties";
+
+    private final Bundle mBundle;
+
+    /** @hide */
+    public AppSearchSchema(@NonNull Bundle bundle) {
+        Preconditions.checkNotNull(bundle);
+        mBundle = bundle;
+    }
+
+    /**
+     * Returns the {@link Bundle} populated by this builder.
+     *
+     * @hide
+     */
+    @NonNull
+    public Bundle getBundle() {
+        return mBundle;
+    }
+
+    @Override
+    public String toString() {
+        return mBundle.toString();
+    }
+
+    /** Returns the name of this schema type, e.g. Email. */
+    @NonNull
+    public String getSchemaType() {
+        return mBundle.getString(SCHEMA_TYPE_FIELD, "");
+    }
+
+    /**
+     * Returns the list of {@link PropertyConfig}s that are part of this schema.
+     *
+     * <p>This method creates a new list when called.
+     */
+    @NonNull
+    public List<PropertyConfig> getProperties() {
+        ArrayList<Bundle> propertyBundles =
+                mBundle.getParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD);
+        if (propertyBundles.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<PropertyConfig> ret = new ArrayList<>(propertyBundles.size());
+        for (int i = 0; i < propertyBundles.size(); i++) {
+            ret.add(new PropertyConfig(propertyBundles.get(i)));
+        }
+        return ret;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof AppSearchSchema)) {
+            return false;
+        }
+        AppSearchSchema otherSchema = (AppSearchSchema) other;
+        if (!getSchemaType().equals(otherSchema.getSchemaType())) {
+            return false;
+        }
+        return getProperties().equals(otherSchema.getProperties());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getSchemaType(), getProperties());
+    }
+
+    /** Builder for {@link AppSearchSchema objects}. */
+    public static final class Builder {
+        private final String mSchemaType;
+        private final ArrayList<Bundle> mPropertyBundles = new ArrayList<>();
+        private final Set<String> mPropertyNames = new ArraySet<>();
+        private boolean mBuilt = false;
+
+        /** Creates a new {@link AppSearchSchema.Builder}. */
+        public Builder(@NonNull String schemaType) {
+            Preconditions.checkNotNull(schemaType);
+            mSchemaType = schemaType;
+        }
+
+        /** Adds a property to the given type. */
+        // TODO(b/171360120): MissingGetterMatchingBuilder expects a method called getPropertys, but
+        //  we provide the (correct) method getProperties. Once the bug referenced in this TODO is
+        //  fixed, remove this SuppressLint.
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(propertyConfig);
+            String name = propertyConfig.getName();
+            if (!mPropertyNames.add(name)) {
+                throw new IllegalSchemaException("Property defined more than once: " + name);
+            }
+            mPropertyBundles.add(propertyConfig.mBundle);
+            return this;
+        }
+
+        /**
+         * Constructs a new {@link AppSearchSchema} from the contents of this builder.
+         *
+         * <p>After calling this method, the builder must no longer be used.
+         */
+        @NonNull
+        public AppSearchSchema build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Bundle bundle = new Bundle();
+            bundle.putString(AppSearchSchema.SCHEMA_TYPE_FIELD, mSchemaType);
+            bundle.putParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD, mPropertyBundles);
+            mBuilt = true;
+            return new AppSearchSchema(bundle);
+        }
+    }
+
+    /**
+     * Configuration for a single property (field) of a document type.
+     *
+     * <p>For example, an {@code EmailMessage} would be a type and the {@code subject} would be a
+     * property.
+     */
+    public static final class PropertyConfig {
+        private static final String NAME_FIELD = "name";
+        private static final String DATA_TYPE_FIELD = "dataType";
+        private static final String SCHEMA_TYPE_FIELD = "schemaType";
+        private static final String CARDINALITY_FIELD = "cardinality";
+        private static final String INDEXING_TYPE_FIELD = "indexingType";
+        private static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
+
+        /**
+         * Physical data-types of the contents of the property.
+         *
+         * @hide
+         */
+        // NOTE: The integer values of these constants must match the proto enum constants in
+        // com.google.android.icing.proto.PropertyConfigProto.DataType.Code.
+        @IntDef(
+                value = {
+                    DATA_TYPE_STRING,
+                    DATA_TYPE_INT64,
+                    DATA_TYPE_DOUBLE,
+                    DATA_TYPE_BOOLEAN,
+                    DATA_TYPE_BYTES,
+                    DATA_TYPE_DOCUMENT,
+                })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface DataType {}
+
+        public static final int DATA_TYPE_STRING = 1;
+        public static final int DATA_TYPE_INT64 = 2;
+        public static final int DATA_TYPE_DOUBLE = 3;
+        public static final int DATA_TYPE_BOOLEAN = 4;
+
+        /** Unstructured BLOB. */
+        public static final int DATA_TYPE_BYTES = 5;
+
+        /**
+         * Indicates that the property is itself a {@link GenericDocument}, making it part of a
+         * hierarchical schema. Any property using this DataType MUST have a valid {@link
+         * PropertyConfig#getSchemaType}.
+         */
+        public static final int DATA_TYPE_DOCUMENT = 6;
+
+        /**
+         * The cardinality of the property (whether it is required, optional or repeated).
+         *
+         * @hide
+         */
+        // NOTE: The integer values of these constants must match the proto enum constants in
+        // com.google.android.icing.proto.PropertyConfigProto.Cardinality.Code.
+        @IntDef(
+                value = {
+                    CARDINALITY_REPEATED,
+                    CARDINALITY_OPTIONAL,
+                    CARDINALITY_REQUIRED,
+                })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Cardinality {}
+
+        /** Any number of items (including zero) [0...*]. */
+        public static final int CARDINALITY_REPEATED = 1;
+
+        /** Zero or one value [0,1]. */
+        public static final int CARDINALITY_OPTIONAL = 2;
+
+        /** Exactly one value [1]. */
+        public static final int CARDINALITY_REQUIRED = 3;
+
+        /**
+         * Encapsulates the configurations on how AppSearch should query/index these terms.
+         *
+         * @hide
+         */
+        @IntDef(
+                value = {
+                    INDEXING_TYPE_NONE,
+                    INDEXING_TYPE_EXACT_TERMS,
+                    INDEXING_TYPE_PREFIXES,
+                })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface IndexingType {}
+
+        /**
+         * Content in this property will not be tokenized or indexed.
+         *
+         * <p>Useful if the data type is not made up of terms (e.g. {@link
+         * PropertyConfig#DATA_TYPE_DOCUMENT} or {@link PropertyConfig#DATA_TYPE_BYTES} type). None
+         * of the properties inside the nested property will be indexed regardless of the value of
+         * {@code indexingType} for the nested properties.
+         */
+        public static final int INDEXING_TYPE_NONE = 0;
+
+        /**
+         * Content in this property should only be returned for queries matching the exact tokens
+         * appearing in this property.
+         *
+         * <p>Ex. A property with "fool" should NOT match a query for "foo".
+         */
+        public static final int INDEXING_TYPE_EXACT_TERMS = 1;
+
+        /**
+         * Content in this property should be returned for queries that are either exact matches or
+         * query matches of the tokens appearing in this property.
+         *
+         * <p>Ex. A property with "fool" <b>should</b> match a query for "foo".
+         */
+        public static final int INDEXING_TYPE_PREFIXES = 2;
+
+        /**
+         * Configures how tokens should be extracted from this property.
+         *
+         * @hide
+         */
+        // NOTE: The integer values of these constants must match the proto enum constants in
+        // com.google.android.icing.proto.IndexingConfig.TokenizerType.Code.
+        @IntDef(
+                value = {
+                    TOKENIZER_TYPE_NONE,
+                    TOKENIZER_TYPE_PLAIN,
+                })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface TokenizerType {}
+
+        /**
+         * It is only valid for tokenizer_type to be 'NONE' if the data type is {@link
+         * PropertyConfig#DATA_TYPE_DOCUMENT}.
+         */
+        public static final int TOKENIZER_TYPE_NONE = 0;
+
+        /** Tokenization for plain text. */
+        public static final int TOKENIZER_TYPE_PLAIN = 1;
+
+        final Bundle mBundle;
+
+        @Nullable private Integer mHashCode;
+
+        PropertyConfig(@NonNull Bundle bundle) {
+            mBundle = Preconditions.checkNotNull(bundle);
+        }
+
+        @Override
+        public String toString() {
+            return mBundle.toString();
+        }
+
+        /** Returns the name of this property. */
+        @NonNull
+        public String getName() {
+            return mBundle.getString(NAME_FIELD, "");
+        }
+
+        /** Returns the type of data the property contains (e.g. string, int, bytes, etc). */
+        public @DataType int getDataType() {
+            return mBundle.getInt(DATA_TYPE_FIELD, -1);
+        }
+
+        /**
+         * Returns the logical schema-type of the contents of this property.
+         *
+         * <p>Only set when {@link #getDataType} is set to {@link #DATA_TYPE_DOCUMENT}. Otherwise,
+         * it is {@code null}.
+         */
+        @Nullable
+        public String getSchemaType() {
+            return mBundle.getString(SCHEMA_TYPE_FIELD);
+        }
+
+        /**
+         * Returns the cardinality of the property (whether it is optional, required or repeated).
+         */
+        public @Cardinality int getCardinality() {
+            return mBundle.getInt(CARDINALITY_FIELD, -1);
+        }
+
+        /** Returns how the property is indexed. */
+        public @IndexingType int getIndexingType() {
+            return mBundle.getInt(INDEXING_TYPE_FIELD);
+        }
+
+        /** Returns how this property is tokenized (split into words). */
+        public @TokenizerType int getTokenizerType() {
+            return mBundle.getInt(TOKENIZER_TYPE_FIELD);
+        }
+
+        @Override
+        public boolean equals(@Nullable Object other) {
+            if (this == other) {
+                return true;
+            }
+            if (!(other instanceof PropertyConfig)) {
+                return false;
+            }
+            PropertyConfig otherProperty = (PropertyConfig) other;
+            return BundleUtil.deepEquals(this.mBundle, otherProperty.mBundle);
+        }
+
+        @Override
+        public int hashCode() {
+            if (mHashCode == null) {
+                mHashCode = BundleUtil.deepHashCode(mBundle);
+            }
+            return mHashCode;
+        }
+
+        /**
+         * Builder for {@link PropertyConfig}.
+         *
+         * <p>The following properties must be set, or {@link PropertyConfig} construction will
+         * fail:
+         *
+         * <ul>
+         *   <li>dataType
+         *   <li>cardinality
+         * </ul>
+         *
+         * <p>In addition, if {@code schemaType} is {@link #DATA_TYPE_DOCUMENT}, {@code schemaType}
+         * is also required.
+         */
+        public static final class Builder {
+            private final Bundle mBundle = new Bundle();
+            private boolean mBuilt = false;
+
+            /** Creates a new {@link PropertyConfig.Builder}. */
+            public Builder(@NonNull String propertyName) {
+                mBundle.putString(NAME_FIELD, propertyName);
+            }
+
+            /**
+             * Type of data the property contains (e.g. string, int, bytes, etc).
+             *
+             * <p>This property must be set.
+             */
+            @NonNull
+            public PropertyConfig.Builder setDataType(@DataType int dataType) {
+                Preconditions.checkState(!mBuilt, "Builder has already been used");
+                Preconditions.checkArgumentInRange(
+                        dataType, DATA_TYPE_STRING, DATA_TYPE_DOCUMENT, "dataType");
+                mBundle.putInt(DATA_TYPE_FIELD, dataType);
+                return this;
+            }
+
+            /**
+             * The logical schema-type of the contents of this property.
+             *
+             * <p>Only required when {@link #setDataType} is set to {@link #DATA_TYPE_DOCUMENT}.
+             * Otherwise, it is ignored.
+             */
+            @NonNull
+            public PropertyConfig.Builder setSchemaType(@NonNull String schemaType) {
+                Preconditions.checkState(!mBuilt, "Builder has already been used");
+                Preconditions.checkNotNull(schemaType);
+                mBundle.putString(SCHEMA_TYPE_FIELD, schemaType);
+                return this;
+            }
+
+            /**
+             * The cardinality of the property (whether it is optional, required or repeated).
+             *
+             * <p>This property must be set.
+             */
+            @NonNull
+            public PropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
+                Preconditions.checkState(!mBuilt, "Builder has already been used");
+                Preconditions.checkArgumentInRange(
+                        cardinality, CARDINALITY_REPEATED, CARDINALITY_REQUIRED, "cardinality");
+                mBundle.putInt(CARDINALITY_FIELD, cardinality);
+                return this;
+            }
+
+            /**
+             * Configures how a property should be indexed so that it can be retrieved by queries.
+             */
+            @NonNull
+            public PropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
+                Preconditions.checkState(!mBuilt, "Builder has already been used");
+                Preconditions.checkArgumentInRange(
+                        indexingType, INDEXING_TYPE_NONE, INDEXING_TYPE_PREFIXES, "indexingType");
+                mBundle.putInt(INDEXING_TYPE_FIELD, indexingType);
+                return this;
+            }
+
+            /** Configures how this property should be tokenized (split into words). */
+            @NonNull
+            public PropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
+                Preconditions.checkState(!mBuilt, "Builder has already been used");
+                Preconditions.checkArgumentInRange(
+                        tokenizerType, TOKENIZER_TYPE_NONE, TOKENIZER_TYPE_PLAIN, "tokenizerType");
+                mBundle.putInt(TOKENIZER_TYPE_FIELD, tokenizerType);
+                return this;
+            }
+
+            /**
+             * Constructs a new {@link PropertyConfig} from the contents of this builder.
+             *
+             * <p>After calling this method, the builder must no longer be used.
+             *
+             * @throws IllegalSchemaException If the property is not correctly populated (e.g.
+             *     missing {@code dataType}).
+             */
+            @NonNull
+            public PropertyConfig build() {
+                Preconditions.checkState(!mBuilt, "Builder has already been used");
+                // TODO(b/147692920): Send the schema to Icing Lib for official validation, instead
+                //     of partially reimplementing some of the validation Icing does here.
+                if (!mBundle.containsKey(DATA_TYPE_FIELD)) {
+                    throw new IllegalSchemaException("Missing field: dataType");
+                }
+                if (mBundle.getString(SCHEMA_TYPE_FIELD, "").isEmpty()
+                        && mBundle.getInt(DATA_TYPE_FIELD) == DATA_TYPE_DOCUMENT) {
+                    throw new IllegalSchemaException(
+                            "Missing field: schemaType (required for configs with "
+                                    + "dataType = DOCUMENT)");
+                }
+                if (!mBundle.containsKey(CARDINALITY_FIELD)) {
+                    throw new IllegalSchemaException("Missing field: cardinality");
+                }
+                mBuilt = true;
+                return new PropertyConfig(mBundle);
+            }
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
new file mode 100644
index 0000000..85207f7
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java
@@ -0,0 +1,837 @@
+/*
+ * Copyright 2020 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.app.appsearch;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.appsearch.exceptions.AppSearchException;
+import android.app.appsearch.util.BundleUtil;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Represents a document unit.
+ *
+ * <p>Documents are constructed via {@link GenericDocument.Builder}.
+ *
+ * @see AppSearchSession#putDocuments
+ * @see AppSearchSession#getByUri
+ * @see AppSearchSession#query
+ */
+public class GenericDocument {
+    private static final String TAG = "AppSearchGenericDocumen";
+
+    /** The default empty namespace. */
+    public static final String DEFAULT_NAMESPACE = "";
+
+    /**
+     * The maximum number of elements in a repeatable field. Will reject the request if exceed this
+     * limit.
+     */
+    private static final int MAX_REPEATED_PROPERTY_LENGTH = 100;
+
+    /**
+     * The maximum {@link String#length} of a {@link String} field. Will reject the request if
+     * {@link String}s longer than this.
+     */
+    private static final int MAX_STRING_LENGTH = 20_000;
+
+    /** The maximum number of indexed properties a document can have. */
+    private static final int MAX_INDEXED_PROPERTIES = 16;
+
+    /** The default score of document. */
+    private static final int DEFAULT_SCORE = 0;
+
+    /** The default time-to-live in millisecond of a document, which is infinity. */
+    private static final long DEFAULT_TTL_MILLIS = 0L;
+
+    private static final String PROPERTIES_FIELD = "properties";
+    private static final String BYTE_ARRAY_FIELD = "byteArray";
+    private static final String SCHEMA_TYPE_FIELD = "schemaType";
+    private static final String URI_FIELD = "uri";
+    private static final String SCORE_FIELD = "score";
+    private static final String TTL_MILLIS_FIELD = "ttlMillis";
+    private static final String CREATION_TIMESTAMP_MILLIS_FIELD = "creationTimestampMillis";
+    private static final String NAMESPACE_FIELD = "namespace";
+
+    /**
+     * The maximum number of indexed properties a document can have.
+     *
+     * <p>Indexed properties are properties where the {@link
+     * AppSearchSchema.PropertyConfig#getIndexingType()} constant is anything other than {@link
+     * AppSearchSchema.PropertyConfig.IndexingType#INDEXING_TYPE_NONE}.
+     */
+    public static int getMaxIndexedProperties() {
+        return MAX_INDEXED_PROPERTIES;
+    }
+
+    /** Contains {@link GenericDocument} basic information (uri, schemaType etc). */
+    @NonNull final Bundle mBundle;
+
+    /**
+     * Contains all properties in {@link GenericDocument} to support getting properties via keys.
+     */
+    @NonNull private final Bundle mProperties;
+
+    @NonNull private final String mUri;
+    @NonNull private final String mSchemaType;
+    private final long mCreationTimestampMillis;
+    @Nullable private Integer mHashCode;
+
+    /**
+     * Rebuilds a {@link GenericDocument} by the a bundle.
+     *
+     * @param bundle Contains {@link GenericDocument} basic information (uri, schemaType etc) and a
+     *     properties bundle contains all properties in {@link GenericDocument} to support getting
+     *     properties via keys.
+     * @hide
+     */
+    public GenericDocument(@NonNull Bundle bundle) {
+        Preconditions.checkNotNull(bundle);
+        mBundle = bundle;
+        mProperties = Preconditions.checkNotNull(bundle.getParcelable(PROPERTIES_FIELD));
+        mUri = Preconditions.checkNotNull(mBundle.getString(URI_FIELD));
+        mSchemaType = Preconditions.checkNotNull(mBundle.getString(SCHEMA_TYPE_FIELD));
+        mCreationTimestampMillis =
+                mBundle.getLong(CREATION_TIMESTAMP_MILLIS_FIELD, System.currentTimeMillis());
+    }
+
+    /**
+     * Creates a new {@link GenericDocument} from an existing instance.
+     *
+     * <p>This method should be only used by constructor of a subclass.
+     */
+    protected GenericDocument(@NonNull GenericDocument document) {
+        this(document.mBundle);
+    }
+
+    /**
+     * Returns the {@link Bundle} populated by this builder.
+     *
+     * @hide
+     */
+    @NonNull
+    public Bundle getBundle() {
+        return mBundle;
+    }
+
+    /** Returns the URI of the {@link GenericDocument}. */
+    @NonNull
+    public String getUri() {
+        return mUri;
+    }
+
+    /** Returns the namespace of the {@link GenericDocument}. */
+    @NonNull
+    public String getNamespace() {
+        return mBundle.getString(NAMESPACE_FIELD, DEFAULT_NAMESPACE);
+    }
+
+    /** Returns the schema type of the {@link GenericDocument}. */
+    @NonNull
+    public String getSchemaType() {
+        return mSchemaType;
+    }
+
+    /**
+     * Returns the creation timestamp of the {@link GenericDocument}, in milliseconds.
+     *
+     * <p>The value is in the {@link System#currentTimeMillis} time base.
+     */
+    public long getCreationTimestampMillis() {
+        return mCreationTimestampMillis;
+    }
+
+    /**
+     * Returns the TTL (Time To Live) of the {@link GenericDocument}, in milliseconds.
+     *
+     * <p>The TTL is measured against {@link #getCreationTimestampMillis}. At the timestamp of
+     * {@code creationTimestampMillis + ttlMillis}, measured in the {@link System#currentTimeMillis}
+     * time base, the document will be auto-deleted.
+     *
+     * <p>The default value is 0, which means the document is permanent and won't be auto-deleted
+     * until the app is uninstalled.
+     */
+    public long getTtlMillis() {
+        return mBundle.getLong(TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
+    }
+
+    /**
+     * Returns the score of the {@link GenericDocument}.
+     *
+     * <p>The score is a query-independent measure of the document's quality, relative to other
+     * {@link GenericDocument}s of the same type.
+     *
+     * <p>Results may be sorted by score using {@link SearchSpec.Builder#setRankingStrategy}.
+     * Documents with higher scores are considered better than documents with lower scores.
+     *
+     * <p>Any nonnegative integer can be used a score.
+     */
+    public int getScore() {
+        return mBundle.getInt(SCORE_FIELD, DEFAULT_SCORE);
+    }
+
+    /** Returns the names of all properties defined in this document. */
+    @NonNull
+    public Set<String> getPropertyNames() {
+        return Collections.unmodifiableSet(mProperties.keySet());
+    }
+
+    /**
+     * Retrieves a {@link String} value by key.
+     *
+     * @param key The key to look for.
+     * @return The first {@link String} associated with the given key or {@code null} if there is no
+     *     such key or the value is of a different type.
+     */
+    @Nullable
+    public String getPropertyString(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        String[] propertyArray = getPropertyStringArray(key);
+        if (propertyArray == null || propertyArray.length == 0) {
+            return null;
+        }
+        warnIfSinglePropertyTooLong("String", key, propertyArray.length);
+        return propertyArray[0];
+    }
+
+    /**
+     * Retrieves a {@code long} value by key.
+     *
+     * @param key The key to look for.
+     * @return The first {@code long} associated with the given key or default value {@code 0} if
+     *     there is no such key or the value is of a different type.
+     */
+    public long getPropertyLong(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        long[] propertyArray = getPropertyLongArray(key);
+        if (propertyArray == null || propertyArray.length == 0) {
+            return 0;
+        }
+        warnIfSinglePropertyTooLong("Long", key, propertyArray.length);
+        return propertyArray[0];
+    }
+
+    /**
+     * Retrieves a {@code double} value by key.
+     *
+     * @param key The key to look for.
+     * @return The first {@code double} associated with the given key or default value {@code 0.0}
+     *     if there is no such key or the value is of a different type.
+     */
+    public double getPropertyDouble(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        double[] propertyArray = getPropertyDoubleArray(key);
+        if (propertyArray == null || propertyArray.length == 0) {
+            return 0.0;
+        }
+        warnIfSinglePropertyTooLong("Double", key, propertyArray.length);
+        return propertyArray[0];
+    }
+
+    /**
+     * Retrieves a {@code boolean} value by key.
+     *
+     * @param key The key to look for.
+     * @return The first {@code boolean} associated with the given key or default value {@code
+     *     false} if there is no such key or the value is of a different type.
+     */
+    public boolean getPropertyBoolean(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        boolean[] propertyArray = getPropertyBooleanArray(key);
+        if (propertyArray == null || propertyArray.length == 0) {
+            return false;
+        }
+        warnIfSinglePropertyTooLong("Boolean", key, propertyArray.length);
+        return propertyArray[0];
+    }
+
+    /**
+     * Retrieves a {@code byte[]} value by key.
+     *
+     * @param key The key to look for.
+     * @return The first {@code byte[]} associated with the given key or {@code null} if there is no
+     *     such key or the value is of a different type.
+     */
+    @Nullable
+    public byte[] getPropertyBytes(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        byte[][] propertyArray = getPropertyBytesArray(key);
+        if (propertyArray == null || propertyArray.length == 0) {
+            return null;
+        }
+        warnIfSinglePropertyTooLong("ByteArray", key, propertyArray.length);
+        return propertyArray[0];
+    }
+
+    /**
+     * Retrieves a {@link GenericDocument} value by key.
+     *
+     * @param key The key to look for.
+     * @return The first {@link GenericDocument} associated with the given key or {@code null} if
+     *     there is no such key or the value is of a different type.
+     */
+    @Nullable
+    public GenericDocument getPropertyDocument(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        GenericDocument[] propertyArray = getPropertyDocumentArray(key);
+        if (propertyArray == null || propertyArray.length == 0) {
+            return null;
+        }
+        warnIfSinglePropertyTooLong("Document", key, propertyArray.length);
+        return propertyArray[0];
+    }
+
+    /** Prints a warning to logcat if the given propertyLength is greater than 1. */
+    private static void warnIfSinglePropertyTooLong(
+            @NonNull String propertyType, @NonNull String key, int propertyLength) {
+        if (propertyLength > 1) {
+            Log.w(
+                    TAG,
+                    "The value for \""
+                            + key
+                            + "\" contains "
+                            + propertyLength
+                            + " elements. Only the first one will be returned from "
+                            + "getProperty"
+                            + propertyType
+                            + "(). Try getProperty"
+                            + propertyType
+                            + "Array().");
+        }
+    }
+
+    /**
+     * Retrieves a repeated {@code String} property by key.
+     *
+     * @param key The key to look for.
+     * @return The {@code String[]} associated with the given key, or {@code null} if no value is
+     *     set or the value is of a different type.
+     */
+    @Nullable
+    public String[] getPropertyStringArray(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        return getAndCastPropertyArray(key, String[].class);
+    }
+
+    /**
+     * Retrieves a repeated {@link String} property by key.
+     *
+     * @param key The key to look for.
+     * @return The {@code long[]} associated with the given key, or {@code null} if no value is set
+     *     or the value is of a different type.
+     */
+    @Nullable
+    public long[] getPropertyLongArray(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        return getAndCastPropertyArray(key, long[].class);
+    }
+
+    /**
+     * Retrieves a repeated {@code double} property by key.
+     *
+     * @param key The key to look for.
+     * @return The {@code double[]} associated with the given key, or {@code null} if no value is
+     *     set or the value is of a different type.
+     */
+    @Nullable
+    public double[] getPropertyDoubleArray(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        return getAndCastPropertyArray(key, double[].class);
+    }
+
+    /**
+     * Retrieves a repeated {@code boolean} property by key.
+     *
+     * @param key The key to look for.
+     * @return The {@code boolean[]} associated with the given key, or {@code null} if no value is
+     *     set or the value is of a different type.
+     */
+    @Nullable
+    public boolean[] getPropertyBooleanArray(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        return getAndCastPropertyArray(key, boolean[].class);
+    }
+
+    /**
+     * Retrieves a {@code byte[][]} property by key.
+     *
+     * @param key The key to look for.
+     * @return The {@code byte[][]} associated with the given key, or {@code null} if no value is
+     *     set or the value is of a different type.
+     */
+    @SuppressLint("ArrayReturn")
+    @Nullable
+    @SuppressWarnings("unchecked")
+    public byte[][] getPropertyBytesArray(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        ArrayList<Bundle> bundles = getAndCastPropertyArray(key, ArrayList.class);
+        if (bundles == null || bundles.size() == 0) {
+            return null;
+        }
+        byte[][] bytes = new byte[bundles.size()][];
+        for (int i = 0; i < bundles.size(); i++) {
+            Bundle bundle = bundles.get(i);
+            if (bundle == null) {
+                Log.e(TAG, "The inner bundle is null at " + i + ", for key: " + key);
+                continue;
+            }
+            byte[] innerBytes = bundle.getByteArray(BYTE_ARRAY_FIELD);
+            if (innerBytes == null) {
+                Log.e(TAG, "The bundle at " + i + " contains a null byte[].");
+                continue;
+            }
+            bytes[i] = innerBytes;
+        }
+        return bytes;
+    }
+
+    /**
+     * Retrieves a repeated {@link GenericDocument} property by key.
+     *
+     * @param key The key to look for.
+     * @return The {@link GenericDocument}[] associated with the given key, or {@code null} if no
+     *     value is set or the value is of a different type.
+     */
+    @SuppressLint("ArrayReturn")
+    @Nullable
+    public GenericDocument[] getPropertyDocumentArray(@NonNull String key) {
+        Preconditions.checkNotNull(key);
+        Bundle[] bundles = getAndCastPropertyArray(key, Bundle[].class);
+        if (bundles == null || bundles.length == 0) {
+            return null;
+        }
+        GenericDocument[] documents = new GenericDocument[bundles.length];
+        for (int i = 0; i < bundles.length; i++) {
+            if (bundles[i] == null) {
+                Log.e(TAG, "The inner bundle is null at " + i + ", for key: " + key);
+                continue;
+            }
+            documents[i] = new GenericDocument(bundles[i]);
+        }
+        return documents;
+    }
+
+    /**
+     * Gets a repeated property of the given key, and casts it to the given class type, which must
+     * be an array class type.
+     */
+    @Nullable
+    private <T> T getAndCastPropertyArray(@NonNull String key, @NonNull Class<T> tClass) {
+        Object value = mProperties.get(key);
+        if (value == null) {
+            return null;
+        }
+        try {
+            return tClass.cast(value);
+        } catch (ClassCastException e) {
+            Log.w(TAG, "Error casting to requested type for key \"" + key + "\"", e);
+            return null;
+        }
+    }
+
+    @Override
+    public boolean equals(@Nullable Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof GenericDocument)) {
+            return false;
+        }
+        GenericDocument otherDocument = (GenericDocument) other;
+        return BundleUtil.deepEquals(this.mBundle, otherDocument.mBundle);
+    }
+
+    @Override
+    public int hashCode() {
+        if (mHashCode == null) {
+            mHashCode = BundleUtil.deepHashCode(mBundle);
+        }
+        return mHashCode;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        return bundleToString(mBundle).toString();
+    }
+
+    @SuppressWarnings("unchecked")
+    private static StringBuilder bundleToString(Bundle bundle) {
+        StringBuilder stringBuilder = new StringBuilder();
+        try {
+            final Set<String> keySet = bundle.keySet();
+            String[] keys = keySet.toArray(new String[0]);
+            // Sort keys to make output deterministic. We need a custom comparator to handle
+            // nulls (arbitrarily putting them first, similar to Comparator.nullsFirst, which is
+            // only available since N).
+            Arrays.sort(
+                    keys,
+                    (@Nullable String s1, @Nullable String s2) -> {
+                        if (s1 == null) {
+                            return s2 == null ? 0 : -1;
+                        } else if (s2 == null) {
+                            return 1;
+                        } else {
+                            return s1.compareTo(s2);
+                        }
+                    });
+            for (String key : keys) {
+                stringBuilder.append("{ key: '").append(key).append("' value: ");
+                Object valueObject = bundle.get(key);
+                if (valueObject == null) {
+                    stringBuilder.append("<null>");
+                } else if (valueObject instanceof Bundle) {
+                    stringBuilder.append(bundleToString((Bundle) valueObject));
+                } else if (valueObject.getClass().isArray()) {
+                    stringBuilder.append("[ ");
+                    for (int i = 0; i < Array.getLength(valueObject); i++) {
+                        Object element = Array.get(valueObject, i);
+                        stringBuilder.append("'");
+                        if (element instanceof Bundle) {
+                            stringBuilder.append(bundleToString((Bundle) element));
+                        } else {
+                            stringBuilder.append(Array.get(valueObject, i));
+                        }
+                        stringBuilder.append("' ");
+                    }
+                    stringBuilder.append("]");
+                } else if (valueObject instanceof ArrayList) {
+                    for (Bundle innerBundle : (ArrayList<Bundle>) valueObject) {
+                        stringBuilder.append(bundleToString(innerBundle));
+                    }
+                } else {
+                    stringBuilder.append(valueObject.toString());
+                }
+                stringBuilder.append(" } ");
+            }
+        } catch (RuntimeException e) {
+            // Catch any exceptions here since corrupt Bundles can throw different types of
+            // exceptions (e.g. b/38445840 & b/68937025).
+            stringBuilder.append("<error>");
+        }
+        return stringBuilder;
+    }
+
+    /**
+     * The builder class for {@link GenericDocument}.
+     *
+     * @param <BuilderType> Type of subclass who extends this.
+     */
+    // This builder is specifically designed to be extended by classes deriving from
+    // GenericDocument.
+    @SuppressLint("StaticFinalBuilder")
+    public static class Builder<BuilderType extends Builder> {
+
+        private final Bundle mProperties = new Bundle();
+        private final Bundle mBundle = new Bundle();
+        private final BuilderType mBuilderTypeInstance;
+        private boolean mBuilt = false;
+
+        /**
+         * Create a new {@link GenericDocument.Builder}.
+         *
+         * @param uri The uri of {@link GenericDocument}.
+         * @param schemaType The schema type of the {@link GenericDocument}. The passed-in {@code
+         *     schemaType} must be defined using {@link AppSearchSession#setSchema} prior to
+         *     inserting a document of this {@code schemaType} into the AppSearch index using {@link
+         *     AppSearchSession#putDocuments}. Otherwise, the document will be rejected by {@link
+         *     AppSearchSession#putDocuments}.
+         */
+        @SuppressWarnings("unchecked")
+        public Builder(@NonNull String uri, @NonNull String schemaType) {
+            Preconditions.checkNotNull(uri);
+            Preconditions.checkNotNull(schemaType);
+            mBuilderTypeInstance = (BuilderType) this;
+            mBundle.putString(GenericDocument.URI_FIELD, uri);
+            mBundle.putString(GenericDocument.SCHEMA_TYPE_FIELD, schemaType);
+            mBundle.putString(GenericDocument.NAMESPACE_FIELD, DEFAULT_NAMESPACE);
+            // Set current timestamp for creation timestamp by default.
+            mBundle.putLong(
+                    GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, System.currentTimeMillis());
+            mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
+            mBundle.putInt(GenericDocument.SCORE_FIELD, DEFAULT_SCORE);
+            mBundle.putBundle(PROPERTIES_FIELD, mProperties);
+        }
+
+        /**
+         * Sets the app-defined namespace this Document resides in. No special values are reserved
+         * or understood by the infrastructure.
+         *
+         * <p>URIs are unique within a namespace.
+         *
+         * <p>The number of namespaces per app should be kept small for efficiency reasons.
+         */
+        @NonNull
+        public BuilderType setNamespace(@NonNull String namespace) {
+            mBundle.putString(GenericDocument.NAMESPACE_FIELD, namespace);
+            return mBuilderTypeInstance;
+        }
+
+        /**
+         * Sets the score of the {@link GenericDocument}.
+         *
+         * <p>The score is a query-independent measure of the document's quality, relative to other
+         * {@link GenericDocument}s of the same type.
+         *
+         * <p>Results may be sorted by score using {@link SearchSpec.Builder#setRankingStrategy}.
+         * Documents with higher scores are considered better than documents with lower scores.
+         *
+         * <p>Any nonnegative integer can be used a score.
+         *
+         * @throws IllegalArgumentException If the provided value is negative.
+         */
+        @NonNull
+        public BuilderType setScore(@IntRange(from = 0, to = Integer.MAX_VALUE) int score) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            if (score < 0) {
+                throw new IllegalArgumentException("Document score cannot be negative.");
+            }
+            mBundle.putInt(GenericDocument.SCORE_FIELD, score);
+            return mBuilderTypeInstance;
+        }
+
+        /**
+         * Sets the creation timestamp of the {@link GenericDocument}, in milliseconds.
+         *
+         * <p>Should be set using a value obtained from the {@link System#currentTimeMillis} time
+         * base.
+         */
+        @NonNull
+        public BuilderType setCreationTimestampMillis(long creationTimestampMillis) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBundle.putLong(
+                    GenericDocument.CREATION_TIMESTAMP_MILLIS_FIELD, creationTimestampMillis);
+            return mBuilderTypeInstance;
+        }
+
+        /**
+         * Sets the TTL (Time To Live) of the {@link GenericDocument}, in milliseconds.
+         *
+         * <p>The TTL is measured against {@link #getCreationTimestampMillis}. At the timestamp of
+         * {@code creationTimestampMillis + ttlMillis}, measured in the {@link
+         * System#currentTimeMillis} time base, the document will be auto-deleted.
+         *
+         * <p>The default value is 0, which means the document is permanent and won't be
+         * auto-deleted until the app is uninstalled.
+         *
+         * @param ttlMillis A non-negative duration in milliseconds.
+         * @throws IllegalArgumentException If the provided value is negative.
+         */
+        @NonNull
+        public BuilderType setTtlMillis(long ttlMillis) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            if (ttlMillis < 0) {
+                throw new IllegalArgumentException("Document ttlMillis cannot be negative.");
+            }
+            mBundle.putLong(GenericDocument.TTL_MILLIS_FIELD, ttlMillis);
+            return mBuilderTypeInstance;
+        }
+
+        /**
+         * Sets one or multiple {@code String} values for a property, replacing its previous values.
+         *
+         * @param key The key associated with the {@code values}.
+         * @param values The {@code String} values of the property.
+         */
+        @NonNull
+        public BuilderType setPropertyString(@NonNull String key, @NonNull String... values) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(key);
+            Preconditions.checkNotNull(values);
+            putInPropertyBundle(key, values);
+            return mBuilderTypeInstance;
+        }
+
+        /**
+         * Sets one or multiple {@code boolean} values for a property, replacing its previous
+         * values.
+         *
+         * @param key The key associated with the {@code values}.
+         * @param values The {@code boolean} values of the property.
+         */
+        @NonNull
+        public BuilderType setPropertyBoolean(@NonNull String key, @NonNull boolean... values) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(key);
+            Preconditions.checkNotNull(values);
+            putInPropertyBundle(key, values);
+            return mBuilderTypeInstance;
+        }
+
+        /**
+         * Sets one or multiple {@code long} values for a property, replacing its previous values.
+         *
+         * @param key The key associated with the {@code values}.
+         * @param values The {@code long} values of the property.
+         */
+        @NonNull
+        public BuilderType setPropertyLong(@NonNull String key, @NonNull long... values) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(key);
+            Preconditions.checkNotNull(values);
+            putInPropertyBundle(key, values);
+            return mBuilderTypeInstance;
+        }
+
+        /**
+         * Sets one or multiple {@code double} values for a property, replacing its previous values.
+         *
+         * @param key The key associated with the {@code values}.
+         * @param values The {@code double} values of the property.
+         */
+        @NonNull
+        public BuilderType setPropertyDouble(@NonNull String key, @NonNull double... values) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(key);
+            Preconditions.checkNotNull(values);
+            putInPropertyBundle(key, values);
+            return mBuilderTypeInstance;
+        }
+
+        /**
+         * Sets one or multiple {@code byte[]} for a property, replacing its previous values.
+         *
+         * @param key The key associated with the {@code values}.
+         * @param values The {@code byte[]} of the property.
+         */
+        @NonNull
+        public BuilderType setPropertyBytes(@NonNull String key, @NonNull byte[]... values) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(key);
+            Preconditions.checkNotNull(values);
+            putInPropertyBundle(key, values);
+            return mBuilderTypeInstance;
+        }
+
+        /**
+         * Sets one or multiple {@link GenericDocument} values for a property, replacing its
+         * previous values.
+         *
+         * @param key The key associated with the {@code values}.
+         * @param values The {@link GenericDocument} values of the property.
+         */
+        @NonNull
+        public BuilderType setPropertyDocument(
+                @NonNull String key, @NonNull GenericDocument... values) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(key);
+            Preconditions.checkNotNull(values);
+            putInPropertyBundle(key, values);
+            return mBuilderTypeInstance;
+        }
+
+        private void putInPropertyBundle(@NonNull String key, @NonNull String[] values)
+                throws IllegalArgumentException {
+            validateRepeatedPropertyLength(key, values.length);
+            for (int i = 0; i < values.length; i++) {
+                if (values[i] == null) {
+                    throw new IllegalArgumentException("The String at " + i + " is null.");
+                } else if (values[i].length() > MAX_STRING_LENGTH) {
+                    throw new IllegalArgumentException(
+                            "The String at "
+                                    + i
+                                    + " length is: "
+                                    + values[i].length()
+                                    + ", which exceeds length limit: "
+                                    + MAX_STRING_LENGTH
+                                    + ".");
+                }
+            }
+            mProperties.putStringArray(key, values);
+        }
+
+        private void putInPropertyBundle(@NonNull String key, @NonNull boolean[] values) {
+            validateRepeatedPropertyLength(key, values.length);
+            mProperties.putBooleanArray(key, values);
+        }
+
+        private void putInPropertyBundle(@NonNull String key, @NonNull double[] values) {
+            validateRepeatedPropertyLength(key, values.length);
+            mProperties.putDoubleArray(key, values);
+        }
+
+        private void putInPropertyBundle(@NonNull String key, @NonNull long[] values) {
+            validateRepeatedPropertyLength(key, values.length);
+            mProperties.putLongArray(key, values);
+        }
+
+        /**
+         * Converts and saves a byte[][] into {@link #mProperties}.
+         *
+         * <p>Bundle doesn't support for two dimension array byte[][], we are converting byte[][]
+         * into ArrayList<Bundle>, and each elements will contain a one dimension byte[].
+         */
+        private void putInPropertyBundle(@NonNull String key, @NonNull byte[][] values) {
+            validateRepeatedPropertyLength(key, values.length);
+            ArrayList<Bundle> bundles = new ArrayList<>(values.length);
+            for (int i = 0; i < values.length; i++) {
+                if (values[i] == null) {
+                    throw new IllegalArgumentException("The byte[] at " + i + " is null.");
+                }
+                Bundle bundle = new Bundle();
+                bundle.putByteArray(BYTE_ARRAY_FIELD, values[i]);
+                bundles.add(bundle);
+            }
+            mProperties.putParcelableArrayList(key, bundles);
+        }
+
+        private void putInPropertyBundle(@NonNull String key, @NonNull GenericDocument[] values) {
+            validateRepeatedPropertyLength(key, values.length);
+            Bundle[] documentBundles = new Bundle[values.length];
+            for (int i = 0; i < values.length; i++) {
+                if (values[i] == null) {
+                    throw new IllegalArgumentException("The document at " + i + " is null.");
+                }
+                documentBundles[i] = values[i].mBundle;
+            }
+            mProperties.putParcelableArray(key, documentBundles);
+        }
+
+        private static void validateRepeatedPropertyLength(@NonNull String key, int length) {
+            if (length == 0) {
+                throw new IllegalArgumentException("The input array is empty.");
+            } else if (length > MAX_REPEATED_PROPERTY_LENGTH) {
+                throw new IllegalArgumentException(
+                        "Repeated property \""
+                                + key
+                                + "\" has length "
+                                + length
+                                + ", which exceeds the limit of "
+                                + MAX_REPEATED_PROPERTY_LENGTH);
+            }
+        }
+
+        /** Builds the {@link GenericDocument} object. */
+        @NonNull
+        public GenericDocument build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBuilt = true;
+            return new GenericDocument(mBundle);
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java
new file mode 100644
index 0000000..74afdd2
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/GetByUriRequest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020 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.app.appsearch;
+
+import android.annotation.NonNull;
+import android.util.ArraySet;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Encapsulates a request to retrieve documents by namespace and URI.
+ *
+ * @see AppSearchSession#getByUri
+ */
+public final class GetByUriRequest {
+    private final String mNamespace;
+    private final Set<String> mUris;
+
+    GetByUriRequest(@NonNull String namespace, @NonNull Set<String> uris) {
+        mNamespace = namespace;
+        mUris = uris;
+    }
+
+    /** Returns the namespace to get documents from. */
+    @NonNull
+    public String getNamespace() {
+        return mNamespace;
+    }
+
+    /** Returns the URIs to get from the namespace. */
+    @NonNull
+    public Set<String> getUris() {
+        return Collections.unmodifiableSet(mUris);
+    }
+
+    /** Builder for {@link GetByUriRequest} objects. */
+    public static final class Builder {
+        private String mNamespace = GenericDocument.DEFAULT_NAMESPACE;
+        private final Set<String> mUris = new ArraySet<>();
+        private boolean mBuilt = false;
+
+        /**
+         * Sets which namespace these documents will be retrieved from.
+         *
+         * <p>If this is not set, it defaults to {@link GenericDocument#DEFAULT_NAMESPACE}.
+         */
+        @NonNull
+        public Builder setNamespace(@NonNull String namespace) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(namespace);
+            mNamespace = namespace;
+            return this;
+        }
+
+        /** Adds one or more URIs to the request. */
+        @NonNull
+        public Builder addUri(@NonNull String... uris) {
+            Preconditions.checkNotNull(uris);
+            return addUri(Arrays.asList(uris));
+        }
+
+        /** Adds one or more URIs to the request. */
+        @NonNull
+        public Builder addUri(@NonNull Collection<String> uris) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(uris);
+            mUris.addAll(uris);
+            return this;
+        }
+
+        /** Builds a new {@link GetByUriRequest}. */
+        @NonNull
+        public GetByUriRequest build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBuilt = true;
+            return new GetByUriRequest(mNamespace, mUris);
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java
new file mode 100644
index 0000000..1c360a6
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2020 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.app.appsearch;
+
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.app.appsearch.exceptions.AppSearchException;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Encapsulates a request to index a document into an {@link AppSearchSession} database.
+ *
+ * @see AppSearchSession#putDocuments
+ */
+public final class PutDocumentsRequest {
+    private final List<GenericDocument> mDocuments;
+
+    PutDocumentsRequest(List<GenericDocument> documents) {
+        mDocuments = documents;
+    }
+
+    /** Returns the documents that are part of this request. */
+    @NonNull
+    public List<GenericDocument> getDocuments() {
+        return Collections.unmodifiableList(mDocuments);
+    }
+
+    /** Builder for {@link PutDocumentsRequest} objects. */
+    public static final class Builder {
+        private final List<GenericDocument> mDocuments = new ArrayList<>();
+        private boolean mBuilt = false;
+
+        /** Adds one or more documents to the request. */
+        @SuppressLint("MissingGetterMatchingBuilder") // Merged list available from getDocuments()
+        @NonNull
+        public Builder addGenericDocument(@NonNull GenericDocument... documents) {
+            Preconditions.checkNotNull(documents);
+            return addGenericDocument(Arrays.asList(documents));
+        }
+
+        /** Adds one or more documents to the request. */
+        @SuppressLint("MissingGetterMatchingBuilder") // Merged list available from getDocuments()
+        @NonNull
+        public Builder addGenericDocument(@NonNull Collection<GenericDocument> documents) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(documents);
+            mDocuments.addAll(documents);
+            return this;
+        }
+
+        /** Builds a new {@link PutDocumentsRequest}. */
+        @NonNull
+        public PutDocumentsRequest build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBuilt = true;
+            return new PutDocumentsRequest(mDocuments);
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java
new file mode 100644
index 0000000..be6d157
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/RemoveByUriRequest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020 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.app.appsearch;
+
+import android.annotation.NonNull;
+import android.util.ArraySet;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Encapsulates a request to remove documents by namespace and URI.
+ *
+ * @see AppSearchSession#removeByUri
+ */
+public final class RemoveByUriRequest {
+    private final String mNamespace;
+    private final Set<String> mUris;
+
+    RemoveByUriRequest(String namespace, Set<String> uris) {
+        mNamespace = namespace;
+        mUris = uris;
+    }
+
+    /** Returns the namespace to remove documents from. */
+    @NonNull
+    public String getNamespace() {
+        return mNamespace;
+    }
+
+    /** Returns the URIs to remove from the namespace. */
+    @NonNull
+    public Set<String> getUris() {
+        return Collections.unmodifiableSet(mUris);
+    }
+
+    /** Builder for {@link RemoveByUriRequest} objects. */
+    public static final class Builder {
+        private String mNamespace = GenericDocument.DEFAULT_NAMESPACE;
+        private final Set<String> mUris = new ArraySet<>();
+        private boolean mBuilt = false;
+
+        /**
+         * Sets which namespace these documents will be removed from.
+         *
+         * <p>If this is not set, it defaults to {@link GenericDocument#DEFAULT_NAMESPACE}.
+         */
+        @NonNull
+        public Builder setNamespace(@NonNull String namespace) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(namespace);
+            mNamespace = namespace;
+            return this;
+        }
+
+        /** Adds one or more URIs to the request. */
+        @NonNull
+        public Builder addUri(@NonNull String... uris) {
+            Preconditions.checkNotNull(uris);
+            return addUri(Arrays.asList(uris));
+        }
+
+        /** Adds one or more URIs to the request. */
+        @NonNull
+        public Builder addUri(@NonNull Collection<String> uris) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(uris);
+            mUris.addAll(uris);
+            return this;
+        }
+
+        /** Builds a new {@link RemoveByUriRequest}. */
+        @NonNull
+        public RemoveByUriRequest build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBuilt = true;
+            return new RemoveByUriRequest(mNamespace, mUris);
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResult.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
similarity index 100%
rename from apex/appsearch/framework/java/android/app/appsearch/SearchResult.java
rename to apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResultPage.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchResultPage.java
similarity index 100%
rename from apex/appsearch/framework/java/android/app/appsearch/SearchResultPage.java
rename to apex/appsearch/framework/java/external/android/app/appsearch/SearchResultPage.java
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java b/apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
similarity index 100%
rename from apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java
rename to apex/appsearch/framework/java/external/android/app/appsearch/SearchSpec.java
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
new file mode 100644
index 0000000..0e03131
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/SetSchemaRequest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2020 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.app.appsearch;
+
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.app.appsearch.exceptions.AppSearchException;
+import android.util.ArraySet;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Encapsulates a request to update the schema of an {@link AppSearchSession} database.
+ *
+ * @see AppSearchSession#setSchema
+ */
+public final class SetSchemaRequest {
+    private final Set<AppSearchSchema> mSchemas;
+    private final Set<String> mSchemasNotPlatformSurfaceable;
+    private final boolean mForceOverride;
+
+    SetSchemaRequest(
+            @NonNull Set<AppSearchSchema> schemas,
+            @NonNull Set<String> schemasNotPlatformSurfaceable,
+            boolean forceOverride) {
+        mSchemas = Preconditions.checkNotNull(schemas);
+        mSchemasNotPlatformSurfaceable = Preconditions.checkNotNull(schemasNotPlatformSurfaceable);
+        mForceOverride = forceOverride;
+    }
+
+    /** Returns the schemas that are part of this request. */
+    @NonNull
+    public Set<AppSearchSchema> getSchemas() {
+        return Collections.unmodifiableSet(mSchemas);
+    }
+
+    /**
+     * Returns the set of schema types that have opted out of being visible on system UI surfaces.
+     *
+     * @hide
+     */
+    @NonNull
+    public Set<String> getSchemasNotPlatformSurfaceable() {
+        return Collections.unmodifiableSet(mSchemasNotPlatformSurfaceable);
+    }
+
+    /** Returns whether this request will force the schema to be overridden. */
+    public boolean isForceOverride() {
+        return mForceOverride;
+    }
+
+    /** Builder for {@link SetSchemaRequest} objects. */
+    public static final class Builder {
+        private final Set<AppSearchSchema> mSchemas = new ArraySet<>();
+        private final Set<String> mSchemasNotPlatformSurfaceable = new ArraySet<>();
+        private boolean mForceOverride = false;
+        private boolean mBuilt = false;
+
+        /**
+         * Adds one or more types to the schema.
+         *
+         * <p>Any documents of these types will be visible on system UI surfaces by default.
+         */
+        @NonNull
+        public Builder addSchema(@NonNull AppSearchSchema... schemas) {
+            Preconditions.checkNotNull(schemas);
+            return addSchema(Arrays.asList(schemas));
+        }
+
+        /**
+         * Adds one or more types to the schema.
+         *
+         * <p>Any documents of these types will be visible on system UI surfaces by default.
+         */
+        @NonNull
+        public Builder addSchema(@NonNull Collection<AppSearchSchema> schemas) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(schemas);
+            mSchemas.addAll(schemas);
+            return this;
+        }
+
+        /**
+         * Sets visibility on system UI surfaces for schema types.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setSchemaTypeVisibilityForSystemUi(
+                boolean visible, @NonNull String... schemaTypes) {
+            Preconditions.checkNotNull(schemaTypes);
+            return this.setSchemaTypeVisibilityForSystemUi(visible, Arrays.asList(schemaTypes));
+        }
+
+        /**
+         * Sets visibility on system UI surfaces for schema types.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setSchemaTypeVisibilityForSystemUi(
+                boolean visible, @NonNull Collection<String> schemaTypes) {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            Preconditions.checkNotNull(schemaTypes);
+            if (visible) {
+                mSchemasNotPlatformSurfaceable.removeAll(schemaTypes);
+            } else {
+                mSchemasNotPlatformSurfaceable.addAll(schemaTypes);
+            }
+            return this;
+        }
+
+        /**
+         * Configures the {@link SetSchemaRequest} to delete any existing documents that don't
+         * follow the new schema.
+         *
+         * <p>By default, this is {@code false} and schema incompatibility causes the {@link
+         * AppSearchSession#setSchema} call to fail.
+         *
+         * @see AppSearchSession#setSchema
+         */
+        @NonNull
+        public Builder setForceOverride(boolean forceOverride) {
+            mForceOverride = forceOverride;
+            return this;
+        }
+
+        /**
+         * Builds a new {@link SetSchemaRequest}.
+         *
+         * @throws IllegalArgumentException If schema types were referenced, but the corresponding
+         *     {@link AppSearchSchema} was never added.
+         */
+        @NonNull
+        public SetSchemaRequest build() {
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mBuilt = true;
+
+            // Verify that any schema types with visibility settings refer to a real schema.
+            // Create a copy because we're going to remove from the set for verification purposes.
+            Set<String> schemasNotPlatformSurfaceableCopy =
+                    new ArraySet<>(mSchemasNotPlatformSurfaceable);
+            for (AppSearchSchema schema : mSchemas) {
+                schemasNotPlatformSurfaceableCopy.remove(schema.getSchemaType());
+            }
+            if (!schemasNotPlatformSurfaceableCopy.isEmpty()) {
+                // We still have schema types that weren't seen in our mSchemas set. This means
+                // there wasn't a corresponding AppSearchSchema.
+                throw new IllegalArgumentException(
+                        "Schema types "
+                                + schemasNotPlatformSurfaceableCopy
+                                + " referenced, but were not added.");
+            }
+
+            return new SetSchemaRequest(mSchemas, mSchemasNotPlatformSurfaceable, mForceOverride);
+        }
+    }
+}
diff --git a/apex/appsearch/framework/java/android/app/appsearch/exceptions/AppSearchException.java b/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/AppSearchException.java
similarity index 100%
rename from apex/appsearch/framework/java/android/app/appsearch/exceptions/AppSearchException.java
rename to apex/appsearch/framework/java/external/android/app/appsearch/exceptions/AppSearchException.java
diff --git a/apex/appsearch/framework/java/android/app/appsearch/exceptions/IllegalSchemaException.java b/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSchemaException.java
similarity index 100%
rename from apex/appsearch/framework/java/android/app/appsearch/exceptions/IllegalSchemaException.java
rename to apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSchemaException.java
diff --git a/apex/appsearch/framework/java/android/app/appsearch/exceptions/IllegalSearchSpecException.java b/apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSearchSpecException.java
similarity index 100%
rename from apex/appsearch/framework/java/android/app/appsearch/exceptions/IllegalSearchSpecException.java
rename to apex/appsearch/framework/java/external/android/app/appsearch/exceptions/IllegalSearchSpecException.java
diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/util/BundleUtil.java b/apex/appsearch/framework/java/external/android/app/appsearch/util/BundleUtil.java
new file mode 100644
index 0000000..1b4d284
--- /dev/null
+++ b/apex/appsearch/framework/java/external/android/app/appsearch/util/BundleUtil.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2020 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.app.appsearch.util;
+
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Utilities for working with {@link android.os.Bundle}.
+ *
+ * @hide
+ */
+public final class BundleUtil {
+    private BundleUtil() {}
+
+    /**
+     * Deeply checks two bundles are equal or not.
+     *
+     * <p>Two bundles will be considered equal if they contain the same keys, and each value is also
+     * equal. Bundle values are compared using deepEquals.
+     */
+    public static boolean deepEquals(@Nullable Bundle one, @Nullable Bundle two) {
+        if (one == null && two == null) {
+            return true;
+        }
+        if (one == null || two == null) {
+            return false;
+        }
+        if (one.size() != two.size()) {
+            return false;
+        }
+        if (!one.keySet().equals(two.keySet())) {
+            return false;
+        }
+        // Bundle inherit its equals() from Object.java, which only compare their memory address.
+        // We should iterate all keys and check their presents and values in both bundle.
+        for (String key : one.keySet()) {
+            if (!bundleValueEquals(one.get(key), two.get(key))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Deeply checks whether two values in a Bundle are equal or not.
+     *
+     * <p>Values of type Bundle are compared using {@link #deepEquals}.
+     */
+    private static boolean bundleValueEquals(@Nullable Object one, @Nullable Object two) {
+        if (one == null && two == null) {
+            return true;
+        }
+        if (one == null || two == null) {
+            return false;
+        }
+        if (one.equals(two)) {
+            return true;
+        }
+        if (one instanceof Bundle && two instanceof Bundle) {
+            return deepEquals((Bundle) one, (Bundle) two);
+        } else if (one instanceof int[] && two instanceof int[]) {
+            return Arrays.equals((int[]) one, (int[]) two);
+        } else if (one instanceof byte[] && two instanceof byte[]) {
+            return Arrays.equals((byte[]) one, (byte[]) two);
+        } else if (one instanceof char[] && two instanceof char[]) {
+            return Arrays.equals((char[]) one, (char[]) two);
+        } else if (one instanceof long[] && two instanceof long[]) {
+            return Arrays.equals((long[]) one, (long[]) two);
+        } else if (one instanceof float[] && two instanceof float[]) {
+            return Arrays.equals((float[]) one, (float[]) two);
+        } else if (one instanceof short[] && two instanceof short[]) {
+            return Arrays.equals((short[]) one, (short[]) two);
+        } else if (one instanceof double[] && two instanceof double[]) {
+            return Arrays.equals((double[]) one, (double[]) two);
+        } else if (one instanceof boolean[] && two instanceof boolean[]) {
+            return Arrays.equals((boolean[]) one, (boolean[]) two);
+        } else if (one instanceof Object[] && two instanceof Object[]) {
+            Object[] arrayOne = (Object[]) one;
+            Object[] arrayTwo = (Object[]) two;
+            if (arrayOne.length != arrayTwo.length) {
+                return false;
+            }
+            if (Arrays.equals(arrayOne, arrayTwo)) {
+                return true;
+            }
+            for (int i = 0; i < arrayOne.length; i++) {
+                if (!bundleValueEquals(arrayOne[i], arrayTwo[i])) {
+                    return false;
+                }
+            }
+            return true;
+        } else if (one instanceof ArrayList && two instanceof ArrayList) {
+            ArrayList<?> listOne = (ArrayList<?>) one;
+            ArrayList<?> listTwo = (ArrayList<?>) two;
+            if (listOne.size() != listTwo.size()) {
+                return false;
+            }
+            for (int i = 0; i < listOne.size(); i++) {
+                if (!bundleValueEquals(listOne.get(i), listTwo.get(i))) {
+                    return false;
+                }
+            }
+            return true;
+        } else if (one instanceof SparseArray && two instanceof SparseArray) {
+            SparseArray<?> arrayOne = (SparseArray<?>) one;
+            SparseArray<?> arrayTwo = (SparseArray<?>) two;
+            if (arrayOne.size() != arrayTwo.size()) {
+                return false;
+            }
+            for (int i = 0; i < arrayOne.size(); i++) {
+                if (arrayOne.keyAt(i) != arrayTwo.keyAt(i)
+                        || !bundleValueEquals(arrayOne.valueAt(i), arrayTwo.valueAt(i))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Calculates the hash code for a bundle.
+     *
+     * <p>The hash code is only effected by the contents in the bundle. Bundles will get consistent
+     * hash code if they have same contents.
+     */
+    public static int deepHashCode(@Nullable Bundle bundle) {
+        if (bundle == null) {
+            return 0;
+        }
+        int[] hashCodes = new int[bundle.size()];
+        int i = 0;
+        // Bundle inherit its hashCode() from Object.java, which only relative to their memory
+        // address. Bundle doesn't have an order, so we should iterate all keys and combine
+        // their value's hashcode into an array. And use the hashcode of the array to be
+        // the hashcode of the bundle.
+        for (String key : bundle.keySet()) {
+            Object value = bundle.get(key);
+            if (value instanceof Bundle) {
+                hashCodes[i++] = deepHashCode((Bundle) value);
+            } else if (value instanceof int[]) {
+                hashCodes[i++] = Arrays.hashCode((int[]) value);
+            } else if (value instanceof byte[]) {
+                hashCodes[i++] = Arrays.hashCode((byte[]) value);
+            } else if (value instanceof char[]) {
+                hashCodes[i++] = Arrays.hashCode((char[]) value);
+            } else if (value instanceof long[]) {
+                hashCodes[i++] = Arrays.hashCode((long[]) value);
+            } else if (value instanceof float[]) {
+                hashCodes[i++] = Arrays.hashCode((float[]) value);
+            } else if (value instanceof short[]) {
+                hashCodes[i++] = Arrays.hashCode((short[]) value);
+            } else if (value instanceof double[]) {
+                hashCodes[i++] = Arrays.hashCode((double[]) value);
+            } else if (value instanceof boolean[]) {
+                hashCodes[i++] = Arrays.hashCode((boolean[]) value);
+            } else if (value instanceof String[]) {
+                // Optimization to avoid Object[] handler creating an inner array for common cases
+                hashCodes[i++] = Arrays.hashCode((String[]) value);
+            } else if (value instanceof Object[]) {
+                Object[] array = (Object[]) value;
+                int[] innerHashCodes = new int[array.length];
+                for (int j = 0; j < array.length; j++) {
+                    if (array[j] instanceof Bundle) {
+                        innerHashCodes[j] = deepHashCode((Bundle) array[j]);
+                    } else if (array[j] != null) {
+                        innerHashCodes[j] = array[j].hashCode();
+                    }
+                }
+                hashCodes[i++] = Arrays.hashCode(innerHashCodes);
+            } else if (value instanceof ArrayList) {
+                ArrayList<?> list = (ArrayList<?>) value;
+                int[] innerHashCodes = new int[list.size()];
+                for (int j = 0; j < innerHashCodes.length; j++) {
+                    Object item = list.get(j);
+                    if (item instanceof Bundle) {
+                        innerHashCodes[j] = deepHashCode((Bundle) item);
+                    } else if (item != null) {
+                        innerHashCodes[j] = item.hashCode();
+                    }
+                }
+                hashCodes[i++] = Arrays.hashCode(innerHashCodes);
+            } else if (value instanceof SparseArray) {
+                SparseArray<?> array = (SparseArray<?>) value;
+                int[] innerHashCodes = new int[array.size() * 2];
+                for (int j = 0; j < array.size(); j++) {
+                    innerHashCodes[j * 2] = array.keyAt(j);
+                    Object item = array.valueAt(j);
+                    if (item instanceof Bundle) {
+                        innerHashCodes[j * 2 + 1] = deepHashCode((Bundle) item);
+                    } else if (item != null) {
+                        innerHashCodes[j * 2 + 1] = item.hashCode();
+                    }
+                }
+                hashCodes[i++] = Arrays.hashCode(innerHashCodes);
+            } else {
+                hashCodes[i++] = value.hashCode();
+            }
+        }
+        return Arrays.hashCode(hashCodes);
+    }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index d5146dd..551347c 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -33,15 +33,14 @@
 import android.os.ParcelableException;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.internal.util.Preconditions;
 import com.android.server.SystemService;
 import com.android.server.appsearch.external.localstorage.AppSearchImpl;
 
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 
 /**
  * TODO(b/142567528): add comments when implement this class
@@ -64,6 +63,7 @@
         public void setSchema(
                 @NonNull String databaseName,
                 @NonNull List<Bundle> schemaBundles,
+                @NonNull List<String> schemasNotPlatformSurfaceable,
                 boolean forceOverride,
                 @NonNull IAppSearchResultCallback callback) {
             Preconditions.checkNotNull(databaseName);
@@ -73,13 +73,13 @@
             int callingUserId = UserHandle.getUserId(callingUid);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
-                Set<AppSearchSchema> schemas = new ArraySet<>(schemaBundles.size());
+                List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
                 for (int i = 0; i < schemaBundles.size(); i++) {
                     schemas.add(new AppSearchSchema(schemaBundles.get(i)));
                 }
                 AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId);
                 databaseName = rewriteDatabaseNameWithUid(databaseName, callingUid);
-                impl.setSchema(databaseName, schemas, forceOverride);
+                impl.setSchema(databaseName, schemas, schemasNotPlatformSurfaceable, forceOverride);
                 invokeCallbackOnResult(callback,
                         AppSearchResult.newSuccessfulResult(/*result=*/ null));
             } catch (Throwable t) {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index 247089b..62b81d0 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -60,6 +60,7 @@
 import com.google.android.icing.proto.StatusProto;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -226,13 +227,16 @@
      *
      * @param databaseName The name of the database where this schema lives.
      * @param schemas Schemas to set for this app.
+     * @param schemasNotPlatformSurfaceable Schema types that should not be surfaced on platform
+     *     surfaces.
      * @param forceOverride Whether to force-apply the schema even if it is incompatible. Documents
      *     which do not comply with the new schema will be deleted.
      * @throws AppSearchException on IcingSearchEngine error.
      */
     public void setSchema(
             @NonNull String databaseName,
-            @NonNull Set<AppSearchSchema> schemas,
+            @NonNull List<AppSearchSchema> schemas,
+            @NonNull List<String> schemasNotPlatformSurfaceable,
             boolean forceOverride)
             throws AppSearchException {
         mReadWriteLock.writeLock().lock();
@@ -240,8 +244,9 @@
             SchemaProto.Builder existingSchemaBuilder = getSchemaProtoLocked().toBuilder();
 
             SchemaProto.Builder newSchemaBuilder = SchemaProto.newBuilder();
-            for (AppSearchSchema schema : schemas) {
-                SchemaTypeConfigProto schemaTypeProto = SchemaToProtoConverter.convert(schema);
+            for (int i = 0; i < schemas.size(); i++) {
+                SchemaTypeConfigProto schemaTypeProto =
+                        SchemaToProtoConverter.toSchemaTypeConfigProto(schemas.get(i));
                 newSchemaBuilder.addTypes(schemaTypeProto);
             }
 
@@ -276,8 +281,16 @@
 
             // Update derived data structures.
             mSchemaMapLocked.put(databaseName, rewrittenSchemaResults.mRewrittenQualifiedTypes);
-            mVisibilityStoreLocked.updateSchemas(
-                    databaseName, rewrittenSchemaResults.mDeletedQualifiedTypes);
+
+            String databasePrefix = getDatabasePrefix(databaseName);
+            Set<String> qualifiedSchemasNotPlatformSurfaceable =
+                    new ArraySet<>(schemasNotPlatformSurfaceable.size());
+            for (int i = 0; i < schemasNotPlatformSurfaceable.size(); i++) {
+                qualifiedSchemasNotPlatformSurfaceable.add(
+                        databasePrefix + schemasNotPlatformSurfaceable.get(i));
+            }
+            mVisibilityStoreLocked.setVisibility(
+                    databaseName, qualifiedSchemasNotPlatformSurfaceable);
 
             // Determine whether to schedule an immediate optimize.
             if (setSchemaResultProto.getDeletedSchemaTypesCount() > 0
@@ -294,38 +307,55 @@
     }
 
     /**
-     * Update the visibility settings for this app.
+     * Retrieves the AppSearch schema for this database.
      *
-     * <p>This method belongs to the mutate group
+     * <p>This method belongs to query group.
      *
-     * @param databaseName The name of the database where the visibility settings will apply.
-     * @param schemasHiddenFromPlatformSurfaces Schemas that should be hidden from platform surfaces
-     * @throws AppSearchException on IcingSearchEngine error
+     * @param databaseName The name of the database where this schema lives.
+     * @throws AppSearchException on IcingSearchEngine error.
      */
-    public void setVisibility(
-            @NonNull String databaseName, @NonNull Set<String> schemasHiddenFromPlatformSurfaces)
-            throws AppSearchException {
-        mReadWriteLock.writeLock().lock();
+    @NonNull
+    public List<AppSearchSchema> getSchema(@NonNull String databaseName) throws AppSearchException {
+        SchemaProto fullSchema;
+        mReadWriteLock.readLock().lock();
         try {
-            String databasePrefix = getDatabasePrefix(databaseName);
-            Set<String> qualifiedSchemasHiddenFromPlatformSurface =
-                    new ArraySet<>(schemasHiddenFromPlatformSurfaces.size());
-            for (String schema : schemasHiddenFromPlatformSurfaces) {
-                Set<String> existingSchemas = mSchemaMapLocked.get(databaseName);
-                if (existingSchemas == null || !existingSchemas.contains(databasePrefix + schema)) {
-                    throw new AppSearchException(
-                            AppSearchResult.RESULT_NOT_FOUND,
-                            "Unknown schema(s): "
-                                    + schemasHiddenFromPlatformSurfaces
-                                    + " provided during setVisibility.");
-                }
-                qualifiedSchemasHiddenFromPlatformSurface.add(databasePrefix + schema);
-            }
-            mVisibilityStoreLocked.setVisibility(
-                    databaseName, qualifiedSchemasHiddenFromPlatformSurface);
+            fullSchema = getSchemaProtoLocked();
         } finally {
-            mReadWriteLock.writeLock().lock();
+            mReadWriteLock.readLock().unlock();
         }
+
+        List<AppSearchSchema> result = new ArrayList<>();
+        for (int i = 0; i < fullSchema.getTypesCount(); i++) {
+            String typeDatabase = getDatabaseName(fullSchema.getTypes(i).getSchemaType());
+            if (!databaseName.equals(typeDatabase)) {
+                continue;
+            }
+            // Rewrite SchemaProto.types.schema_type
+            SchemaTypeConfigProto.Builder typeConfigBuilder = fullSchema.getTypes(i).toBuilder();
+            String newSchemaType =
+                    typeConfigBuilder.getSchemaType().substring(databaseName.length() + 1);
+            typeConfigBuilder.setSchemaType(newSchemaType);
+
+            // Rewrite SchemaProto.types.properties.schema_type
+            for (int propertyIdx = 0;
+                    propertyIdx < typeConfigBuilder.getPropertiesCount();
+                    propertyIdx++) {
+                PropertyConfigProto.Builder propertyConfigBuilder =
+                        typeConfigBuilder.getProperties(propertyIdx).toBuilder();
+                if (!propertyConfigBuilder.getSchemaType().isEmpty()) {
+                    String newPropertySchemaType =
+                            propertyConfigBuilder
+                                    .getSchemaType()
+                                    .substring(databaseName.length() + 1);
+                    propertyConfigBuilder.setSchemaType(newPropertySchemaType);
+                    typeConfigBuilder.setProperties(propertyIdx, propertyConfigBuilder);
+                }
+            }
+
+            AppSearchSchema schema = SchemaToProtoConverter.toAppSearchSchema(typeConfigBuilder);
+            result.add(schema);
+        }
+        return result;
     }
 
     /**
@@ -340,7 +370,7 @@
     public void putDocument(@NonNull String databaseName, @NonNull GenericDocument document)
             throws AppSearchException {
         DocumentProto.Builder documentBuilder =
-                GenericDocumentToProtoConverter.convert(document).toBuilder();
+                GenericDocumentToProtoConverter.toDocumentProto(document).toBuilder();
         addPrefixToDocument(documentBuilder, getDatabasePrefix(databaseName));
 
         PutResultProto putResultProto;
@@ -384,7 +414,7 @@
 
         DocumentProto.Builder documentBuilder = getResultProto.getDocument().toBuilder();
         removeDatabasesFromDocument(documentBuilder);
-        return GenericDocumentToProtoConverter.convert(documentBuilder.build());
+        return GenericDocumentToProtoConverter.toGenericDocument(documentBuilder.build());
     }
 
     /**
@@ -969,7 +999,7 @@
                 resultsBuilder.setResults(i, resultBuilder);
             }
         }
-        return SearchResultToProtoConverter.convertToSearchResultPage(resultsBuilder);
+        return SearchResultToProtoConverter.toSearchResultPage(resultsBuilder);
     }
 
     @GuardedBy("mReadWriteLock")
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/VisibilityStore.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/VisibilityStore.java
index 4722822..0b68ebc 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/VisibilityStore.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/VisibilityStore.java
@@ -53,19 +53,23 @@
 class VisibilityStore {
     // Schema type for documents that hold AppSearch's metadata, e.g. visibility settings
     @VisibleForTesting static final String SCHEMA_TYPE = "Visibility";
+
     // Property that holds the list of platform-hidden schemas, as part of the visibility
     // settings.
-    @VisibleForTesting static final String PLATFORM_HIDDEN_PROPERTY = "platformHidden";
+    @VisibleForTesting
+    static final String NOT_PLATFORM_SURFACEABLE_PROPERTY = "notPlatformSurfaceable";
     // Database name to prefix all visibility schemas and documents with. Special-cased to
     // minimize the chance of collision with a client-supplied database.
+
     @VisibleForTesting static final String DATABASE_NAME = "$$__AppSearch__Database";
+
     // Namespace of documents that contain visibility settings
     private static final String NAMESPACE = "namespace";
     private final AppSearchImpl mAppSearchImpl;
 
     // The map contains schemas that are platform-hidden for each database. All schemas in the map
     // have a database name prefix.
-    private final Map<String, Set<String>> mPlatformHiddenMap = new ArrayMap<>();
+    private final Map<String, Set<String>> mNotPlatformSurfaceableMap = new ArrayMap<>();
 
     /**
      * Creates an uninitialized VisibilityStore object. Callers must also call {@link #initialize()}
@@ -82,8 +86,8 @@
      *
      * <p>This is kept separate from the constructor because this will call methods on
      * AppSearchImpl. Some may even then recursively call back into VisibilityStore (for example,
-     * {@link AppSearchImpl#setSchema} will call {@link #updateSchemas}. We need to have both
-     * AppSearchImpl and VisibilityStore fully initialized for this call flow to work.
+     * {@link AppSearchImpl#setSchema} will call {@link #setVisibility(String, Set)}. We need to
+     * have both AppSearchImpl and VisibilityStore fully initialized for this call flow to work.
      *
      * @throws AppSearchException AppSearchException on AppSearchImpl error.
      */
@@ -92,11 +96,11 @@
             // Schema type doesn't exist yet. Add it.
             mAppSearchImpl.setSchema(
                     DATABASE_NAME,
-                    Collections.singleton(
+                    Collections.singletonList(
                             new AppSearchSchema.Builder(SCHEMA_TYPE)
                                     .addProperty(
                                             new AppSearchSchema.PropertyConfig.Builder(
-                                                            PLATFORM_HIDDEN_PROPERTY)
+                                                            NOT_PLATFORM_SURFACEABLE_PROPERTY)
                                                     .setDataType(
                                                             AppSearchSchema.PropertyConfig
                                                                     .DATA_TYPE_STRING)
@@ -105,6 +109,7 @@
                                                                     .CARDINALITY_REPEATED)
                                                     .build())
                                     .build()),
+                    /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                     /*forceOverride=*/ false);
         }
 
@@ -120,8 +125,9 @@
                 GenericDocument document =
                         mAppSearchImpl.getDocument(DATABASE_NAME, NAMESPACE, /*uri=*/ database);
 
-                String[] schemas = document.getPropertyStringArray(PLATFORM_HIDDEN_PROPERTY);
-                mPlatformHiddenMap.put(database, new ArraySet<>(Arrays.asList(schemas)));
+                String[] schemas =
+                        document.getPropertyStringArray(NOT_PLATFORM_SURFACEABLE_PROPERTY);
+                mNotPlatformSurfaceableMap.put(database, new ArraySet<>(Arrays.asList(schemas)));
             } catch (AppSearchException e) {
                 if (e.getResultCode() == AppSearchResult.RESULT_NOT_FOUND) {
                     // TODO(b/172068212): This indicates some desync error. We were expecting a
@@ -136,94 +142,33 @@
     }
 
     /**
-     * Update visibility settings for the {@code databaseName}.
-     *
-     * @param schemasToRemove Database-prefixed schemas that should be removed
-     */
-    public void updateSchemas(@NonNull String databaseName, @NonNull Set<String> schemasToRemove)
-            throws AppSearchException {
-        Preconditions.checkNotNull(databaseName);
-        Preconditions.checkNotNull(schemasToRemove);
-
-        GenericDocument visibilityDocument;
-        try {
-            visibilityDocument =
-                    mAppSearchImpl.getDocument(DATABASE_NAME, NAMESPACE, /*uri=*/ databaseName);
-        } catch (AppSearchException e) {
-            if (e.getResultCode() == AppSearchResult.RESULT_NOT_FOUND) {
-                // This might be the first time we're seeing visibility changes for a database.
-                // Create a new visibility document.
-                mAppSearchImpl.putDocument(
-                        DATABASE_NAME,
-                        new GenericDocument.Builder(/*uri=*/ databaseName, SCHEMA_TYPE)
-                                .setNamespace(NAMESPACE)
-                                .build());
-
-                // Since we know there was nothing that existed before, we don't need to remove
-                // anything either. Return early.
-                return;
-            }
-            // Otherwise, this is some real error we should pass up.
-            throw e;
-        }
-
-        String[] hiddenSchemas =
-                visibilityDocument.getPropertyStringArray(PLATFORM_HIDDEN_PROPERTY);
-        if (hiddenSchemas == null) {
-            // Nothing to remove.
-            return;
-        }
-
-        // Create a new set so we can remove from it.
-        Set<String> remainingSchemas = new ArraySet<>(Arrays.asList(hiddenSchemas));
-        boolean changed = remainingSchemas.removeAll(schemasToRemove);
-        if (!changed) {
-            // Nothing was actually removed. Can return early.
-            return;
-        }
-
-        // Update our persisted document
-        // TODO(b/171882200): Switch to a .toBuilder API when it's available.
-        GenericDocument.Builder newVisibilityDocument =
-                new GenericDocument.Builder(/*uri=*/ databaseName, SCHEMA_TYPE)
-                        .setNamespace(NAMESPACE);
-        if (!remainingSchemas.isEmpty()) {
-            newVisibilityDocument.setPropertyString(
-                    PLATFORM_HIDDEN_PROPERTY, remainingSchemas.toArray(new String[0]));
-        }
-        mAppSearchImpl.putDocument(DATABASE_NAME, newVisibilityDocument.build());
-
-        // Update derived data structures
-        mPlatformHiddenMap.put(databaseName, remainingSchemas);
-    }
-
-    /**
      * Sets visibility settings for {@code databaseName}. Any previous visibility settings will be
      * overwritten.
      *
-     * @param databaseName Database name that owns the {@code platformHiddenSchemas}.
-     * @param platformHiddenSchemas Set of database-qualified schemas that should be hidden from the
-     *     platform.
+     * @param databaseName Database name that owns the {@code schemasNotPlatformSurfaceable}.
+     * @param schemasNotPlatformSurfaceable Set of database-qualified schemas that should be hidden
+     *     from the platform.
      * @throws AppSearchException on AppSearchImpl error.
      */
     public void setVisibility(
-            @NonNull String databaseName, @NonNull Set<String> platformHiddenSchemas)
+            @NonNull String databaseName, @NonNull Set<String> schemasNotPlatformSurfaceable)
             throws AppSearchException {
         Preconditions.checkNotNull(databaseName);
-        Preconditions.checkNotNull(platformHiddenSchemas);
+        Preconditions.checkNotNull(schemasNotPlatformSurfaceable);
 
         // Persist the document
         GenericDocument.Builder visibilityDocument =
                 new GenericDocument.Builder(/*uri=*/ databaseName, SCHEMA_TYPE)
                         .setNamespace(NAMESPACE);
-        if (!platformHiddenSchemas.isEmpty()) {
+        if (!schemasNotPlatformSurfaceable.isEmpty()) {
             visibilityDocument.setPropertyString(
-                    PLATFORM_HIDDEN_PROPERTY, platformHiddenSchemas.toArray(new String[0]));
+                    NOT_PLATFORM_SURFACEABLE_PROPERTY,
+                    schemasNotPlatformSurfaceable.toArray(new String[0]));
         }
         mAppSearchImpl.putDocument(DATABASE_NAME, visibilityDocument.build());
 
         // Update derived data structures.
-        mPlatformHiddenMap.put(databaseName, platformHiddenSchemas);
+        mNotPlatformSurfaceableMap.put(databaseName, schemasNotPlatformSurfaceable);
     }
 
     /**
@@ -235,13 +180,13 @@
      *     none exist.
      */
     @NonNull
-    public Set<String> getPlatformHiddenSchemas(@NonNull String databaseName) {
+    public Set<String> getSchemasNotPlatformSurfaceable(@NonNull String databaseName) {
         Preconditions.checkNotNull(databaseName);
-        Set<String> platformHiddenSchemas = mPlatformHiddenMap.get(databaseName);
-        if (platformHiddenSchemas == null) {
+        Set<String> schemasNotPlatformSurfaceable = mNotPlatformSurfaceableMap.get(databaseName);
+        if (schemasNotPlatformSurfaceable == null) {
             return Collections.emptySet();
         }
-        return platformHiddenSchemas;
+        return schemasNotPlatformSurfaceable;
     }
 
     /**
@@ -251,7 +196,7 @@
      * @throws AppSearchException on AppSearchImpl error.
      */
     public void handleReset() throws AppSearchException {
-        mPlatformHiddenMap.clear();
+        mNotPlatformSurfaceableMap.clear();
         initialize();
     }
 }
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
index 8f4e7ff6..5474cd0 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
@@ -39,7 +39,7 @@
     /** Converts a {@link GenericDocument} into a {@link DocumentProto}. */
     @NonNull
     @SuppressWarnings("unchecked")
-    public static DocumentProto convert(@NonNull GenericDocument document) {
+    public static DocumentProto toDocumentProto(@NonNull GenericDocument document) {
         Preconditions.checkNotNull(document);
         DocumentProto.Builder mProtoBuilder = DocumentProto.newBuilder();
         mProtoBuilder
@@ -82,7 +82,7 @@
                 }
             } else if (documentValues != null) {
                 for (int j = 0; j < documentValues.length; j++) {
-                    DocumentProto proto = convert(documentValues[j]);
+                    DocumentProto proto = toDocumentProto(documentValues[j]);
                     propertyProto.addDocumentValues(proto);
                 }
             } else {
@@ -96,7 +96,7 @@
 
     /** Converts a {@link DocumentProto} into a {@link GenericDocument}. */
     @NonNull
-    public static GenericDocument convert(@NonNull DocumentProto proto) {
+    public static GenericDocument toGenericDocument(@NonNull DocumentProto proto) {
         Preconditions.checkNotNull(proto);
         GenericDocument.Builder<?> documentBuilder =
                 new GenericDocument.Builder<>(proto.getUri(), proto.getSchema())
@@ -141,7 +141,7 @@
             } else if (property.getDocumentValuesCount() > 0) {
                 GenericDocument[] values = new GenericDocument[property.getDocumentValuesCount()];
                 for (int j = 0; j < values.length; j++) {
-                    values[j] = convert(property.getDocumentValues(j));
+                    values[j] = toGenericDocument(property.getDocumentValues(j));
                 }
                 documentBuilder.setPropertyDocument(name, values);
             } else {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
index 642c2a7..4165af3 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
@@ -18,11 +18,13 @@
 
 import android.annotation.NonNull;
 import android.app.appsearch.AppSearchSchema;
+import android.util.Log;
 
 import com.android.internal.util.Preconditions;
 
 import com.google.android.icing.proto.PropertyConfigProto;
 import com.google.android.icing.proto.SchemaTypeConfigProto;
+import com.google.android.icing.proto.SchemaTypeConfigProtoOrBuilder;
 import com.google.android.icing.proto.StringIndexingConfig;
 import com.google.android.icing.proto.TermMatchType;
 
@@ -34,6 +36,8 @@
  * @hide
  */
 public final class SchemaToProtoConverter {
+    private static final String TAG = "AppSearchSchemaToProtoC";
+
     private SchemaToProtoConverter() {}
 
     /**
@@ -41,23 +45,23 @@
      * SchemaTypeConfigProto}.
      */
     @NonNull
-    public static SchemaTypeConfigProto convert(@NonNull AppSearchSchema schema) {
+    public static SchemaTypeConfigProto toSchemaTypeConfigProto(@NonNull AppSearchSchema schema) {
         Preconditions.checkNotNull(schema);
         SchemaTypeConfigProto.Builder protoBuilder =
                 SchemaTypeConfigProto.newBuilder().setSchemaType(schema.getSchemaType());
         List<AppSearchSchema.PropertyConfig> properties = schema.getProperties();
         for (int i = 0; i < properties.size(); i++) {
-            PropertyConfigProto propertyProto = convertProperty(properties.get(i));
+            PropertyConfigProto propertyProto = toPropertyConfigProto(properties.get(i));
             protoBuilder.addProperties(propertyProto);
         }
         return protoBuilder.build();
     }
 
     @NonNull
-    private static PropertyConfigProto convertProperty(
+    private static PropertyConfigProto toPropertyConfigProto(
             @NonNull AppSearchSchema.PropertyConfig property) {
         Preconditions.checkNotNull(property);
-        PropertyConfigProto.Builder propertyConfigProto =
+        PropertyConfigProto.Builder builder =
                 PropertyConfigProto.newBuilder().setPropertyName(property.getName());
         StringIndexingConfig.Builder indexingConfig = StringIndexingConfig.newBuilder();
 
@@ -68,12 +72,12 @@
         if (dataTypeProto == null) {
             throw new IllegalArgumentException("Invalid dataType: " + dataType);
         }
-        propertyConfigProto.setDataType(dataTypeProto);
+        builder.setDataType(dataTypeProto);
 
         // Set schemaType
         String schemaType = property.getSchemaType();
         if (schemaType != null) {
-            propertyConfigProto.setSchemaType(schemaType);
+            builder.setSchemaType(schemaType);
         }
 
         // Set cardinality
@@ -83,7 +87,7 @@
         if (cardinalityProto == null) {
             throw new IllegalArgumentException("Invalid cardinality: " + dataType);
         }
-        propertyConfigProto.setCardinality(cardinalityProto);
+        builder.setCardinality(cardinalityProto);
 
         // Set indexingType
         @AppSearchSchema.PropertyConfig.IndexingType int indexingType = property.getIndexingType();
@@ -114,7 +118,63 @@
         indexingConfig.setTokenizerType(tokenizerTypeProto);
 
         // Build!
-        propertyConfigProto.setStringIndexingConfig(indexingConfig);
-        return propertyConfigProto.build();
+        builder.setStringIndexingConfig(indexingConfig);
+        return builder.build();
+    }
+
+    /**
+     * Converts a {@link SchemaTypeConfigProto} into an {@link
+     * android.app.appsearch.AppSearchSchema}.
+     */
+    @NonNull
+    public static AppSearchSchema toAppSearchSchema(@NonNull SchemaTypeConfigProtoOrBuilder proto) {
+        Preconditions.checkNotNull(proto);
+        AppSearchSchema.Builder builder = new AppSearchSchema.Builder(proto.getSchemaType());
+        List<PropertyConfigProto> properties = proto.getPropertiesList();
+        for (int i = 0; i < properties.size(); i++) {
+            AppSearchSchema.PropertyConfig propertyConfig = toPropertyConfig(properties.get(i));
+            builder.addProperty(propertyConfig);
+        }
+        return builder.build();
+    }
+
+    @NonNull
+    private static AppSearchSchema.PropertyConfig toPropertyConfig(
+            @NonNull PropertyConfigProto proto) {
+        Preconditions.checkNotNull(proto);
+        AppSearchSchema.PropertyConfig.Builder builder =
+                new AppSearchSchema.PropertyConfig.Builder(proto.getPropertyName())
+                        .setDataType(proto.getDataType().getNumber())
+                        .setCardinality(proto.getCardinality().getNumber())
+                        .setTokenizerType(
+                                proto.getStringIndexingConfig().getTokenizerType().getNumber());
+
+        // Set schema
+        if (!proto.getSchemaType().isEmpty()) {
+            builder.setSchemaType(proto.getSchemaType());
+        }
+
+        // Set indexingType
+        @AppSearchSchema.PropertyConfig.IndexingType int indexingType;
+        TermMatchType.Code termMatchTypeProto = proto.getStringIndexingConfig().getTermMatchType();
+        switch (termMatchTypeProto) {
+            case UNKNOWN:
+                indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE;
+                break;
+            case EXACT_ONLY:
+                indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_EXACT_TERMS;
+                break;
+            case PREFIX:
+                indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_PREFIXES;
+                break;
+            default:
+                // Avoid crashing in the 'read' path; we should try to interpret the document to the
+                // extent possible.
+                Log.w(TAG, "Invalid indexingType: " + termMatchTypeProto.getNumber());
+                indexingType = AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE;
+        }
+        builder.setIndexingType(indexingType);
+
+        return builder.build();
     }
 }
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
index b91a393..4d107a9 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
@@ -39,13 +39,12 @@
 
     /** Translate a {@link SearchResultProto} into {@link SearchResultPage}. */
     @NonNull
-    public static SearchResultPage convertToSearchResultPage(
-            @NonNull SearchResultProtoOrBuilder proto) {
+    public static SearchResultPage toSearchResultPage(@NonNull SearchResultProtoOrBuilder proto) {
         Bundle bundle = new Bundle();
         bundle.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, proto.getNextPageToken());
         ArrayList<Bundle> resultBundles = new ArrayList<>(proto.getResultsCount());
         for (int i = 0; i < proto.getResultsCount(); i++) {
-            resultBundles.add(convertToSearchResultBundle(proto.getResults(i)));
+            resultBundles.add(toSearchResultBundle(proto.getResults(i)));
         }
         bundle.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, resultBundles);
         return new SearchResultPage(bundle);
@@ -53,10 +52,11 @@
 
     /** Translate a {@link SearchResultProto.ResultProto} into {@link SearchResult}. */
     @NonNull
-    private static Bundle convertToSearchResultBundle(
+    private static Bundle toSearchResultBundle(
             @NonNull SearchResultProto.ResultProtoOrBuilder proto) {
         Bundle bundle = new Bundle();
-        GenericDocument document = GenericDocumentToProtoConverter.convert(proto.getDocument());
+        GenericDocument document =
+                GenericDocumentToProtoConverter.toGenericDocument(proto.getDocument());
         bundle.putBundle(SearchResult.DOCUMENT_FIELD, document.getBundle());
 
         ArrayList<Bundle> matchList = new ArrayList<>();
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index a2bf0d5..57c48d8 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-I2decd83fab4c4d58fe38c9970f804046479c942c
+If5fd2bd705d5507d044706701a94b2e1496ef1df
diff --git a/apex/jobscheduler/OWNERS b/apex/jobscheduler/OWNERS
index d004eed..0fe6cdf 100644
--- a/apex/jobscheduler/OWNERS
+++ b/apex/jobscheduler/OWNERS
@@ -1,6 +1,6 @@
 yamasani@google.com
 omakoto@google.com
-ctate@android.com
+ctate@google.com
 ctate@google.com
 kwekua@google.com
 suprabh@google.com
\ No newline at end of file
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index 3597c27..d16217d 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -274,13 +274,20 @@
 
     /**
      * This job needs to be exempted from the app standby throttling. Only the system (UID 1000)
-     * can set it. Jobs with a time constrant must not have it.
+     * can set it. Jobs with a time constraint must not have it.
      *
      * @hide
      */
     public static final int FLAG_EXEMPT_FROM_APP_STANDBY = 1 << 3;
 
     /**
+     * Whether it's a so-called "HPJ" or not.
+     *
+     * @hide
+     */
+    public static final int FLAG_FOREGROUND_JOB = 1 << 4;
+
+    /**
      * @hide
      */
     public static final int CONSTRAINT_FLAG_CHARGING = 1 << 0;
@@ -571,6 +578,7 @@
 
     /**
      * Return the backoff policy of this job.
+     *
      * @see JobInfo.Builder#setBackoffCriteria(long, int)
      */
     public @BackoffPolicy int getBackoffPolicy() {
@@ -578,6 +586,13 @@
     }
 
     /**
+     * @see JobInfo.Builder#setForeground(boolean)
+     */
+    public boolean isForegroundJob() {
+        return (flags & FLAG_FOREGROUND_JOB) != 0;
+    }
+
+    /**
      * @see JobInfo.Builder#setImportantWhileForeground(boolean)
      */
     public boolean isImportantWhileForeground() {
@@ -1442,6 +1457,41 @@
         }
 
         /**
+         * Setting this to true indicates that this job is important and needs to run as soon as
+         * possible with stronger guarantees than regular jobs. These "foreground" jobs will:
+         * <ol>
+         *     <li>Run as soon as possible</li>
+         *     <li>Be exempted from Doze and battery saver restrictions</li>
+         *     <li>Have network access</li>
+         * </ol>
+         *
+         * Since these jobs have stronger guarantees than regular jobs, they will be subject to
+         * stricter quotas. As long as an app has available foreground quota, jobs scheduled with
+         * this set to true will run with these guarantees. If an app has run out of available
+         * foreground quota, any pending foreground jobs will run as regular jobs.
+         * {@link JobParameters#isForegroundJob()} can be used to know whether the executing job
+         * has foreground guarantees or not. In addition, {@link JobScheduler#schedule(JobInfo)}
+         * will immediately return {@link JobScheduler#RESULT_FAILURE} if the app does not have
+         * available quota (and the job will not be successfully scheduled).
+         *
+         * Foreground jobs may only set network constraints. No other constraints are allowed.
+         *
+         * Note: Even though foreground jobs are meant to run as soon as possible, they may be
+         * deferred if the system is under heavy load or the network constraint is satisfied
+         *
+         * @see JobInfo#isForegroundJob()
+         */
+        @NonNull
+        public Builder setForeground(boolean foreground) {
+            if (foreground) {
+                mFlags |= FLAG_FOREGROUND_JOB;
+            } else {
+                mFlags &= (~FLAG_FOREGROUND_JOB);
+            }
+            return this;
+        }
+
+        /**
          * Setting this to true indicates that this job is important while the scheduling app
          * is in the foreground or on the temporary whitelist for background restrictions.
          * This means that the system will relax doze restrictions on this job during this time.
@@ -1456,7 +1506,9 @@
          * @param importantWhileForeground whether to relax doze restrictions for this job when the
          *                                 app is in the foreground. False by default.
          * @see JobInfo#isImportantWhileForeground()
+         * @deprecated Use {@link #setForeground(boolean)} instead.
          */
+        @Deprecated
         public Builder setImportantWhileForeground(boolean importantWhileForeground) {
             if (importantWhileForeground) {
                 mFlags |= FLAG_IMPORTANT_WHILE_FOREGROUND;
@@ -1580,6 +1632,29 @@
             throw new IllegalArgumentException(
                     "An important while foreground job cannot have a time delay");
         }
+
+        if ((flags & FLAG_FOREGROUND_JOB) != 0) {
+            if (hasEarlyConstraint) {
+                throw new IllegalArgumentException("A foreground job cannot have a time delay");
+            }
+            if (hasLateConstraint) {
+                throw new IllegalArgumentException("A foreground job cannot have a deadline");
+            }
+            if (isPeriodic) {
+                throw new IllegalArgumentException("A foreground job cannot be periodic");
+            }
+            if (isPersisted) {
+                throw new IllegalArgumentException("A foreground job cannot be persisted");
+            }
+            if (constraintFlags != 0 || (flags & ~FLAG_FOREGROUND_JOB) != 0) {
+                throw new IllegalArgumentException(
+                        "A foreground job can only have network constraints");
+            }
+            if (triggerContentUris != null && triggerContentUris.length > 0) {
+                throw new IllegalArgumentException(
+                        "Can't call addTriggerContentUri() on a foreground job");
+            }
+        }
     }
 
     /**
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
index e251ff0..a71b856 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
@@ -111,6 +111,9 @@
     @UnsupportedAppUsage
     private final IBinder callback;
     private final boolean overrideDeadlineExpired;
+    // HPJs = foreground jobs.
+    // TODO(171305774): clean up naming
+    private final boolean mIsHpj;
     private final Uri[] mTriggeredContentUris;
     private final String[] mTriggeredContentAuthorities;
     private final Network network;
@@ -121,7 +124,7 @@
     /** @hide */
     public JobParameters(IBinder callback, int jobId, PersistableBundle extras,
             Bundle transientExtras, ClipData clipData, int clipGrantFlags,
-            boolean overrideDeadlineExpired, Uri[] triggeredContentUris,
+            boolean overrideDeadlineExpired, boolean isHpj, Uri[] triggeredContentUris,
             String[] triggeredContentAuthorities, Network network) {
         this.jobId = jobId;
         this.extras = extras;
@@ -130,6 +133,7 @@
         this.clipGrantFlags = clipGrantFlags;
         this.callback = callback;
         this.overrideDeadlineExpired = overrideDeadlineExpired;
+        this.mIsHpj = isHpj;
         this.mTriggeredContentUris = triggeredContentUris;
         this.mTriggeredContentAuthorities = triggeredContentAuthorities;
         this.network = network;
@@ -195,6 +199,17 @@
     }
 
     /**
+     * @return Whether this job is running as a foreground job or not. A job is guaranteed to have
+     * all foreground job guarantees for the duration of the job execution if this returns
+     * {@code true}. This will return {@code false} if the job that wasn't requested to run as a
+     * foreground job, or if it was requested to run as a foreground job but the app didn't have
+     * any remaining foreground job quota at the time of execution.
+     */
+    public boolean isForegroundJob() {
+        return mIsHpj;
+    }
+
+    /**
      * For jobs with {@link android.app.job.JobInfo.Builder#setOverrideDeadline(long)} set, this
      * provides an easy way to tell whether the job is being executed due to the deadline
      * expiring. Note: If the job is running because its deadline expired, it implies that its
@@ -337,6 +352,7 @@
         }
         callback = in.readStrongBinder();
         overrideDeadlineExpired = in.readInt() == 1;
+        mIsHpj = in.readBoolean();
         mTriggeredContentUris = in.createTypedArray(Uri.CREATOR);
         mTriggeredContentAuthorities = in.createStringArray();
         if (in.readInt() != 0) {
@@ -373,6 +389,7 @@
         }
         dest.writeStrongBinder(callback);
         dest.writeInt(overrideDeadlineExpired ? 1 : 0);
+        dest.writeBoolean(mIsHpj);
         dest.writeTypedArray(mTriggeredContentUris, flags);
         dest.writeStringArray(mTriggeredContentAuthorities);
         if (network != null) {
diff --git a/apex/jobscheduler/framework/java/android/app/job/OWNERS b/apex/jobscheduler/framework/java/android/app/job/OWNERS
new file mode 100644
index 0000000..b4a45f5
--- /dev/null
+++ b/apex/jobscheduler/framework/java/android/app/job/OWNERS
@@ -0,0 +1,7 @@
+# Bug component: 330738
+
+yamasani@google.com
+omakoto@google.com
+ctate@android.com
+ctate@google.com
+kwekua@google.com
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index b35a7be..0feaade 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -205,7 +205,9 @@
     }
 
     private boolean isFgJob(JobStatus job) {
-        return job.lastEvaluatedPriority >= JobInfo.PRIORITY_TOP_APP;
+        // (It's super confusing PRIORITY_BOUND_FOREGROUND_SERVICE isn't FG here)
+        return job.lastEvaluatedPriority >= JobInfo.PRIORITY_TOP_APP
+                || job.shouldTreatAsForegroundJob();
     }
 
     @GuardedBy("mLock")
@@ -336,6 +338,8 @@
                 continue;
             }
 
+            // TODO(171305774): make sure HPJs aren't pre-empted and add dedicated contexts for them
+
             final boolean isPendingFg = isFgJob(nextPending);
 
             // Find an available slot for nextPending. The context should be available OR
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 255e2f6..99a9b979 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -834,6 +834,13 @@
             // Higher override state (OVERRIDE_FULL) should be before lower state (OVERRIDE_SOFT)
             return o2.overrideState - o1.overrideState;
         }
+        if (o1.getSourceUid() == o2.getSourceUid()) {
+            final boolean o1FGJ = o1.isRequestedForegroundJob();
+            if (o1FGJ != o2.isRequestedForegroundJob()) {
+                // Attempt to run requested HPJs ahead of regular jobs, regardless of HPJ quota.
+                return o1FGJ ? -1 : 1;
+            }
+        }
         if (o1.enqueueTime < o2.enqueueTime) {
             return -1;
         }
@@ -1136,6 +1143,12 @@
 
             JobStatus jobStatus = JobStatus.createFromJobInfo(job, uId, packageName, userId, tag);
 
+            // Return failure early if HPJ quota used up.
+            if (jobStatus.isRequestedForegroundJob()
+                    && !mQuotaController.isWithinHpjQuotaLocked(jobStatus)) {
+                return JobScheduler.RESULT_FAILURE;
+            }
+
             // Give exemption if the source is in the foreground just now.
             // Note if it's a sync job, this method is called on the handler so it's not exactly
             // the state when requestSync() was called, but that should be fine because of the
@@ -1791,9 +1804,9 @@
      * time of the job to be the time of completion (i.e. the time at which this function is
      * called).
      * <p>This could be inaccurate b/c the job can run for as long as
-     * {@link com.android.server.job.JobServiceContext#EXECUTING_TIMESLICE_MILLIS}, but will lead
-     * to underscheduling at least, rather than if we had taken the last execution time to be the
-     * start of the execution.
+     * {@link com.android.server.job.JobServiceContext#DEFAULT_EXECUTING_TIMESLICE_MILLIS}, but
+     * will lead to underscheduling at least, rather than if we had taken the last execution time
+     * to be the start of the execution.
      *
      * @return A new job representing the execution criteria for this instantiation of the
      * recurring job.
@@ -1884,6 +1897,10 @@
             Slog.d(TAG, "Completed " + jobStatus + ", reschedule=" + needsReschedule);
         }
 
+        // Intentionally not checking HPJ quota here. An app can't find out if it's run out of quota
+        // when it asks JS to reschedule an HPJ. Instead, the rescheduled HPJ will just be demoted
+        // to a regular job if the app has no HPJ quota left.
+
         // If the job wants to be rescheduled, we first need to make the next upcoming
         // job so we can transfer any appropriate state over from the previous job when
         // we stop it.
@@ -2027,7 +2044,6 @@
 
                 }
                 maybeRunPendingJobsLocked();
-                // Don't remove JOB_EXPIRED in case one came along while processing the queue.
             }
         }
     }
@@ -2093,6 +2109,15 @@
      * as many as we can.
      */
     private void queueReadyJobsForExecutionLocked() {
+        // This method will check and capture all ready jobs, so we don't need to keep any messages
+        // in the queue.
+        mHandler.removeMessages(MSG_CHECK_JOB_GREEDY);
+        // MSG_CHECK_JOB is a weaker form of _GREEDY. Since we're checking and queueing all ready
+        // jobs, we don't need to keep any MSG_CHECK_JOB messages in the queue.
+        mHandler.removeMessages(MSG_CHECK_JOB);
+        // This method will capture all expired jobs that are ready, so there's no need to keep
+        // the _EXPIRED messages in the queue.
+        mHandler.removeMessages(MSG_JOB_EXPIRED);
         if (DEBUG) {
             Slog.d(TAG, "queuing all ready jobs for execution:");
         }
@@ -2382,7 +2407,7 @@
     public long getMaxJobExecutionTimeMs(JobStatus job) {
         synchronized (mLock) {
             return Math.min(mQuotaController.getMaxJobExecutionTimeMsLocked(job),
-                    JobServiceContext.EXECUTING_TIMESLICE_MILLIS);
+                    JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS);
         }
     }
 
@@ -2600,7 +2625,6 @@
         // job that runs one of the app's services, as well as verifying that the
         // named service properly requires the BIND_JOB_SERVICE permission
         private void enforceValidJobRequest(int uid, JobInfo job) {
-            job.enforceValidity();
             final PackageManager pm = getContext()
                     .createContextAsUser(UserHandle.getUserHandleForUid(uid), 0)
                     .getPackageManager();
@@ -2649,6 +2673,7 @@
         }
 
         private void validateJobFlags(JobInfo job, int callingUid) {
+            job.enforceValidity();
             if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) {
                 getContext().enforceCallingOrSelfPermission(
                         android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 565ed95..5fed199 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -16,6 +16,7 @@
 
 package com.android.server.job;
 
+import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 
 import android.app.job.IJobCallback;
@@ -73,7 +74,13 @@
 
     private static final String TAG = "JobServiceContext";
     /** Amount of time a job is allowed to execute for before being considered timed-out. */
-    public static final long EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000;  // 10mins.
+    public static final long DEFAULT_EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000;  // 10mins.
+    /**
+     * Amount of time a RESTRICTED HPJ is allowed to execute for before being considered
+     * timed-out.
+     */
+    public static final long DEFAULT_RESTRICTED_HPJ_EXECUTING_TIMESLICE_MILLIS =
+            DEFAULT_EXECUTING_TIMESLICE_MILLIS / 2;
     /** Amount of time the JobScheduler waits for the initial service launch+bind. */
     private static final long OP_BIND_TIMEOUT_MILLIS = 18 * 1000;
     /** Amount of time the JobScheduler will wait for a response from an app for a message. */
@@ -224,7 +231,8 @@
             final JobInfo ji = job.getJob();
             mParams = new JobParameters(mRunningCallback, job.getJobId(), ji.getExtras(),
                     ji.getTransientExtras(), ji.getClipData(), ji.getClipGrantFlags(),
-                    isDeadlineExpired, triggeredUris, triggeredAuthorities, job.network);
+                    isDeadlineExpired, job.shouldTreatAsForegroundJob(),
+                    triggeredUris, triggeredAuthorities, job.network);
             mExecutionStartTimeElapsed = sElapsedRealtimeClock.millis();
 
             final long whenDeferred = job.getWhenStandbyDeferred();
@@ -250,9 +258,18 @@
             final Intent intent = new Intent().setComponent(job.getServiceComponent());
             boolean binding = false;
             try {
-                binding = mContext.bindServiceAsUser(intent, this,
-                        Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
-                        | Context.BIND_NOT_PERCEPTIBLE,
+                final int bindFlags;
+                if (job.shouldTreatAsForegroundJob()) {
+                    // Add BIND_FOREGROUND_SERVICE to make it BFGS. Without it, it'll be
+                    // PROCESS_STATE_IMPORTANT_FOREGROUND. Unclear which is better here.
+                    // TODO(171305774): The job should run on the little cores. We'll probably need
+                    // another binding flag for that.
+                    bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
+                } else {
+                    bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
+                            | Context.BIND_NOT_PERCEPTIBLE;
+                }
+                binding = mContext.bindServiceAsUser(intent, this, bindFlags,
                         UserHandle.of(job.getUserId()));
             } catch (SecurityException e) {
                 // Some permission policy, for example INTERACT_ACROSS_USERS and
@@ -848,7 +865,10 @@
         final long timeoutMillis;
         switch (mVerb) {
             case VERB_EXECUTING:
-                timeoutMillis = EXECUTING_TIMESLICE_MILLIS;
+                timeoutMillis = mRunningJob.shouldTreatAsForegroundJob()
+                        && mRunningJob.getStandbyBucket() == RESTRICTED_INDEX
+                        ? DEFAULT_RESTRICTED_HPJ_EXECUTING_TIMESLICE_MILLIS
+                        : DEFAULT_EXECUTING_TIMESLICE_MILLIS;
                 break;
 
             case VERB_BINDING:
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index 8f6c68d..5ec1b89 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -85,6 +85,7 @@
     static final int CONSTRAINT_CONTENT_TRIGGER = 1<<26;
     static final int CONSTRAINT_DEVICE_NOT_DOZING = 1 << 25; // Implicit constraint
     static final int CONSTRAINT_WITHIN_QUOTA = 1 << 24;      // Implicit constraint
+    static final int CONSTRAINT_WITHIN_HPJ_QUOTA = 1 << 23;  // Implicit constraint
     static final int CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 1 << 22; // Implicit constraint
 
     /**
@@ -376,6 +377,9 @@
     /** The job is within its quota based on its standby bucket. */
     private boolean mReadyWithinQuota;
 
+    /** The job is a foreground job with sufficient quota to run as a foreground job. */
+    private boolean mReadyWithinHpjQuota;
+
     /** The job's dynamic requirements have been satisfied. */
     private boolean mReadyDynamicSatisfied;
 
@@ -1036,20 +1040,34 @@
         mPersistedUtcTimes = null;
     }
 
+    /** @return true if the app has requested that this run as a foreground job. */
+    public boolean isRequestedForegroundJob() {
+        return (getFlags() & JobInfo.FLAG_FOREGROUND_JOB) != 0;
+    }
+
+    /**
+     * @return true if all foreground job requirements are satisfied and therefore this should be
+     * treated as a foreground job.
+     */
+    public boolean shouldTreatAsForegroundJob() {
+        return mReadyWithinHpjQuota && isRequestedForegroundJob();
+    }
+
     /**
      * @return true if the job is exempted from Doze restrictions and therefore allowed to run
      * in Doze.
      */
     public boolean canRunInDoze() {
-        return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
+        return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0 || shouldTreatAsForegroundJob();
     }
 
     boolean canRunInBatterySaver() {
-        return (getInternalFlags() & INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION) != 0;
+        return (getInternalFlags() & INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION) != 0
+                || shouldTreatAsForegroundJob();
     }
 
     boolean shouldIgnoreNetworkBlocking() {
-        return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
+        return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0 || shouldTreatAsForegroundJob();
     }
 
     /** @return true if the constraint was changed, false otherwise. */
@@ -1128,6 +1146,16 @@
         return false;
     }
 
+    /** @return true if the constraint was changed, false otherwise. */
+    boolean setForegroundJobQuotaConstraintSatisfied(boolean state) {
+        if (setConstraintSatisfied(CONSTRAINT_WITHIN_HPJ_QUOTA, state)) {
+            // The constraint was changed. Update the ready flag.
+            mReadyWithinHpjQuota = state;
+            return true;
+        }
+        return false;
+    }
+
     /** @return true if the state was changed, false otherwise. */
     boolean setUidActive(final boolean newActiveState) {
         if (newActiveState != uidActive) {
@@ -1257,6 +1285,10 @@
                 oldValue = mReadyWithinQuota;
                 mReadyWithinQuota = true;
                 break;
+            case CONSTRAINT_WITHIN_HPJ_QUOTA:
+                oldValue = mReadyWithinHpjQuota;
+                mReadyWithinHpjQuota = true;
+                break;
             default:
                 satisfied |= constraint;
                 mReadyDynamicSatisfied = mDynamicConstraints != 0
@@ -1279,6 +1311,9 @@
             case CONSTRAINT_WITHIN_QUOTA:
                 mReadyWithinQuota = oldValue;
                 break;
+            case CONSTRAINT_WITHIN_HPJ_QUOTA:
+                mReadyWithinHpjQuota = oldValue;
+                break;
             default:
                 mReadyDynamicSatisfied = mDynamicConstraints != 0
                         && mDynamicConstraints == (satisfiedConstraints & mDynamicConstraints);
@@ -1293,7 +1328,7 @@
         // sessions (exempt from dynamic restrictions), we need the additional check to ensure
         // that NEVER jobs don't run.
         // TODO: cleanup quota and standby bucket management so we don't need the additional checks
-        if ((!mReadyWithinQuota && !mReadyDynamicSatisfied)
+        if ((!mReadyWithinQuota && !mReadyDynamicSatisfied && !shouldTreatAsForegroundJob())
                 || getEffectiveStandbyBucket() == NEVER_INDEX) {
             return false;
         }
@@ -1506,6 +1541,9 @@
         if ((constraints & CONSTRAINT_WITHIN_QUOTA) != 0) {
             pw.print(" WITHIN_QUOTA");
         }
+        if ((constraints & CONSTRAINT_WITHIN_HPJ_QUOTA) != 0) {
+            pw.print(" WITHIN_HPJ_QUOTA");
+        }
         if (constraints != 0) {
             pw.print(" [0x");
             pw.print(Integer.toHexString(constraints));
@@ -1578,6 +1616,9 @@
         if ((constraints & CONSTRAINT_BACKGROUND_NOT_RESTRICTED) != 0) {
             proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_BACKGROUND_NOT_RESTRICTED);
         }
+        if ((constraints & CONSTRAINT_WITHIN_HPJ_QUOTA) != 0) {
+            proto.write(fieldId, JobServerProtoEnums.CONSTRAINT_WITHIN_HPJ_QUOTA);
+        }
     }
 
     private void dumpJobWorkItem(PrintWriter pw, String prefix, JobWorkItem work, int index) {
@@ -1795,6 +1836,11 @@
         pw.print(prefix);
         pw.print("  readyComponentEnabled: ");
         pw.println(serviceInfo != null);
+        if ((getFlags() & JobInfo.FLAG_FOREGROUND_JOB) != 0) {
+            pw.print(prefix);
+            pw.print("  mReadyWithinHpjQuota: ");
+            pw.println(mReadyWithinHpjQuota);
+        }
 
         if (changedAuthorities != null) {
             pw.print(prefix); pw.println("Changed authorities:");
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index 1d72b42..a3a20c6 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -36,6 +36,9 @@
 import android.app.AlarmManager;
 import android.app.AppGlobals;
 import android.app.IUidObserver;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManagerInternal;
+import android.app.usage.UsageStatsManagerInternal.UsageEventListener;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -53,6 +56,7 @@
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.SparseArrayMap;
 import android.util.SparseBooleanArray;
 import android.util.SparseSetArray;
@@ -297,10 +301,17 @@
     /** Timer for each package-userId combo. */
     private final SparseArrayMap<String, Timer> mPkgTimers = new SparseArrayMap<>();
 
-    /** List of all timing sessions for a package-userId combo, in chronological order. */
+    /** Timer for HPJs for each package-userId combo. */
+    private final SparseArrayMap<String, Timer> mHpjPkgTimers = new SparseArrayMap<>();
+
+    /** List of all regular timing sessions for a package-userId combo, in chronological order. */
     private final SparseArrayMap<String, List<TimingSession>> mTimingSessions =
             new SparseArrayMap<>();
 
+    /** List of all hpj timing sessions for a package-userId combo, in chronological order. */
+    private final SparseArrayMap<String, List<TimingSession>> mHpjTimingSessions =
+            new SparseArrayMap<>();
+
     /**
      * Listener to track and manage when each package comes back within quota.
      */
@@ -311,6 +322,10 @@
     private final SparseArrayMap<String, ExecutionStats[]> mExecutionStatsCache =
             new SparseArrayMap<>();
 
+    private final SparseArrayMap<String, ShrinkableDebits> mHpjStats = new SparseArrayMap<>();
+
+    private final SparseArrayMap<String, TopAppTimer> mTopAppTrackers = new SparseArrayMap<>();
+
     /** List of UIDs currently in the foreground. */
     private final SparseBooleanArray mForegroundUids = new SparseBooleanArray();
 
@@ -327,7 +342,7 @@
     private final ActivityManagerInternal mActivityManagerInternal;
     private final AlarmManager mAlarmManager;
     private final ChargingTracker mChargeTracker;
-    private final Handler mHandler;
+    private final QcHandler mHandler;
     private final QcConstants mQcConstants;
 
     /** How much time each app will have to run jobs within their standby bucket window. */
@@ -474,14 +489,63 @@
     private long mTimingSessionCoalescingDurationMs =
             QcConstants.DEFAULT_TIMING_SESSION_COALESCING_DURATION_MS;
 
+    /**
+     * The rolling window size for each standby bucket. Within each window, an app will have 10
+     * minutes to run its jobs.
+     */
+    private final long[] mHpjLimitsMs = new long[]{
+            QcConstants.DEFAULT_HPJ_LIMIT_ACTIVE_MS,
+            QcConstants.DEFAULT_HPJ_LIMIT_WORKING_MS,
+            QcConstants.DEFAULT_HPJ_LIMIT_FREQUENT_MS,
+            QcConstants.DEFAULT_HPJ_LIMIT_RARE_MS,
+            0, // NEVER
+            QcConstants.DEFAULT_HPJ_LIMIT_RESTRICTED_MS
+    };
+
+    /**
+     * The period of time used to calculate HPJ sessions. Apps can only have HPJ sessions
+     * totalling {@link #mHpjLimitsMs}[bucket within this period of time (without factoring in any
+     * rewards or free HPJs).
+     */
+    private long mHpjLimitWindowSizeMs = QcConstants.DEFAULT_HPJ_WINDOW_SIZE_MS;
+
+    /**
+     * Length of time used to split an app's top time into chunks.
+     */
+    public long mHpjTopAppTimeChunkSizeMs = QcConstants.DEFAULT_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS;
+
+    /**
+     * How much HPJ quota to give back to an app based on the number of top app time chunks it had.
+     */
+    public long mHpjRewardTopAppMs = QcConstants.DEFAULT_HPJ_REWARD_TOP_APP_MS;
+
+    /**
+     * How much HPJ quota to give back to an app based on each non-top user interaction.
+     */
+    public long mHpjRewardInteractionMs = QcConstants.DEFAULT_HPJ_REWARD_INTERACTION_MS;
+
+    /**
+     * How much HPJ quota to give back to an app based on each notification seen event.
+     */
+    public long mHpjRewardNotificationSeenMs = QcConstants.DEFAULT_HPJ_REWARD_NOTIFICATION_SEEN_MS;
+
     /** An app has reached its quota. The message should contain a {@link Package} object. */
-    private static final int MSG_REACHED_QUOTA = 0;
+    @VisibleForTesting
+    static final int MSG_REACHED_QUOTA = 0;
     /** Drop any old timing sessions. */
     private static final int MSG_CLEAN_UP_SESSIONS = 1;
     /** Check if a package is now within its quota. */
     private static final int MSG_CHECK_PACKAGE = 2;
     /** Process state for a UID has changed. */
     private static final int MSG_UID_PROCESS_STATE_CHANGED = 3;
+    /** An app has reached its HPJ quota. The message should contain a {@link Package} object. */
+    @VisibleForTesting
+    static final int MSG_REACHED_HPJ_QUOTA = 4;
+    /**
+     * Process a new {@link UsageEvents.Event}. The event will be the message's object and the
+     * userId will the first arg.
+     */
+    private static final int MSG_PROCESS_USAGE_EVENT = 5;
 
     public QuotaController(JobSchedulerService service) {
         super(service);
@@ -499,6 +563,9 @@
         AppStandbyInternal appStandby = LocalServices.getService(AppStandbyInternal.class);
         appStandby.addListener(new StandbyTracker());
 
+        UsageStatsManagerInternal usmi = LocalServices.getService(UsageStatsManagerInternal.class);
+        usmi.registerListener(new UsageEventTracker());
+
         try {
             ActivityManager.getService().registerUidObserver(mUidObserver,
                     ActivityManager.UID_OBSERVER_PROCSTATE,
@@ -521,7 +588,15 @@
         jobStatus.setTrackingController(JobStatus.TRACKING_QUOTA);
         final boolean isWithinQuota = isWithinQuotaLocked(jobStatus);
         setConstraintSatisfied(jobStatus, isWithinQuota);
-        if (!isWithinQuota) {
+        final boolean outOfHpjQuota;
+        if (jobStatus.isRequestedForegroundJob()) {
+            final boolean isWithinHpjQuota = isWithinHpjQuotaLocked(jobStatus);
+            jobStatus.setForegroundJobQuotaConstraintSatisfied(isWithinHpjQuota);
+            outOfHpjQuota = !isWithinHpjQuota;
+        } else {
+            outOfHpjQuota = false;
+        }
+        if (!isWithinQuota || outOfHpjQuota) {
             maybeScheduleStartAlarmLocked(userId, pkgName, jobStatus.getEffectiveStandbyBucket());
         }
     }
@@ -544,10 +619,12 @@
 
         final int userId = jobStatus.getSourceUserId();
         final String packageName = jobStatus.getSourcePackageName();
-        Timer timer = mPkgTimers.get(userId, packageName);
+        final SparseArrayMap<String, Timer> timerMap =
+                jobStatus.shouldTreatAsForegroundJob() ? mHpjPkgTimers : mPkgTimers;
+        Timer timer = timerMap.get(userId, packageName);
         if (timer == null) {
-            timer = new Timer(uid, userId, packageName);
-            mPkgTimers.add(userId, packageName, timer);
+            timer = new Timer(uid, userId, packageName, !jobStatus.shouldTreatAsForegroundJob());
+            timerMap.add(userId, packageName, timer);
         }
         timer.startTrackingJobLocked(jobStatus);
     }
@@ -561,6 +638,13 @@
             if (timer != null) {
                 timer.stopTrackingJob(jobStatus);
             }
+            if (jobStatus.isRequestedForegroundJob()) {
+                timer = mHpjPkgTimers.get(jobStatus.getSourceUserId(),
+                        jobStatus.getSourcePackageName());
+                if (timer != null) {
+                    timer.stopTrackingJob(jobStatus);
+                }
+            }
             ArraySet<JobStatus> jobs = mTrackedJobs.get(jobStatus.getSourceUserId(),
                     jobStatus.getSourcePackageName());
             if (jobs != null) {
@@ -585,26 +669,37 @@
     public void onUserRemovedLocked(int userId) {
         mTrackedJobs.delete(userId);
         mPkgTimers.delete(userId);
+        mHpjPkgTimers.delete(userId);
         mTimingSessions.delete(userId);
+        mHpjTimingSessions.delete(userId);
         mInQuotaAlarmListener.removeAlarmsLocked(userId);
         mExecutionStatsCache.delete(userId);
+        mHpjStats.delete(userId);
         mUidToPackageCache.clear();
     }
 
     /** Drop all historical stats and stop tracking any active sessions for the specified app. */
     public void clearAppStatsLocked(int userId, @NonNull String packageName) {
         mTrackedJobs.delete(userId, packageName);
-        Timer timer = mPkgTimers.get(userId, packageName);
+        Timer timer = mPkgTimers.delete(userId, packageName);
         if (timer != null) {
             if (timer.isActive()) {
                 Slog.e(TAG, "clearAppStats called before Timer turned off.");
                 timer.dropEverythingLocked();
             }
-            mPkgTimers.delete(userId, packageName);
+        }
+        timer = mHpjPkgTimers.delete(userId, packageName);
+        if (timer != null) {
+            if (timer.isActive()) {
+                Slog.e(TAG, "clearAppStats called before HPJ Timer turned off.");
+                timer.dropEverythingLocked();
+            }
         }
         mTimingSessions.delete(userId, packageName);
+        mHpjTimingSessions.delete(userId, packageName);
         mInQuotaAlarmListener.removeAlarmLocked(userId, packageName);
         mExecutionStatsCache.delete(userId, packageName);
+        mHpjStats.delete(userId, packageName);
     }
 
     private boolean isUidInForeground(int uid) {
@@ -627,11 +722,53 @@
         if (mChargeTracker.isCharging()
                 || isTopStartedJobLocked(jobStatus)
                 || isUidInForeground(jobStatus.getSourceUid())) {
-            return JobServiceContext.EXECUTING_TIMESLICE_MILLIS;
+            return JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS;
+        }
+        if (jobStatus.shouldTreatAsForegroundJob()) {
+            return jobStatus.getStandbyBucket() == RESTRICTED_INDEX
+                    ? JobServiceContext.DEFAULT_RESTRICTED_HPJ_EXECUTING_TIMESLICE_MILLIS
+                    : JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS;
         }
         return getRemainingExecutionTimeLocked(jobStatus);
     }
 
+    /** @return true if the job is within hpj quota. */
+    public boolean isWithinHpjQuotaLocked(@NonNull final JobStatus jobStatus) {
+        if (isQuotaFree(jobStatus.getEffectiveStandbyBucket())) {
+            return true;
+        }
+        // A job is within quota if one of the following is true:
+        //   1. it's already running (already executing HPJS should be allowed to finish)
+        //   2. the app is currently in the foreground
+        //   3. the app overall is within its quota
+        if (isTopStartedJobLocked(jobStatus) || isUidInForeground(jobStatus.getSourceUid())) {
+            return true;
+        }
+        Timer hpjTimer = mHpjPkgTimers.get(jobStatus.getSourceUserId(),
+                jobStatus.getSourcePackageName());
+        // Any already executing HPJs should be allowed to finish.
+        if (hpjTimer != null && hpjTimer.isRunning(jobStatus)) {
+            return true;
+        }
+
+        return 0 < getRemainingHpjExecutionTimeLocked(
+                jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
+    }
+
+    @NonNull
+    private ShrinkableDebits getHpjQuotaLocked(final int userId,
+            @NonNull final String packageName) {
+        ShrinkableDebits debits = mHpjStats.get(userId, packageName);
+        if (debits == null) {
+            debits = new ShrinkableDebits(
+                    JobSchedulerService.standbyBucketForPackage(
+                            packageName, userId, sElapsedRealtimeClock.millis())
+            );
+            mHpjStats.add(userId, packageName, debits);
+        }
+        return debits;
+    }
+
     @VisibleForTesting
     boolean isWithinQuotaLocked(@NonNull final JobStatus jobStatus) {
         final int standbyBucket = jobStatus.getEffectiveStandbyBucket();
@@ -645,19 +782,22 @@
                 jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), standbyBucket);
     }
 
+    private boolean isQuotaFree(final int standbyBucket) {
+        // Quota constraint is not enforced while charging.
+        if (mChargeTracker.isCharging()) {
+            // Restricted jobs require additional constraints when charging, so don't immediately
+            // mark quota as free when charging.
+            return standbyBucket != RESTRICTED_INDEX;
+        }
+        return false;
+    }
+
     @VisibleForTesting
     boolean isWithinQuotaLocked(final int userId, @NonNull final String packageName,
             final int standbyBucket) {
         if (standbyBucket == NEVER_INDEX) return false;
 
-        // Quota constraint is not enforced while charging.
-        if (mChargeTracker.isCharging()) {
-            // Restricted jobs require additional constraints when charging, so don't immediately
-            // mark quota as free when charging.
-            if (standbyBucket != RESTRICTED_INDEX) {
-                return true;
-            }
-        }
+        if (isQuotaFree(standbyBucket)) return true;
 
         ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket);
         return getRemainingExecutionTimeLocked(stats) > 0
@@ -717,6 +857,49 @@
                 mMaxExecutionTimeMs - stats.executionTimeInMaxPeriodMs);
     }
 
+    @VisibleForTesting
+    long getRemainingHpjExecutionTimeLocked(final int userId, @NonNull final String packageName) {
+        ShrinkableDebits quota = getHpjQuotaLocked(userId, packageName);
+        if (quota.getStandbyBucketLocked() == NEVER_INDEX) {
+            return 0;
+        }
+        final long limitMs = mHpjLimitsMs[quota.getStandbyBucketLocked()];
+        long remainingMs = limitMs - quota.getTallyLocked();
+
+        // Stale sessions may still be factored into tally. Make sure they're removed.
+        List<TimingSession> timingSessions = mHpjTimingSessions.get(userId, packageName);
+        final long nowElapsed = sElapsedRealtimeClock.millis();
+        final long windowStartTimeElapsed = nowElapsed - mHpjLimitWindowSizeMs;
+        if (timingSessions != null) {
+            while (timingSessions.size() > 0) {
+                TimingSession ts = timingSessions.get(0);
+                if (ts.endTimeElapsed < windowStartTimeElapsed) {
+                    final long duration = ts.endTimeElapsed - ts.startTimeElapsed;
+                    remainingMs += duration;
+                    quota.transactOnDebitsLocked(-duration);
+                    timingSessions.remove(0);
+                } else if (ts.startTimeElapsed < windowStartTimeElapsed) {
+                    remainingMs += windowStartTimeElapsed - ts.startTimeElapsed;
+                    break;
+                } else {
+                    // Fully within the window.
+                    break;
+                }
+            }
+        }
+
+        Timer timer = mHpjPkgTimers.get(userId, packageName);
+        if (timer == null) {
+            return remainingMs;
+        }
+        // There's a case where the debits tally is 0 but a currently running HPJ still counts
+        // towards quota. If the app gets a reward in this case, the reward is lost and the HPJ
+        // run is still fully counted.
+        // TODO(171305774)/STOPSHIP: make sure getting rewards while HPJ currently executing isn't
+        // treated negatively
+        return remainingMs - timer.getCurrentDuration(sElapsedRealtimeClock.millis());
+    }
+
     /**
      * Returns the amount of time, in milliseconds, until the package would have reached its
      * duration quota, assuming it has a job counting towards its quota the entire time. This takes
@@ -802,6 +985,61 @@
         return timeUntilQuotaConsumedMs;
     }
 
+    /**
+     * Returns the amount of time, in milliseconds, until the package would have reached its HPJ
+     * quota, assuming it has a job counting towards the quota the entire time and the quota isn't
+     * replenished at all in that time.
+     */
+    @VisibleForTesting
+    long getTimeUntilHpjQuotaConsumedLocked(final int userId, @NonNull final String packageName) {
+        final long remainingExecutionTimeMs =
+                getRemainingHpjExecutionTimeLocked(userId, packageName);
+
+        List<TimingSession> sessions = mHpjTimingSessions.get(userId, packageName);
+        if (sessions == null || sessions.size() == 0) {
+            return remainingExecutionTimeMs;
+        }
+
+        final long nowElapsed = sElapsedRealtimeClock.millis();
+        ShrinkableDebits quota = getHpjQuotaLocked(userId, packageName);
+        final long limitMs = mHpjLimitsMs[quota.getStandbyBucketLocked()];
+        final long startWindowElapsed = Math.max(0, nowElapsed - mHpjLimitWindowSizeMs);
+        long remainingDeadSpaceMs = remainingExecutionTimeMs;
+        // Total time looked at where a session wouldn't be phasing out.
+        long deadSpaceMs = 0;
+        // Time regained from sessions phasing out
+        long phasedOutSessionTimeMs = 0;
+
+        for (int i = 0; i < sessions.size(); ++i) {
+            TimingSession session = sessions.get(i);
+            if (session.endTimeElapsed < startWindowElapsed) {
+                // Edge case where a session became stale in the time between the call to
+                // getRemainingHpjExecutionTimeLocked and this line.
+                remainingDeadSpaceMs += session.endTimeElapsed - session.startTimeElapsed;
+                sessions.remove(i);
+                i--;
+            } else if (session.startTimeElapsed < startWindowElapsed) {
+                // Session straddles start of window
+                phasedOutSessionTimeMs = session.endTimeElapsed - startWindowElapsed;
+            } else {
+                // Session fully inside window
+                final long timeBetweenSessions = session.startTimeElapsed
+                        - (i == 0 ? startWindowElapsed : sessions.get(i - 1).endTimeElapsed);
+                final long usedDeadSpaceMs = Math.min(remainingDeadSpaceMs, timeBetweenSessions);
+                deadSpaceMs += usedDeadSpaceMs;
+                if (usedDeadSpaceMs == timeBetweenSessions) {
+                    phasedOutSessionTimeMs += session.endTimeElapsed - session.startTimeElapsed;
+                }
+                remainingDeadSpaceMs -= usedDeadSpaceMs;
+                if (remainingDeadSpaceMs <= 0) {
+                    break;
+                }
+            }
+        }
+
+        return Math.min(limitMs, deadSpaceMs + phasedOutSessionTimeMs + remainingDeadSpaceMs);
+    }
+
     /** Returns the execution stats of the app in the most recent window. */
     @VisibleForTesting
     @NonNull
@@ -1053,18 +1291,36 @@
 
     @VisibleForTesting
     void saveTimingSession(final int userId, @NonNull final String packageName,
-            @NonNull final TimingSession session) {
+            @NonNull final TimingSession session, boolean isHpj) {
         synchronized (mLock) {
-            List<TimingSession> sessions = mTimingSessions.get(userId, packageName);
+            final SparseArrayMap<String, List<TimingSession>> sessionMap =
+                    isHpj ? mHpjTimingSessions : mTimingSessions;
+            List<TimingSession> sessions = sessionMap.get(userId, packageName);
             if (sessions == null) {
                 sessions = new ArrayList<>();
-                mTimingSessions.add(userId, packageName, sessions);
+                sessionMap.add(userId, packageName, sessions);
             }
             sessions.add(session);
-            // Adding a new session means that the current stats are now incorrect.
-            invalidateAllExecutionStatsLocked(userId, packageName);
+            if (isHpj) {
+                final ShrinkableDebits quota = getHpjQuotaLocked(userId, packageName);
+                quota.transactOnDebitsLocked(session.endTimeElapsed - session.startTimeElapsed);
+            } else {
+                // Adding a new session means that the current stats are now incorrect.
+                invalidateAllExecutionStatsLocked(userId, packageName);
 
-            maybeScheduleCleanupAlarmLocked();
+                maybeScheduleCleanupAlarmLocked();
+            }
+        }
+    }
+
+    private void grantRewardForInstantEvent(
+            final int userId, @NonNull final String packageName, final long credit) {
+        synchronized (mLock) {
+            final ShrinkableDebits quota = getHpjQuotaLocked(userId, packageName);
+            quota.transactOnDebitsLocked(-credit);
+            if (maybeUpdateConstraintForPkgLocked(userId, packageName)) {
+                mStateChangedListener.onControllerStateChanged();
+            }
         }
     }
 
@@ -1100,6 +1356,7 @@
         }
         mEarliestEndTimeFunctor.reset();
         mTimingSessions.forEach(mEarliestEndTimeFunctor);
+        mHpjTimingSessions.forEach(mEarliestEndTimeFunctor);
         final long earliestEndElapsed = mEarliestEndTimeFunctor.earliestEndElapsed;
         if (earliestEndElapsed == Long.MAX_VALUE) {
             // Couldn't find a good time to clean up. Maybe this was called after we deleted all
@@ -1155,6 +1412,7 @@
             Slog.d(TAG, "handleNewChargingStateLocked: " + mChargeTracker.isCharging());
         }
         // Deal with Timers first.
+        mHpjPkgTimers.forEach(mTimerChargingUpdateFunctor);
         mPkgTimers.forEach(mTimerChargingUpdateFunctor);
         // Now update jobs.
         maybeUpdateAllConstraintsLocked();
@@ -1189,6 +1447,7 @@
         // Quota is the same for all jobs within a package.
         final int realStandbyBucket = jobs.valueAt(0).getStandbyBucket();
         final boolean realInQuota = isWithinQuotaLocked(userId, packageName, realStandbyBucket);
+        boolean outOfHpjQuota = false;
         boolean changed = false;
         for (int i = jobs.size() - 1; i >= 0; --i) {
             final JobStatus js = jobs.valueAt(i);
@@ -1206,8 +1465,14 @@
                 // This job is somehow exempted. Need to determine its own quota status.
                 changed |= setConstraintSatisfied(js, isWithinQuotaLocked(js));
             }
+
+            if (js.isRequestedForegroundJob()) {
+                boolean isWithinHpjQuota = isWithinHpjQuotaLocked(js);
+                changed |= js.setForegroundJobQuotaConstraintSatisfied(isWithinHpjQuota);
+                outOfHpjQuota |= !isWithinHpjQuota;
+            }
         }
-        if (!realInQuota) {
+        if (!realInQuota || outOfHpjQuota) {
             // Don't want to use the effective standby bucket here since that bump the bucket to
             // ACTIVE for one of the jobs, which doesn't help with other jobs that aren't
             // exempted.
@@ -1226,10 +1491,22 @@
         @Override
         public void accept(JobStatus jobStatus) {
             wasJobChanged |= setConstraintSatisfied(jobStatus, isWithinQuotaLocked(jobStatus));
+            final boolean outOfHpjQuota;
+            if (jobStatus.isRequestedForegroundJob()) {
+                final boolean isWithinHpjQuota = isWithinHpjQuotaLocked(jobStatus);
+                wasJobChanged |= jobStatus.setForegroundJobQuotaConstraintSatisfied(
+                        isWithinHpjQuota);
+                outOfHpjQuota = !isWithinHpjQuota;
+            } else {
+                outOfHpjQuota = false;
+            }
+
             final int userId = jobStatus.getSourceUserId();
             final String packageName = jobStatus.getSourcePackageName();
             final int realStandbyBucket = jobStatus.getStandbyBucket();
-            if (isWithinQuotaLocked(userId, packageName, realStandbyBucket)) {
+            if (isWithinQuotaLocked(userId, packageName, realStandbyBucket) && !outOfHpjQuota) {
+                // TODO(141645789): we probably shouldn't cancel the alarm until we've verified
+                // that all jobs for the userId-package are within quota.
                 mInQuotaAlarmListener.removeAlarmLocked(userId, packageName);
             } else {
                 mToScheduleStartAlarms.add(userId, packageName, realStandbyBucket);
@@ -1280,11 +1557,13 @@
         final boolean isUnderJobCountQuota = isUnderJobCountQuotaLocked(stats, standbyBucket);
         final boolean isUnderTimingSessionCountQuota = isUnderSessionCountQuotaLocked(stats,
                 standbyBucket);
+        final long remainingHpjQuota = getRemainingHpjExecutionTimeLocked(userId, packageName);
 
         if (stats.executionTimeInWindowMs < mAllowedTimePerPeriodMs
                 && stats.executionTimeInMaxPeriodMs < mMaxExecutionTimeMs
                 && isUnderJobCountQuota
-                && isUnderTimingSessionCountQuota) {
+                && isUnderTimingSessionCountQuota
+                && remainingHpjQuota > 0) {
             // Already in quota. Why was this method called?
             if (DEBUG) {
                 Slog.e(TAG, "maybeScheduleStartAlarmLocked called for " + pkgString
@@ -1297,19 +1576,44 @@
             return;
         }
 
-        // The time this app will have quota again.
-        long inQuotaTimeElapsed = stats.inQuotaTimeElapsed;
-        if (!isUnderJobCountQuota && stats.bgJobCountInWindow < stats.jobCountLimit) {
-            // App hit the rate limit.
-            inQuotaTimeElapsed = Math.max(inQuotaTimeElapsed,
-                    stats.jobRateLimitExpirationTimeElapsed);
+        long inRegularQuotaTimeElapsed = Long.MAX_VALUE;
+        long inHpjQuotaTimeElapsed = Long.MAX_VALUE;
+        if (!(stats.executionTimeInWindowMs < mAllowedTimePerPeriodMs
+                && stats.executionTimeInMaxPeriodMs < mMaxExecutionTimeMs
+                && isUnderJobCountQuota
+                && isUnderTimingSessionCountQuota)) {
+            // The time this app will have quota again.
+            long inQuotaTimeElapsed = stats.inQuotaTimeElapsed;
+            if (!isUnderJobCountQuota && stats.bgJobCountInWindow < stats.jobCountLimit) {
+                // App hit the rate limit.
+                inQuotaTimeElapsed =
+                        Math.max(inQuotaTimeElapsed, stats.jobRateLimitExpirationTimeElapsed);
+            }
+            if (!isUnderTimingSessionCountQuota
+                    && stats.sessionCountInWindow < stats.sessionCountLimit) {
+                // App hit the rate limit.
+                inQuotaTimeElapsed =
+                        Math.max(inQuotaTimeElapsed, stats.sessionRateLimitExpirationTimeElapsed);
+            }
+            inRegularQuotaTimeElapsed = inQuotaTimeElapsed;
         }
-        if (!isUnderTimingSessionCountQuota
-                && stats.sessionCountInWindow < stats.sessionCountLimit) {
-            // App hit the rate limit.
-            inQuotaTimeElapsed = Math.max(inQuotaTimeElapsed,
-                    stats.sessionRateLimitExpirationTimeElapsed);
+        if (remainingHpjQuota <= 0) {
+            final long limitMs = mHpjLimitsMs[standbyBucket] - mQuotaBufferMs;
+            List<TimingSession> timingSessions = mHpjTimingSessions.get(userId, packageName);
+            long sumMs = 0;
+            for (int i = timingSessions.size() - 1; i >= 0; --i) {
+                TimingSession ts = timingSessions.get(i);
+                final long durationMs = ts.endTimeElapsed - ts.startTimeElapsed;
+                sumMs += durationMs;
+                if (sumMs >= limitMs) {
+                    inHpjQuotaTimeElapsed =
+                            ts.startTimeElapsed + (sumMs - limitMs) + mHpjLimitWindowSizeMs;
+                    break;
+                }
+            }
         }
+        long inQuotaTimeElapsed = Math.min(inRegularQuotaTimeElapsed, inHpjQuotaTimeElapsed);
+
         if (inQuotaTimeElapsed <= sElapsedRealtimeClock.millis()) {
             final long nowElapsed = sElapsedRealtimeClock.millis();
             Slog.wtf(TAG,
@@ -1450,9 +1754,52 @@
         }
     }
 
+    private static final class ShrinkableDebits {
+        /** The amount of quota remaining. Can be negative if limit changes. */
+        private long mDebitTally;
+        private int mStandbyBucket;
+
+        ShrinkableDebits(int standbyBucket) {
+            mDebitTally = 0;
+            mStandbyBucket = standbyBucket;
+        }
+
+        long getTallyLocked() {
+            return mDebitTally;
+        }
+
+        /**
+         * Negative if the tally should decrease (therefore increasing available quota);
+         * or positive if the tally should increase (therefore decreasing available quota).
+         */
+        void transactOnDebitsLocked(final long amount) {
+            mDebitTally = Math.max(0, mDebitTally + amount);
+        }
+
+        void setStandbyBucketLocked(int standbyBucket) {
+            mStandbyBucket = standbyBucket;
+        }
+
+        int getStandbyBucketLocked() {
+            return mStandbyBucket;
+        }
+
+        @Override
+        public String toString() {
+            return "ShrinkableDebits { debit tally: "
+                    + mDebitTally + ", bucket: " + mStandbyBucket
+                    + " }";
+        }
+
+        void dumpLocked(IndentingPrintWriter pw) {
+            pw.println(toString());
+        }
+    }
+
     private final class Timer {
         private final Package mPkg;
         private final int mUid;
+        private final boolean mRegularJobTimer;
 
         // List of jobs currently running for this app that started when the app wasn't in the
         // foreground.
@@ -1460,9 +1807,10 @@
         private long mStartTimeElapsed;
         private int mBgJobCount;
 
-        Timer(int uid, int userId, String packageName) {
+        Timer(int uid, int userId, String packageName, boolean regularJobTimer) {
             mPkg = new Package(userId, packageName);
             mUid = uid;
+            mRegularJobTimer = regularJobTimer;
         }
 
         void startTrackingJobLocked(@NonNull JobStatus jobStatus) {
@@ -1482,12 +1830,17 @@
             mRunningBgJobs.add(jobStatus);
             if (shouldTrackLocked()) {
                 mBgJobCount++;
-                incrementJobCountLocked(mPkg.userId, mPkg.packageName, 1);
+                if (mRegularJobTimer) {
+                    incrementJobCountLocked(mPkg.userId, mPkg.packageName, 1);
+                }
                 if (mRunningBgJobs.size() == 1) {
                     // Started tracking the first job.
                     mStartTimeElapsed = sElapsedRealtimeClock.millis();
-                    // Starting the timer means that all cached execution stats are now incorrect.
-                    invalidateAllExecutionStatsLocked(mPkg.userId, mPkg.packageName);
+                    if (mRegularJobTimer) {
+                        // Starting the timer means that all cached execution stats are now
+                        // incorrect.
+                        invalidateAllExecutionStatsLocked(mPkg.userId, mPkg.packageName);
+                    }
                     scheduleCutoff();
                 }
             }
@@ -1529,13 +1882,15 @@
                 return;
             }
             TimingSession ts = new TimingSession(mStartTimeElapsed, nowElapsed, mBgJobCount);
-            saveTimingSession(mPkg.userId, mPkg.packageName, ts);
+            saveTimingSession(mPkg.userId, mPkg.packageName, ts, !mRegularJobTimer);
             mBgJobCount = 0;
             // Don't reset the tracked jobs list as we need to keep tracking the current number
             // of jobs.
             // However, cancel the currently scheduled cutoff since it's not currently useful.
             cancelCutoff();
-            incrementTimingSessionCountLocked(mPkg.userId, mPkg.packageName);
+            if (mRegularJobTimer) {
+                incrementTimingSessionCountLocked(mPkg.userId, mPkg.packageName);
+            }
         }
 
         /**
@@ -1582,10 +1937,13 @@
                     // repeatedly plugged in and unplugged, or an app changes foreground state
                     // very frequently, the job count for a package may be artificially high.
                     mBgJobCount = mRunningBgJobs.size();
-                    incrementJobCountLocked(mPkg.userId, mPkg.packageName, mBgJobCount);
-                    // Starting the timer means that all cached execution stats are now
-                    // incorrect.
-                    invalidateAllExecutionStatsLocked(mPkg.userId, mPkg.packageName);
+
+                    if (mRegularJobTimer) {
+                        incrementJobCountLocked(mPkg.userId, mPkg.packageName, mBgJobCount);
+                        // Starting the timer means that all cached execution stats are now
+                        // incorrect.
+                        invalidateAllExecutionStatsLocked(mPkg.userId, mPkg.packageName);
+                    }
                     // Schedule cutoff since we're now actively tracking for quotas again.
                     scheduleCutoff();
                 }
@@ -1605,11 +1963,15 @@
                 if (!isActive()) {
                     return;
                 }
-                Message msg = mHandler.obtainMessage(MSG_REACHED_QUOTA, mPkg);
-                final long timeRemainingMs = getTimeUntilQuotaConsumedLocked(mPkg.userId,
-                        mPkg.packageName);
+                Message msg = mHandler.obtainMessage(
+                        mRegularJobTimer ? MSG_REACHED_QUOTA : MSG_REACHED_HPJ_QUOTA, mPkg);
+                final long timeRemainingMs = mRegularJobTimer
+                        ? getTimeUntilQuotaConsumedLocked(mPkg.userId, mPkg.packageName)
+                        : getTimeUntilHpjQuotaConsumedLocked(mPkg.userId, mPkg.packageName);
                 if (DEBUG) {
-                    Slog.i(TAG, "Job for " + mPkg + " has " + timeRemainingMs + "ms left.");
+                    Slog.i(TAG,
+                            (mRegularJobTimer ? "Regular job" : "HPJ") + " for " + mPkg + " has "
+                                    + timeRemainingMs + "ms left.");
                 }
                 // If the job was running the entire time, then the system would be up, so it's
                 // fine to use uptime millis for these messages.
@@ -1618,11 +1980,14 @@
         }
 
         private void cancelCutoff() {
-            mHandler.removeMessages(MSG_REACHED_QUOTA, mPkg);
+            mHandler.removeMessages(
+                    mRegularJobTimer ? MSG_REACHED_QUOTA : MSG_REACHED_HPJ_QUOTA, mPkg);
         }
 
         public void dump(IndentingPrintWriter pw, Predicate<JobStatus> predicate) {
-            pw.print("Timer{");
+            pw.print("Timer<");
+            pw.print(mRegularJobTimer ? "REG" : " HPJ");
+            pw.print(">{");
             pw.print(mPkg);
             pw.print("} ");
             if (isActive()) {
@@ -1668,6 +2033,98 @@
         }
     }
 
+    private final class TopAppTimer {
+        private final Package mPkg;
+
+        // List of jobs currently running for this app that started when the app wasn't in the
+        // foreground.
+        private final SparseArray<UsageEvents.Event> mActivities = new SparseArray<>();
+        private long mStartTimeElapsed;
+
+        TopAppTimer(int userId, String packageName) {
+            mPkg = new Package(userId, packageName);
+        }
+
+        void processEventLocked(@NonNull UsageEvents.Event event) {
+            final long nowElapsed = sElapsedRealtimeClock.millis();
+            switch (event.getEventType()) {
+                case UsageEvents.Event.ACTIVITY_RESUMED:
+                    if (mActivities.size() == 0) {
+                        mStartTimeElapsed = nowElapsed;
+                    }
+                    mActivities.put(event.mInstanceId, event);
+                    break;
+                case UsageEvents.Event.ACTIVITY_PAUSED:
+                case UsageEvents.Event.ACTIVITY_STOPPED:
+                case UsageEvents.Event.ACTIVITY_DESTROYED:
+                    final UsageEvents.Event existingEvent =
+                            mActivities.removeReturnOld(event.mInstanceId);
+                    if (existingEvent != null && mActivities.size() == 0) {
+                        final long totalTopTimeMs = nowElapsed - mStartTimeElapsed;
+                        int numTimeChunks = (int) (totalTopTimeMs / mHpjTopAppTimeChunkSizeMs);
+                        final long remainderMs = totalTopTimeMs % mHpjTopAppTimeChunkSizeMs;
+                        if (remainderMs >= SECOND_IN_MILLIS) {
+                            // "Round up"
+                            numTimeChunks++;
+                        }
+                        if (DEBUG) {
+                            Slog.d(TAG,
+                                    "Crediting " + mPkg + " for " + numTimeChunks + " time chunks");
+                        }
+                        final ShrinkableDebits quota =
+                                getHpjQuotaLocked(mPkg.userId, mPkg.packageName);
+                        quota.transactOnDebitsLocked(-mHpjRewardTopAppMs * numTimeChunks);
+                        if (maybeUpdateConstraintForPkgLocked(mPkg.userId, mPkg.packageName)) {
+                            mStateChangedListener.onControllerStateChanged();
+                        }
+                    }
+                    break;
+            }
+        }
+
+        boolean isActive() {
+            synchronized (mLock) {
+                return mActivities.size() > 0;
+            }
+        }
+
+        public void dump(IndentingPrintWriter pw) {
+            pw.print("TopAppTimer{");
+            pw.print(mPkg);
+            pw.print("} ");
+            if (isActive()) {
+                pw.print("started at ");
+                pw.print(mStartTimeElapsed);
+                pw.print(" (");
+                pw.print(sElapsedRealtimeClock.millis() - mStartTimeElapsed);
+                pw.print("ms ago)");
+            } else {
+                pw.print("NOT active");
+            }
+            pw.println();
+            pw.increaseIndent();
+            for (int i = 0; i < mActivities.size(); i++) {
+                UsageEvents.Event event = mActivities.valueAt(i);
+                pw.println(event.getClassName());
+            }
+            pw.decreaseIndent();
+        }
+
+        public void dump(ProtoOutputStream proto, long fieldId) {
+            final long token = proto.start(fieldId);
+
+            mPkg.dumpDebug(proto, StateControllerProto.QuotaController.TopAppTimer.PKG);
+            proto.write(StateControllerProto.QuotaController.TopAppTimer.IS_ACTIVE, isActive());
+            proto.write(StateControllerProto.QuotaController.TopAppTimer.START_TIME_ELAPSED,
+                    mStartTimeElapsed);
+            proto.write(StateControllerProto.QuotaController.TopAppTimer.ACTIVITY_COUNT,
+                    mActivities.size());
+            // TODO: maybe dump activities/events
+
+            proto.end(token);
+        }
+    }
+
     /**
      * Tracking of app assignments to standby buckets
      */
@@ -1693,8 +2150,14 @@
         }
         List<JobStatus> restrictedChanges = new ArrayList<>();
         synchronized (mLock) {
+            ShrinkableDebits debits = mHpjStats.get(userId, packageName);
+            if (debits != null) {
+                debits.setStandbyBucketLocked(bucketIndex);
+            }
+
             ArraySet<JobStatus> jobs = mTrackedJobs.get(userId, packageName);
             if (jobs == null || jobs.size() == 0) {
+                // Nothing further to do.
                 return;
             }
             for (int i = jobs.size() - 1; i >= 0; i--) {
@@ -1711,6 +2174,10 @@
             if (timer != null && timer.isActive()) {
                 timer.rescheduleCutoff();
             }
+            timer = mHpjPkgTimers.get(userId, packageName);
+            if (timer != null && timer.isActive()) {
+                timer.rescheduleCutoff();
+            }
             if (maybeUpdateConstraintForPkgLocked(userId, packageName)) {
                 mStateChangedListener.onControllerStateChanged();
             }
@@ -1720,6 +2187,16 @@
         }
     }
 
+    final class UsageEventTracker implements UsageEventListener {
+        /**
+         * Callback to inform listeners of a new event.
+         */
+        @Override
+        public void onUsageEvent(int userId, @NonNull UsageEvents.Event event) {
+            mHandler.obtainMessage(MSG_PROCESS_USAGE_EVENT, userId, 0, event);
+        }
+    }
+
     private final class DeleteTimingSessionsFunctor implements Consumer<List<TimingSession>> {
         private final Predicate<TimingSession> mTooOld = new Predicate<TimingSession>() {
             public boolean test(TimingSession ts) {
@@ -1742,9 +2219,13 @@
     @VisibleForTesting
     void deleteObsoleteSessionsLocked() {
         mTimingSessions.forEach(mDeleteOldSessionsFunctor);
+        // Don't delete HPJ timing sessions here. They'll be removed in
+        // getRemainingHpjExecutionTimeLocked().
     }
 
     private class QcHandler extends Handler {
+        private boolean mIsProcessing;
+
         QcHandler(Looper looper) {
             super(looper);
         }
@@ -1752,6 +2233,8 @@
         @Override
         public void handleMessage(Message msg) {
             synchronized (mLock) {
+                mIsProcessing = true;
+
                 switch (msg.what) {
                     case MSG_REACHED_QUOTA: {
                         Package pkg = (Package) msg.obj;
@@ -1781,6 +2264,33 @@
                         }
                         break;
                     }
+                    case MSG_REACHED_HPJ_QUOTA: {
+                        Package pkg = (Package) msg.obj;
+                        if (DEBUG) {
+                            Slog.d(TAG, "Checking if " + pkg + " has reached its HPJ quota.");
+                        }
+
+                        long timeRemainingMs = getRemainingHpjExecutionTimeLocked(
+                                pkg.userId, pkg.packageName);
+                        if (timeRemainingMs <= 0) {
+                            if (DEBUG) Slog.d(TAG, pkg + " has reached its HPJ quota.");
+                            if (maybeUpdateConstraintForPkgLocked(pkg.userId, pkg.packageName)) {
+                                mStateChangedListener.onControllerStateChanged();
+                            }
+                        } else {
+                            // This could potentially happen if an old session phases out while a
+                            // job is currently running.
+                            // Reschedule message
+                            Message rescheduleMsg = obtainMessage(MSG_REACHED_HPJ_QUOTA, pkg);
+                            timeRemainingMs = getTimeUntilHpjQuotaConsumedLocked(
+                                    pkg.userId, pkg.packageName);
+                            if (DEBUG) {
+                                Slog.d(TAG, pkg + " has " + timeRemainingMs + "ms left for HPJ");
+                            }
+                            sendMessageDelayed(rescheduleMsg, timeRemainingMs);
+                        }
+                        break;
+                    }
                     case MSG_CLEAN_UP_SESSIONS:
                         if (DEBUG) {
                             Slog.d(TAG, "Cleaning up timing sessions.");
@@ -1816,7 +2326,8 @@
                                 isQuotaFree = false;
                             }
                             // Update Timers first.
-                            if (mPkgTimers.indexOfKey(userId) >= 0) {
+                            if (mPkgTimers.indexOfKey(userId) >= 0
+                                    || mHpjPkgTimers.indexOfKey(userId) >= 0) {
                                 ArraySet<String> packages = mUidToPackageCache.get(uid);
                                 if (packages == null) {
                                     try {
@@ -1834,7 +2345,11 @@
                                 }
                                 if (packages != null) {
                                     for (int i = packages.size() - 1; i >= 0; --i) {
-                                        Timer t = mPkgTimers.get(userId, packages.valueAt(i));
+                                        Timer t = mHpjPkgTimers.get(userId, packages.valueAt(i));
+                                        if (t != null) {
+                                            t.onStateChangedLocked(nowElapsed, isQuotaFree);
+                                        }
+                                        t = mPkgTimers.get(userId, packages.valueAt(i));
                                         if (t != null) {
                                             t.onStateChangedLocked(nowElapsed, isQuotaFree);
                                         }
@@ -1847,8 +2362,46 @@
                         }
                         break;
                     }
+                    case MSG_PROCESS_USAGE_EVENT: {
+                        final int userId = msg.arg1;
+                        final UsageEvents.Event event = (UsageEvents.Event) msg.obj;
+                        final String pkgName = event.getPackageName();
+                        switch (event.getEventType()) {
+                            case UsageEvents.Event.ACTIVITY_RESUMED:
+                            case UsageEvents.Event.ACTIVITY_PAUSED:
+                            case UsageEvents.Event.ACTIVITY_STOPPED:
+                            case UsageEvents.Event.ACTIVITY_DESTROYED:
+                                synchronized (mLock) {
+                                    TopAppTimer timer = mTopAppTrackers.get(userId, pkgName);
+                                    if (timer == null) {
+                                        timer = new TopAppTimer(userId, pkgName);
+                                        mTopAppTrackers.add(userId, pkgName, timer);
+                                    }
+                                    timer.processEventLocked(event);
+                                }
+                                break;
+                            case UsageEvents.Event.USER_INTERACTION:
+                            case UsageEvents.Event.CHOOSER_ACTION:
+                            case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
+                                // Don't need to include SHORTCUT_INVOCATION. The app will be
+                                // launched through it (if it's not already on top).
+                                grantRewardForInstantEvent(
+                                        userId, pkgName, mHpjRewardInteractionMs);
+                                break;
+                            case UsageEvents.Event.NOTIFICATION_SEEN:
+                                // Intentionally don't give too much for notification seen.
+                                // Interactions will award more.
+                                grantRewardForInstantEvent(
+                                        userId, pkgName, mHpjRewardNotificationSeenMs);
+                                break;
+                        }
+
+                        break;
+                    }
                 }
             }
+
+            mIsProcessing = false;
         }
     }
 
@@ -2030,6 +2583,7 @@
         mQcConstants.mShouldReevaluateConstraints = false;
         mQcConstants.mRateLimitingConstantsUpdated = false;
         mQcConstants.mExecutionPeriodConstantsUpdated = false;
+        mQcConstants.mHpjLimitConstantsUpdated = false;
     }
 
     @Override
@@ -2055,6 +2609,7 @@
         private boolean mShouldReevaluateConstraints = false;
         private boolean mRateLimitingConstantsUpdated = false;
         private boolean mExecutionPeriodConstantsUpdated = false;
+        private boolean mHpjLimitConstantsUpdated = false;
 
         /** Prefix to use with all constant keys in order to "sub-namespace" the keys. */
         private static final String QC_CONSTANT_PREFIX = "qc_";
@@ -2128,6 +2683,36 @@
         @VisibleForTesting
         static final String KEY_MIN_QUOTA_CHECK_DELAY_MS =
                 QC_CONSTANT_PREFIX + "min_quota_check_delay_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_LIMIT_ACTIVE_MS =
+                QC_CONSTANT_PREFIX + "hpj_limit_active_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_LIMIT_WORKING_MS =
+                QC_CONSTANT_PREFIX + "hpj_limit_working_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_LIMIT_FREQUENT_MS =
+                QC_CONSTANT_PREFIX + "hpj_limit_frequent_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_LIMIT_RARE_MS =
+                QC_CONSTANT_PREFIX + "hpj_limit_rare_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_LIMIT_RESTRICTED_MS =
+                QC_CONSTANT_PREFIX + "hpj_limit_restricted_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_WINDOW_SIZE_MS =
+                QC_CONSTANT_PREFIX + "hpj_window_size_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS =
+                QC_CONSTANT_PREFIX + "hpj_top_app_time_chunk_size_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_REWARD_TOP_APP_MS =
+                QC_CONSTANT_PREFIX + "hpj_reward_top_app_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_REWARD_INTERACTION_MS =
+                QC_CONSTANT_PREFIX + "hpj_reward_interaction_ms";
+        @VisibleForTesting
+        static final String KEY_HPJ_REWARD_NOTIFICATION_SEEN_MS =
+                QC_CONSTANT_PREFIX + "hpj_reward_notification_seen_ms";
 
         private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_MS =
                 10 * 60 * 1000L; // 10 minutes
@@ -2169,6 +2754,16 @@
         private static final int DEFAULT_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = 20;
         private static final long DEFAULT_TIMING_SESSION_COALESCING_DURATION_MS = 5000; // 5 seconds
         private static final long DEFAULT_MIN_QUOTA_CHECK_DELAY_MS = MINUTE_IN_MILLIS;
+        private static final long DEFAULT_HPJ_LIMIT_ACTIVE_MS = 30 * MINUTE_IN_MILLIS;
+        private static final long DEFAULT_HPJ_LIMIT_WORKING_MS = DEFAULT_HPJ_LIMIT_ACTIVE_MS;
+        private static final long DEFAULT_HPJ_LIMIT_FREQUENT_MS = 10 * MINUTE_IN_MILLIS;
+        private static final long DEFAULT_HPJ_LIMIT_RARE_MS = DEFAULT_HPJ_LIMIT_FREQUENT_MS;
+        private static final long DEFAULT_HPJ_LIMIT_RESTRICTED_MS = 5 * MINUTE_IN_MILLIS;
+        private static final long DEFAULT_HPJ_WINDOW_SIZE_MS = 24 * HOUR_IN_MILLIS;
+        private static final long DEFAULT_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS = 30 * SECOND_IN_MILLIS;
+        private static final long DEFAULT_HPJ_REWARD_TOP_APP_MS = 10 * SECOND_IN_MILLIS;
+        private static final long DEFAULT_HPJ_REWARD_INTERACTION_MS = 15 * SECOND_IN_MILLIS;
+        private static final long DEFAULT_HPJ_REWARD_NOTIFICATION_SEEN_MS = 0;
 
         /** How much time each app will have to run jobs within their standby bucket window. */
         public long ALLOWED_TIME_PER_PERIOD_MS = DEFAULT_ALLOWED_TIME_PER_PERIOD_MS;
@@ -2328,6 +2923,74 @@
         /** The minimum value that {@link #RATE_LIMITING_WINDOW_MS} can have. */
         private static final long MIN_RATE_LIMITING_WINDOW_MS = 30 * SECOND_IN_MILLIS;
 
+        /**
+         * The total session limit of the particular standby bucket. Apps in this standby bucket
+         * can
+         * only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+         * HPJs).
+         */
+        public long HPJ_LIMIT_ACTIVE_MS = DEFAULT_HPJ_LIMIT_ACTIVE_MS;
+
+        /**
+         * The total session limit of the particular standby bucket. Apps in this standby bucket
+         * can
+         * only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+         * HPJs).
+         */
+        public long HPJ_LIMIT_WORKING_MS = DEFAULT_HPJ_LIMIT_WORKING_MS;
+
+        /**
+         * The total session limit of the particular standby bucket. Apps in this standby bucket
+         * can
+         * only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+         * HPJs).
+         */
+        public long HPJ_LIMIT_FREQUENT_MS = DEFAULT_HPJ_LIMIT_FREQUENT_MS;
+
+        /**
+         * The total session limit of the particular standby bucket. Apps in this standby bucket
+         * can
+         * only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+         * HPJs).
+         */
+        public long HPJ_LIMIT_RARE_MS = DEFAULT_HPJ_LIMIT_RARE_MS;
+
+        /**
+         * The total session limit of the particular standby bucket. Apps in this standby bucket
+         * can
+         * only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+         * HPJs).
+         */
+        public long HPJ_LIMIT_RESTRICTED_MS = DEFAULT_HPJ_LIMIT_RESTRICTED_MS;
+
+        /**
+         * The period of time used to calculate HPJ sessions. Apps can only have HPJ sessions
+         * totalling HPJ_LIMIT_<bucket>_MS within this period of time (without factoring in any
+         * rewards or free HPJs).
+         */
+        public long HPJ_WINDOW_SIZE_MS = DEFAULT_HPJ_WINDOW_SIZE_MS;
+
+        /**
+         * Length of time used to split an app's top time into chunks.
+         */
+        public long HPJ_TOP_APP_TIME_CHUNK_SIZE_MS = DEFAULT_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS;
+
+        /**
+         * How much HPJ quota to give back to an app based on the number of top app time chunks it
+         * had.
+         */
+        public long HPJ_REWARD_TOP_APP_MS = DEFAULT_HPJ_REWARD_TOP_APP_MS;
+
+        /**
+         * How much HPJ quota to give back to an app based on each non-top user interaction.
+         */
+        public long HPJ_REWARD_INTERACTION_MS = DEFAULT_HPJ_REWARD_INTERACTION_MS;
+
+        /**
+         * How much HPJ quota to give back to an app based on each notification seen event.
+         */
+        public long HPJ_REWARD_NOTIFICATION_SEEN_MS = DEFAULT_HPJ_REWARD_NOTIFICATION_SEEN_MS;
+
         public void processConstantLocked(@NonNull DeviceConfig.Properties properties,
                 @NonNull String key) {
             switch (key) {
@@ -2348,6 +3011,15 @@
                     updateRateLimitingConstantsLocked();
                     break;
 
+                case KEY_HPJ_LIMIT_ACTIVE_MS:
+                case KEY_HPJ_LIMIT_WORKING_MS:
+                case KEY_HPJ_LIMIT_FREQUENT_MS:
+                case KEY_HPJ_LIMIT_RARE_MS:
+                case KEY_HPJ_LIMIT_RESTRICTED_MS:
+                case KEY_HPJ_WINDOW_SIZE_MS:
+                    updateHpjLimitConstantsLocked();
+                    break;
+
                 case KEY_MAX_JOB_COUNT_ACTIVE:
                     MAX_JOB_COUNT_ACTIVE = properties.getInt(key, DEFAULT_MAX_JOB_COUNT_ACTIVE);
                     int newActiveMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_ACTIVE);
@@ -2458,6 +3130,64 @@
                     mInQuotaAlarmListener.setMinQuotaCheckDelayMs(
                             Math.min(15 * MINUTE_IN_MILLIS, Math.max(0, MIN_QUOTA_CHECK_DELAY_MS)));
                     break;
+                case KEY_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS:
+                    // We don't need to re-evaluate execution stats or constraint status for this.
+                    HPJ_TOP_APP_TIME_CHUNK_SIZE_MS =
+                            properties.getLong(key, DEFAULT_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS);
+                    // Limit chunking to be in the range [1 millisecond, 15 minutes] per event.
+                    long newChunkSizeMs = Math.min(15 * MINUTE_IN_MILLIS,
+                            Math.max(1, HPJ_TOP_APP_TIME_CHUNK_SIZE_MS));
+                    if (mHpjTopAppTimeChunkSizeMs != newChunkSizeMs) {
+                        mHpjTopAppTimeChunkSizeMs = newChunkSizeMs;
+                        if (mHpjTopAppTimeChunkSizeMs < mHpjRewardTopAppMs) {
+                            // Not making chunk sizes and top rewards to be the upper/lower
+                            // limits of the other to allow trying different policies. Just log
+                            // the discrepancy.
+                            Slog.w(TAG, "HPJ top app time chunk less than reward: "
+                                    + mHpjTopAppTimeChunkSizeMs + " vs " + mHpjRewardTopAppMs);
+                        }
+                    }
+                    break;
+                case KEY_HPJ_REWARD_TOP_APP_MS:
+                    // We don't need to re-evaluate execution stats or constraint status for this.
+                    HPJ_REWARD_TOP_APP_MS =
+                            properties.getLong(key, DEFAULT_HPJ_REWARD_TOP_APP_MS);
+                    // Limit top reward to be in the range [10 seconds, 15 minutes] per event.
+                    long newTopReward = Math.min(15 * MINUTE_IN_MILLIS,
+                            Math.max(10 * SECOND_IN_MILLIS, HPJ_REWARD_TOP_APP_MS));
+                    if (mHpjRewardTopAppMs != newTopReward) {
+                        mHpjRewardTopAppMs = newTopReward;
+                        if (mHpjTopAppTimeChunkSizeMs < mHpjRewardTopAppMs) {
+                            // Not making chunk sizes and top rewards to be the upper/lower
+                            // limits of the other to allow trying different policies. Just log
+                            // the discrepancy.
+                            Slog.w(TAG, "HPJ top app time chunk less than reward: "
+                                    + mHpjTopAppTimeChunkSizeMs + " vs " + mHpjRewardTopAppMs);
+                        }
+                    }
+                    break;
+                case KEY_HPJ_REWARD_INTERACTION_MS:
+                    // We don't need to re-evaluate execution stats or constraint status for this.
+                    HPJ_REWARD_INTERACTION_MS =
+                            properties.getLong(key, DEFAULT_HPJ_REWARD_INTERACTION_MS);
+                    // Limit interaction reward to be in the range [5 seconds, 15 minutes] per
+                    // event.
+                    long newInteractionReward = Math.min(15 * MINUTE_IN_MILLIS,
+                            Math.max(5 * SECOND_IN_MILLIS, HPJ_REWARD_INTERACTION_MS));
+                    if (mHpjRewardInteractionMs != newInteractionReward) {
+                        mHpjRewardInteractionMs = newInteractionReward;
+                    }
+                    break;
+                case KEY_HPJ_REWARD_NOTIFICATION_SEEN_MS:
+                    // We don't need to re-evaluate execution stats or constraint status for this.
+                    HPJ_REWARD_NOTIFICATION_SEEN_MS =
+                            properties.getLong(key, DEFAULT_HPJ_REWARD_NOTIFICATION_SEEN_MS);
+                    // Limit notification seen reward to be in the range [0, 5] minutes per event.
+                    long newNotiSeenReward = Math.min(5 * MINUTE_IN_MILLIS,
+                            Math.max(0, HPJ_REWARD_NOTIFICATION_SEEN_MS));
+                    if (mHpjRewardNotificationSeenMs != newNotiSeenReward) {
+                        mHpjRewardNotificationSeenMs = newNotiSeenReward;
+                    }
             }
         }
 
@@ -2598,6 +3328,75 @@
             }
         }
 
+        private void updateHpjLimitConstantsLocked() {
+            if (mHpjLimitConstantsUpdated) {
+                return;
+            }
+            mHpjLimitConstantsUpdated = true;
+
+            // Query the values as an atomic set.
+            final DeviceConfig.Properties properties = DeviceConfig.getProperties(
+                    DeviceConfig.NAMESPACE_JOB_SCHEDULER,
+                    KEY_HPJ_LIMIT_ACTIVE_MS, KEY_HPJ_LIMIT_WORKING_MS,
+                    KEY_HPJ_LIMIT_FREQUENT_MS, KEY_HPJ_LIMIT_RARE_MS,
+                    KEY_HPJ_LIMIT_RESTRICTED_MS, KEY_HPJ_WINDOW_SIZE_MS);
+            HPJ_LIMIT_ACTIVE_MS = properties.getLong(
+                    KEY_HPJ_LIMIT_ACTIVE_MS, DEFAULT_HPJ_LIMIT_ACTIVE_MS);
+            HPJ_LIMIT_WORKING_MS = properties.getLong(
+                    KEY_HPJ_LIMIT_WORKING_MS, DEFAULT_HPJ_LIMIT_WORKING_MS);
+            HPJ_LIMIT_FREQUENT_MS = properties.getLong(
+                    KEY_HPJ_LIMIT_FREQUENT_MS, DEFAULT_HPJ_LIMIT_FREQUENT_MS);
+            HPJ_LIMIT_RARE_MS = properties.getLong(
+                    KEY_HPJ_LIMIT_RARE_MS, DEFAULT_HPJ_LIMIT_RARE_MS);
+            HPJ_LIMIT_RESTRICTED_MS = properties.getLong(
+                    KEY_HPJ_LIMIT_RESTRICTED_MS, DEFAULT_HPJ_LIMIT_RESTRICTED_MS);
+            HPJ_WINDOW_SIZE_MS = properties.getLong(
+                    KEY_HPJ_WINDOW_SIZE_MS, DEFAULT_HPJ_WINDOW_SIZE_MS);
+
+            // The window must be in the range [1 hour, 24 hours].
+            long newWindowSizeMs = Math.max(HOUR_IN_MILLIS,
+                    Math.min(MAX_PERIOD_MS, HPJ_WINDOW_SIZE_MS));
+            if (mHpjLimitWindowSizeMs != newWindowSizeMs) {
+                mHpjLimitWindowSizeMs = newWindowSizeMs;
+                mShouldReevaluateConstraints = true;
+            }
+            // The limit must be in the range [15 minutes, window size].
+            long newActiveLimitMs = Math.max(15 * MINUTE_IN_MILLIS,
+                    Math.min(newWindowSizeMs, HPJ_LIMIT_ACTIVE_MS));
+            if (mHpjLimitsMs[ACTIVE_INDEX] != newActiveLimitMs) {
+                mHpjLimitsMs[ACTIVE_INDEX] = newActiveLimitMs;
+                mShouldReevaluateConstraints = true;
+            }
+            // The limit must be in the range [15 minutes, active limit].
+            long newWorkingLimitMs = Math.max(15 * MINUTE_IN_MILLIS,
+                    Math.min(newActiveLimitMs, HPJ_LIMIT_WORKING_MS));
+            if (mHpjLimitsMs[WORKING_INDEX] != newWorkingLimitMs) {
+                mHpjLimitsMs[WORKING_INDEX] = newWorkingLimitMs;
+                mShouldReevaluateConstraints = true;
+            }
+            // The limit must be in the range [10 minutes, working limit].
+            long newFrequentLimitMs = Math.max(10 * MINUTE_IN_MILLIS,
+                    Math.min(newWorkingLimitMs, HPJ_LIMIT_FREQUENT_MS));
+            if (mHpjLimitsMs[FREQUENT_INDEX] != newFrequentLimitMs) {
+                mHpjLimitsMs[FREQUENT_INDEX] = newFrequentLimitMs;
+                mShouldReevaluateConstraints = true;
+            }
+            // The limit must be in the range [10 minutes, frequent limit].
+            long newRareLimitMs = Math.max(10 * MINUTE_IN_MILLIS,
+                    Math.min(newFrequentLimitMs, HPJ_LIMIT_RARE_MS));
+            if (mHpjLimitsMs[RARE_INDEX] != newRareLimitMs) {
+                mHpjLimitsMs[RARE_INDEX] = newRareLimitMs;
+                mShouldReevaluateConstraints = true;
+            }
+            // The limit must be in the range [0 minutes, rare limit].
+            long newRestrictedLimitMs = Math.max(0,
+                    Math.min(newRareLimitMs, HPJ_LIMIT_RESTRICTED_MS));
+            if (mHpjLimitsMs[RESTRICTED_INDEX] != newRestrictedLimitMs) {
+                mHpjLimitsMs[RESTRICTED_INDEX] = newRestrictedLimitMs;
+                mShouldReevaluateConstraints = true;
+            }
+        }
+
         private void dump(IndentingPrintWriter pw) {
             pw.println();
             pw.println("QuotaController:");
@@ -2628,6 +3427,19 @@
             pw.print(KEY_TIMING_SESSION_COALESCING_DURATION_MS,
                     TIMING_SESSION_COALESCING_DURATION_MS).println();
             pw.print(KEY_MIN_QUOTA_CHECK_DELAY_MS, MIN_QUOTA_CHECK_DELAY_MS).println();
+
+            pw.print(KEY_HPJ_LIMIT_ACTIVE_MS, HPJ_LIMIT_ACTIVE_MS).println();
+            pw.print(KEY_HPJ_LIMIT_WORKING_MS, HPJ_LIMIT_WORKING_MS).println();
+            pw.print(KEY_HPJ_LIMIT_FREQUENT_MS, HPJ_LIMIT_FREQUENT_MS).println();
+            pw.print(KEY_HPJ_LIMIT_RARE_MS, HPJ_LIMIT_RARE_MS).println();
+            pw.print(KEY_HPJ_LIMIT_RESTRICTED_MS, HPJ_LIMIT_RESTRICTED_MS).println();
+            pw.print(KEY_HPJ_WINDOW_SIZE_MS, HPJ_WINDOW_SIZE_MS).println();
+            pw.print(KEY_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS, HPJ_TOP_APP_TIME_CHUNK_SIZE_MS).println();
+            pw.print(KEY_HPJ_REWARD_TOP_APP_MS, HPJ_REWARD_TOP_APP_MS).println();
+            pw.print(KEY_HPJ_REWARD_INTERACTION_MS, HPJ_REWARD_INTERACTION_MS).println();
+            pw.print(KEY_HPJ_REWARD_NOTIFICATION_SEEN_MS,
+                    HPJ_REWARD_NOTIFICATION_SEEN_MS).println();
+
             pw.decreaseIndent();
         }
 
@@ -2675,6 +3487,24 @@
                     TIMING_SESSION_COALESCING_DURATION_MS);
             proto.write(ConstantsProto.QuotaController.MIN_QUOTA_CHECK_DELAY_MS,
                     MIN_QUOTA_CHECK_DELAY_MS);
+
+            proto.write(ConstantsProto.QuotaController.HPJ_LIMIT_ACTIVE_MS, HPJ_LIMIT_ACTIVE_MS);
+            proto.write(ConstantsProto.QuotaController.HPJ_LIMIT_WORKING_MS, HPJ_LIMIT_WORKING_MS);
+            proto.write(ConstantsProto.QuotaController.HPJ_LIMIT_FREQUENT_MS,
+                    HPJ_LIMIT_FREQUENT_MS);
+            proto.write(ConstantsProto.QuotaController.HPJ_LIMIT_RARE_MS, HPJ_LIMIT_RARE_MS);
+            proto.write(ConstantsProto.QuotaController.HPJ_LIMIT_RESTRICTED_MS,
+                    HPJ_LIMIT_RESTRICTED_MS);
+            proto.write(ConstantsProto.QuotaController.HPJ_WINDOW_SIZE_MS, HPJ_WINDOW_SIZE_MS);
+            proto.write(ConstantsProto.QuotaController.HPJ_TOP_APP_TIME_CHUNK_SIZE_MS,
+                    HPJ_TOP_APP_TIME_CHUNK_SIZE_MS);
+            proto.write(ConstantsProto.QuotaController.HPJ_REWARD_TOP_APP_MS,
+                    HPJ_REWARD_TOP_APP_MS);
+            proto.write(ConstantsProto.QuotaController.HPJ_REWARD_INTERACTION_MS,
+                    HPJ_REWARD_INTERACTION_MS);
+            proto.write(ConstantsProto.QuotaController.HPJ_REWARD_NOTIFICATION_SEEN_MS,
+                    HPJ_REWARD_NOTIFICATION_SEEN_MS);
+
             proto.end(qcToken);
         }
     }
@@ -2717,6 +3547,49 @@
     }
 
     @VisibleForTesting
+    @NonNull
+    long[] getHpjLimitsMs() {
+        return mHpjLimitsMs;
+    }
+
+    @VisibleForTesting
+    @NonNull
+    long getHpjLimitWindowSizeMs() {
+        return mHpjLimitWindowSizeMs;
+    }
+
+    @VisibleForTesting
+    @NonNull
+    long getHpjRewardInteractionMs() {
+        return mHpjRewardInteractionMs;
+    }
+
+    @VisibleForTesting
+    @NonNull
+    long getHpjRewardNotificationSeenMs() {
+        return mHpjRewardNotificationSeenMs;
+    }
+
+    @VisibleForTesting
+    @NonNull
+    long getHpjRewardTopAppMs() {
+        return mHpjRewardTopAppMs;
+    }
+
+
+    @VisibleForTesting
+    @Nullable
+    List<TimingSession> getHpjTimingSessions(int userId, String packageName) {
+        return mHpjTimingSessions.get(userId, packageName);
+    }
+
+    @VisibleForTesting
+    @NonNull
+    long getHpjTopAppTimeChunkSizeMs() {
+        return mHpjTopAppTimeChunkSizeMs;
+    }
+
+    @VisibleForTesting
     long getInQuotaBufferMs() {
         return mQuotaBufferMs;
     }
@@ -2763,6 +3636,11 @@
         return mQcConstants;
     }
 
+    @VisibleForTesting
+    boolean isActiveBackgroundProcessing() {
+        return mHandler.mIsProcessing;
+    }
+
     //////////////////////////// DATA DUMP //////////////////////////////
 
     @Override
@@ -2805,16 +3683,24 @@
                 pw.increaseIndent();
                 pw.print(JobStatus.bucketName(js.getEffectiveStandbyBucket()));
                 pw.print(", ");
-                if (js.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)) {
-                    pw.print("within quota");
+                if (js.shouldTreatAsForegroundJob()) {
+                    pw.print("within HPJ quota");
+                } else if (js.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)) {
+                    pw.print("within regular quota");
                 } else {
                     pw.print("not within quota");
                 }
                 pw.print(", ");
-                pw.print(getRemainingExecutionTimeLocked(js));
-                pw.print("ms remaining in quota");
-                pw.decreaseIndent();
+                if (js.shouldTreatAsForegroundJob()) {
+                    pw.print(getRemainingHpjExecutionTimeLocked(
+                            js.getSourceUserId(), js.getSourcePackageName()));
+                    pw.print("ms remaining in HPJ quota");
+                } else {
+                    pw.print(getRemainingExecutionTimeLocked(js));
+                    pw.print("ms remaining in quota");
+                }
                 pw.println();
+                pw.decreaseIndent();
             }
         });
 
@@ -2841,6 +3727,33 @@
             }
         }
 
+        pw.println();
+        for (int u = 0; u < mHpjPkgTimers.numMaps(); ++u) {
+            final int userId = mHpjPkgTimers.keyAt(u);
+            for (int p = 0; p < mHpjPkgTimers.numElementsForKey(userId); ++p) {
+                final String pkgName = mHpjPkgTimers.keyAt(u, p);
+                mHpjPkgTimers.valueAt(u, p).dump(pw, predicate);
+                pw.println();
+                List<TimingSession> sessions = mHpjTimingSessions.get(userId, pkgName);
+                if (sessions != null) {
+                    pw.increaseIndent();
+                    pw.println("Saved sessions:");
+                    pw.increaseIndent();
+                    for (int j = sessions.size() - 1; j >= 0; j--) {
+                        TimingSession session = sessions.get(j);
+                        session.dump(pw);
+                    }
+                    pw.decreaseIndent();
+                    pw.decreaseIndent();
+                    pw.println();
+                }
+            }
+        }
+
+        pw.println();
+        mTopAppTrackers.forEach((timer) -> timer.dump(pw));
+
+        pw.println();
         pw.println("Cached execution stats:");
         pw.increaseIndent();
         for (int u = 0; u < mExecutionStatsCache.numMaps(); ++u) {
@@ -2865,6 +3778,22 @@
         pw.decreaseIndent();
 
         pw.println();
+        pw.println("HPJ debits:");
+        pw.increaseIndent();
+        for (int u = 0; u < mHpjStats.numMaps(); ++u) {
+            final int userId = mHpjStats.keyAt(u);
+            for (int p = 0; p < mHpjStats.numElementsForKey(userId); ++p) {
+                final String pkgName = mHpjStats.keyAt(u, p);
+                ShrinkableDebits debits = mHpjStats.valueAt(u, p);
+
+                pw.print(string(userId, pkgName));
+                pw.print(": ");
+                debits.dumpLocked(pw);
+            }
+        }
+        pw.decreaseIndent();
+
+        pw.println();
         mInQuotaAlarmListener.dumpLocked(pw);
         pw.decreaseIndent();
     }
@@ -2919,6 +3848,12 @@
                         js.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
                 proto.write(StateControllerProto.QuotaController.TrackedJob.REMAINING_QUOTA_MS,
                         getRemainingExecutionTimeLocked(js));
+                proto.write(
+                        StateControllerProto.QuotaController.TrackedJob.IS_REQUESTED_FOREGROUND_JOB,
+                        js.isRequestedForegroundJob());
+                proto.write(
+                        StateControllerProto.QuotaController.TrackedJob.IS_WITHIN_FG_JOB_QUOTA,
+                        js.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
                 proto.end(jsToken);
             }
         });
@@ -2929,8 +3864,15 @@
                 final String pkgName = mPkgTimers.keyAt(u, p);
                 final long psToken = proto.start(
                         StateControllerProto.QuotaController.PACKAGE_STATS);
+
                 mPkgTimers.valueAt(u, p).dump(proto,
                         StateControllerProto.QuotaController.PackageStats.TIMER, predicate);
+                final Timer hpjTimer = mHpjPkgTimers.get(userId, pkgName);
+                if (hpjTimer != null) {
+                    hpjTimer.dump(proto,
+                            StateControllerProto.QuotaController.PackageStats.FG_JOB_TIMER,
+                            predicate);
+                }
 
                 List<TimingSession> sessions = mTimingSessions.get(userId, pkgName);
                 if (sessions != null) {
diff --git a/apex/statsd/.clang-format b/apex/statsd/.clang-format
deleted file mode 100644
index cead3a0..0000000
--- a/apex/statsd/.clang-format
+++ /dev/null
@@ -1,17 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: false
-AllowShortLoopsOnASingleLine: true
-BinPackArguments: true
-BinPackParameters: true
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-ContinuationIndentWidth: 8
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-AccessModifierOffset: -4
-IncludeCategories:
-  - Regex:    '^"Log\.h"'
-    Priority:    -1
diff --git a/apex/statsd/Android.bp b/apex/statsd/Android.bp
deleted file mode 100644
index f13861e..0000000
--- a/apex/statsd/Android.bp
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2019 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.
-
-apex {
-    name: "com.android.os.statsd",
-    defaults: ["com.android.os.statsd-defaults"],
-    manifest: "apex_manifest.json",
-}
-
-apex_defaults {
-    jni_libs: [
-        "libstats_jni",
-    ],
-    native_shared_libs: [
-        "libstatspull",
-        "libstatssocket",
-    ],
-    binaries: ["statsd"],
-    java_libs: [
-        "framework-statsd",
-        "service-statsd",
-    ],
-    compile_multilib: "both",
-    prebuilts: ["com.android.os.statsd.init.rc"],
-    name: "com.android.os.statsd-defaults",
-    updatable: true,
-    min_sdk_version: "30",
-    key: "com.android.os.statsd.key",
-    certificate: ":com.android.os.statsd.certificate",
-}
-
-apex_key {
-    name: "com.android.os.statsd.key",
-    public_key: "com.android.os.statsd.avbpubkey",
-    private_key: "com.android.os.statsd.pem",
-}
-
-android_app_certificate {
-    name: "com.android.os.statsd.certificate",
-    // This will use com.android.os.statsd.x509.pem (the cert) and
-    // com.android.os.statsd.pk8 (the private key)
-    certificate: "com.android.os.statsd",
-}
-
-prebuilt_etc {
-    name: "com.android.os.statsd.init.rc",
-    src: "statsd.rc",
-    filename: "init.rc",
-    installable: false,
-}
-
-// JNI library for StatsLog.write
-cc_library_shared {
-    name: "libstats_jni",
-    srcs: ["jni/**/*.cpp"],
-    header_libs: ["libnativehelper_header_only"],
-    shared_libs: [
-        "liblog",  // Has a stable abi - should not be copied into apex.
-        "libstatssocket",
-    ],
-    stl: "libc++_static",
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wextra",
-        "-Wno-unused-parameter",
-    ],
-    apex_available: [
-        "com.android.os.statsd",
-        "test_com.android.os.statsd",
-    ],
-}
diff --git a/apex/statsd/OWNERS b/apex/statsd/OWNERS
deleted file mode 100644
index bed9600..0000000
--- a/apex/statsd/OWNERS
+++ /dev/null
@@ -1,9 +0,0 @@
-jeffreyhuang@google.com
-joeo@google.com
-jtnguyen@google.com
-muhammadq@google.com
-ruchirr@google.com
-singhtejinder@google.com
-tsaichristine@google.com
-yaochen@google.com
-yro@google.com
\ No newline at end of file
diff --git a/apex/statsd/TEST_MAPPING b/apex/statsd/TEST_MAPPING
deleted file mode 100644
index 331fe77..0000000
--- a/apex/statsd/TEST_MAPPING
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "presubmit" : [
-    {
-      "name" : "FrameworkStatsdTest"
-    },
-    {
-      "name" : "LibStatsPullTests"
-    }
-  ],
-
-  "postsubmit" : [
-    {
-      "name" : "CtsStatsdHostTestCases"
-    },
-    {
-      "name" : "GtsStatsdHostTestCases"
-    }
-  ]
-}
diff --git a/apex/statsd/aidl/Android.bp b/apex/statsd/aidl/Android.bp
deleted file mode 100644
index f66cf7c..0000000
--- a/apex/statsd/aidl/Android.bp
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (C) 2019 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.
-//
-filegroup {
-    name: "framework-statsd-aidl-sources",
-    srcs: ["**/*.aidl"],
-}
-
-aidl_interface {
-    name: "statsd-aidl",
-    unstable: true,
-    srcs: [
-        "android/os/IPendingIntentRef.aidl",
-        "android/os/IPullAtomCallback.aidl",
-        "android/os/IPullAtomResultReceiver.aidl",
-        "android/os/IStatsCompanionService.aidl",
-        "android/os/IStatsd.aidl",
-        "android/os/StatsDimensionsValueParcel.aidl",
-        "android/util/StatsEventParcel.aidl",
-    ],
-    host_supported: true,
-    backend: {
-        java: {
-            enabled: false, // framework-statsd and service-statsd use framework-statsd-aidl-sources
-        },
-        cpp: {
-            enabled: false,
-        },
-        ndk: {
-            enabled: true,
-            apex_available: [
-                // TODO(b/145923087): Remove this once statsd binary is in apex
-                "//apex_available:platform",
-
-                "com.android.os.statsd",
-                "test_com.android.os.statsd",
-            ],
-        },
-    }
-}
diff --git a/apex/statsd/aidl/android/os/IPendingIntentRef.aidl b/apex/statsd/aidl/android/os/IPendingIntentRef.aidl
deleted file mode 100644
index 000a699..0000000
--- a/apex/statsd/aidl/android/os/IPendingIntentRef.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 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.os;
-
-import android.os.StatsDimensionsValueParcel;
-
-/**
-  * Binder interface to hold a PendingIntent for StatsCompanionService.
-  * {@hide}
-  */
-interface IPendingIntentRef {
-
-    /**
-     * Sends a broadcast to the specified PendingIntent that it should getData now.
-     * This should be only called from StatsCompanionService.
-     */
-     oneway void sendDataBroadcast(long lastReportTimeNs);
-
-    /**
-     * Send a broadcast to the specified PendingIntent notifying it that the list of active configs
-     * has changed. This should be only called from StatsCompanionService.
-     */
-     oneway void sendActiveConfigsChangedBroadcast(in long[] configIds);
-
-     /**
-      * Send a broadcast to the specified PendingIntent, along with the other information
-      * specified. This should only be called from StatsCompanionService.
-      */
-     oneway void sendSubscriberBroadcast(long configUid, long configId, long subscriptionId,
-                                         long subscriptionRuleId, in String[] cookies,
-                                         in StatsDimensionsValueParcel dimensionsValueParcel);
-}
diff --git a/apex/statsd/aidl/android/os/IPullAtomCallback.aidl b/apex/statsd/aidl/android/os/IPullAtomCallback.aidl
deleted file mode 100644
index ff0b97b..0000000
--- a/apex/statsd/aidl/android/os/IPullAtomCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 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.os;
-
-import android.os.IPullAtomResultReceiver;
-
-/**
-  * Binder interface to pull atoms for the stats service.
-  * {@hide}
-  */
-interface IPullAtomCallback {
-    /**
-     * Initiate a request for a pull for an atom.
-     */
-     oneway void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver);
-
-}
diff --git a/apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl b/apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl
deleted file mode 100644
index 00d026e..0000000
--- a/apex/statsd/aidl/android/os/IPullAtomResultReceiver.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 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.os;
-
-import android.util.StatsEventParcel;
-
-/**
-  * Binder interface to pull atoms for the stats service.
-  * {@hide}
-  */
-interface IPullAtomResultReceiver {
-
-    /**
-     * Indicate that a pull request for an atom is complete.
-     */
-     oneway void pullFinished(int atomTag, boolean success, in StatsEventParcel[] output);
-
-}
diff --git a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl b/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
deleted file mode 100644
index d56a4bd..0000000
--- a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 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.os;
-
-/**
-  * Binder interface to communicate with the Java-based statistics service helper.
-  * {@hide}
-  */
-interface IStatsCompanionService {
-    /**
-     * Tell statscompanion that stastd is up and running.
-     */
-    oneway void statsdReady();
-
-    /**
-      * Register a repeating alarm for pulling to fire at the given timestamp and every
-      * intervalMs thereafter (in ms since epoch).
-      * If polling alarm had already been registered, it will be replaced by new one.
-      * Uses AlarmManager.setRepeating API, so if the timestamp is in past, alarm fires immediately,
-      * and alarm is inexact.
-      */
-    oneway void setPullingAlarm(long nextPullTimeMs);
-
-    /** Cancel any repeating pulling alarm. */
-    oneway void cancelPullingAlarm();
-
-    /**
-      * Register an alarm when we want to trigger subscribers at the given
-      * timestamp (in ms since epoch).
-      * If an alarm had already been registered, it will be replaced by new one.
-      */
-    oneway void setAlarmForSubscriberTriggering(long timestampMs);
-
-    /** Cancel any alarm for the purpose of subscriber triggering. */
-    oneway void cancelAlarmForSubscriberTriggering();
-
-    /**
-     * Ask StatsCompanionService if the given permission is allowed for a particular process
-     * and user ID. statsd is incapable of doing this check itself because checkCallingPermission
-     * is not currently supported by libbinder_ndk.
-     */
-    boolean checkPermission(String permission, int pid, int uid);
-}
diff --git a/apex/statsd/aidl/android/os/IStatsManagerService.aidl b/apex/statsd/aidl/android/os/IStatsManagerService.aidl
deleted file mode 100644
index b59a97e..0000000
--- a/apex/statsd/aidl/android/os/IStatsManagerService.aidl
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * Copyright (c) 2019, 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.os;
-
-import android.app.PendingIntent;
-import android.os.IPullAtomCallback;
-
-/**
-  * Binder interface to communicate with the Java-based statistics service helper.
-  * Contains parcelable objects available only in Java.
-  * {@hide}
-  */
-interface IStatsManagerService {
-
-    /**
-     * Registers the given pending intent for this config key. This intent is invoked when the
-     * memory consumed by the metrics for this configuration approach the pre-defined limits. There
-     * can be at most one listener per config key.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    void setDataFetchOperation(long configId, in PendingIntent pendingIntent,
-        in String packageName);
-
-    /**
-     * Removes the data fetch operation for the specified configuration.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    void removeDataFetchOperation(long configId, in String packageName);
-
-    /**
-     * Registers the given pending intent for this packagename. This intent is invoked when the
-     * active status of any of the configs sent by this package changes and will contain a list of
-     * config ids that are currently active. It also returns the list of configs that are currently
-     * active. There can be at most one active configs changed listener per package.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    long[] setActiveConfigsChangedOperation(in PendingIntent pendingIntent, in String packageName);
-
-    /**
-     * Removes the active configs changed operation for the specified package name.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    void removeActiveConfigsChangedOperation(in String packageName);
-
-    /**
-     * Set the PendingIntent to be used when broadcasting subscriber
-     * information to the given subscriberId within the given config.
-     *
-     * Suppose that the calling uid has added a config with key configKey, and that in this config
-     * it is specified that when a particular anomaly is detected, a broadcast should be sent to
-     * a BroadcastSubscriber with id subscriberId. This function links the given pendingIntent with
-     * that subscriberId (for that config), so that this pendingIntent is used to send the broadcast
-     * when the anomaly is detected.
-     *
-     * This function can only be called by the owner (uid) of the config. It must be called each
-     * time statsd starts. Later calls overwrite previous calls; only one PendingIntent is stored.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    void setBroadcastSubscriber(long configKey, long subscriberId, in PendingIntent pendingIntent,
-                                in String packageName);
-
-    /**
-     * Undoes setBroadcastSubscriber() for the (configKey, subscriberId) pair.
-     * Any broadcasts associated with subscriberId will henceforth not be sent.
-     * No-op if this (configKey, subscriberId) pair was not associated with an PendingIntent.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    void unsetBroadcastSubscriber(long configKey, long subscriberId, in String packageName);
-
-    /**
-     * Returns the most recently registered experiment IDs.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    long[] getRegisteredExperimentIds();
-
-    /**
-     * Fetches metadata across statsd. Returns byte array representing wire-encoded proto.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    byte[] getMetadata(in String packageName);
-
-    /**
-     * Fetches data for the specified configuration key. Returns a byte array representing proto
-     * wire-encoded of ConfigMetricsReportList.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    byte[] getData(in long key, in String packageName);
-
-    /**
-     * Sets a configuration with the specified config id and subscribes to updates for this
-     * configuration id. Broadcasts will be sent if this configuration needs to be collected.
-     * The configuration must be a wire-encoded StatsdConfig. The receiver for this data is
-     * registered in a separate function.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    void addConfiguration(in long configId, in byte[] config, in String packageName);
-
-    /**
-     * Removes the configuration with the matching config id. No-op if this config id does not
-     * exist.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    void removeConfiguration(in long configId, in String packageName);
-
-    /** Tell StatsManagerService to register a puller for the given atom tag with statsd. */
-    oneway void registerPullAtomCallback(int atomTag, long coolDownMillis, long timeoutMillis,
-            in int[] additiveFields, IPullAtomCallback pullerCallback);
-
-    /** Tell StatsManagerService to unregister the pulller for the given atom tag from statsd. */
-    oneway void unregisterPullAtomCallback(int atomTag);
-}
diff --git a/apex/statsd/aidl/android/os/IStatsd.aidl b/apex/statsd/aidl/android/os/IStatsd.aidl
deleted file mode 100644
index 066412a..0000000
--- a/apex/statsd/aidl/android/os/IStatsd.aidl
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
- * Copyright (c) 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.os;
-
-import android.os.IPendingIntentRef;
-import android.os.IPullAtomCallback;
-import android.os.ParcelFileDescriptor;
-
-/**
-  * Binder interface to communicate with the statistics management service.
-  * {@hide}
-  */
-interface IStatsd {
-    /**
-     * Tell the stats daemon that the android system server is up and running.
-     */
-    oneway void systemRunning();
-
-    /**
-     * Tell the stats daemon that the android system has finished booting.
-     */
-    oneway void bootCompleted();
-
-    /**
-     * Tell the stats daemon that the StatsCompanionService is up and running.
-     * Two-way binder call so that caller knows message received.
-     */
-    void statsCompanionReady();
-
-    /**
-     * Tells statsd that it is time to poll some stats. Statsd will be responsible for determing
-     * what stats to poll and initiating the polling.
-     * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
-     */
-    void informPollAlarmFired();
-
-    /**
-     * Tells statsd that it is time to handle periodic alarms. Statsd will be responsible for
-     * determing what alarm subscriber to trigger.
-     * Two-way binder call so that caller's method (and corresponding wakelocks) will linger.
-     */
-    void informAlarmForSubscriberTriggeringFired();
-
-    /**
-     * Tells statsd that the device is about to shutdown.
-     */
-    void informDeviceShutdown();
-
-    /**
-     * Inform statsd about a file descriptor for a pipe through which we will pipe version
-     * and package information for each uid.
-     * Versions and package information are supplied via UidData proto where info for each app
-     * is captured in its own element of a repeated ApplicationInfo message.
-     */
-    oneway void informAllUidData(in ParcelFileDescriptor fd);
-
-    /**
-     * Inform statsd what the uid, version, version_string, and installer are for one app that was
-     * updated.
-     */
-    oneway void informOnePackage(in String app, in int uid, in long version,
-        in String version_string, in String installer);
-
-    /**
-     * Inform stats that an app was removed.
-     */
-    oneway void informOnePackageRemoved(in String app, in int uid);
-
-    /**
-     * Fetches data for the specified configuration key. Returns a byte array representing proto
-     * wire-encoded of ConfigMetricsReportList.
-     *
-     * Requires Manifest.permission.DUMP.
-     */
-    byte[] getData(in long key, int callingUid);
-
-    /**
-     * Fetches metadata across statsd. Returns byte array representing wire-encoded proto.
-     *
-     * Requires Manifest.permission.DUMP.
-     */
-    byte[] getMetadata();
-
-    /**
-     * Sets a configuration with the specified config id and subscribes to updates for this
-     * configuration key. Broadcasts will be sent if this configuration needs to be collected.
-     * The configuration must be a wire-encoded StatsdConfig. The receiver for this data is
-     * registered in a separate function.
-     *
-     * Requires Manifest.permission.DUMP.
-     */
-    void addConfiguration(in long configId, in byte[] config, in int callingUid);
-
-    /**
-     * Registers the given pending intent for this config key. This intent is invoked when the
-     * memory consumed by the metrics for this configuration approach the pre-defined limits. There
-     * can be at most one listener per config key.
-     *
-     * Requires Manifest.permission.DUMP.
-     */
-    void setDataFetchOperation(long configId, in IPendingIntentRef pendingIntentRef,
-                               int callingUid);
-
-    /**
-     * Removes the data fetch operation for the specified configuration.
-     *
-     * Requires Manifest.permission.DUMP.
-     */
-    void removeDataFetchOperation(long configId, int callingUid);
-
-    /**
-     * Registers the given pending intent for this packagename. This intent is invoked when the
-     * active status of any of the configs sent by this package changes and will contain a list of
-     * config ids that are currently active. It also returns the list of configs that are currently
-     * active. There can be at most one active configs changed listener per package.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    long[] setActiveConfigsChangedOperation(in IPendingIntentRef pendingIntentRef, int callingUid);
-
-    /**
-     * Removes the active configs changed operation for the specified package name.
-     *
-     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
-     */
-    void removeActiveConfigsChangedOperation(int callingUid);
-
-    /**
-     * Removes the configuration with the matching config id. No-op if this config id does not
-     * exist.
-     *
-     * Requires Manifest.permission.DUMP.
-     */
-    void removeConfiguration(in long configId, in int callingUid);
-
-    /**
-     * Set the PendingIntentRef to be used when broadcasting subscriber
-     * information to the given subscriberId within the given config.
-     *
-     * Suppose that the calling uid has added a config with key configId, and that in this config
-     * it is specified that when a particular anomaly is detected, a broadcast should be sent to
-     * a BroadcastSubscriber with id subscriberId. This function links the given pendingIntent with
-     * that subscriberId (for that config), so that this pendingIntent is used to send the broadcast
-     * when the anomaly is detected.
-     *
-     * This function can only be called by the owner (uid) of the config. It must be called each
-     * time statsd starts. Later calls overwrite previous calls; only one pendingIntent is stored.
-     *
-     * Requires Manifest.permission.DUMP.
-     */
-    void setBroadcastSubscriber(long configId, long subscriberId, in IPendingIntentRef pir,
-                                int callingUid);
-
-    /**
-     * Undoes setBroadcastSubscriber() for the (configId, subscriberId) pair.
-     * Any broadcasts associated with subscriberId will henceforth not be sent.
-     * No-op if this (configKey, subscriberId) pair was not associated with an PendingIntentRef.
-     *
-     * Requires Manifest.permission.DUMP.
-     */
-    void unsetBroadcastSubscriber(long configId, long subscriberId, int callingUid);
-
-    /**
-     * Tell the stats daemon that all the pullers registered during boot have been sent.
-     */
-    oneway void allPullersFromBootRegistered();
-
-    /**
-     * Registers a puller callback function that, when invoked, pulls the data
-     * for the specified atom tag.
-     */
-    oneway void registerPullAtomCallback(int uid, int atomTag, long coolDownMillis,
-                                         long timeoutMillis,in int[] additiveFields,
-                                         IPullAtomCallback pullerCallback);
-
-    /**
-     * Registers a puller callback function that, when invoked, pulls the data
-     * for the specified atom tag.
-     *
-     * Enforces the REGISTER_STATS_PULL_ATOM permission.
-     */
-    oneway void registerNativePullAtomCallback(int atomTag, long coolDownMillis, long timeoutMillis,
-                           in int[] additiveFields, IPullAtomCallback pullerCallback);
-
-    /**
-     * Unregisters any pullAtomCallback for the given uid/atom.
-     */
-    oneway void unregisterPullAtomCallback(int uid, int atomTag);
-
-    /**
-     * Unregisters any pullAtomCallback for the given atom + caller.
-     *
-     * Enforces the REGISTER_STATS_PULL_ATOM permission.
-     */
-    oneway void unregisterNativePullAtomCallback(int atomTag);
-
-    /**
-     * The install requires staging.
-     */
-    const int FLAG_REQUIRE_STAGING = 0x01;
-
-    /**
-     * Rollback is enabled with this install.
-     */
-    const int FLAG_ROLLBACK_ENABLED = 0x02;
-
-    /**
-     * Requires low latency monitoring.
-     */
-    const int FLAG_REQUIRE_LOW_LATENCY_MONITOR = 0x04;
-
-    /**
-     * Returns the most recently registered experiment IDs.
-     */
-    long[] getRegisteredExperimentIds();
-}
diff --git a/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl b/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl
deleted file mode 100644
index 05f78d0..0000000
--- a/apex/statsd/aidl/android/os/StatsDimensionsValueParcel.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-package android.os;
-
-/**
- * @hide
- */
-parcelable StatsDimensionsValueParcel {
-    // Field equals atomTag for top level StatsDimensionsValueParcels or
-    // positions in depth (1-indexed) for lower level parcels.
-    int field;
-
-    // Indicator for which type of value is stored. Should be set to one
-    // of the constants in StatsDimensionsValue.java.
-    int valueType;
-
-    String stringValue;
-    int intValue;
-    long longValue;
-    boolean boolValue;
-    float floatValue;
-    StatsDimensionsValueParcel[] tupleValue;
-}
diff --git a/apex/statsd/aidl/android/util/StatsEventParcel.aidl b/apex/statsd/aidl/android/util/StatsEventParcel.aidl
deleted file mode 100644
index add8bfb..0000000
--- a/apex/statsd/aidl/android/util/StatsEventParcel.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.util;
-
-/**
- * @hide
- */
-parcelable StatsEventParcel {
-    byte[] buffer;
-}
diff --git a/apex/statsd/apex_manifest.json b/apex/statsd/apex_manifest.json
deleted file mode 100644
index 1d029c6..0000000
--- a/apex/statsd/apex_manifest.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "name": "com.android.os.statsd",
-  "version": 309999900
-}
-
diff --git a/apex/statsd/com.android.os.statsd.avbpubkey b/apex/statsd/com.android.os.statsd.avbpubkey
deleted file mode 100644
index d78af8b..0000000
--- a/apex/statsd/com.android.os.statsd.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/statsd/com.android.os.statsd.pem b/apex/statsd/com.android.os.statsd.pem
deleted file mode 100644
index 558e17f..0000000
--- a/apex/statsd/com.android.os.statsd.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKgIBAAKCAgEA893bbpkivKEiNgfknYBSlzC0csaKU/ddBm5Pb4ZFuab+LQSR
-9DDc5JrsmxyrsrvuwL/zAtMbkyYWzEiUxJtx/w0bw8rC90GoPRSCmxyI0ZK8FuPy
-IAQ7UeNfTWZ485mAUaTSasGIfQ3DY4F0P+aUSijeG3NUY02nALHDMqJX7lXR+mL1
-DUYDg05KB0jxQwlYqBeujTPPiAzEqm3PlBoHuan8/qgK2wdQMTVg/fieUD3lupmV
-Wj2dRZgqfBPA16ZbV4Uo0j0bZSf+fQLiXlU2VJGb5i/FQfjLqMKGABDI0MgK7Sc2
-m4ySpV4g4XKDv/vw6Dw4kwWC7mATEVAkH+q6V7uiZeN6a7w30UMtPI8fPaUvAP3L
-VBjCBIv/3m+CKkWcNxOZ3sQBQl5bS05dxcfiVsBvBLYbvQgC+Wy0Sc3b+1pXFT/E
-uAsbZ4CyVsi1+PAdx3h5e2QAyNCXgZDOcvTUyxY6JLTE0LOVHmI4fJEujBex//Oz
-PCRHvC8K+KiljyQWf/NYrLSD3QGYAjVMtQh7yu2yhzWzgBUxyhuv3rY4ATXsN3bJ
-wW4w7/L/RSLSW5+lp/NoJOD9utbsKTyGMHOY6K8JLOmhv3ORoAEmLYlFTI+FqBi9
-AH1HQEKCyh8Z/bYHLUzGWl6FqAMtcnuintv40BbKyt0/D1ItdbSNKmOZ5rkCAwEA
-AQKCAgAY7ll8mRNADYkd1Pi+UVwgMM6B3WJO6z8LZUOhtyxxqmzZ1VnGiShMBrqh
-sPCsuSHTeswxQbvT81TpVZI/91RUKtbn0VbVSFUWyX4AtY4XPtUT0gHy2/vkh0Y6
-93ruDIdd0Wfhmh+GCV4sUhO8ZKpMWpk6XTQHYuzr2UCHcKlkqElrO6qpzLqXNe3D
-iOWBYPc7WBB0RxO0aPnCIq/SCEc55/MBZdSWR80e+sILtNsagPl3djQaoanub3wI
-a0yPv2YfMHHX7H9cfBY8WYsi8bs4MhqqEcAs2m6XtitU3mJpVcooLJYcmOZ1GYZr
-BfYKLouWcnGmNi4IiLHqVzMaQDkEhAZsRaAXCkoVVrFBedLlmLPpiUIQlINF4vxe
-3IcekTKWyMzkU6h+K8T15MU5mLSqeL2Gji1JIwKJno51FZ9uc++pUJVtfYQmNny8
-8RKvQ1hv/S5yLQKgN+VkNbaWlUoMP73dtUe3m/At71/2Dj7xB0KtcgT1lEMrM1GR
-oynJAJLz/d0n5RUUREwkZZMcA4fQVC7Db6vpK69jPiQMShpZ3JKCEjfYLUuN0slt
-FPhjiR175E0vTRuLoIj4kXNwLLswH0c9zqrKM2S92SCxAV3E4JJGKhUZalvT9s1g
-LrPhMCl6CsOES98T87d3RyAIK0iVRCnRUG3bc+8rzyRd4fzkAQKCAQEA/UjmCSm3
-H46t/1w7YBZPew7SFQOAJe81iDzbonc3fNPD2R8lxtD3MwdvrQ5f9fhT4+uveWNr
-dyBX7ppnissyM3LZRN+7BdeIVVeIPVen6Ou9W2i7q18ZoQx9IpRcZEw5tGJFZaGx
-EmyPN4i1K0ccUkGbBvbXXQ/tcG3wElRpBAc5/TQ8vrpUgHll2/MbYhowx6P9uHv5
-thoyG98X+7Fbg8ikzw5GtyuedXfyX1CpJ7yUQVS2PEaOMXOkZdx2bbWRAYYCpsqB
-dMmjs2PsFhZHu6CpLhlocHbfUiRztCUCaMZJPQXFSVmy8QDMvZEdVLvad9Poi8ny
-lmHVRgxaNbAtIQKCAQEA9nscqRaaO7hIX9bOUxcDbI0486Ws4H0hAFApIN+6/LP4
-hkxey3xWArTYWrvSG1d5GkJAdn99ayWzo2PevmJlrhIJiO1QqYBAk+87cnhwSCmB
-kb0sGkNWcc/xNRy7eqdhyCmVhaUnIbORee+cD6qiu/l2BAclTf2ZARFOGXjhQkvt
-cDbc/9ZR467ceXbiTIU34Be4xnNAY1mo59jvwl9eqxgpefYTqPhcZ7OmlDli77Hd
-XuRfuxLZCscv7A9M5Enc2zwOEP5VwRNwYzYtMm2Yh9CQZxNWC7JVh1Gw5MPFzsGl
-sgEdb4WGneN6PPLQHK7NF0f7wYSNnF0i3XSME9MumQKCAQEA0qMbWydr+TyJC0LC
-xigHtUkgAQXGPsXuePxTk4sdhBwAVcKHgg4qZi+a+gpoV4BLE9LfPU4nAwzM08to
-rI5Lk2nBsnt1Z2hVItQGoy0QoK3b7fbti5ktETf3oRhMtcSGgLLxD5ImVjId8Isq
-T3F15hpVOLdzZxtl1Qg4jKXSJ91yplYY5mzC9Yz/3qkQbsdlJcIFsLS5eG3UmkUw
-Bsr6VmA4X1F6Eb6eqwYzdHz6D+fOS36NhxcODaYkY+myO46xptixv8/NVTiTgQ5q
-OfwRb8Iur/3FUzIoioFyD7Bvjn7ITY1NArEsFS0bF9Nk1yDakKiUThyGN/Xojbac
-FuYKwQKCAQEAxOWJ+qU8phJLdowBHC0ZJiEWasRhep9auoZOpJ01IWOfV6EwZLs5
-dkYDQ1Agwoi5DDn6hu7HQM3IV/CS4mF2OnzcMw7ozc7PR53nTkVZ5LuLbuHAlmZO
-avKjDDucpJmLqjtV34IT5X8t6kt3zqgQAbuBBCy1Jz07ebfaPMzsnWpMDcU1/AW4
-OvrX0wweMOSGwzQP/i/ZMsRQAo2w0gQfeuv9Thk+kU99ebXwjx3co//hCEnFE4s1
-6L8/0AJU+VTr4hJyZi7WUDt4HzkLF+qm22/Hux+eMA/Q9R1UAxtFLCpTdAQiAJGY
-/Q3X+1I434DgAwYU3f1Gpq9cB65vq/KamQKCAQEAjIub5wde/ttHlLALvnOXrbqe
-nUIfWHExMzhul/rkr8fFEJwij2nZUuN2EWUGzBWQQoNXw5QKHLZyPsyFUOa/P2BS
-osnffAa+sumL4k36E71xFdTVV5ExyTXZVB49sPmUpivP9gEucFFqDHKjGsF45dBF
-+DZdykLUIv+/jQUzXGkZ5Wv/r52YUNho4EZdwnlJ2so7cxnsYnjW+c1nlp17tkq5
-DfwktkeD9iFzlaZ66vLoO44luaBm+lC3xM2sHinOTwbk0gvhJAIoLfkOYhpmGc8A
-4W/E1OHfVz6xqVDsMBFhRbQpHNkf8XZNqkIoqHVMTaMOJJlM+lb0+A9B8Bm/XA==
------END RSA PRIVATE KEY-----
diff --git a/apex/statsd/com.android.os.statsd.pk8 b/apex/statsd/com.android.os.statsd.pk8
deleted file mode 100644
index 49910f8..0000000
--- a/apex/statsd/com.android.os.statsd.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/statsd/com.android.os.statsd.x509.pem b/apex/statsd/com.android.os.statsd.x509.pem
deleted file mode 100644
index e7b16b2..0000000
--- a/apex/statsd/com.android.os.statsd.x509.pem
+++ /dev/null
@@ -1,30 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFDTCCAvWgAwIBAgIUCnta1LAl5fMMLLQx//4zWz9A2A8wDQYJKoZIhvcNAQEL
-BQAwFTETMBEGA1UECgwKR29vZ2xlIExMQzAgFw0xOTA4MTIyMjM5MzBaGA80NzU3
-MDcwODIyMzkzMFowFTETMBEGA1UECgwKR29vZ2xlIExMQzCCAiIwDQYJKoZIhvcN
-AQEBBQADggIPADCCAgoCggIBAOranWZ19jkXCF9WIlXv01tUUvLKMHWKV7X9Earw
-cL7/aax0pFbNJutgyBUiOszbR+0T7quZxz6jACu+6y7iaMJnvMluZsfTi+p2UvQt
-y6Ql7ZUOQ7bVluCFIW5hZ+8d9RrLmZdvX1r4YfF6HufDBkAbj+os+y6407OezJAV
-8EATpemc9gsCC4RJZpwzTs1RUXMD4UoNrLZAE8+7iaJZeBxmz0MAPj92pYc9M7/d
-xInzYvOR08/uEpHt8jlMdVgSQS/FaRlIOIqcGBk3cjkjDlpVATQ4Hyjy+IPQPjTD
-bJUmDJiYeBCyY/pYZQvTQjl8s+fvykTsF9Lfb+E+PhZ0+N8pRi7sUSpisZHSiqaN
-W3oxYWc0YQSuzygHHog8HH/azHX5L805g/+Rwfb/cUF9eJgjq0vrkFnsz4UKgKNV
-hHL90mfqpbc2UvJ8VY8BvIjbsHQ77LrBKlqI9VMPorttpTOuwHHJPKsyN972F0Ul
-lRB6CwFE8csVGWXoNaDZWBv7xTDdbdirmlKDNueg9pw6ksYV2Is9Dv8PxmsZvb+4
-oftC/hb4X1Pudn01PPs9Tx44CwHuVLENUwlDEVzG5zNetsv9kAuCYt3VRVF+NYqj
-NAfLbxCKLe25wGzJrZUEJ1YrYIjpUbfwnttEad/9Pu13DAS7HZwn5vwqEKB/1LlT
-NSUXAgMBAAGjUzBRMB0GA1UdDgQWBBSKElkhJSbzgh8+iysye8SrkmJ62DAfBgNV
-HSMEGDAWgBSKElkhJSbzgh8+iysye8SrkmJ62DAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBCwUAA4ICAQANFGnc2wJBrFbh2nzhl06g4TjPKGRCw365vZ1A3T9O
-jXP0lToHDxB33TpKk6d7zszR1uPphQQxgzhSVZB/jx8q4kWSSoKoF9Dlx7h8rAt+
-2TM5DaBvxrwu5mqOALwQuF81wap1Pl2L2fFHvygCm8b+Ci4iS5vcr0axNnp1rK1b
-vUtRWY4mfxTjJYcgeCVUGskqTb+cCxQZ6Icno6VTKajT1FybRmD3KZJaUuLbNEN+
-IE4nGTMG2WZ5Hl2vR8JJp1sYYn8T3ElMAb0MSNFkqsfI+tToEwGsuJDgYEdtEnzf
-lTycQvn5NhrIZRRN3pqSyWpAU7p9mmyTK0PHMz2D/Rtfb7lE692vXzxCmZND51mc
-YXCCoanV6eZZ7Sbqzh60+5QV38hgFBst5l8CcFaWWSFK9nBWdzS5lhs9lmQ4aiYd
-IE0qsNZgMob+TTP1VW39hu4EDjNmOrKfimM9J2tcPZ5QP01DgETPvAsB7vn2Xz9J
-HGt5ntiSV4W2izDP8viQ1M5NvfdBaUhcnNsE6/sxfU0USRs2hrEp1oiqrv4p6V0P
-qOt7C2/YtJzkrxfsHZAxBUSRHa7LwtzgeiJDUivHn94VnAzSAH8MLx6CzDPQ8HWN
-NiZFxTKfMVyjEmbQ2PalHWB8pWtpdEh7X4rzaqhnLBTis3pGssASgo3ArLIYleAU
-+g==
------END CERTIFICATE-----
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
deleted file mode 100644
index bf4323d..0000000
--- a/apex/statsd/framework/Android.bp
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (C) 2019 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 {
-    default_visibility: [ ":__pkg__" ]
-}
-
-genrule {
-    name: "statslog-statsd-java-gen",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --java $(out) --module statsd" +
-         " --javaPackage com.android.internal.statsd --javaClass StatsdStatsLog",
-    out: ["com/android/internal/statsd/StatsdStatsLog.java"],
-}
-
-java_library_static {
-    name: "statslog-statsd",
-    srcs: [
-        ":statslog-statsd-java-gen",
-    ],
-    visibility: [
-        "//cts/hostsidetests/statsd/apps:__subpackages__",
-        "//vendor:__subpackages__",
-    ],
-}
-
-filegroup {
-    name: "framework-statsd-sources",
-    srcs: [
-        "java/**/*.java",
-        ":framework-statsd-aidl-sources",
-        ":statslog-statsd-java-gen",
-    ],
-    visibility: [
-        "//frameworks/base", // For the "global" stubs.
-        "//frameworks/base/apex/statsd:__subpackages__",
-    ],
-}
-java_sdk_library {
-    name: "framework-statsd",
-    defaults: ["framework-module-defaults"],
-    installable: true,
-
-    srcs: [
-        ":framework-statsd-sources",
-    ],
-
-    permitted_packages: [
-        "android.app",
-        "android.os",
-        "android.util",
-        // From :statslog-statsd-java-gen
-        "com.android.internal.statsd",
-    ],
-
-    api_packages: [
-        "android.app",
-        "android.os",
-        "android.util",
-    ],
-
-    hostdex: true, // for hiddenapi check
-
-    impl_library_visibility: ["//frameworks/base/apex/statsd/framework/test:__subpackages__"],
-
-    apex_available: [
-        "com.android.os.statsd",
-        "test_com.android.os.statsd",
-    ],
-}
diff --git a/apex/statsd/framework/api/current.txt b/apex/statsd/framework/api/current.txt
deleted file mode 100644
index a655693..0000000
--- a/apex/statsd/framework/api/current.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-// Signature format: 2.0
-package android.util {
-
-  public final class StatsLog {
-    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public static boolean logBinaryPushStateChanged(@NonNull String, long, int, int, @NonNull long[]);
-    method public static boolean logEvent(int);
-    method public static boolean logStart(int);
-    method public static boolean logStop(int);
-  }
-
-}
-
diff --git a/apex/statsd/framework/api/module-lib-current.txt b/apex/statsd/framework/api/module-lib-current.txt
deleted file mode 100644
index 8b6e217..0000000
--- a/apex/statsd/framework/api/module-lib-current.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-// Signature format: 2.0
-package android.os {
-
-  public class StatsFrameworkInitializer {
-    method public static void registerServiceWrappers();
-    method public static void setStatsServiceManager(@NonNull android.os.StatsServiceManager);
-  }
-
-}
-
diff --git a/apex/statsd/framework/api/module-lib-removed.txt b/apex/statsd/framework/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/statsd/framework/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/statsd/framework/api/removed.txt b/apex/statsd/framework/api/removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/statsd/framework/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/statsd/framework/api/system-current.txt b/apex/statsd/framework/api/system-current.txt
deleted file mode 100644
index 3ea5724..0000000
--- a/apex/statsd/framework/api/system-current.txt
+++ /dev/null
@@ -1,111 +0,0 @@
-// Signature format: 2.0
-package android.app {
-
-  public final class StatsManager {
-    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void addConfig(long, byte[]) throws android.app.StatsManager.StatsUnavailableException;
-    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean addConfiguration(long, byte[]);
-    method @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM) public void clearPullAtomCallback(int);
-    method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getData(long);
-    method @Deprecated @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getMetadata();
-    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] getRegisteredExperimentIds() throws android.app.StatsManager.StatsUnavailableException;
-    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getReports(long) throws android.app.StatsManager.StatsUnavailableException;
-    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
-    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
-    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
-    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
-    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setBroadcastSubscriber(android.app.PendingIntent, long, long) throws android.app.StatsManager.StatsUnavailableException;
-    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
-    method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
-    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setFetchReportsOperation(android.app.PendingIntent, long) throws android.app.StatsManager.StatsUnavailableException;
-    method @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM) public void setPullAtomCallback(int, @Nullable android.app.StatsManager.PullAtomMetadata, @NonNull java.util.concurrent.Executor, @NonNull android.app.StatsManager.StatsPullAtomCallback);
-    field public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
-    field public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS = "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
-    field public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES = "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
-    field public static final String EXTRA_STATS_CONFIG_KEY = "android.app.extra.STATS_CONFIG_KEY";
-    field public static final String EXTRA_STATS_CONFIG_UID = "android.app.extra.STATS_CONFIG_UID";
-    field public static final String EXTRA_STATS_DIMENSIONS_VALUE = "android.app.extra.STATS_DIMENSIONS_VALUE";
-    field public static final String EXTRA_STATS_SUBSCRIPTION_ID = "android.app.extra.STATS_SUBSCRIPTION_ID";
-    field public static final String EXTRA_STATS_SUBSCRIPTION_RULE_ID = "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
-    field public static final int PULL_SKIP = 1; // 0x1
-    field public static final int PULL_SUCCESS = 0; // 0x0
-  }
-
-  public static class StatsManager.PullAtomMetadata {
-    method @Nullable public int[] getAdditiveFields();
-    method public long getCoolDownMillis();
-    method public long getTimeoutMillis();
-  }
-
-  public static class StatsManager.PullAtomMetadata.Builder {
-    ctor public StatsManager.PullAtomMetadata.Builder();
-    method @NonNull public android.app.StatsManager.PullAtomMetadata build();
-    method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setAdditiveFields(@NonNull int[]);
-    method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setCoolDownMillis(long);
-    method @NonNull public android.app.StatsManager.PullAtomMetadata.Builder setTimeoutMillis(long);
-  }
-
-  public static interface StatsManager.StatsPullAtomCallback {
-    method public int onPullAtom(int, @NonNull java.util.List<android.util.StatsEvent>);
-  }
-
-  public static class StatsManager.StatsUnavailableException extends android.util.AndroidException {
-    ctor public StatsManager.StatsUnavailableException(String);
-    ctor public StatsManager.StatsUnavailableException(String, Throwable);
-  }
-
-}
-
-package android.os {
-
-  public final class StatsDimensionsValue implements android.os.Parcelable {
-    method public int describeContents();
-    method public boolean getBooleanValue();
-    method public int getField();
-    method public float getFloatValue();
-    method public int getIntValue();
-    method public long getLongValue();
-    method public String getStringValue();
-    method public java.util.List<android.os.StatsDimensionsValue> getTupleValueList();
-    method public int getValueType();
-    method public boolean isValueType(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int BOOLEAN_VALUE_TYPE = 5; // 0x5
-    field @NonNull public static final android.os.Parcelable.Creator<android.os.StatsDimensionsValue> CREATOR;
-    field public static final int FLOAT_VALUE_TYPE = 6; // 0x6
-    field public static final int INT_VALUE_TYPE = 3; // 0x3
-    field public static final int LONG_VALUE_TYPE = 4; // 0x4
-    field public static final int STRING_VALUE_TYPE = 2; // 0x2
-    field public static final int TUPLE_VALUE_TYPE = 7; // 0x7
-  }
-
-}
-
-package android.util {
-
-  public final class StatsEvent {
-    method @NonNull public static android.util.StatsEvent.Builder newBuilder();
-  }
-
-  public static final class StatsEvent.Builder {
-    method @NonNull public android.util.StatsEvent.Builder addBooleanAnnotation(byte, boolean);
-    method @NonNull public android.util.StatsEvent.Builder addIntAnnotation(byte, int);
-    method @NonNull public android.util.StatsEvent build();
-    method @NonNull public android.util.StatsEvent.Builder setAtomId(int);
-    method @NonNull public android.util.StatsEvent.Builder usePooledBuffer();
-    method @NonNull public android.util.StatsEvent.Builder writeAttributionChain(@NonNull int[], @NonNull String[]);
-    method @NonNull public android.util.StatsEvent.Builder writeBoolean(boolean);
-    method @NonNull public android.util.StatsEvent.Builder writeByteArray(@NonNull byte[]);
-    method @NonNull public android.util.StatsEvent.Builder writeFloat(float);
-    method @NonNull public android.util.StatsEvent.Builder writeInt(int);
-    method @NonNull public android.util.StatsEvent.Builder writeKeyValuePairs(@Nullable android.util.SparseIntArray, @Nullable android.util.SparseLongArray, @Nullable android.util.SparseArray<java.lang.String>, @Nullable android.util.SparseArray<java.lang.Float>);
-    method @NonNull public android.util.StatsEvent.Builder writeLong(long);
-    method @NonNull public android.util.StatsEvent.Builder writeString(@NonNull String);
-  }
-
-  public final class StatsLog {
-    method public static void write(@NonNull android.util.StatsEvent);
-    method public static void writeRaw(@NonNull byte[], int);
-  }
-
-}
-
diff --git a/apex/statsd/framework/api/system-removed.txt b/apex/statsd/framework/api/system-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apex/statsd/framework/api/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apex/statsd/framework/java/android/app/StatsManager.java b/apex/statsd/framework/java/android/app/StatsManager.java
deleted file mode 100644
index 41803cf..0000000
--- a/apex/statsd/framework/java/android/app/StatsManager.java
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * 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.app;
-
-import static android.Manifest.permission.DUMP;
-import static android.Manifest.permission.PACKAGE_USAGE_STATS;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.Binder;
-import android.os.IPullAtomCallback;
-import android.os.IPullAtomResultReceiver;
-import android.os.IStatsManagerService;
-import android.os.RemoteException;
-import android.os.StatsFrameworkInitializer;
-import android.util.AndroidException;
-import android.util.Log;
-import android.util.StatsEvent;
-import android.util.StatsEventParcel;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * API for statsd clients to send configurations and retrieve data.
- *
- * @hide
- */
-@SystemApi
-public final class StatsManager {
-    private static final String TAG = "StatsManager";
-    private static final boolean DEBUG = false;
-
-    private static final Object sLock = new Object();
-    private final Context mContext;
-
-    @GuardedBy("sLock")
-    private IStatsManagerService mStatsManagerService;
-
-    /**
-     * Long extra of uid that added the relevant stats config.
-     */
-    public static final String EXTRA_STATS_CONFIG_UID = "android.app.extra.STATS_CONFIG_UID";
-    /**
-     * Long extra of the relevant stats config's configKey.
-     */
-    public static final String EXTRA_STATS_CONFIG_KEY = "android.app.extra.STATS_CONFIG_KEY";
-    /**
-     * Long extra of the relevant statsd_config.proto's Subscription.id.
-     */
-    public static final String EXTRA_STATS_SUBSCRIPTION_ID =
-            "android.app.extra.STATS_SUBSCRIPTION_ID";
-    /**
-     * Long extra of the relevant statsd_config.proto's Subscription.rule_id.
-     */
-    public static final String EXTRA_STATS_SUBSCRIPTION_RULE_ID =
-            "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
-    /**
-     *   List<String> of the relevant statsd_config.proto's BroadcastSubscriberDetails.cookie.
-     *   Obtain using {@link android.content.Intent#getStringArrayListExtra(String)}.
-     */
-    public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES =
-            "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
-    /**
-     * Extra of a {@link android.os.StatsDimensionsValue} representing sliced dimension value
-     * information.
-     */
-    public static final String EXTRA_STATS_DIMENSIONS_VALUE =
-            "android.app.extra.STATS_DIMENSIONS_VALUE";
-    /**
-     * Long array extra of the active configs for the uid that added those configs.
-     */
-    public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS =
-            "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
-
-    /**
-     * Broadcast Action: Statsd has started.
-     * Configurations and PendingIntents can now be sent to it.
-     */
-    public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
-
-    // Pull atom callback return codes.
-    /**
-     * Value indicating that this pull was successful and that the result should be used.
-     *
-     **/
-    public static final int PULL_SUCCESS = 0;
-
-    /**
-     * Value indicating that this pull was unsuccessful and that the result should not be used.
-     **/
-    public static final int PULL_SKIP = 1;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting public static final long DEFAULT_COOL_DOWN_MILLIS = 1_000L; // 1 second.
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting public static final long DEFAULT_TIMEOUT_MILLIS = 2_000L; // 2 seconds.
-
-    /**
-     * Constructor for StatsManagerClient.
-     *
-     * @hide
-     */
-    public StatsManager(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * Adds the given configuration and associates it with the given configKey. If a config with the
-     * given configKey already exists for the caller's uid, it is replaced with the new one.
-     *
-     * @param configKey An arbitrary integer that allows clients to track the configuration.
-     * @param config    Wire-encoded StatsdConfig proto that specifies metrics (and all
-     *                  dependencies eg, conditions and matchers).
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     * @throws IllegalArgumentException if config is not a wire-encoded StatsdConfig proto
-     */
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public void addConfig(long configKey, byte[] config) throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                // can throw IllegalArgumentException
-                service.addConfiguration(configKey, config, mContext.getOpPackageName());
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to connect to statsmanager when adding configuration");
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (SecurityException e) {
-                throw new StatsUnavailableException(e.getMessage(), e);
-            } catch (IllegalStateException e) {
-                Log.e(TAG, "Failed to addConfig in statsmanager");
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
-    }
-
-    // TODO: Temporary for backwards compatibility. Remove.
-    /**
-     * @deprecated Use {@link #addConfig(long, byte[])}
-     */
-    @Deprecated
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public boolean addConfiguration(long configKey, byte[] config) {
-        try {
-            addConfig(configKey, config);
-            return true;
-        } catch (StatsUnavailableException | IllegalArgumentException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Remove a configuration from logging.
-     *
-     * @param configKey Configuration key to remove.
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     */
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public void removeConfig(long configKey) throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                service.removeConfiguration(configKey, mContext.getOpPackageName());
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to connect to statsmanager when removing configuration");
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (SecurityException e) {
-                throw new StatsUnavailableException(e.getMessage(), e);
-            } catch (IllegalStateException e) {
-                Log.e(TAG, "Failed to removeConfig in statsmanager");
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
-    }
-
-    // TODO: Temporary for backwards compatibility. Remove.
-    /**
-     * @deprecated Use {@link #removeConfig(long)}
-     */
-    @Deprecated
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public boolean removeConfiguration(long configKey) {
-        try {
-            removeConfig(configKey);
-            return true;
-        } catch (StatsUnavailableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Set the PendingIntent to be used when broadcasting subscriber information to the given
-     * subscriberId within the given config.
-     * <p>
-     * Suppose that the calling uid has added a config with key configKey, and that in this config
-     * it is specified that when a particular anomaly is detected, a broadcast should be sent to
-     * a BroadcastSubscriber with id subscriberId. This function links the given pendingIntent with
-     * that subscriberId (for that config), so that this pendingIntent is used to send the broadcast
-     * when the anomaly is detected.
-     * <p>
-     * When statsd sends the broadcast, the PendingIntent will used to send an intent with
-     * information of
-     * {@link #EXTRA_STATS_CONFIG_UID},
-     * {@link #EXTRA_STATS_CONFIG_KEY},
-     * {@link #EXTRA_STATS_SUBSCRIPTION_ID},
-     * {@link #EXTRA_STATS_SUBSCRIPTION_RULE_ID},
-     * {@link #EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES}, and
-     * {@link #EXTRA_STATS_DIMENSIONS_VALUE}.
-     * <p>
-     * This function can only be called by the owner (uid) of the config. It must be called each
-     * time statsd starts. The config must have been added first (via {@link #addConfig}).
-     *
-     * @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
-     *                      associated with the given subscriberId. May be null, in which case
-     *                      it undoes any previous setting of this subscriberId.
-     * @param configKey     The integer naming the config to which this subscriber is attached.
-     * @param subscriberId  ID of the subscriber, as used in the config.
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     */
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public void setBroadcastSubscriber(
-            PendingIntent pendingIntent, long configKey, long subscriberId)
-            throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                if (pendingIntent != null) {
-                    service.setBroadcastSubscriber(configKey, subscriberId, pendingIntent,
-                            mContext.getOpPackageName());
-                } else {
-                    service.unsetBroadcastSubscriber(configKey, subscriberId,
-                            mContext.getOpPackageName());
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to connect to statsmanager when adding broadcast subscriber",
-                        e);
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (SecurityException e) {
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
-    }
-
-    // TODO: Temporary for backwards compatibility. Remove.
-    /**
-     * @deprecated Use {@link #setBroadcastSubscriber(PendingIntent, long, long)}
-     */
-    @Deprecated
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public boolean setBroadcastSubscriber(
-            long configKey, long subscriberId, PendingIntent pendingIntent) {
-        try {
-            setBroadcastSubscriber(pendingIntent, configKey, subscriberId);
-            return true;
-        } catch (StatsUnavailableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Registers the operation that is called to retrieve the metrics data. This must be called
-     * each time statsd starts. The config must have been added first (via {@link #addConfig},
-     * although addConfig could have been called on a previous boot). This operation allows
-     * statsd to send metrics data whenever statsd determines that the metrics in memory are
-     * approaching the memory limits. The fetch operation should call {@link #getReports} to fetch
-     * the data, which also deletes the retrieved metrics from statsd's memory.
-     *
-     * @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
-     *                      associated with the given subscriberId. May be null, in which case
-     *                      it removes any associated pending intent with this configKey.
-     * @param configKey     The integer naming the config to which this operation is attached.
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     */
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public void setFetchReportsOperation(PendingIntent pendingIntent, long configKey)
-            throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                if (pendingIntent == null) {
-                    service.removeDataFetchOperation(configKey, mContext.getOpPackageName());
-                } else {
-                    service.setDataFetchOperation(configKey, pendingIntent,
-                            mContext.getOpPackageName());
-                }
-
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to connect to statsmanager when registering data listener.");
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (SecurityException e) {
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
-    }
-
-    /**
-     * Registers the operation that is called whenever there is a change in which configs are
-     * active. This must be called each time statsd starts. This operation allows
-     * statsd to inform clients that they should pull data of the configs that are currently
-     * active. The activeConfigsChangedOperation should set periodic alarms to pull data of configs
-     * that are active and stop pulling data of configs that are no longer active.
-     *
-     * @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
-     *                      associated with the given subscriberId. May be null, in which case
-     *                      it removes any associated pending intent for this client.
-     * @return A list of configs that are currently active for this client. If the pendingIntent is
-     *         null, this will be an empty list.
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     */
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public @NonNull long[] setActiveConfigsChangedOperation(@Nullable PendingIntent pendingIntent)
-            throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                if (pendingIntent == null) {
-                    service.removeActiveConfigsChangedOperation(mContext.getOpPackageName());
-                    return new long[0];
-                } else {
-                    return service.setActiveConfigsChangedOperation(pendingIntent,
-                            mContext.getOpPackageName());
-                }
-
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to connect to statsmanager "
-                        + "when registering active configs listener.");
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (SecurityException e) {
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
-    }
-
-    // TODO: Temporary for backwards compatibility. Remove.
-    /**
-     * @deprecated Use {@link #setFetchReportsOperation(PendingIntent, long)}
-     */
-    @Deprecated
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public boolean setDataFetchOperation(long configKey, PendingIntent pendingIntent) {
-        try {
-            setFetchReportsOperation(pendingIntent, configKey);
-            return true;
-        } catch (StatsUnavailableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Request the data collected for the given configKey.
-     * This getter is destructive - it also clears the retrieved metrics from statsd's memory.
-     *
-     * @param configKey Configuration key to retrieve data from.
-     * @return Serialized ConfigMetricsReportList proto.
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     */
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public byte[] getReports(long configKey) throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                return service.getData(configKey, mContext.getOpPackageName());
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to connect to statsmanager when getting data");
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (SecurityException e) {
-                throw new StatsUnavailableException(e.getMessage(), e);
-            } catch (IllegalStateException e) {
-                Log.e(TAG, "Failed to getReports in statsmanager");
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
-    }
-
-    // TODO: Temporary for backwards compatibility. Remove.
-    /**
-     * @deprecated Use {@link #getReports(long)}
-     */
-    @Deprecated
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public @Nullable byte[] getData(long configKey) {
-        try {
-            return getReports(configKey);
-        } catch (StatsUnavailableException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Clients can request metadata for statsd. Will contain stats across all configurations but not
-     * the actual metrics themselves (metrics must be collected via {@link #getReports(long)}.
-     * This getter is not destructive and will not reset any metrics/counters.
-     *
-     * @return Serialized StatsdStatsReport proto.
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     */
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public byte[] getStatsMetadata() throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                return service.getMetadata(mContext.getOpPackageName());
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to connect to statsmanager when getting metadata");
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (SecurityException e) {
-                throw new StatsUnavailableException(e.getMessage(), e);
-            } catch (IllegalStateException e) {
-                Log.e(TAG, "Failed to getStatsMetadata in statsmanager");
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
-    }
-
-    // TODO: Temporary for backwards compatibility. Remove.
-    /**
-     * @deprecated Use {@link #getStatsMetadata()}
-     */
-    @Deprecated
-    @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public @Nullable byte[] getMetadata() {
-        try {
-            return getStatsMetadata();
-        } catch (StatsUnavailableException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Returns the experiments IDs registered with statsd, or an empty array if there aren't any.
-     *
-     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
-     */
-    @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
-    public long[] getRegisteredExperimentIds()
-            throws StatsUnavailableException {
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                return service.getRegisteredExperimentIds();
-            } catch (RemoteException e) {
-                if (DEBUG) {
-                    Log.d(TAG,
-                            "Failed to connect to StatsManagerService when getting "
-                                    + "registered experiment IDs");
-                }
-                throw new StatsUnavailableException("could not connect", e);
-            } catch (IllegalStateException e) {
-                Log.e(TAG, "Failed to getRegisteredExperimentIds in statsmanager");
-                throw new StatsUnavailableException(e.getMessage(), e);
-            }
-        }
-    }
-
-    /**
-     * Sets a callback for an atom when that atom is to be pulled. The stats service will
-     * invoke pullData in the callback when the stats service determines that this atom needs to be
-     * pulled. This method should not be called by third-party apps.
-     *
-     * @param atomTag           The tag of the atom for this puller callback.
-     * @param metadata          Optional metadata specifying the timeout, cool down time, and
-     *                          additive fields for mapping isolated to host uids.
-     * @param executor          The executor in which to run the callback.
-     * @param callback          The callback to be invoked when the stats service pulls the atom.
-     *
-     */
-    @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM)
-    public void setPullAtomCallback(int atomTag, @Nullable PullAtomMetadata metadata,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull StatsPullAtomCallback callback) {
-        long coolDownMillis =
-                metadata == null ? DEFAULT_COOL_DOWN_MILLIS : metadata.mCoolDownMillis;
-        long timeoutMillis = metadata == null ? DEFAULT_TIMEOUT_MILLIS : metadata.mTimeoutMillis;
-        int[] additiveFields = metadata == null ? new int[0] : metadata.mAdditiveFields;
-        if (additiveFields == null) {
-            additiveFields = new int[0];
-        }
-
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                PullAtomCallbackInternal rec =
-                    new PullAtomCallbackInternal(atomTag, callback, executor);
-                service.registerPullAtomCallback(
-                        atomTag, coolDownMillis, timeoutMillis, additiveFields, rec);
-            } catch (RemoteException e) {
-                throw new RuntimeException("Unable to register pull callback", e);
-            }
-        }
-    }
-
-    /**
-     * Clears a callback for an atom when that atom is to be pulled. Note that any ongoing
-     * pulls will still occur. This method should not be called by third-party apps.
-     *
-     * @param atomTag           The tag of the atom of which to unregister
-     *
-     */
-    @RequiresPermission(android.Manifest.permission.REGISTER_STATS_PULL_ATOM)
-    public void clearPullAtomCallback(int atomTag) {
-        synchronized (sLock) {
-            try {
-                IStatsManagerService service = getIStatsManagerServiceLocked();
-                service.unregisterPullAtomCallback(atomTag);
-            } catch (RemoteException e) {
-                throw new RuntimeException("Unable to unregister pull atom callback");
-            }
-        }
-    }
-
-    private static class PullAtomCallbackInternal extends IPullAtomCallback.Stub {
-        public final int mAtomId;
-        public final StatsPullAtomCallback mCallback;
-        public final Executor mExecutor;
-
-        PullAtomCallbackInternal(int atomId, StatsPullAtomCallback callback, Executor executor) {
-            mAtomId = atomId;
-            mCallback = callback;
-            mExecutor = executor;
-        }
-
-        @Override
-        public void onPullAtom(int atomTag, IPullAtomResultReceiver resultReceiver) {
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mExecutor.execute(() -> {
-                    List<StatsEvent> data = new ArrayList<>();
-                    int successInt = mCallback.onPullAtom(atomTag, data);
-                    boolean success = successInt == PULL_SUCCESS;
-                    StatsEventParcel[] parcels = new StatsEventParcel[data.size()];
-                    for (int i = 0; i < data.size(); i++) {
-                        parcels[i] = new StatsEventParcel();
-                        parcels[i].buffer = data.get(i).getBytes();
-                    }
-                    try {
-                        resultReceiver.pullFinished(atomTag, success, parcels);
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId
-                                + " due to TransactionTooLarge. Calling pullFinish with no data");
-                        StatsEventParcel[] emptyData = new StatsEventParcel[0];
-                        try {
-                            resultReceiver.pullFinished(atomTag, /*success=*/false, emptyData);
-                        } catch (RemoteException nestedException) {
-                            Log.w(TAG, "StatsPullResultReceiver failed for tag " + mAtomId
-                                    + " with empty payload");
-                        }
-                    }
-                });
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-    }
-
-    /**
-     * Metadata required for registering a StatsPullAtomCallback.
-     * All fields are optional, and defaults will be used for fields that are unspecified.
-     *
-     */
-    public static class PullAtomMetadata {
-        private final long mCoolDownMillis;
-        private final long mTimeoutMillis;
-        private final int[] mAdditiveFields;
-
-        // Private Constructor for builder
-        private PullAtomMetadata(long coolDownMillis, long timeoutMillis, int[] additiveFields) {
-            mCoolDownMillis = coolDownMillis;
-            mTimeoutMillis = timeoutMillis;
-            mAdditiveFields = additiveFields;
-        }
-
-        /**
-         *  Builder for PullAtomMetadata.
-         */
-        public static class Builder {
-            private long mCoolDownMillis;
-            private long mTimeoutMillis;
-            private int[] mAdditiveFields;
-
-            /**
-             * Returns a new PullAtomMetadata.Builder object for constructing PullAtomMetadata for
-             * StatsManager#registerPullAtomCallback
-             */
-            public Builder() {
-                mCoolDownMillis = DEFAULT_COOL_DOWN_MILLIS;
-                mTimeoutMillis = DEFAULT_TIMEOUT_MILLIS;
-                mAdditiveFields = null;
-            }
-
-            /**
-             * Set the cool down time of the pull in milliseconds. If two successive pulls are
-             * issued within the cool down, a cached version of the first pull will be used for the
-             * second pull. The minimum allowed cool down is 1 second.
-             */
-            @NonNull
-            public Builder setCoolDownMillis(long coolDownMillis) {
-                mCoolDownMillis = coolDownMillis;
-                return this;
-            }
-
-            /**
-             * Set the maximum time the pull can take in milliseconds. The maximum allowed timeout
-             * is 10 seconds.
-             */
-            @NonNull
-            public Builder setTimeoutMillis(long timeoutMillis) {
-                mTimeoutMillis = timeoutMillis;
-                return this;
-            }
-
-            /**
-             * Set the additive fields of this pulled atom.
-             *
-             * This is only applicable for atoms which have a uid field. When tasks are run in
-             * isolated processes, the data will be attributed to the host uid. Additive fields
-             * will be combined when the non-additive fields are the same.
-             */
-            @NonNull
-            public Builder setAdditiveFields(@NonNull int[] additiveFields) {
-                mAdditiveFields = additiveFields;
-                return this;
-            }
-
-            /**
-             * Builds and returns a PullAtomMetadata object with the values set in the builder and
-             * defaults for unset fields.
-             */
-            @NonNull
-            public PullAtomMetadata build() {
-                return new PullAtomMetadata(mCoolDownMillis, mTimeoutMillis, mAdditiveFields);
-            }
-        }
-
-        /**
-         * Return the cool down time of this pull in milliseconds.
-         */
-        public long getCoolDownMillis() {
-            return mCoolDownMillis;
-        }
-
-        /**
-         * Return the maximum amount of time this pull can take in milliseconds.
-         */
-        public long getTimeoutMillis() {
-            return mTimeoutMillis;
-        }
-
-        /**
-         * Return the additive fields of this pulled atom.
-         *
-         * This is only applicable for atoms that have a uid field. When tasks are run in
-         * isolated processes, the data will be attributed to the host uid. Additive fields
-         * will be combined when the non-additive fields are the same.
-         */
-        @Nullable
-        public int[] getAdditiveFields() {
-            return mAdditiveFields;
-        }
-    }
-
-    /**
-     * Callback interface for pulling atoms requested by the stats service.
-     *
-     */
-    public interface StatsPullAtomCallback {
-        /**
-         * Pull data for the specified atom tag, filling in the provided list of StatsEvent data.
-         * @return {@link #PULL_SUCCESS} if the pull was successful, or {@link #PULL_SKIP} if not.
-         */
-        int onPullAtom(int atomTag, @NonNull List<StatsEvent> data);
-    }
-
-    @GuardedBy("sLock")
-    private IStatsManagerService getIStatsManagerServiceLocked() {
-        if (mStatsManagerService != null) {
-            return mStatsManagerService;
-        }
-        mStatsManagerService = IStatsManagerService.Stub.asInterface(
-                StatsFrameworkInitializer
-                .getStatsServiceManager()
-                .getStatsManagerServiceRegisterer()
-                .get());
-        return mStatsManagerService;
-    }
-
-    /**
-     * Exception thrown when communication with the stats service fails (eg if it is not available).
-     * This might be thrown early during boot before the stats service has started or if it crashed.
-     */
-    public static class StatsUnavailableException extends AndroidException {
-        public StatsUnavailableException(String reason) {
-            super("Failed to connect to statsd: " + reason);
-        }
-
-        public StatsUnavailableException(String reason, Throwable e) {
-            super("Failed to connect to statsd: " + reason, e);
-        }
-    }
-}
diff --git a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java b/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
deleted file mode 100644
index 7d9349c..0000000
--- a/apex/statsd/framework/java/android/os/StatsDimensionsValue.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright 2018 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.os;
-
-import android.annotation.SystemApi;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Container for statsd dimension value information, corresponding to a
- * stats_log.proto's DimensionValue.
- *
- * This consists of a field (an int representing a statsd atom field)
- * and a value (which may be one of a number of types).
- *
- * <p>
- * Only a single value is held, and it is necessarily one of the following types:
- * {@link String}, int, long, boolean, float,
- * or tuple (i.e. {@link List} of {@code StatsDimensionsValue}).
- *
- * The type of value held can be retrieved using {@link #getValueType()}, which returns one of the
- * following ints, depending on the type of value:
- * <ul>
- *  <li>{@link #STRING_VALUE_TYPE}</li>
- *  <li>{@link #INT_VALUE_TYPE}</li>
- *  <li>{@link #LONG_VALUE_TYPE}</li>
- *  <li>{@link #BOOLEAN_VALUE_TYPE}</li>
- *  <li>{@link #FLOAT_VALUE_TYPE}</li>
- *  <li>{@link #TUPLE_VALUE_TYPE}</li>
- * </ul>
- * Alternatively, this can be determined using {@link #isValueType(int)} with one of these constants
- * as a parameter.
- * The value itself can be retrieved using the correct get...Value() function for its type.
- *
- * <p>
- * The field is always an int, and always exists; it can be obtained using {@link #getField()}.
- *
- *
- * @hide
- */
-@SystemApi
-public final class StatsDimensionsValue implements Parcelable {
-    private static final String TAG = "StatsDimensionsValue";
-
-    // Values of the value type correspond to stats_log.proto's DimensionValue fields.
-    // Keep constants in sync with frameworks/base/cmds/statsd/src/HashableDimensionKey.cpp.
-    /** Indicates that this holds a String. */
-    public static final int STRING_VALUE_TYPE = 2;
-    /** Indicates that this holds an int. */
-    public static final int INT_VALUE_TYPE = 3;
-    /** Indicates that this holds a long. */
-    public static final int LONG_VALUE_TYPE = 4;
-    /** Indicates that this holds a boolean. */
-    public static final int BOOLEAN_VALUE_TYPE = 5;
-    /** Indicates that this holds a float. */
-    public static final int FLOAT_VALUE_TYPE = 6;
-    /** Indicates that this holds a List of StatsDimensionsValues. */
-    public static final int TUPLE_VALUE_TYPE = 7;
-
-    private final StatsDimensionsValueParcel mInner;
-
-    /**
-     * Creates a {@code StatsDimensionValue} from a parcel.
-     *
-     * @hide
-     */
-    public StatsDimensionsValue(Parcel in) {
-        mInner = StatsDimensionsValueParcel.CREATOR.createFromParcel(in);
-    }
-
-    /**
-     * Creates a {@code StatsDimensionsValue} from a StatsDimensionsValueParcel
-     *
-     * @hide
-     */
-    public StatsDimensionsValue(StatsDimensionsValueParcel parcel) {
-        mInner = parcel;
-    }
-
-    /**
-     * Return the field, i.e. the tag of a statsd atom.
-     *
-     * @return the field
-     */
-    public int getField() {
-        return mInner.field;
-    }
-
-    /**
-     * Retrieve the String held, if any.
-     *
-     * @return the {@link String} held if {@link #getValueType()} == {@link #STRING_VALUE_TYPE},
-     *         null otherwise
-     */
-    public String getStringValue() {
-        if (mInner.valueType == STRING_VALUE_TYPE) {
-            return mInner.stringValue;
-        } else {
-            Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not string.");
-            return null;
-        }
-    }
-
-    /**
-     * Retrieve the int held, if any.
-     *
-     * @return the int held if {@link #getValueType()} == {@link #INT_VALUE_TYPE}, 0 otherwise
-     */
-    public int getIntValue() {
-        if (mInner.valueType == INT_VALUE_TYPE) {
-            return mInner.intValue;
-        } else {
-            Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not int.");
-            return 0;
-        }
-    }
-
-    /**
-     * Retrieve the long held, if any.
-     *
-     * @return the long held if {@link #getValueType()} == {@link #LONG_VALUE_TYPE}, 0 otherwise
-     */
-    public long getLongValue() {
-        if (mInner.valueType == LONG_VALUE_TYPE) {
-            return mInner.longValue;
-        } else {
-            Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not long.");
-            return 0;
-        }
-    }
-
-    /**
-     * Retrieve the boolean held, if any.
-     *
-     * @return the boolean held if {@link #getValueType()} == {@link #BOOLEAN_VALUE_TYPE},
-     *         false otherwise
-     */
-    public boolean getBooleanValue() {
-        if (mInner.valueType == BOOLEAN_VALUE_TYPE) {
-            return mInner.boolValue;
-        } else {
-            Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not boolean.");
-            return false;
-        }
-    }
-
-    /**
-     * Retrieve the float held, if any.
-     *
-     * @return the float held if {@link #getValueType()} == {@link #FLOAT_VALUE_TYPE}, 0 otherwise
-     */
-    public float getFloatValue() {
-        if (mInner.valueType == FLOAT_VALUE_TYPE) {
-            return mInner.floatValue;
-        } else {
-            Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not float.");
-            return 0;
-        }
-    }
-
-    /**
-     * Retrieve the tuple, in the form of a {@link List} of {@link StatsDimensionsValue}, held,
-     * if any.
-     *
-     * @return the {@link List} of {@link StatsDimensionsValue} held
-     *         if {@link #getValueType()} == {@link #TUPLE_VALUE_TYPE},
-     *         null otherwise
-     */
-    public List<StatsDimensionsValue> getTupleValueList() {
-        if (mInner.valueType == TUPLE_VALUE_TYPE) {
-            int length = (mInner.tupleValue == null) ? 0 : mInner.tupleValue.length;
-            List<StatsDimensionsValue> tupleValues = new ArrayList<>(length);
-            for (int i = 0; i < length; i++) {
-                tupleValues.add(new StatsDimensionsValue(mInner.tupleValue[i]));
-            }
-            return tupleValues;
-        } else {
-            Log.w(TAG, "Value type is " + getValueTypeAsString() + ", not tuple.");
-            return null;
-        }
-    }
-
-    /**
-     * Returns the constant representing the type of value stored, namely one of
-     * <ul>
-     *   <li>{@link #STRING_VALUE_TYPE}</li>
-     *   <li>{@link #INT_VALUE_TYPE}</li>
-     *   <li>{@link #LONG_VALUE_TYPE}</li>
-     *   <li>{@link #BOOLEAN_VALUE_TYPE}</li>
-     *   <li>{@link #FLOAT_VALUE_TYPE}</li>
-     *   <li>{@link #TUPLE_VALUE_TYPE}</li>
-     * </ul>
-     *
-     * @return the constant representing the type of value stored
-     */
-    public int getValueType() {
-        return mInner.valueType;
-    }
-
-    /**
-     * Returns whether the type of value stored is equal to the given type.
-     *
-     * @param valueType int representing the type of value stored, as used in {@link #getValueType}
-     * @return true if {@link #getValueType()} is equal to {@code valueType}.
-     */
-    public boolean isValueType(int valueType) {
-        return mInner.valueType == valueType;
-    }
-
-    /**
-     * Returns a String representing the information in this StatsDimensionValue.
-     * No guarantees are made about the format of this String.
-     *
-     * @return String representation
-     *
-     * @hide
-     */
-    // Follows the format of statsd's dimension.h toString.
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(mInner.field);
-        sb.append(":");
-        switch (mInner.valueType) {
-            case STRING_VALUE_TYPE:
-                sb.append(mInner.stringValue);
-                break;
-            case INT_VALUE_TYPE:
-                sb.append(String.valueOf(mInner.intValue));
-                break;
-            case LONG_VALUE_TYPE:
-                sb.append(String.valueOf(mInner.longValue));
-                break;
-            case BOOLEAN_VALUE_TYPE:
-                sb.append(String.valueOf(mInner.boolValue));
-                break;
-            case FLOAT_VALUE_TYPE:
-                sb.append(String.valueOf(mInner.floatValue));
-                break;
-            case TUPLE_VALUE_TYPE:
-                sb.append("{");
-                int length = (mInner.tupleValue == null) ? 0 : mInner.tupleValue.length;
-                for (int i = 0; i < length; i++) {
-                    StatsDimensionsValue child = new StatsDimensionsValue(mInner.tupleValue[i]);
-                    sb.append(child.toString());
-                    sb.append("|");
-                }
-                sb.append("}");
-                break;
-            default:
-                Log.w(TAG, "Incorrect value type");
-                break;
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Parcelable Creator for StatsDimensionsValue.
-     */
-    public static final @android.annotation.NonNull
-            Parcelable.Creator<StatsDimensionsValue> CREATOR = new
-            Parcelable.Creator<StatsDimensionsValue>() {
-                public StatsDimensionsValue createFromParcel(Parcel in) {
-                    return new StatsDimensionsValue(in);
-                }
-
-                public StatsDimensionsValue[] newArray(int size) {
-                    return new StatsDimensionsValue[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        mInner.writeToParcel(out, flags);
-    }
-
-    /**
-     * Returns a string representation of the type of value stored.
-     */
-    private String getValueTypeAsString() {
-        switch (mInner.valueType) {
-            case STRING_VALUE_TYPE:
-                return "string";
-            case INT_VALUE_TYPE:
-                return "int";
-            case LONG_VALUE_TYPE:
-                return "long";
-            case BOOLEAN_VALUE_TYPE:
-                return "boolean";
-            case FLOAT_VALUE_TYPE:
-                return "float";
-            case TUPLE_VALUE_TYPE:
-                return "tuple";
-            default:
-                return "unknown";
-        }
-    }
-}
diff --git a/apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java b/apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java
deleted file mode 100644
index 8dc9123..0000000
--- a/apex/statsd/framework/java/android/os/StatsFrameworkInitializer.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2020 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.os;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.annotation.SystemApi.Client;
-import android.app.StatsManager;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-
-/**
- * Class for performing registration for all stats services
- *
- * @hide
- */
-@SystemApi(client = Client.MODULE_LIBRARIES)
-public class StatsFrameworkInitializer {
-    private StatsFrameworkInitializer() {
-    }
-
-    private static volatile StatsServiceManager sStatsServiceManager;
-
-    /**
-     * Sets an instance of {@link StatsServiceManager} that allows
-     * the statsd mainline module to register/obtain stats binder services. This is called
-     * by the platform during the system initialization.
-     *
-     * @param statsServiceManager instance of {@link StatsServiceManager} that allows
-     * the statsd mainline module to register/obtain statsd binder services.
-     */
-    public static void setStatsServiceManager(
-            @NonNull StatsServiceManager statsServiceManager) {
-        if (sStatsServiceManager != null) {
-            throw new IllegalStateException("setStatsServiceManager called twice!");
-        }
-
-        if (statsServiceManager == null) {
-            throw new NullPointerException("statsServiceManager is null");
-        }
-
-        sStatsServiceManager = statsServiceManager;
-    }
-
-    /** @hide */
-    public static StatsServiceManager getStatsServiceManager() {
-        return sStatsServiceManager;
-    }
-
-    /**
-     * Called by {@link SystemServiceRegistry}'s static initializer and registers all statsd
-     * services to {@link Context}, so that {@link Context#getSystemService} can return them.
-     *
-     * @throws IllegalStateException if this is called from anywhere besides
-     * {@link SystemServiceRegistry}
-     */
-    public static void registerServiceWrappers() {
-        SystemServiceRegistry.registerContextAwareService(
-                Context.STATS_MANAGER,
-                StatsManager.class,
-                context -> new StatsManager(context)
-        );
-    }
-}
diff --git a/apex/statsd/framework/java/android/util/StatsEvent.java b/apex/statsd/framework/java/android/util/StatsEvent.java
deleted file mode 100644
index 8be5c63..0000000
--- a/apex/statsd/framework/java/android/util/StatsEvent.java
+++ /dev/null
@@ -1,879 +0,0 @@
-/*
- * Copyright (C) 2019 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.util;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.SystemClock;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Arrays;
-
-/**
- * StatsEvent builds and stores the buffer sent over the statsd socket.
- * This class defines and encapsulates the socket protocol.
- *
- * <p>Usage:</p>
- * <pre>
- *      // Pushed event
- *      StatsEvent statsEvent = StatsEvent.newBuilder()
- *          .setAtomId(atomId)
- *          .writeBoolean(false)
- *          .writeString("annotated String field")
- *          .addBooleanAnnotation(annotationId, true)
- *          .usePooledBuffer()
- *          .build();
- *      StatsLog.write(statsEvent);
- *
- *      // Pulled event
- *      StatsEvent statsEvent = StatsEvent.newBuilder()
- *          .setAtomId(atomId)
- *          .writeBoolean(false)
- *          .writeString("annotated String field")
- *          .addBooleanAnnotation(annotationId, true)
- *          .build();
- * </pre>
- * @hide
- **/
-@SystemApi
-public final class StatsEvent {
-    // Type Ids.
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_INT = 0x00;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_LONG = 0x01;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_STRING = 0x02;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_LIST = 0x03;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_FLOAT = 0x04;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_BOOLEAN = 0x05;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_BYTE_ARRAY = 0x06;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_OBJECT = 0x07;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_KEY_VALUE_PAIRS = 0x08;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_ATTRIBUTION_CHAIN = 0x09;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_ERRORS = 0x0F;
-
-    // Error flags.
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_NO_TIMESTAMP = 0x1;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_NO_ATOM_ID = 0x2;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_OVERFLOW = 0x4;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ATTRIBUTION_CHAIN_TOO_LONG = 0x8;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_TOO_MANY_KEY_VALUE_PAIRS = 0x10;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD = 0x20;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_INVALID_ANNOTATION_ID = 0x40;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ANNOTATION_ID_TOO_LARGE = 0x80;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_TOO_MANY_ANNOTATIONS = 0x100;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_TOO_MANY_FIELDS = 0x200;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL = 0x1000;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ATOM_ID_INVALID_POSITION = 0x2000;
-
-    // Size limits.
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int MAX_ANNOTATION_COUNT = 15;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int MAX_ATTRIBUTION_NODES = 127;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int MAX_NUM_ELEMENTS = 127;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int MAX_KEY_VALUE_PAIRS = 127;
-
-    private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;
-
-    // Max payload size is 4 bytes less as 4 bytes are reserved for statsEventTag.
-    // See android_util_StatsLog.cpp.
-    private static final int MAX_PUSH_PAYLOAD_SIZE = LOGGER_ENTRY_MAX_PAYLOAD - 4;
-
-    private static final int MAX_PULL_PAYLOAD_SIZE = 50 * 1024; // 50 KB
-
-    private final int mAtomId;
-    private final byte[] mPayload;
-    private Buffer mBuffer;
-    private final int mNumBytes;
-
-    private StatsEvent(final int atomId, @Nullable final Buffer buffer,
-            @NonNull final byte[] payload, final int numBytes) {
-        mAtomId = atomId;
-        mBuffer = buffer;
-        mPayload = payload;
-        mNumBytes = numBytes;
-    }
-
-    /**
-     * Returns a new StatsEvent.Builder for building StatsEvent object.
-     **/
-    @NonNull
-    public static StatsEvent.Builder newBuilder() {
-        return new StatsEvent.Builder(Buffer.obtain());
-    }
-
-    /**
-     * Get the atom Id of the atom encoded in this StatsEvent object.
-     *
-     * @hide
-     **/
-    public int getAtomId() {
-        return mAtomId;
-    }
-
-    /**
-     * Get the byte array that contains the encoded payload that can be sent to statsd.
-     *
-     * @hide
-     **/
-    @NonNull
-    public byte[] getBytes() {
-        return mPayload;
-    }
-
-    /**
-     * Get the number of bytes used to encode the StatsEvent payload.
-     *
-     * @hide
-     **/
-    public int getNumBytes() {
-        return mNumBytes;
-    }
-
-    /**
-     * Recycle resources used by this StatsEvent object.
-     * No actions should be taken on this StatsEvent after release() is called.
-     *
-     * @hide
-     **/
-    public void release() {
-        if (mBuffer != null) {
-            mBuffer.release();
-            mBuffer = null;
-        }
-    }
-
-    /**
-     * Builder for constructing a StatsEvent object.
-     *
-     * <p>This class defines and encapsulates the socket encoding for the buffer.
-     * The write methods must be called in the same order as the order of fields in the
-     * atom definition.</p>
-     *
-     * <p>setAtomId() can be called anytime before build().</p>
-     *
-     * <p>Example:</p>
-     * <pre>
-     *     // Atom definition.
-     *     message MyAtom {
-     *         optional int32 field1 = 1;
-     *         optional int64 field2 = 2;
-     *         optional string field3 = 3 [(annotation1) = true];
-     *     }
-     *
-     *     // StatsEvent construction for pushed event.
-     *     StatsEvent.newBuilder()
-     *     StatsEvent statsEvent = StatsEvent.newBuilder()
-     *         .setAtomId(atomId)
-     *         .writeInt(3) // field1
-     *         .writeLong(8L) // field2
-     *         .writeString("foo") // field 3
-     *         .addBooleanAnnotation(annotation1Id, true)
-     *         .usePooledBuffer()
-     *         .build();
-     *
-     *     // StatsEvent construction for pulled event.
-     *     StatsEvent.newBuilder()
-     *     StatsEvent statsEvent = StatsEvent.newBuilder()
-     *         .setAtomId(atomId)
-     *         .writeInt(3) // field1
-     *         .writeLong(8L) // field2
-     *         .writeString("foo") // field 3
-     *         .addBooleanAnnotation(annotation1Id, true)
-     *         .build();
-     * </pre>
-     **/
-    public static final class Builder {
-        // Fixed positions.
-        private static final int POS_NUM_ELEMENTS = 1;
-        private static final int POS_TIMESTAMP_NS = POS_NUM_ELEMENTS + Byte.BYTES;
-        private static final int POS_ATOM_ID = POS_TIMESTAMP_NS + Byte.BYTES + Long.BYTES;
-
-        private final Buffer mBuffer;
-        private long mTimestampNs;
-        private int mAtomId;
-        private byte mCurrentAnnotationCount;
-        private int mPos;
-        private int mPosLastField;
-        private byte mLastType;
-        private int mNumElements;
-        private int mErrorMask;
-        private boolean mUsePooledBuffer = false;
-
-        private Builder(final Buffer buffer) {
-            mBuffer = buffer;
-            mCurrentAnnotationCount = 0;
-            mAtomId = 0;
-            mTimestampNs = SystemClock.elapsedRealtimeNanos();
-            mNumElements = 0;
-
-            // Set mPos to 0 for writing TYPE_OBJECT at 0th position.
-            mPos = 0;
-            writeTypeId(TYPE_OBJECT);
-
-            // Write timestamp.
-            mPos = POS_TIMESTAMP_NS;
-            writeLong(mTimestampNs);
-        }
-
-        /**
-         * Sets the atom id for this StatsEvent.
-         *
-         * This should be called immediately after StatsEvent.newBuilder()
-         * and should only be called once.
-         * Not calling setAtomId will result in ERROR_NO_ATOM_ID.
-         * Calling setAtomId out of order will result in ERROR_ATOM_ID_INVALID_POSITION.
-         **/
-        @NonNull
-        public Builder setAtomId(final int atomId) {
-            if (0 == mAtomId) {
-                mAtomId = atomId;
-
-                if (1 == mNumElements) { // Only timestamp is written so far.
-                    writeInt(atomId);
-                } else {
-                    // setAtomId called out of order.
-                    mErrorMask |= ERROR_ATOM_ID_INVALID_POSITION;
-                }
-            }
-
-            return this;
-        }
-
-        /**
-         * Write a boolean field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeBoolean(final boolean value) {
-            // Write boolean typeId byte followed by boolean byte representation.
-            writeTypeId(TYPE_BOOLEAN);
-            mPos += mBuffer.putBoolean(mPos, value);
-            mNumElements++;
-            return this;
-        }
-
-        /**
-         * Write an integer field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeInt(final int value) {
-            // Write integer typeId byte followed by 4-byte representation of value.
-            writeTypeId(TYPE_INT);
-            mPos += mBuffer.putInt(mPos, value);
-            mNumElements++;
-            return this;
-        }
-
-        /**
-         * Write a long field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeLong(final long value) {
-            // Write long typeId byte followed by 8-byte representation of value.
-            writeTypeId(TYPE_LONG);
-            mPos += mBuffer.putLong(mPos, value);
-            mNumElements++;
-            return this;
-        }
-
-        /**
-         * Write a float field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeFloat(final float value) {
-            // Write float typeId byte followed by 4-byte representation of value.
-            writeTypeId(TYPE_FLOAT);
-            mPos += mBuffer.putFloat(mPos, value);
-            mNumElements++;
-            return this;
-        }
-
-        /**
-         * Write a String field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeString(@NonNull final String value) {
-            // Write String typeId byte, followed by 4-byte representation of number of bytes
-            // in the UTF-8 encoding, followed by the actual UTF-8 byte encoding of value.
-            final byte[] valueBytes = stringToBytes(value);
-            writeByteArray(valueBytes, TYPE_STRING);
-            return this;
-        }
-
-        /**
-         * Write a byte array field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeByteArray(@NonNull final byte[] value) {
-            // Write byte array typeId byte, followed by 4-byte representation of number of bytes
-            // in value, followed by the actual byte array.
-            writeByteArray(value, TYPE_BYTE_ARRAY);
-            return this;
-        }
-
-        private void writeByteArray(@NonNull final byte[] value, final byte typeId) {
-            writeTypeId(typeId);
-            final int numBytes = value.length;
-            mPos += mBuffer.putInt(mPos, numBytes);
-            mPos += mBuffer.putByteArray(mPos, value);
-            mNumElements++;
-        }
-
-        /**
-         * Write an attribution chain field to this StatsEvent.
-         *
-         * The sizes of uids and tags must be equal. The AttributionNode at position i is
-         * made up of uids[i] and tags[i].
-         *
-         * @param uids array of uids in the attribution nodes.
-         * @param tags array of tags in the attribution nodes.
-         **/
-        @NonNull
-        public Builder writeAttributionChain(
-                @NonNull final int[] uids, @NonNull final String[] tags) {
-            final byte numUids = (byte) uids.length;
-            final byte numTags = (byte) tags.length;
-
-            if (numUids != numTags) {
-                mErrorMask |= ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL;
-            } else if (numUids > MAX_ATTRIBUTION_NODES) {
-                mErrorMask |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
-            } else {
-                // Write attribution chain typeId byte, followed by 1-byte representation of
-                // number of attribution nodes, followed by encoding of each attribution node.
-                writeTypeId(TYPE_ATTRIBUTION_CHAIN);
-                mPos += mBuffer.putByte(mPos, numUids);
-                for (int i = 0; i < numUids; i++) {
-                    // Each uid is encoded as 4-byte representation of its int value.
-                    mPos += mBuffer.putInt(mPos, uids[i]);
-
-                    // Each tag is encoded as 4-byte representation of number of bytes in its
-                    // UTF-8 encoding, followed by the actual UTF-8 bytes.
-                    final byte[] tagBytes = stringToBytes(tags[i]);
-                    mPos += mBuffer.putInt(mPos, tagBytes.length);
-                    mPos += mBuffer.putByteArray(mPos, tagBytes);
-                }
-                mNumElements++;
-            }
-            return this;
-        }
-
-        /**
-         * Write KeyValuePairsAtom entries to this StatsEvent.
-         *
-         * @param intMap Integer key-value pairs.
-         * @param longMap Long key-value pairs.
-         * @param stringMap String key-value pairs.
-         * @param floatMap Float key-value pairs.
-         **/
-        @NonNull
-        public Builder writeKeyValuePairs(
-                @Nullable final SparseIntArray intMap,
-                @Nullable final SparseLongArray longMap,
-                @Nullable final SparseArray<String> stringMap,
-                @Nullable final SparseArray<Float> floatMap) {
-            final int intMapSize = null == intMap ? 0 : intMap.size();
-            final int longMapSize = null == longMap ? 0 : longMap.size();
-            final int stringMapSize = null == stringMap ? 0 : stringMap.size();
-            final int floatMapSize = null == floatMap ? 0 : floatMap.size();
-            final int totalCount = intMapSize + longMapSize + stringMapSize + floatMapSize;
-
-            if (totalCount > MAX_KEY_VALUE_PAIRS) {
-                mErrorMask |= ERROR_TOO_MANY_KEY_VALUE_PAIRS;
-            } else {
-                writeTypeId(TYPE_KEY_VALUE_PAIRS);
-                mPos += mBuffer.putByte(mPos, (byte) totalCount);
-
-                for (int i = 0; i < intMapSize; i++) {
-                    final int key = intMap.keyAt(i);
-                    final int value = intMap.valueAt(i);
-                    mPos += mBuffer.putInt(mPos, key);
-                    writeTypeId(TYPE_INT);
-                    mPos += mBuffer.putInt(mPos, value);
-                }
-
-                for (int i = 0; i < longMapSize; i++) {
-                    final int key = longMap.keyAt(i);
-                    final long value = longMap.valueAt(i);
-                    mPos += mBuffer.putInt(mPos, key);
-                    writeTypeId(TYPE_LONG);
-                    mPos += mBuffer.putLong(mPos, value);
-                }
-
-                for (int i = 0; i < stringMapSize; i++) {
-                    final int key = stringMap.keyAt(i);
-                    final String value = stringMap.valueAt(i);
-                    mPos += mBuffer.putInt(mPos, key);
-                    writeTypeId(TYPE_STRING);
-                    final byte[] valueBytes = stringToBytes(value);
-                    mPos += mBuffer.putInt(mPos, valueBytes.length);
-                    mPos += mBuffer.putByteArray(mPos, valueBytes);
-                }
-
-                for (int i = 0; i < floatMapSize; i++) {
-                    final int key = floatMap.keyAt(i);
-                    final float value = floatMap.valueAt(i);
-                    mPos += mBuffer.putInt(mPos, key);
-                    writeTypeId(TYPE_FLOAT);
-                    mPos += mBuffer.putFloat(mPos, value);
-                }
-
-                mNumElements++;
-            }
-
-            return this;
-        }
-
-        /**
-         * Write a boolean annotation for the last field written.
-         **/
-        @NonNull
-        public Builder addBooleanAnnotation(
-                final byte annotationId, final boolean value) {
-            // Ensure there's a field written to annotate.
-            if (mNumElements < 2) {
-                mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
-            } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
-                mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
-            } else {
-                mPos += mBuffer.putByte(mPos, annotationId);
-                mPos += mBuffer.putByte(mPos, TYPE_BOOLEAN);
-                mPos += mBuffer.putBoolean(mPos, value);
-                mCurrentAnnotationCount++;
-                writeAnnotationCount();
-            }
-
-            return this;
-        }
-
-        /**
-         * Write an integer annotation for the last field written.
-         **/
-        @NonNull
-        public Builder addIntAnnotation(final byte annotationId, final int value) {
-            if (mNumElements < 2) {
-                mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
-            } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
-                mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
-            } else {
-                mPos += mBuffer.putByte(mPos, annotationId);
-                mPos += mBuffer.putByte(mPos, TYPE_INT);
-                mPos += mBuffer.putInt(mPos, value);
-                mCurrentAnnotationCount++;
-                writeAnnotationCount();
-            }
-
-            return this;
-        }
-
-        /**
-         * Indicates to reuse Buffer's byte array as the underlying payload in StatsEvent.
-         * This should be called for pushed events to reduce memory allocations and garbage
-         * collections.
-         **/
-        @NonNull
-        public Builder usePooledBuffer() {
-            mUsePooledBuffer = true;
-            mBuffer.setMaxSize(MAX_PUSH_PAYLOAD_SIZE, mPos);
-            return this;
-        }
-
-        /**
-         * Builds a StatsEvent object with values entered in this Builder.
-         **/
-        @NonNull
-        public StatsEvent build() {
-            if (0L == mTimestampNs) {
-                mErrorMask |= ERROR_NO_TIMESTAMP;
-            }
-            if (0 == mAtomId) {
-                mErrorMask |= ERROR_NO_ATOM_ID;
-            }
-            if (mBuffer.hasOverflowed()) {
-                mErrorMask |= ERROR_OVERFLOW;
-            }
-            if (mNumElements > MAX_NUM_ELEMENTS) {
-                mErrorMask |= ERROR_TOO_MANY_FIELDS;
-            }
-
-            if (0 == mErrorMask) {
-                mBuffer.putByte(POS_NUM_ELEMENTS, (byte) mNumElements);
-            } else {
-                // Write atom id and error mask. Overwrite any annotations for atom Id.
-                mPos = POS_ATOM_ID;
-                mPos += mBuffer.putByte(mPos, TYPE_INT);
-                mPos += mBuffer.putInt(mPos, mAtomId);
-                mPos += mBuffer.putByte(mPos, TYPE_ERRORS);
-                mPos += mBuffer.putInt(mPos, mErrorMask);
-                mBuffer.putByte(POS_NUM_ELEMENTS, (byte) 3);
-            }
-
-            final int size = mPos;
-
-            if (mUsePooledBuffer) {
-                return new StatsEvent(mAtomId, mBuffer, mBuffer.getBytes(), size);
-            } else {
-                // Create a copy of the buffer with the required number of bytes.
-                final byte[] payload = new byte[size];
-                System.arraycopy(mBuffer.getBytes(), 0, payload, 0, size);
-
-                // Return Buffer instance to the pool.
-                mBuffer.release();
-
-                return new StatsEvent(mAtomId, null, payload, size);
-            }
-        }
-
-        private void writeTypeId(final byte typeId) {
-            mPosLastField = mPos;
-            mLastType = typeId;
-            mCurrentAnnotationCount = 0;
-            final byte encodedId = (byte) (typeId & 0x0F);
-            mPos += mBuffer.putByte(mPos, encodedId);
-        }
-
-        private void writeAnnotationCount() {
-            // Use first 4 bits for annotation count and last 4 bits for typeId.
-            final byte encodedId = (byte) ((mCurrentAnnotationCount << 4) | (mLastType & 0x0F));
-            mBuffer.putByte(mPosLastField, encodedId);
-        }
-
-        @NonNull
-        private static byte[] stringToBytes(@Nullable final String value) {
-            return (null == value ? "" : value).getBytes(UTF_8);
-        }
-    }
-
-    private static final class Buffer {
-        private static Object sLock = new Object();
-
-        @GuardedBy("sLock")
-        private static Buffer sPool;
-
-        private byte[] mBytes = new byte[MAX_PUSH_PAYLOAD_SIZE];
-        private boolean mOverflow = false;
-        private int mMaxSize = MAX_PULL_PAYLOAD_SIZE;
-
-        @NonNull
-        private static Buffer obtain() {
-            final Buffer buffer;
-            synchronized (sLock) {
-                buffer = null == sPool ? new Buffer() : sPool;
-                sPool = null;
-            }
-            buffer.reset();
-            return buffer;
-        }
-
-        private Buffer() {
-        }
-
-        @NonNull
-        private byte[] getBytes() {
-            return mBytes;
-        }
-
-        private void release() {
-            // Recycle this Buffer if its size is MAX_PUSH_PAYLOAD_SIZE or under.
-            if (mBytes.length <= MAX_PUSH_PAYLOAD_SIZE) {
-                synchronized (sLock) {
-                    if (null == sPool) {
-                        sPool = this;
-                    }
-                }
-            }
-        }
-
-        private void reset() {
-            mOverflow = false;
-            mMaxSize = MAX_PULL_PAYLOAD_SIZE;
-        }
-
-        private void setMaxSize(final int maxSize, final int numBytesWritten) {
-            mMaxSize = maxSize;
-            if (numBytesWritten > maxSize) {
-                mOverflow = true;
-            }
-        }
-
-        private boolean hasOverflowed() {
-            return mOverflow;
-        }
-
-        /**
-         * Checks for available space in the byte array.
-         *
-         * @param index starting position in the buffer to start the check.
-         * @param numBytes number of bytes to check from index.
-         * @return true if space is available, false otherwise.
-         **/
-        private boolean hasEnoughSpace(final int index, final int numBytes) {
-            final int totalBytesNeeded = index + numBytes;
-
-            if (totalBytesNeeded > mMaxSize) {
-                mOverflow = true;
-                return false;
-            }
-
-            // Expand buffer if needed.
-            if (mBytes.length < mMaxSize && totalBytesNeeded > mBytes.length) {
-                int newSize = mBytes.length;
-                do {
-                    newSize *= 2;
-                } while (newSize <= totalBytesNeeded);
-
-                if (newSize > mMaxSize) {
-                    newSize = mMaxSize;
-                }
-
-                mBytes = Arrays.copyOf(mBytes, newSize);
-            }
-
-            return true;
-        }
-
-        /**
-         * Writes a byte into the buffer.
-         *
-         * @param index position in the buffer where the byte is written.
-         * @param value the byte to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putByte(final int index, final byte value) {
-            if (hasEnoughSpace(index, Byte.BYTES)) {
-                mBytes[index] = (byte) (value);
-                return Byte.BYTES;
-            }
-            return 0;
-        }
-
-        /**
-         * Writes a boolean into the buffer.
-         *
-         * @param index position in the buffer where the boolean is written.
-         * @param value the boolean to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putBoolean(final int index, final boolean value) {
-            return putByte(index, (byte) (value ? 1 : 0));
-        }
-
-        /**
-         * Writes an integer into the buffer.
-         *
-         * @param index position in the buffer where the integer is written.
-         * @param value the integer to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putInt(final int index, final int value) {
-            if (hasEnoughSpace(index, Integer.BYTES)) {
-                // Use little endian byte order.
-                mBytes[index] = (byte) (value);
-                mBytes[index + 1] = (byte) (value >> 8);
-                mBytes[index + 2] = (byte) (value >> 16);
-                mBytes[index + 3] = (byte) (value >> 24);
-                return Integer.BYTES;
-            }
-            return 0;
-        }
-
-        /**
-         * Writes a long into the buffer.
-         *
-         * @param index position in the buffer where the long is written.
-         * @param value the long to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putLong(final int index, final long value) {
-            if (hasEnoughSpace(index, Long.BYTES)) {
-                // Use little endian byte order.
-                mBytes[index] = (byte) (value);
-                mBytes[index + 1] = (byte) (value >> 8);
-                mBytes[index + 2] = (byte) (value >> 16);
-                mBytes[index + 3] = (byte) (value >> 24);
-                mBytes[index + 4] = (byte) (value >> 32);
-                mBytes[index + 5] = (byte) (value >> 40);
-                mBytes[index + 6] = (byte) (value >> 48);
-                mBytes[index + 7] = (byte) (value >> 56);
-                return Long.BYTES;
-            }
-            return 0;
-        }
-
-        /**
-         * Writes a float into the buffer.
-         *
-         * @param index position in the buffer where the float is written.
-         * @param value the float to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putFloat(final int index, final float value) {
-            return putInt(index, Float.floatToIntBits(value));
-        }
-
-        /**
-         * Copies a byte array into the buffer.
-         *
-         * @param index position in the buffer where the byte array is copied.
-         * @param value the byte array to copy.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putByteArray(final int index, @NonNull final byte[] value) {
-            final int numBytes = value.length;
-            if (hasEnoughSpace(index, numBytes)) {
-                System.arraycopy(value, 0, mBytes, index, numBytes);
-                return numBytes;
-            }
-            return 0;
-        }
-    }
-}
diff --git a/apex/statsd/framework/java/android/util/StatsLog.java b/apex/statsd/framework/java/android/util/StatsLog.java
deleted file mode 100644
index 0a9f4eb..0000000
--- a/apex/statsd/framework/java/android/util/StatsLog.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 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.util;
-
-import static android.Manifest.permission.DUMP;
-import static android.Manifest.permission.PACKAGE_USAGE_STATS;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.IStatsd;
-import android.os.Process;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.statsd.StatsdStatsLog;
-
-/**
- * StatsLog provides an API for developers to send events to statsd. The events can be used to
- * define custom metrics inside statsd.
- */
-public final class StatsLog {
-
-    // Load JNI library
-    static {
-        System.loadLibrary("stats_jni");
-    }
-    private static final String TAG = "StatsLog";
-    private static final boolean DEBUG = false;
-    private static final int EXPERIMENT_IDS_FIELD_ID = 1;
-
-    private StatsLog() {
-    }
-
-    /**
-     * Logs a start event.
-     *
-     * @param label developer-chosen label.
-     * @return True if the log request was sent to statsd.
-     */
-    public static boolean logStart(int label) {
-        int callingUid = Process.myUid();
-        StatsdStatsLog.write(
-                StatsdStatsLog.APP_BREADCRUMB_REPORTED,
-                callingUid,
-                label,
-                StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__START);
-        return true;
-    }
-
-    /**
-     * Logs a stop event.
-     *
-     * @param label developer-chosen label.
-     * @return True if the log request was sent to statsd.
-     */
-    public static boolean logStop(int label) {
-        int callingUid = Process.myUid();
-        StatsdStatsLog.write(
-                StatsdStatsLog.APP_BREADCRUMB_REPORTED,
-                callingUid,
-                label,
-                StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP);
-        return true;
-    }
-
-    /**
-     * Logs an event that does not represent a start or stop boundary.
-     *
-     * @param label developer-chosen label.
-     * @return True if the log request was sent to statsd.
-     */
-    public static boolean logEvent(int label) {
-        int callingUid = Process.myUid();
-        StatsdStatsLog.write(
-                StatsdStatsLog.APP_BREADCRUMB_REPORTED,
-                callingUid,
-                label,
-                StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED);
-        return true;
-    }
-
-    /**
-     * Logs an event for binary push for module updates.
-     *
-     * @param trainName        name of install train.
-     * @param trainVersionCode version code of the train.
-     * @param options          optional flags about this install.
-     *                         The last 3 bits indicate options:
-     *                             0x01: FLAG_REQUIRE_STAGING
-     *                             0x02: FLAG_ROLLBACK_ENABLED
-     *                             0x04: FLAG_REQUIRE_LOW_LATENCY_MONITOR
-     * @param state            current install state. Defined as State enums in
-     *                         BinaryPushStateChanged atom in
-     *                         frameworks/base/cmds/statsd/src/atoms.proto
-     * @param experimentIds    experiment ids.
-     * @return True if the log request was sent to statsd.
-     */
-    @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
-    public static boolean logBinaryPushStateChanged(@NonNull String trainName,
-            long trainVersionCode, int options, int state,
-            @NonNull long[] experimentIds) {
-        ProtoOutputStream proto = new ProtoOutputStream();
-        for (long id : experimentIds) {
-            proto.write(
-                    ProtoOutputStream.FIELD_TYPE_INT64
-                    | ProtoOutputStream.FIELD_COUNT_REPEATED
-                    | EXPERIMENT_IDS_FIELD_ID,
-                    id);
-        }
-        StatsdStatsLog.write(StatsdStatsLog.BINARY_PUSH_STATE_CHANGED,
-                trainName,
-                trainVersionCode,
-                (options & IStatsd.FLAG_REQUIRE_STAGING) > 0,
-                (options & IStatsd.FLAG_ROLLBACK_ENABLED) > 0,
-                (options & IStatsd.FLAG_REQUIRE_LOW_LATENCY_MONITOR) > 0,
-                state,
-                proto.getBytes(),
-                0,
-                0,
-                false);
-        return true;
-    }
-
-    /**
-     * Write an event to stats log using the raw format.
-     *
-     * @param buffer    The encoded buffer of data to write.
-     * @param size      The number of bytes from the buffer to write.
-     * @hide
-     */
-    // TODO(b/144935988): Mark deprecated.
-    @SystemApi
-    public static void writeRaw(@NonNull byte[] buffer, int size) {
-        // TODO(b/144935988): make this no-op once clients have migrated to StatsEvent.
-        writeImpl(buffer, size, 0);
-    }
-
-    /**
-     * Write an event to stats log using the raw format.
-     *
-     * @param buffer    The encoded buffer of data to write.
-     * @param size      The number of bytes from the buffer to write.
-     * @param atomId    The id of the atom to which the event belongs.
-     */
-    private static native void writeImpl(@NonNull byte[] buffer, int size, int atomId);
-
-    /**
-     * Write an event to stats log using the raw format encapsulated in StatsEvent.
-     * After writing to stats log, release() is called on the StatsEvent object.
-     * No further action should be taken on the StatsEvent object following this call.
-     *
-     * @param statsEvent    The StatsEvent object containing the encoded buffer of data to write.
-     * @hide
-     */
-    @SystemApi
-    public static void write(@NonNull final StatsEvent statsEvent) {
-        writeImpl(statsEvent.getBytes(), statsEvent.getNumBytes(), statsEvent.getAtomId());
-        statsEvent.release();
-    }
-
-    private static void enforceDumpCallingPermission(Context context) {
-        context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission.");
-    }
-
-    private static void enforcesageStatsCallingPermission(Context context) {
-        context.enforceCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS,
-                "Need PACKAGE_USAGE_STATS permission.");
-    }
-}
diff --git a/apex/statsd/framework/test/Android.bp b/apex/statsd/framework/test/Android.bp
deleted file mode 100644
index 5cc5647..0000000
--- a/apex/statsd/framework/test/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2020 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.
-
-android_test {
-    name: "FrameworkStatsdTest",
-    sdk_version: "module_current",
-    srcs: [ "**/*.java" ],
-    manifest: "AndroidManifest.xml",
-    static_libs: [
-        "androidx.test.rules",
-        "truth-prebuilt",
-    ],
-    libs: [
-        "android.test.runner.stubs",
-        "android.test.base.stubs",
-        "framework-statsd.impl",
-    ],
-    test_suites: [
-        "device-tests",
-        "mts",
-    ],
-}
diff --git a/apex/statsd/framework/test/AndroidManifest.xml b/apex/statsd/framework/test/AndroidManifest.xml
deleted file mode 100644
index 8f89d23..0000000
--- a/apex/statsd/framework/test/AndroidManifest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.os.statsd.framework.test"
-        >
-
-    <instrumentation
-            android:name="androidx.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.os.statsd.framework.test"
-            android:label="Framework Statsd Tests" />
-
-</manifest>
diff --git a/apex/statsd/framework/test/AndroidTest.xml b/apex/statsd/framework/test/AndroidTest.xml
deleted file mode 100644
index fb51915..0000000
--- a/apex/statsd/framework/test/AndroidTest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Runs Tests for Statsd.">
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="FrameworkStatsdTest.apk" />
-        <option name="install-arg" value="-g" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="mts" />
-    <option name="test-tag" value="FrameworkStatsdTest" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.os.statsd.framework.test" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-
-    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
-    </object>
-</configuration>
\ No newline at end of file
diff --git a/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java b/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java
deleted file mode 100644
index fd386bd..0000000
--- a/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2019 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.app;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.StatsManager.PullAtomMetadata;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class PullAtomMetadataTest {
-
-    @Test
-    public void testEmpty() {
-        PullAtomMetadata metadata = new PullAtomMetadata.Builder().build();
-        assertThat(metadata.getTimeoutMillis()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_MILLIS);
-        assertThat(metadata.getCoolDownMillis()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_MILLIS);
-        assertThat(metadata.getAdditiveFields()).isNull();
-    }
-
-    @Test
-    public void testSetTimeoutMillis() {
-        long timeoutMillis = 500L;
-        PullAtomMetadata metadata =
-                new PullAtomMetadata.Builder().setTimeoutMillis(timeoutMillis).build();
-        assertThat(metadata.getTimeoutMillis()).isEqualTo(timeoutMillis);
-        assertThat(metadata.getCoolDownMillis()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_MILLIS);
-        assertThat(metadata.getAdditiveFields()).isNull();
-    }
-
-    @Test
-    public void testSetCoolDownMillis() {
-        long coolDownMillis = 10_000L;
-        PullAtomMetadata metadata =
-                new PullAtomMetadata.Builder().setCoolDownMillis(coolDownMillis).build();
-        assertThat(metadata.getTimeoutMillis()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_MILLIS);
-        assertThat(metadata.getCoolDownMillis()).isEqualTo(coolDownMillis);
-        assertThat(metadata.getAdditiveFields()).isNull();
-    }
-
-    @Test
-    public void testSetAdditiveFields() {
-        int[] fields = {2, 4, 6};
-        PullAtomMetadata metadata =
-                new PullAtomMetadata.Builder().setAdditiveFields(fields).build();
-        assertThat(metadata.getTimeoutMillis()).isEqualTo(StatsManager.DEFAULT_TIMEOUT_MILLIS);
-        assertThat(metadata.getCoolDownMillis()).isEqualTo(StatsManager.DEFAULT_COOL_DOWN_MILLIS);
-        assertThat(metadata.getAdditiveFields()).isEqualTo(fields);
-    }
-
-    @Test
-    public void testSetAllElements() {
-        long timeoutMillis = 300L;
-        long coolDownMillis = 9572L;
-        int[] fields = {3, 2};
-        PullAtomMetadata metadata = new PullAtomMetadata.Builder()
-                .setTimeoutMillis(timeoutMillis)
-                .setCoolDownMillis(coolDownMillis)
-                .setAdditiveFields(fields)
-                .build();
-        assertThat(metadata.getTimeoutMillis()).isEqualTo(timeoutMillis);
-        assertThat(metadata.getCoolDownMillis()).isEqualTo(coolDownMillis);
-        assertThat(metadata.getAdditiveFields()).isEqualTo(fields);
-    }
-}
diff --git a/apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java b/apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java
deleted file mode 100644
index db25911..0000000
--- a/apex/statsd/framework/test/src/android/os/StatsDimensionsValueTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 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.os;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.List;
-
-@RunWith(JUnit4.class)
-public final class StatsDimensionsValueTest {
-
-    @Test
-    public void testConversionFromStructuredParcel() {
-        int tupleField = 100; // atom id
-        String stringValue = "Hello";
-        int intValue = 123;
-        long longValue = 123456789L;
-        float floatValue = 1.1f;
-        boolean boolValue = true;
-
-        // Construct structured parcel
-        StatsDimensionsValueParcel sdvp = new StatsDimensionsValueParcel();
-        sdvp.field = tupleField;
-        sdvp.valueType = StatsDimensionsValue.TUPLE_VALUE_TYPE;
-        sdvp.tupleValue = new StatsDimensionsValueParcel[5];
-
-        for (int i = 0; i < 5; i++) {
-            sdvp.tupleValue[i] = new StatsDimensionsValueParcel();
-            sdvp.tupleValue[i].field = i + 1;
-        }
-
-        sdvp.tupleValue[0].valueType = StatsDimensionsValue.STRING_VALUE_TYPE;
-        sdvp.tupleValue[1].valueType = StatsDimensionsValue.INT_VALUE_TYPE;
-        sdvp.tupleValue[2].valueType = StatsDimensionsValue.LONG_VALUE_TYPE;
-        sdvp.tupleValue[3].valueType = StatsDimensionsValue.FLOAT_VALUE_TYPE;
-        sdvp.tupleValue[4].valueType = StatsDimensionsValue.BOOLEAN_VALUE_TYPE;
-
-        sdvp.tupleValue[0].stringValue = stringValue;
-        sdvp.tupleValue[1].intValue = intValue;
-        sdvp.tupleValue[2].longValue = longValue;
-        sdvp.tupleValue[3].floatValue = floatValue;
-        sdvp.tupleValue[4].boolValue = boolValue;
-
-        // Convert to StatsDimensionsValue and check result
-        StatsDimensionsValue sdv = new StatsDimensionsValue(sdvp);
-
-        assertThat(sdv.getField()).isEqualTo(tupleField);
-        assertThat(sdv.getValueType()).isEqualTo(StatsDimensionsValue.TUPLE_VALUE_TYPE);
-        List<StatsDimensionsValue> sdvChildren = sdv.getTupleValueList();
-        assertThat(sdvChildren.size()).isEqualTo(5);
-
-        for (int i = 0; i < 5; i++) {
-            assertThat(sdvChildren.get(i).getField()).isEqualTo(i + 1);
-        }
-
-        assertThat(sdvChildren.get(0).getValueType())
-              .isEqualTo(StatsDimensionsValue.STRING_VALUE_TYPE);
-        assertThat(sdvChildren.get(1).getValueType())
-              .isEqualTo(StatsDimensionsValue.INT_VALUE_TYPE);
-        assertThat(sdvChildren.get(2).getValueType())
-              .isEqualTo(StatsDimensionsValue.LONG_VALUE_TYPE);
-        assertThat(sdvChildren.get(3).getValueType())
-              .isEqualTo(StatsDimensionsValue.FLOAT_VALUE_TYPE);
-        assertThat(sdvChildren.get(4).getValueType())
-              .isEqualTo(StatsDimensionsValue.BOOLEAN_VALUE_TYPE);
-
-        assertThat(sdvChildren.get(0).getStringValue()).isEqualTo(stringValue);
-        assertThat(sdvChildren.get(1).getIntValue()).isEqualTo(intValue);
-        assertThat(sdvChildren.get(2).getLongValue()).isEqualTo(longValue);
-        assertThat(sdvChildren.get(3).getFloatValue()).isEqualTo(floatValue);
-        assertThat(sdvChildren.get(4).getBooleanValue()).isEqualTo(boolValue);
-
-        // Ensure that StatsDimensionsValue and StatsDimensionsValueParcel are
-        // parceled equivalently
-        Parcel sdvpParcel = Parcel.obtain();
-        Parcel sdvParcel = Parcel.obtain();
-        sdvp.writeToParcel(sdvpParcel, 0);
-        sdv.writeToParcel(sdvParcel, 0);
-        assertThat(sdvpParcel.dataSize()).isEqualTo(sdvParcel.dataSize());
-    }
-
-    @Test
-    public void testNullTupleArray() {
-        int tupleField = 100; // atom id
-
-        StatsDimensionsValueParcel parcel = new StatsDimensionsValueParcel();
-        parcel.field = tupleField;
-        parcel.valueType = StatsDimensionsValue.TUPLE_VALUE_TYPE;
-        parcel.tupleValue = null;
-
-        StatsDimensionsValue sdv = new StatsDimensionsValue(parcel);
-        assertThat(sdv.getField()).isEqualTo(tupleField);
-        assertThat(sdv.getValueType()).isEqualTo(StatsDimensionsValue.TUPLE_VALUE_TYPE);
-        List<StatsDimensionsValue> sdvChildren = sdv.getTupleValueList();
-        assertThat(sdvChildren.size()).isEqualTo(0);
-    }
-}
diff --git a/apex/statsd/framework/test/src/android/util/StatsEventTest.java b/apex/statsd/framework/test/src/android/util/StatsEventTest.java
deleted file mode 100644
index 8d26369..0000000
--- a/apex/statsd/framework/test/src/android/util/StatsEventTest.java
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * Copyright (C) 2019 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.util;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.os.SystemClock;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.common.collect.Range;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Random;
-
-/**
- * Internal tests for {@link StatsEvent}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class StatsEventTest {
-
-    @Test
-    public void testNoFields() {
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder().usePooledBuffer().build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        final int expectedAtomId = 0;
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get()).isEqualTo(3);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id")
-                .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertWithMessage("Third element is not errors type")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ERRORS);
-
-        final int errorMask = buffer.getInt();
-
-        assertWithMessage("ERROR_NO_ATOM_ID should be the only error in the error mask")
-                .that(errorMask).isEqualTo(StatsEvent.ERROR_NO_ATOM_ID);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testOnlyAtomId() {
-        final int expectedAtomId = 109;
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder()
-                .setAtomId(expectedAtomId)
-                .usePooledBuffer()
-                .build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get()).isEqualTo(2);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id")
-                .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testIntBooleanIntInt() {
-        final int expectedAtomId = 109;
-        final int field1 = 1;
-        final boolean field2 = true;
-        final int field3 = 3;
-        final int field4 = 4;
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder()
-                .setAtomId(expectedAtomId)
-                .writeInt(field1)
-                .writeBoolean(field2)
-                .writeInt(field3)
-                .writeInt(field4)
-                .usePooledBuffer()
-                .build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get()).isEqualTo(6);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id")
-                .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertWithMessage("First field is not Int")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect field 1")
-                .that(buffer.getInt()).isEqualTo(field1);
-
-        assertWithMessage("Second field is not Boolean")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN);
-
-        assertWithMessage("Incorrect field 2")
-                .that(buffer.get()).isEqualTo(1);
-
-        assertWithMessage("Third field is not Int")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect field 3")
-                .that(buffer.getInt()).isEqualTo(field3);
-
-        assertWithMessage("Fourth field is not Int")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect field 4")
-                .that(buffer.getInt()).isEqualTo(field4);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testStringFloatByteArray() {
-        final int expectedAtomId = 109;
-        final String field1 = "Str 1";
-        final float field2 = 9.334f;
-        final byte[] field3 = new byte[] { 56, 23, 89, -120 };
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder()
-                .setAtomId(expectedAtomId)
-                .writeString(field1)
-                .writeFloat(field2)
-                .writeByteArray(field3)
-                .usePooledBuffer()
-                .build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get()).isEqualTo(5);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id")
-                .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertWithMessage("First field is not String")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_STRING);
-
-        final String field1Actual = getStringFromByteBuffer(buffer);
-        assertWithMessage("Incorrect field 1")
-                .that(field1Actual).isEqualTo(field1);
-
-        assertWithMessage("Second field is not Float")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_FLOAT);
-
-        assertWithMessage("Incorrect field 2")
-                .that(buffer.getFloat()).isEqualTo(field2);
-
-        assertWithMessage("Third field is not byte array")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BYTE_ARRAY);
-
-        final byte[] field3Actual = getByteArrayFromByteBuffer(buffer);
-        assertWithMessage("Incorrect field 3")
-                .that(field3Actual).isEqualTo(field3);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testAttributionChainLong() {
-        final int expectedAtomId = 109;
-        final int[] uids = new int[] { 1, 2, 3, 4, 5 };
-        final String[] tags = new String[] { "1", "2", "3", "4", "5" };
-        final long field2 = -230909823L;
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder()
-                .setAtomId(expectedAtomId)
-                .writeAttributionChain(uids, tags)
-                .writeLong(field2)
-                .usePooledBuffer()
-                .build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get()).isEqualTo(4);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id")
-                .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertWithMessage("First field is not Attribution Chain")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ATTRIBUTION_CHAIN);
-
-        assertWithMessage("Incorrect number of attribution nodes")
-                .that(buffer.get()).isEqualTo((byte) uids.length);
-
-        for (int i = 0; i < tags.length; i++) {
-            assertWithMessage("Incorrect uid in Attribution Chain")
-                    .that(buffer.getInt()).isEqualTo(uids[i]);
-
-            final String tag = getStringFromByteBuffer(buffer);
-            assertWithMessage("Incorrect tag in Attribution Chain")
-                    .that(tag).isEqualTo(tags[i]);
-        }
-
-        assertWithMessage("Second field is not Long")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect field 2")
-                .that(buffer.getLong()).isEqualTo(field2);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testKeyValuePairs() {
-        final int expectedAtomId = 109;
-        final SparseIntArray intMap = new SparseIntArray();
-        final SparseLongArray longMap = new SparseLongArray();
-        final SparseArray<String> stringMap = new SparseArray<>();
-        final SparseArray<Float> floatMap = new SparseArray<>();
-        intMap.put(1, -1);
-        intMap.put(2, -2);
-        stringMap.put(3, "abc");
-        stringMap.put(4, "2h");
-        floatMap.put(9, -234.344f);
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder()
-                .setAtomId(expectedAtomId)
-                .writeKeyValuePairs(intMap, longMap, stringMap, floatMap)
-                .usePooledBuffer()
-                .build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get()).isEqualTo(3);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id")
-                .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertWithMessage("First field is not KeyValuePairs")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_KEY_VALUE_PAIRS);
-
-        assertWithMessage("Incorrect number of key value pairs")
-                .that(buffer.get()).isEqualTo(
-                        (byte) (intMap.size() + longMap.size() + stringMap.size()
-                                + floatMap.size()));
-
-        for (int i = 0; i < intMap.size(); i++) {
-            assertWithMessage("Incorrect key in intMap")
-                    .that(buffer.getInt()).isEqualTo(intMap.keyAt(i));
-            assertWithMessage("The type id of the value should be TYPE_INT in intMap")
-                    .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-            assertWithMessage("Incorrect value in intMap")
-                    .that(buffer.getInt()).isEqualTo(intMap.valueAt(i));
-        }
-
-        for (int i = 0; i < longMap.size(); i++) {
-            assertWithMessage("Incorrect key in longMap")
-                    .that(buffer.getInt()).isEqualTo(longMap.keyAt(i));
-            assertWithMessage("The type id of the value should be TYPE_LONG in longMap")
-                    .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-            assertWithMessage("Incorrect value in longMap")
-                    .that(buffer.getLong()).isEqualTo(longMap.valueAt(i));
-        }
-
-        for (int i = 0; i < stringMap.size(); i++) {
-            assertWithMessage("Incorrect key in stringMap")
-                    .that(buffer.getInt()).isEqualTo(stringMap.keyAt(i));
-            assertWithMessage("The type id of the value should be TYPE_STRING in stringMap")
-                    .that(buffer.get()).isEqualTo(StatsEvent.TYPE_STRING);
-            final String value = getStringFromByteBuffer(buffer);
-            assertWithMessage("Incorrect value in stringMap")
-                    .that(value).isEqualTo(stringMap.valueAt(i));
-        }
-
-        for (int i = 0; i < floatMap.size(); i++) {
-            assertWithMessage("Incorrect key in floatMap")
-                    .that(buffer.getInt()).isEqualTo(floatMap.keyAt(i));
-            assertWithMessage("The type id of the value should be TYPE_FLOAT in floatMap")
-                    .that(buffer.get()).isEqualTo(StatsEvent.TYPE_FLOAT);
-            assertWithMessage("Incorrect value in floatMap")
-                    .that(buffer.getFloat()).isEqualTo(floatMap.valueAt(i));
-        }
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testSingleAnnotations() {
-        final int expectedAtomId = 109;
-        final int field1 = 1;
-        final byte field1AnnotationId = 45;
-        final boolean field1AnnotationValue = false;
-        final boolean field2 = true;
-        final byte field2AnnotationId = 1;
-        final int field2AnnotationValue = 23;
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder()
-                .setAtomId(expectedAtomId)
-                .writeInt(field1)
-                .addBooleanAnnotation(field1AnnotationId, field1AnnotationValue)
-                .writeBoolean(field2)
-                .addIntAnnotation(field2AnnotationId, field2AnnotationValue)
-                .usePooledBuffer()
-                .build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get()).isEqualTo(4);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id")
-                .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        final byte field1Header = buffer.get();
-        final int field1AnnotationValueCount = field1Header >> 4;
-        final byte field1Type = (byte) (field1Header & 0x0F);
-        assertWithMessage("First field is not Int")
-                .that(field1Type).isEqualTo(StatsEvent.TYPE_INT);
-        assertWithMessage("First field annotation count is wrong")
-                .that(field1AnnotationValueCount).isEqualTo(1);
-        assertWithMessage("Incorrect field 1")
-                .that(buffer.getInt()).isEqualTo(field1);
-        assertWithMessage("First field's annotation id is wrong")
-                .that(buffer.get()).isEqualTo(field1AnnotationId);
-        assertWithMessage("First field's annotation type is wrong")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN);
-        assertWithMessage("First field's annotation value is wrong")
-                .that(buffer.get()).isEqualTo(field1AnnotationValue ? 1 : 0);
-
-        final byte field2Header = buffer.get();
-        final int field2AnnotationValueCount = field2Header >> 4;
-        final byte field2Type = (byte) (field2Header & 0x0F);
-        assertWithMessage("Second field is not boolean")
-                .that(field2Type).isEqualTo(StatsEvent.TYPE_BOOLEAN);
-        assertWithMessage("Second field annotation count is wrong")
-                .that(field2AnnotationValueCount).isEqualTo(1);
-        assertWithMessage("Incorrect field 2")
-                .that(buffer.get()).isEqualTo(field2 ? 1 : 0);
-        assertWithMessage("Second field's annotation id is wrong")
-                .that(buffer.get()).isEqualTo(field2AnnotationId);
-        assertWithMessage("Second field's annotation type is wrong")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-        assertWithMessage("Second field's annotation value is wrong")
-                .that(buffer.getInt()).isEqualTo(field2AnnotationValue);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testAtomIdAnnotations() {
-        final int expectedAtomId = 109;
-        final byte atomAnnotationId = 84;
-        final int atomAnnotationValue = 9;
-        final int field1 = 1;
-        final byte field1AnnotationId = 45;
-        final boolean field1AnnotationValue = false;
-        final boolean field2 = true;
-        final byte field2AnnotationId = 1;
-        final int field2AnnotationValue = 23;
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder()
-                .setAtomId(expectedAtomId)
-                .addIntAnnotation(atomAnnotationId, atomAnnotationValue)
-                .writeInt(field1)
-                .addBooleanAnnotation(field1AnnotationId, field1AnnotationValue)
-                .writeBoolean(field2)
-                .addIntAnnotation(field2AnnotationId, field2AnnotationValue)
-                .usePooledBuffer()
-                .build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get()).isEqualTo(4);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        final byte atomIdHeader = buffer.get();
-        final int atomIdAnnotationValueCount = atomIdHeader >> 4;
-        final byte atomIdValueType = (byte) (atomIdHeader & 0x0F);
-        assertWithMessage("Second element is not atom id")
-                .that(atomIdValueType).isEqualTo(StatsEvent.TYPE_INT);
-        assertWithMessage("Atom id annotation count is wrong")
-                .that(atomIdAnnotationValueCount).isEqualTo(1);
-        assertWithMessage("Incorrect atom id")
-                .that(buffer.getInt()).isEqualTo(expectedAtomId);
-        assertWithMessage("Atom id's annotation id is wrong")
-                .that(buffer.get()).isEqualTo(atomAnnotationId);
-        assertWithMessage("Atom id's annotation type is wrong")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-        assertWithMessage("Atom id's annotation value is wrong")
-                .that(buffer.getInt()).isEqualTo(atomAnnotationValue);
-
-        final byte field1Header = buffer.get();
-        final int field1AnnotationValueCount = field1Header >> 4;
-        final byte field1Type = (byte) (field1Header & 0x0F);
-        assertWithMessage("First field is not Int")
-                .that(field1Type).isEqualTo(StatsEvent.TYPE_INT);
-        assertWithMessage("First field annotation count is wrong")
-                .that(field1AnnotationValueCount).isEqualTo(1);
-        assertWithMessage("Incorrect field 1")
-                .that(buffer.getInt()).isEqualTo(field1);
-        assertWithMessage("First field's annotation id is wrong")
-                .that(buffer.get()).isEqualTo(field1AnnotationId);
-        assertWithMessage("First field's annotation type is wrong")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_BOOLEAN);
-        assertWithMessage("First field's annotation value is wrong")
-                .that(buffer.get()).isEqualTo(field1AnnotationValue ? 1 : 0);
-
-        final byte field2Header = buffer.get();
-        final int field2AnnotationValueCount = field2Header >> 4;
-        final byte field2Type = (byte) (field2Header & 0x0F);
-        assertWithMessage("Second field is not boolean")
-                .that(field2Type).isEqualTo(StatsEvent.TYPE_BOOLEAN);
-        assertWithMessage("Second field annotation count is wrong")
-                .that(field2AnnotationValueCount).isEqualTo(1);
-        assertWithMessage("Incorrect field 2")
-                .that(buffer.get()).isEqualTo(field2 ? 1 : 0);
-        assertWithMessage("Second field's annotation id is wrong")
-                .that(buffer.get()).isEqualTo(field2AnnotationId);
-        assertWithMessage("Second field's annotation type is wrong")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-        assertWithMessage("Second field's annotation value is wrong")
-                .that(buffer.getInt()).isEqualTo(field2AnnotationValue);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testSetAtomIdNotCalledImmediately() {
-        final int expectedAtomId = 109;
-        final int field1 = 25;
-        final boolean field2 = true;
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder()
-                .writeInt(field1)
-                .setAtomId(expectedAtomId)
-                .writeBoolean(field2)
-                .usePooledBuffer()
-                .build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get()).isEqualTo(3);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong()).isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id")
-                .that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertWithMessage("Third element is not errors type")
-                .that(buffer.get()).isEqualTo(StatsEvent.TYPE_ERRORS);
-
-        final int errorMask = buffer.getInt();
-
-        assertWithMessage("ERROR_ATOM_ID_INVALID_POSITION should be the only error in the mask")
-                .that(errorMask).isEqualTo(StatsEvent.ERROR_ATOM_ID_INVALID_POSITION);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testLargePulledEvent() {
-        final int expectedAtomId = 10_020;
-        byte[] field1 = new byte[10 * 1024];
-        new Random().nextBytes(field1);
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent =
-                StatsEvent.newBuilder().setAtomId(expectedAtomId).writeByteArray(field1).build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get())
-                .isEqualTo(3);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong())
-                .isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id").that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertWithMessage("Third element is not byte array")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_BYTE_ARRAY);
-
-        final byte[] field1Actual = getByteArrayFromByteBuffer(buffer);
-        assertWithMessage("Incorrect field 1").that(field1Actual).isEqualTo(field1);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testPulledEventOverflow() {
-        final int expectedAtomId = 10_020;
-        byte[] field1 = new byte[50 * 1024];
-        new Random().nextBytes(field1);
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent =
-                StatsEvent.newBuilder().setAtomId(expectedAtomId).writeByteArray(field1).build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get())
-                .isEqualTo(3);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong())
-                .isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id").that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertWithMessage("Third element is not errors type")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_ERRORS);
-
-        final int errorMask = buffer.getInt();
-
-        assertWithMessage("ERROR_OVERFLOW should be the only error in the error mask")
-                .that(errorMask)
-                .isEqualTo(StatsEvent.ERROR_OVERFLOW);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    @Test
-    public void testPushedEventOverflow() {
-        final int expectedAtomId = 10_020;
-        byte[] field1 = new byte[10 * 1024];
-        new Random().nextBytes(field1);
-
-        final long minTimestamp = SystemClock.elapsedRealtimeNanos();
-        final StatsEvent statsEvent = StatsEvent.newBuilder()
-                                              .setAtomId(expectedAtomId)
-                                              .writeByteArray(field1)
-                                              .usePooledBuffer()
-                                              .build();
-        final long maxTimestamp = SystemClock.elapsedRealtimeNanos();
-
-        assertThat(statsEvent.getAtomId()).isEqualTo(expectedAtomId);
-
-        final ByteBuffer buffer =
-                ByteBuffer.wrap(statsEvent.getBytes()).order(ByteOrder.LITTLE_ENDIAN);
-
-        assertWithMessage("Root element in buffer is not TYPE_OBJECT")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_OBJECT);
-
-        assertWithMessage("Incorrect number of elements in root object")
-                .that(buffer.get())
-                .isEqualTo(3);
-
-        assertWithMessage("First element is not timestamp")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_LONG);
-
-        assertWithMessage("Incorrect timestamp")
-                .that(buffer.getLong())
-                .isIn(Range.closed(minTimestamp, maxTimestamp));
-
-        assertWithMessage("Second element is not atom id")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_INT);
-
-        assertWithMessage("Incorrect atom id").that(buffer.getInt()).isEqualTo(expectedAtomId);
-
-        assertWithMessage("Third element is not errors type")
-                .that(buffer.get())
-                .isEqualTo(StatsEvent.TYPE_ERRORS);
-
-        final int errorMask = buffer.getInt();
-
-        assertWithMessage("ERROR_OVERFLOW should be the only error in the error mask")
-                .that(errorMask)
-                .isEqualTo(StatsEvent.ERROR_OVERFLOW);
-
-        assertThat(statsEvent.getNumBytes()).isEqualTo(buffer.position());
-
-        statsEvent.release();
-    }
-
-    private static byte[] getByteArrayFromByteBuffer(final ByteBuffer buffer) {
-        final int numBytes = buffer.getInt();
-        byte[] bytes = new byte[numBytes];
-        buffer.get(bytes);
-        return bytes;
-    }
-
-    private static String getStringFromByteBuffer(final ByteBuffer buffer) {
-        final byte[] bytes = getByteArrayFromByteBuffer(buffer);
-        return new String(bytes, UTF_8);
-    }
-}
diff --git a/apex/statsd/jni/android_util_StatsLog.cpp b/apex/statsd/jni/android_util_StatsLog.cpp
deleted file mode 100644
index 71ce949..0000000
--- a/apex/statsd/jni/android_util_StatsLog.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define LOG_NAMESPACE "StatsLog.tag."
-#define LOG_TAG "StatsLog_println"
-
-#include <jni.h>
-#include <log/log.h>
-#include <nativehelper/scoped_local_ref.h>
-#include "stats_buffer_writer.h"
-
-namespace android {
-
-static void android_util_StatsLog_write(JNIEnv* env, jobject clazz, jbyteArray buf, jint size,
-        jint atomId) {
-    if (buf == NULL) {
-        return;
-    }
-    jint actualSize = env->GetArrayLength(buf);
-    if (actualSize < size) {
-        return;
-    }
-
-    jbyte* bufferArray = env->GetByteArrayElements(buf, NULL);
-    if (bufferArray == NULL) {
-        return;
-    }
-
-    write_buffer_to_statsd((void*) bufferArray, size, atomId);
-
-    env->ReleaseByteArrayElements(buf, bufferArray, 0);
-}
-
-/*
- * JNI registration.
- */
-static const JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "writeImpl", "([BII)V", (void*) android_util_StatsLog_write },
-};
-
-int register_android_util_StatsLog(JNIEnv* env)
-{
-    static const char* kStatsLogClass = "android/util/StatsLog";
-
-    ScopedLocalRef<jclass> cls(env, env->FindClass(kStatsLogClass));
-    if (cls.get() == nullptr) {
-        ALOGE("jni statsd registration failure, class not found '%s'", kStatsLogClass);
-        return JNI_ERR;
-    }
-
-    const jint count = sizeof(gMethods) / sizeof(gMethods[0]);
-    int status = env->RegisterNatives(cls.get(), gMethods, count);
-    if (status < 0) {
-        ALOGE("jni statsd registration failure, status: %d", status);
-        return JNI_ERR;
-    }
-    return JNI_VERSION_1_4;
-}
-
-}; // namespace android
-
-/*
- * JNI Initialization
- */
-jint JNI_OnLoad(JavaVM* jvm, void* reserved) {
-    JNIEnv* e;
-
-    ALOGV("statsd : loading JNI\n");
-    // Check JNI version
-    if (jvm->GetEnv((void**)&e, JNI_VERSION_1_4)) {
-        ALOGE("JNI version mismatch error");
-        return JNI_ERR;
-    }
-
-    return android::register_android_util_StatsLog(e);
-}
diff --git a/apex/statsd/service/Android.bp b/apex/statsd/service/Android.bp
deleted file mode 100644
index df0ccfc..0000000
--- a/apex/statsd/service/Android.bp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2020 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.
-
-filegroup {
-    name: "service-statsd-sources",
-    srcs: [
-        "java/**/*.java",
-    ],
-}
-
-java_library {
-    name: "service-statsd",
-    srcs: [ ":service-statsd-sources" ],
-    sdk_version: "system_server_current",
-    libs: [
-        "framework-annotations-lib",
-        "framework-statsd",
-    ],
-    plugins: ["java_api_finder"],
-    apex_available: [
-        "com.android.os.statsd",
-        "test_com.android.os.statsd",
-    ],
-}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java
deleted file mode 100644
index dc477a5..0000000
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanion.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.server.stats;
-
-import android.app.PendingIntent;
-import android.app.StatsManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.IPendingIntentRef;
-import android.os.Process;
-import android.os.StatsDimensionsValue;
-import android.os.StatsDimensionsValueParcel;
-import android.util.Log;
-
-import com.android.server.SystemService;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * @hide
- */
-public class StatsCompanion {
-    private static final String TAG = "StatsCompanion";
-    private static final boolean DEBUG = false;
-
-    private static final int AID_STATSD = 1066;
-
-    private static final String STATS_COMPANION_SERVICE = "statscompanion";
-    private static final String STATS_MANAGER_SERVICE = "statsmanager";
-
-    static void enforceStatsdCallingUid() {
-        if (Binder.getCallingPid() == Process.myPid()) {
-            return;
-        }
-        if (Binder.getCallingUid() != AID_STATSD) {
-            throw new SecurityException("Not allowed to access StatsCompanion");
-        }
-    }
-
-    /**
-     * Lifecycle class for both {@link StatsCompanionService} and {@link StatsManagerService}.
-     */
-    public static final class Lifecycle extends SystemService {
-        private StatsCompanionService mStatsCompanionService;
-        private StatsManagerService mStatsManagerService;
-
-        public Lifecycle(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void onStart() {
-            mStatsCompanionService = new StatsCompanionService(getContext());
-            mStatsManagerService = new StatsManagerService(getContext());
-            mStatsCompanionService.setStatsManagerService(mStatsManagerService);
-            mStatsManagerService.setStatsCompanionService(mStatsCompanionService);
-
-            try {
-                publishBinderService(STATS_COMPANION_SERVICE, mStatsCompanionService);
-                if (DEBUG) Log.d(TAG, "Published " + STATS_COMPANION_SERVICE);
-                publishBinderService(STATS_MANAGER_SERVICE, mStatsManagerService);
-                if (DEBUG) Log.d(TAG, "Published " + STATS_MANAGER_SERVICE);
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to publishBinderService", e);
-            }
-        }
-
-        @Override
-        public void onBootPhase(int phase) {
-            super.onBootPhase(phase);
-            if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
-                mStatsCompanionService.systemReady();
-            }
-            if (phase == PHASE_BOOT_COMPLETED) {
-                mStatsCompanionService.bootCompleted();
-            }
-        }
-    }
-
-    /**
-     * Wrapper for {@link PendingIntent}. Allows Statsd to send PendingIntents.
-     */
-    public static class PendingIntentRef extends IPendingIntentRef.Stub {
-
-        private static final String TAG = "PendingIntentRef";
-
-        /**
-         * The last report time is provided with each intent registered to
-         * StatsManager#setFetchReportsOperation. This allows easy de-duping in the receiver if
-         * statsd is requesting the client to retrieve the same statsd data. The last report time
-         * corresponds to the last_report_elapsed_nanos that will provided in the current
-         * ConfigMetricsReport, and this timestamp also corresponds to the
-         * current_report_elapsed_nanos of the most recently obtained ConfigMetricsReport.
-         */
-        private static final String EXTRA_LAST_REPORT_TIME = "android.app.extra.LAST_REPORT_TIME";
-        private static final int CODE_DATA_BROADCAST = 1;
-        private static final int CODE_ACTIVE_CONFIGS_BROADCAST = 1;
-        private static final int CODE_SUBSCRIBER_BROADCAST = 1;
-
-        private final PendingIntent mPendingIntent;
-        private final Context mContext;
-
-        public PendingIntentRef(PendingIntent pendingIntent, Context context) {
-            mPendingIntent = pendingIntent;
-            mContext = context;
-        }
-
-        @Override
-        public void sendDataBroadcast(long lastReportTimeNs) {
-            enforceStatsdCallingUid();
-            Intent intent = new Intent();
-            intent.putExtra(EXTRA_LAST_REPORT_TIME, lastReportTimeNs);
-            try {
-                mPendingIntent.send(mContext, CODE_DATA_BROADCAST, intent, null, null);
-            } catch (PendingIntent.CanceledException e) {
-                Log.w(TAG, "Unable to send PendingIntent");
-            }
-        }
-
-        @Override
-        public void sendActiveConfigsChangedBroadcast(long[] configIds) {
-            enforceStatsdCallingUid();
-            Intent intent = new Intent();
-            intent.putExtra(StatsManager.EXTRA_STATS_ACTIVE_CONFIG_KEYS, configIds);
-            try {
-                mPendingIntent.send(mContext, CODE_ACTIVE_CONFIGS_BROADCAST, intent, null, null);
-                if (DEBUG) {
-                    Log.d(TAG, "Sent broadcast with config ids " + Arrays.toString(configIds));
-                }
-            } catch (PendingIntent.CanceledException e) {
-                Log.w(TAG, "Unable to send active configs changed broadcast using PendingIntent");
-            }
-        }
-
-        @Override
-        public void sendSubscriberBroadcast(long configUid, long configId, long subscriptionId,
-                long subscriptionRuleId, String[] cookies,
-                StatsDimensionsValueParcel dimensionsValueParcel) {
-            enforceStatsdCallingUid();
-            StatsDimensionsValue dimensionsValue = new StatsDimensionsValue(dimensionsValueParcel);
-            Intent intent =
-                    new Intent()
-                            .putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid)
-                            .putExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, configId)
-                            .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, subscriptionId)
-                            .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_RULE_ID,
-                                    subscriptionRuleId)
-                            .putExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, dimensionsValue);
-
-            ArrayList<String> cookieList = new ArrayList<>(cookies.length);
-            cookieList.addAll(Arrays.asList(cookies));
-            intent.putStringArrayListExtra(
-                    StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookieList);
-
-            if (DEBUG) {
-                Log.d(TAG,
-                        String.format(
-                                "Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}",
-                                configUid, configId, subscriptionId, subscriptionRuleId,
-                                Arrays.toString(cookies),
-                                dimensionsValue));
-            }
-            try {
-                mPendingIntent.send(mContext, CODE_SUBSCRIBER_BROADCAST, intent, null, null);
-            } catch (PendingIntent.CanceledException e) {
-                Log.w(TAG,
-                        "Unable to send using PendingIntent from uid " + configUid
-                                + "; presumably it had been cancelled.");
-            }
-        }
-    }
-}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
deleted file mode 100644
index fbda86f..0000000
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ /dev/null
@@ -1,770 +0,0 @@
-/*
- * Copyright (C) 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 com.android.server.stats;
-
-import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
-
-import android.app.AlarmManager;
-import android.app.AlarmManager.OnAlarmListener;
-import android.app.StatsManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.IStatsCompanionService;
-import android.os.IStatsd;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.StatsFrameworkInitializer;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Helper service for statsd (the native stats management service in cmds/statsd/).
- * Used for registering and receiving alarms on behalf of statsd.
- *
- * @hide
- */
-public class StatsCompanionService extends IStatsCompanionService.Stub {
-
-    private static final long MILLIS_IN_A_DAY = TimeUnit.DAYS.toMillis(1);
-
-    public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
-    public static final String CONFIG_DIR = "/data/misc/stats-service";
-
-    static final String TAG = "StatsCompanionService";
-    static final boolean DEBUG = false;
-    /**
-     * Hard coded field ids of frameworks/base/cmds/statsd/src/uid_data.proto
-     * to be used in ProtoOutputStream.
-     */
-    private static final int APPLICATION_INFO_FIELD_ID = 1;
-    private static final int UID_FIELD_ID = 1;
-    private static final int VERSION_FIELD_ID = 2;
-    private static final int VERSION_STRING_FIELD_ID = 3;
-    private static final int PACKAGE_NAME_FIELD_ID = 4;
-    private static final int INSTALLER_FIELD_ID = 5;
-
-    public static final int DEATH_THRESHOLD = 10;
-
-    static final class CompanionHandler extends Handler {
-        CompanionHandler(Looper looper) {
-            super(looper);
-        }
-    }
-
-    private final Context mContext;
-    private final AlarmManager mAlarmManager;
-    @GuardedBy("sStatsdLock")
-    private static IStatsd sStatsd;
-    private static final Object sStatsdLock = new Object();
-
-    private final OnAlarmListener mPullingAlarmListener;
-    private final OnAlarmListener mPeriodicAlarmListener;
-
-    private StatsManagerService mStatsManagerService;
-
-    @GuardedBy("sStatsdLock")
-    private final HashSet<Long> mDeathTimeMillis = new HashSet<>();
-    @GuardedBy("sStatsdLock")
-    private final HashMap<Long, String> mDeletedFiles = new HashMap<>();
-    private final CompanionHandler mHandler;
-
-    // Flag that is set when PHASE_BOOT_COMPLETED is triggered in the StatsCompanion lifecycle.
-    private AtomicBoolean mBootCompleted = new AtomicBoolean(false);
-
-    public StatsCompanionService(Context context) {
-        super();
-        mContext = context;
-        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        if (DEBUG) Log.d(TAG, "Registered receiver for ACTION_PACKAGE_REPLACED and ADDED.");
-        HandlerThread handlerThread = new HandlerThread(TAG);
-        handlerThread.start();
-        mHandler = new CompanionHandler(handlerThread.getLooper());
-
-        mPullingAlarmListener = new PullingAlarmListener(context);
-        mPeriodicAlarmListener = new PeriodicAlarmListener(context);
-    }
-
-    private final static int[] toIntArray(List<Integer> list) {
-        int[] ret = new int[list.size()];
-        for (int i = 0; i < ret.length; i++) {
-            ret[i] = list.get(i);
-        }
-        return ret;
-    }
-
-    private final static long[] toLongArray(List<Long> list) {
-        long[] ret = new long[list.size()];
-        for (int i = 0; i < ret.length; i++) {
-            ret[i] = list.get(i);
-        }
-        return ret;
-    }
-
-    /**
-     * Non-blocking call to retrieve a reference to statsd
-     *
-     * @return IStatsd object if statsd is ready, null otherwise.
-     */
-    private static IStatsd getStatsdNonblocking() {
-        synchronized (sStatsdLock) {
-            return sStatsd;
-        }
-    }
-
-    private static void informAllUids(Context context) {
-        ParcelFileDescriptor[] fds;
-        try {
-            fds = ParcelFileDescriptor.createPipe();
-        } catch (IOException e) {
-            Log.e(TAG, "Failed to create a pipe to send uid map data.", e);
-            return;
-        }
-        HandlerThread backgroundThread = new HandlerThread(
-                "statsCompanionService.bg", THREAD_PRIORITY_BACKGROUND);
-        backgroundThread.start();
-        Handler handler = new Handler(backgroundThread.getLooper());
-        handler.post(() -> {
-            UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
-            PackageManager pm = context.getPackageManager();
-            final List<UserHandle> users = um.getUserHandles(true);
-            if (DEBUG) {
-                Log.d(TAG, "Iterating over " + users.size() + " userHandles.");
-            }
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd == null) {
-                return;
-            }
-            try {
-                statsd.informAllUidData(fds[0]);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to send uid map to statsd");
-            }
-            try {
-                fds[0].close();
-            } catch (IOException e) {
-                Log.e(TAG, "Failed to close the read side of the pipe.", e);
-            }
-            final ParcelFileDescriptor writeFd = fds[1];
-            FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(writeFd);
-            try {
-                ProtoOutputStream output = new ProtoOutputStream(fout);
-                int numRecords = 0;
-                // Add in all the apps for every user/profile.
-                for (UserHandle userHandle : users) {
-                    List<PackageInfo> packagesPlusApex = getAllPackagesWithApex(pm, userHandle);
-                    for (int j = 0; j < packagesPlusApex.size(); j++) {
-                        if (packagesPlusApex.get(j).applicationInfo != null) {
-                            String installer;
-                            try {
-                                installer = pm.getInstallerPackageName(
-                                        packagesPlusApex.get(j).packageName);
-                            } catch (IllegalArgumentException e) {
-                                installer = "";
-                            }
-                            long applicationInfoToken =
-                                    output.start(ProtoOutputStream.FIELD_TYPE_MESSAGE
-                                            | ProtoOutputStream.FIELD_COUNT_REPEATED
-                                            | APPLICATION_INFO_FIELD_ID);
-                            output.write(ProtoOutputStream.FIELD_TYPE_INT32
-                                            | ProtoOutputStream.FIELD_COUNT_SINGLE | UID_FIELD_ID,
-                                    packagesPlusApex.get(j).applicationInfo.uid);
-                            output.write(ProtoOutputStream.FIELD_TYPE_INT64
-                                            | ProtoOutputStream.FIELD_COUNT_SINGLE
-                                            | VERSION_FIELD_ID,
-                                    packagesPlusApex.get(j).getLongVersionCode());
-                            output.write(ProtoOutputStream.FIELD_TYPE_STRING
-                                            | ProtoOutputStream.FIELD_COUNT_SINGLE
-                                            | VERSION_STRING_FIELD_ID,
-                                    packagesPlusApex.get(j).versionName);
-                            output.write(ProtoOutputStream.FIELD_TYPE_STRING
-                                    | ProtoOutputStream.FIELD_COUNT_SINGLE
-                                    | PACKAGE_NAME_FIELD_ID, packagesPlusApex.get(j).packageName);
-                            output.write(ProtoOutputStream.FIELD_TYPE_STRING
-                                            | ProtoOutputStream.FIELD_COUNT_SINGLE
-                                            | INSTALLER_FIELD_ID,
-                                    installer == null ? "" : installer);
-                            numRecords++;
-                            output.end(applicationInfoToken);
-                        }
-                    }
-                }
-                output.flush();
-                if (DEBUG) {
-                    Log.d(TAG, "Sent data for " + numRecords + " apps");
-                }
-            } finally {
-                FileUtils.closeQuietly(fout);
-                backgroundThread.quit();
-                backgroundThread.interrupt();
-            }
-        });
-    }
-
-    private static List<PackageInfo> getAllPackagesWithApex(PackageManager pm,
-            UserHandle userHandle) {
-        // We want all the uninstalled packages because uninstalled package uids can still be logged
-        // to statsd.
-        List<PackageInfo> allPackages = new ArrayList<>(
-                pm.getInstalledPackagesAsUser(PackageManager.MATCH_UNINSTALLED_PACKAGES
-                                | PackageManager.MATCH_ANY_USER,
-                        userHandle.getIdentifier()));
-        // We make a second query to package manager for the apex modules because package manager
-        // returns both installed and uninstalled apexes with
-        // PackageManager.MATCH_UNINSTALLED_PACKAGES flag. We only want active apexes because
-        // inactive apexes can conflict with active ones.
-        for (PackageInfo packageInfo : pm.getInstalledPackages(PackageManager.MATCH_APEX)) {
-            if (packageInfo.isApex) {
-                allPackages.add(packageInfo);
-            }
-        }
-        return allPackages;
-    }
-
-    private static class WakelockThread extends Thread {
-        private final PowerManager.WakeLock mWl;
-        private final Runnable mRunnable;
-
-        WakelockThread(Context context, String wakelockName, Runnable runnable) {
-            PowerManager powerManager = (PowerManager)
-                    context.getSystemService(Context.POWER_SERVICE);
-            mWl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, wakelockName);
-            mRunnable = runnable;
-        }
-        @Override
-        public void run() {
-            try {
-                mRunnable.run();
-            } finally {
-                mWl.release();
-            }
-        }
-        @Override
-        public void start() {
-            mWl.acquire();
-            super.start();
-        }
-    }
-
-    private final static class AppUpdateReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            /**
-             * App updates actually consist of REMOVE, ADD, and then REPLACE broadcasts. To avoid
-             * waste, we ignore the REMOVE and ADD broadcasts that contain the replacing flag.
-             * If we can't find the value for EXTRA_REPLACING, we default to false.
-             */
-            if (!intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)
-                    && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-                return; // Keep only replacing or normal add and remove.
-            }
-            if (DEBUG) Log.d(TAG, "StatsCompanionService noticed an app was updated.");
-            synchronized (sStatsdLock) {
-                if (sStatsd == null) {
-                    Log.w(TAG, "Could not access statsd to inform it of an app update");
-                    return;
-                }
-                try {
-                    if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
-                        Bundle b = intent.getExtras();
-                        int uid = b.getInt(Intent.EXTRA_UID);
-                        boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
-                        if (!replacing) {
-                            // Don't bother sending an update if we're right about to get another
-                            // intent for the new version that's added.
-                            String app = intent.getData().getSchemeSpecificPart();
-                            sStatsd.informOnePackageRemoved(app, uid);
-                        }
-                    } else {
-                        PackageManager pm = context.getPackageManager();
-                        Bundle b = intent.getExtras();
-                        int uid = b.getInt(Intent.EXTRA_UID);
-                        String app = intent.getData().getSchemeSpecificPart();
-                        PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER);
-                        String installer;
-                        try {
-                            installer = pm.getInstallerPackageName(app);
-                        } catch (IllegalArgumentException e) {
-                            installer = "";
-                        }
-                        sStatsd.informOnePackage(
-                                app,
-                                uid,
-                                pi.getLongVersionCode(),
-                                pi.versionName == null ? "" : pi.versionName,
-                                installer == null ? "" : installer);
-                    }
-                } catch (Exception e) {
-                    Log.w(TAG, "Failed to inform statsd of an app update", e);
-                }
-            }
-        }
-    }
-
-    private static final class UserUpdateReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            // Pull the latest state of UID->app name, version mapping.
-            // Needed since the new user basically has a version of every app.
-            informAllUids(context);
-        }
-    }
-
-    public final static class PullingAlarmListener implements OnAlarmListener {
-        private final Context mContext;
-
-        PullingAlarmListener(Context context) {
-            mContext = context;
-        }
-
-        @Override
-        public void onAlarm() {
-            if (DEBUG) {
-                Log.d(TAG, "Time to poll something.");
-            }
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd == null) {
-                Log.w(TAG, "Could not access statsd to inform it of pulling alarm firing.");
-                return;
-            }
-
-            // Wakelock needs to be retained while calling statsd.
-            Thread thread = new WakelockThread(mContext,
-                    PullingAlarmListener.class.getCanonicalName(), new Runnable() {
-                        @Override
-                        public void run() {
-                            try {
-                                statsd.informPollAlarmFired();
-                            } catch (RemoteException e) {
-                                Log.w(TAG, "Failed to inform statsd of pulling alarm firing.", e);
-                            }
-                        }
-                    });
-            thread.start();
-        }
-    }
-
-    public final static class PeriodicAlarmListener implements OnAlarmListener {
-        private final Context mContext;
-
-        PeriodicAlarmListener(Context context) {
-            mContext = context;
-        }
-
-        @Override
-        public void onAlarm() {
-            if (DEBUG) {
-                Log.d(TAG, "Time to trigger periodic alarm.");
-            }
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd == null) {
-                Log.w(TAG, "Could not access statsd to inform it of periodic alarm firing.");
-                return;
-            }
-
-            // Wakelock needs to be retained while calling statsd.
-            Thread thread = new WakelockThread(mContext,
-                    PeriodicAlarmListener.class.getCanonicalName(), new Runnable() {
-                        @Override
-                        public void run() {
-                            try {
-                                statsd.informAlarmForSubscriberTriggeringFired();
-                            } catch (RemoteException e) {
-                                Log.w(TAG, "Failed to inform statsd of periodic alarm firing.", e);
-                            }
-                        }
-                    });
-            thread.start();
-        }
-    }
-
-    public final static class ShutdownEventReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            /**
-             * Skip immediately if intent is not relevant to device shutdown.
-             */
-            if (!intent.getAction().equals(Intent.ACTION_REBOOT)
-                    && !(intent.getAction().equals(Intent.ACTION_SHUTDOWN)
-                    && (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0)) {
-                return;
-            }
-
-            if (DEBUG) {
-                Log.i(TAG, "StatsCompanionService noticed a shutdown.");
-            }
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd == null) {
-                Log.w(TAG, "Could not access statsd to inform it of a shutdown event.");
-                return;
-            }
-            try {
-                // two way binder call
-                statsd.informDeviceShutdown();
-            } catch (Exception e) {
-                Log.w(TAG, "Failed to inform statsd of a shutdown event.", e);
-            }
-        }
-    }
-
-    @Override // Binder call
-    public void setAlarmForSubscriberTriggering(long timestampMs) {
-        StatsCompanion.enforceStatsdCallingUid();
-        if (DEBUG) {
-            Log.d(TAG,
-                    "Setting periodic alarm in about " + (timestampMs
-                            - SystemClock.elapsedRealtime()));
-        }
-        final long callingToken = Binder.clearCallingIdentity();
-        try {
-            // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
-            // only fire when it awakens.
-            mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".periodic",
-                    mPeriodicAlarmListener, mHandler);
-        } finally {
-            Binder.restoreCallingIdentity(callingToken);
-        }
-    }
-
-    @Override // Binder call
-    public void cancelAlarmForSubscriberTriggering() {
-        StatsCompanion.enforceStatsdCallingUid();
-        if (DEBUG) {
-            Log.d(TAG, "Cancelling periodic alarm");
-        }
-        final long callingToken = Binder.clearCallingIdentity();
-        try {
-            mAlarmManager.cancel(mPeriodicAlarmListener);
-        } finally {
-            Binder.restoreCallingIdentity(callingToken);
-        }
-    }
-
-    @Override // Binder call
-    public void setPullingAlarm(long nextPullTimeMs) {
-        StatsCompanion.enforceStatsdCallingUid();
-        if (DEBUG) {
-            Log.d(TAG, "Setting pulling alarm in about "
-                    + (nextPullTimeMs - SystemClock.elapsedRealtime()));
-        }
-        final long callingToken = Binder.clearCallingIdentity();
-        try {
-            // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
-            // only fire when it awakens.
-            mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, nextPullTimeMs, TAG + ".pull",
-                    mPullingAlarmListener, mHandler);
-        } finally {
-            Binder.restoreCallingIdentity(callingToken);
-        }
-    }
-
-    @Override // Binder call
-    public void cancelPullingAlarm() {
-        StatsCompanion.enforceStatsdCallingUid();
-        if (DEBUG) {
-            Log.d(TAG, "Cancelling pulling alarm");
-        }
-        final long callingToken = Binder.clearCallingIdentity();
-        try {
-            mAlarmManager.cancel(mPullingAlarmListener);
-        } finally {
-            Binder.restoreCallingIdentity(callingToken);
-        }
-    }
-
-    @Override // Binder call
-    public void statsdReady() {
-        StatsCompanion.enforceStatsdCallingUid();
-        if (DEBUG) {
-            Log.d(TAG, "learned that statsdReady");
-        }
-        sayHiToStatsd(); // tell statsd that we're ready too and link to it
-
-        final Intent intent = new Intent(StatsManager.ACTION_STATSD_STARTED);
-        // Retrieve list of broadcast receivers for this broadcast & send them directed broadcasts
-        // to wake them up (if they're in background).
-        List<ResolveInfo> resolveInfos =
-                mContext.getPackageManager().queryBroadcastReceiversAsUser(
-                        intent, 0, UserHandle.SYSTEM);
-        if (resolveInfos == null || resolveInfos.isEmpty()) {
-            return; // No need to send broadcast.
-        }
-
-        for (ResolveInfo resolveInfo : resolveInfos) {
-            Intent intentToSend = new Intent(intent);
-            intentToSend.setComponent(new ComponentName(
-                    resolveInfo.activityInfo.applicationInfo.packageName,
-                    resolveInfo.activityInfo.name));
-            mContext.sendBroadcastAsUser(intentToSend, UserHandle.SYSTEM,
-                    android.Manifest.permission.DUMP);
-        }
-    }
-
-    @Override // Binder call
-    public boolean checkPermission(String permission, int pid, int uid) {
-        StatsCompanion.enforceStatsdCallingUid();
-        return mContext.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED;
-    }
-
-    // Statsd related code
-
-    /**
-     * Fetches the statsd IBinder service. This is a blocking call that always refetches statsd
-     * instead of returning the cached sStatsd.
-     * Note: This should only be called from {@link #sayHiToStatsd()}. All other clients should use
-     * the cached sStatsd via {@link #getStatsdNonblocking()}.
-     */
-    private IStatsd fetchStatsdServiceLocked() {
-        sStatsd = IStatsd.Stub.asInterface(StatsFrameworkInitializer
-                .getStatsServiceManager()
-                .getStatsdServiceRegisterer()
-                .get());
-        return sStatsd;
-    }
-
-    private void registerStatsdDeathRecipient(IStatsd statsd, List<BroadcastReceiver> receivers) {
-        StatsdDeathRecipient deathRecipient = new StatsdDeathRecipient(statsd, receivers);
-
-        try {
-            statsd.asBinder().linkToDeath(deathRecipient, /*flags=*/0);
-        } catch (RemoteException e) {
-            Log.e(TAG, "linkToDeath (StatsdDeathRecipient) failed");
-            // Statsd has already died. Unregister receivers ourselves.
-            for (BroadcastReceiver receiver : receivers) {
-                mContext.unregisterReceiver(receiver);
-            }
-            synchronized (sStatsdLock) {
-                if (statsd == sStatsd) {
-                    statsdNotReadyLocked();
-                }
-            }
-        }
-    }
-
-    /**
-     * Now that the android system is ready, StatsCompanion is ready too, so inform statsd.
-     */
-    void systemReady() {
-        if (DEBUG) Log.d(TAG, "Learned that systemReady");
-        sayHiToStatsd();
-    }
-
-    void setStatsManagerService(StatsManagerService statsManagerService) {
-        mStatsManagerService = statsManagerService;
-    }
-
-    /**
-     * Tells statsd that statscompanion is ready. If the binder call returns, link to
-     * statsd.
-     */
-    private void sayHiToStatsd() {
-        IStatsd statsd;
-        synchronized (sStatsdLock) {
-            if (sStatsd != null && sStatsd.asBinder().isBinderAlive()) {
-                Log.e(TAG, "statsd has already been fetched before",
-                        new IllegalStateException("IStatsd object should be null or dead"));
-                return;
-            }
-            statsd = fetchStatsdServiceLocked();
-        }
-
-        if (statsd == null) {
-            Log.i(TAG, "Could not yet find statsd to tell it that StatsCompanion is alive.");
-            return;
-        }
-
-        // Cleann up from previous statsd - cancel any alarms that had been set. Do this here
-        // instead of in binder death because statsd can come back and set different alarms, or not
-        // want to set an alarm when it had been set. This guarantees that when we get a new statsd,
-        // we cancel any alarms before it is able to set them.
-        cancelPullingAlarm();
-        cancelAlarmForSubscriberTriggering();
-
-        if (DEBUG) Log.d(TAG, "Saying hi to statsd");
-        mStatsManagerService.statsdReady(statsd);
-        try {
-            statsd.statsCompanionReady();
-
-            BroadcastReceiver appUpdateReceiver = new AppUpdateReceiver();
-            BroadcastReceiver userUpdateReceiver = new UserUpdateReceiver();
-            BroadcastReceiver shutdownEventReceiver = new ShutdownEventReceiver();
-
-            // Setup broadcast receiver for updates.
-            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REPLACED);
-            filter.addAction(Intent.ACTION_PACKAGE_ADDED);
-            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-            filter.addDataScheme("package");
-            mContext.registerReceiverForAllUsers(appUpdateReceiver, filter, null, null);
-
-            // Setup receiver for user initialize (which happens once for a new user)
-            // and if a user is removed.
-            filter = new IntentFilter(Intent.ACTION_USER_INITIALIZE);
-            filter.addAction(Intent.ACTION_USER_REMOVED);
-            mContext.registerReceiverForAllUsers(userUpdateReceiver, filter, null, null);
-
-            // Setup receiver for device reboots or shutdowns.
-            filter = new IntentFilter(Intent.ACTION_REBOOT);
-            filter.addAction(Intent.ACTION_SHUTDOWN);
-            mContext.registerReceiverForAllUsers(shutdownEventReceiver, filter, null, null);
-
-            // Register death recipient.
-            List<BroadcastReceiver> broadcastReceivers =
-                    List.of(appUpdateReceiver, userUpdateReceiver, shutdownEventReceiver);
-            registerStatsdDeathRecipient(statsd, broadcastReceivers);
-
-            // Tell statsd that boot has completed. The signal may have already been sent, but since
-            // the signal-receiving function is idempotent, that's ok.
-            if (mBootCompleted.get()) {
-                statsd.bootCompleted();
-            }
-
-            // Pull the latest state of UID->app name, version mapping when statsd starts.
-            informAllUids(mContext);
-
-            Log.i(TAG, "Told statsd that StatsCompanionService is alive.");
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to inform statsd that statscompanion is ready", e);
-        }
-    }
-
-    private class StatsdDeathRecipient implements IBinder.DeathRecipient {
-
-        private final IStatsd mStatsd;
-        private final List<BroadcastReceiver> mReceiversToUnregister;
-
-        StatsdDeathRecipient(IStatsd statsd, List<BroadcastReceiver> receivers) {
-            mStatsd = statsd;
-            mReceiversToUnregister = receivers;
-        }
-
-        // It is possible for binderDied to be called after a restarted statsd calls statsdReady,
-        // but that's alright because the code does not assume an ordering of the two calls.
-        @Override
-        public void binderDied() {
-            Log.i(TAG, "Statsd is dead - erase all my knowledge, except pullers");
-            synchronized (sStatsdLock) {
-                long now = SystemClock.elapsedRealtime();
-                for (Long timeMillis : mDeathTimeMillis) {
-                    long ageMillis = now - timeMillis;
-                    if (ageMillis > MILLIS_IN_A_DAY) {
-                        mDeathTimeMillis.remove(timeMillis);
-                    }
-                }
-                for (Long timeMillis : mDeletedFiles.keySet()) {
-                    long ageMillis = now - timeMillis;
-                    if (ageMillis > MILLIS_IN_A_DAY * 7) {
-                        mDeletedFiles.remove(timeMillis);
-                    }
-                }
-                mDeathTimeMillis.add(now);
-                if (mDeathTimeMillis.size() >= DEATH_THRESHOLD) {
-                    mDeathTimeMillis.clear();
-                    File[] configs = new File(CONFIG_DIR).listFiles();
-                    if (configs != null && configs.length > 0) {
-                        String fileName = configs[0].getName();
-                        if (configs[0].delete()) {
-                            mDeletedFiles.put(now, fileName);
-                        }
-                    }
-                }
-
-                // Unregister receivers on death because receivers can only be unregistered once.
-                // Otherwise, an IllegalArgumentException is thrown.
-                for (BroadcastReceiver receiver: mReceiversToUnregister) {
-                    mContext.unregisterReceiver(receiver);
-                }
-
-                // It's possible for statsd to have restarted and called statsdReady, causing a new
-                // sStatsd binder object to be fetched, before the binderDied callback runs. Only
-                // call #statsdNotReadyLocked if that hasn't happened yet.
-                if (mStatsd == sStatsd) {
-                    statsdNotReadyLocked();
-                }
-            }
-        }
-    }
-
-    private void statsdNotReadyLocked() {
-        sStatsd = null;
-        mStatsManagerService.statsdNotReady();
-    }
-
-    void bootCompleted() {
-        mBootCompleted.set(true);
-        IStatsd statsd = getStatsdNonblocking();
-        if (statsd == null) {
-            // Statsd is not yet ready.
-            // Delay the boot completed ping to {@link #sayHiToStatsd()}
-            return;
-        }
-        try {
-            statsd.bootCompleted();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to notify statsd that boot completed");
-        }
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                != PackageManager.PERMISSION_GRANTED) {
-            return;
-        }
-
-        synchronized (sStatsdLock) {
-            writer.println("Number of configuration files deleted: " + mDeletedFiles.size());
-            if (mDeletedFiles.size() > 0) {
-                writer.println("  timestamp, deleted file name");
-            }
-            long lastBootMillis =
-                    SystemClock.currentThreadTimeMillis() - SystemClock.elapsedRealtime();
-            for (Long elapsedMillis : mDeletedFiles.keySet()) {
-                long deletionMillis = lastBootMillis + elapsedMillis;
-                writer.println("  " + deletionMillis + ", " + mDeletedFiles.get(elapsedMillis));
-            }
-        }
-    }
-}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java b/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java
deleted file mode 100644
index 1e3846b..0000000
--- a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java
+++ /dev/null
@@ -1,668 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.server.stats;
-
-import static com.android.server.stats.StatsCompanion.PendingIntentRef;
-
-import android.Manifest;
-import android.annotation.Nullable;
-import android.app.AppOpsManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.Binder;
-import android.os.IPullAtomCallback;
-import android.os.IStatsManagerService;
-import android.os.IStatsd;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.RemoteException;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Service for {@link android.app.StatsManager}.
- *
- * @hide
- */
-public class StatsManagerService extends IStatsManagerService.Stub {
-
-    private static final String TAG = "StatsManagerService";
-    private static final boolean DEBUG = false;
-
-    private static final int STATSD_TIMEOUT_MILLIS = 5000;
-
-    private static final String USAGE_STATS_PERMISSION_OPS = "android:get_usage_stats";
-
-    @GuardedBy("mLock")
-    private IStatsd mStatsd;
-    private final Object mLock = new Object();
-
-    private StatsCompanionService mStatsCompanionService;
-    private Context mContext;
-
-    @GuardedBy("mLock")
-    private ArrayMap<ConfigKey, PendingIntentRef> mDataFetchPirMap = new ArrayMap<>();
-    @GuardedBy("mLock")
-    private ArrayMap<Integer, PendingIntentRef> mActiveConfigsPirMap = new ArrayMap<>();
-    @GuardedBy("mLock")
-    private ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> mBroadcastSubscriberPirMap =
-            new ArrayMap<>();
-
-    public StatsManagerService(Context context) {
-        super();
-        mContext = context;
-    }
-
-    private static class ConfigKey {
-        private final int mUid;
-        private final long mConfigId;
-
-        ConfigKey(int uid, long configId) {
-            mUid = uid;
-            mConfigId = configId;
-        }
-
-        public int getUid() {
-            return mUid;
-        }
-
-        public long getConfigId() {
-            return mConfigId;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mUid, mConfigId);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof ConfigKey) {
-                ConfigKey other = (ConfigKey) obj;
-                return this.mUid == other.getUid() && this.mConfigId == other.getConfigId();
-            }
-            return false;
-        }
-    }
-
-    private static class PullerKey {
-        private final int mUid;
-        private final int mAtomTag;
-
-        PullerKey(int uid, int atom) {
-            mUid = uid;
-            mAtomTag = atom;
-        }
-
-        public int getUid() {
-            return mUid;
-        }
-
-        public int getAtom() {
-            return mAtomTag;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mUid, mAtomTag);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof PullerKey) {
-                PullerKey other = (PullerKey) obj;
-                return this.mUid == other.getUid() && this.mAtomTag == other.getAtom();
-            }
-            return false;
-        }
-    }
-
-    private static class PullerValue {
-        private final long mCoolDownMillis;
-        private final long mTimeoutMillis;
-        private final int[] mAdditiveFields;
-        private final IPullAtomCallback mCallback;
-
-        PullerValue(long coolDownMillis, long timeoutMillis, int[] additiveFields,
-                IPullAtomCallback callback) {
-            mCoolDownMillis = coolDownMillis;
-            mTimeoutMillis = timeoutMillis;
-            mAdditiveFields = additiveFields;
-            mCallback = callback;
-        }
-
-        public long getCoolDownMillis() {
-            return mCoolDownMillis;
-        }
-
-        public long getTimeoutMillis() {
-            return mTimeoutMillis;
-        }
-
-        public int[] getAdditiveFields() {
-            return mAdditiveFields;
-        }
-
-        public IPullAtomCallback getCallback() {
-            return mCallback;
-        }
-    }
-
-    private final ArrayMap<PullerKey, PullerValue> mPullers = new ArrayMap<>();
-
-    @Override
-    public void registerPullAtomCallback(int atomTag, long coolDownMillis, long timeoutMillis,
-            int[] additiveFields, IPullAtomCallback pullerCallback) {
-        enforceRegisterStatsPullAtomPermission();
-        if (pullerCallback == null) {
-            Log.w(TAG, "Puller callback is null for atom " + atomTag);
-            return;
-        }
-        int callingUid = Binder.getCallingUid();
-        PullerKey key = new PullerKey(callingUid, atomTag);
-        PullerValue val =
-                new PullerValue(coolDownMillis, timeoutMillis, additiveFields, pullerCallback);
-
-        // Always cache the puller in StatsManagerService. If statsd is down, we will register the
-        // puller when statsd comes back up.
-        synchronized (mLock) {
-            mPullers.put(key, val);
-        }
-
-        IStatsd statsd = getStatsdNonblocking();
-        if (statsd == null) {
-            return;
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            statsd.registerPullAtomCallback(callingUid, atomTag, coolDownMillis, timeoutMillis,
-                    additiveFields, pullerCallback);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to access statsd to register puller for atom " + atomTag);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public void unregisterPullAtomCallback(int atomTag) {
-        enforceRegisterStatsPullAtomPermission();
-        int callingUid = Binder.getCallingUid();
-        PullerKey key = new PullerKey(callingUid, atomTag);
-
-        // Always remove the puller from StatsManagerService even if statsd is down. When statsd
-        // comes back up, we will not re-register the removed puller.
-        synchronized (mLock) {
-            mPullers.remove(key);
-        }
-
-        IStatsd statsd = getStatsdNonblocking();
-        if (statsd == null) {
-            return;
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            statsd.unregisterPullAtomCallback(callingUid, atomTag);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to access statsd to unregister puller for atom " + atomTag);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public void setDataFetchOperation(long configId, PendingIntent pendingIntent,
-            String packageName) {
-        enforceDumpAndUsageStatsPermission(packageName);
-        int callingUid = Binder.getCallingUid();
-        final long token = Binder.clearCallingIdentity();
-        PendingIntentRef pir = new PendingIntentRef(pendingIntent, mContext);
-        ConfigKey key = new ConfigKey(callingUid, configId);
-        // We add the PIR to a map so we can reregister if statsd is unavailable.
-        synchronized (mLock) {
-            mDataFetchPirMap.put(key, pir);
-        }
-        try {
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd != null) {
-                statsd.setDataFetchOperation(configId, pir, callingUid);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to setDataFetchOperation with statsd");
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public void removeDataFetchOperation(long configId, String packageName) {
-        enforceDumpAndUsageStatsPermission(packageName);
-        int callingUid = Binder.getCallingUid();
-        final long token = Binder.clearCallingIdentity();
-        ConfigKey key = new ConfigKey(callingUid, configId);
-        synchronized (mLock) {
-            mDataFetchPirMap.remove(key);
-        }
-        try {
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd != null) {
-                statsd.removeDataFetchOperation(configId, callingUid);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to removeDataFetchOperation with statsd");
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public long[] setActiveConfigsChangedOperation(PendingIntent pendingIntent,
-            String packageName) {
-        enforceDumpAndUsageStatsPermission(packageName);
-        int callingUid = Binder.getCallingUid();
-        final long token = Binder.clearCallingIdentity();
-        PendingIntentRef pir = new PendingIntentRef(pendingIntent, mContext);
-        // We add the PIR to a map so we can reregister if statsd is unavailable.
-        synchronized (mLock) {
-            mActiveConfigsPirMap.put(callingUid, pir);
-        }
-        try {
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd != null) {
-                return statsd.setActiveConfigsChangedOperation(pir, callingUid);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to setActiveConfigsChangedOperation with statsd");
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-        return new long[] {};
-    }
-
-    @Override
-    public void removeActiveConfigsChangedOperation(String packageName) {
-        enforceDumpAndUsageStatsPermission(packageName);
-        int callingUid = Binder.getCallingUid();
-        final long token = Binder.clearCallingIdentity();
-        synchronized (mLock) {
-            mActiveConfigsPirMap.remove(callingUid);
-        }
-        try {
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd != null) {
-                statsd.removeActiveConfigsChangedOperation(callingUid);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to removeActiveConfigsChangedOperation with statsd");
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public void setBroadcastSubscriber(long configId, long subscriberId,
-            PendingIntent pendingIntent, String packageName) {
-        enforceDumpAndUsageStatsPermission(packageName);
-        int callingUid = Binder.getCallingUid();
-        final long token = Binder.clearCallingIdentity();
-        PendingIntentRef pir = new PendingIntentRef(pendingIntent, mContext);
-        ConfigKey key = new ConfigKey(callingUid, configId);
-        // We add the PIR to a map so we can reregister if statsd is unavailable.
-        synchronized (mLock) {
-            ArrayMap<Long, PendingIntentRef> innerMap = mBroadcastSubscriberPirMap
-                    .getOrDefault(key, new ArrayMap<>());
-            innerMap.put(subscriberId, pir);
-            mBroadcastSubscriberPirMap.put(key, innerMap);
-        }
-        try {
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd != null) {
-                statsd.setBroadcastSubscriber(
-                        configId, subscriberId, pir, callingUid);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to setBroadcastSubscriber with statsd");
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public void unsetBroadcastSubscriber(long configId, long subscriberId, String packageName) {
-        enforceDumpAndUsageStatsPermission(packageName);
-        int callingUid = Binder.getCallingUid();
-        final long token = Binder.clearCallingIdentity();
-        ConfigKey key = new ConfigKey(callingUid, configId);
-        synchronized (mLock) {
-            ArrayMap<Long, PendingIntentRef> innerMap = mBroadcastSubscriberPirMap
-                    .getOrDefault(key, new ArrayMap<>());
-            innerMap.remove(subscriberId);
-            if (innerMap.isEmpty()) {
-                mBroadcastSubscriberPirMap.remove(key);
-            }
-        }
-        try {
-            IStatsd statsd = getStatsdNonblocking();
-            if (statsd != null) {
-                statsd.unsetBroadcastSubscriber(configId, subscriberId, callingUid);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to unsetBroadcastSubscriber with statsd");
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public long[] getRegisteredExperimentIds() throws IllegalStateException {
-        enforceDumpAndUsageStatsPermission(null);
-        final long token = Binder.clearCallingIdentity();
-        try {
-            IStatsd statsd = waitForStatsd();
-            if (statsd != null) {
-                return statsd.getRegisteredExperimentIds();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to getRegisteredExperimentIds with statsd");
-            throw new IllegalStateException(e.getMessage(), e);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-        throw new IllegalStateException("Failed to connect to statsd to registerExperimentIds");
-    }
-
-    @Override
-    public byte[] getMetadata(String packageName) throws IllegalStateException {
-        enforceDumpAndUsageStatsPermission(packageName);
-        final long token = Binder.clearCallingIdentity();
-        try {
-            IStatsd statsd = waitForStatsd();
-            if (statsd != null) {
-                return statsd.getMetadata();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to getMetadata with statsd");
-            throw new IllegalStateException(e.getMessage(), e);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-        throw new IllegalStateException("Failed to connect to statsd to getMetadata");
-    }
-
-    @Override
-    public byte[] getData(long key, String packageName) throws IllegalStateException {
-        enforceDumpAndUsageStatsPermission(packageName);
-        PowerManager powerManager = (PowerManager)
-                mContext.getSystemService(Context.POWER_SERVICE);
-        PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                /*tag=*/ StatsManagerService.class.getCanonicalName());
-        int callingUid = Binder.getCallingUid();
-        final long token = Binder.clearCallingIdentity();
-        wl.acquire();
-        try {
-            IStatsd statsd = waitForStatsd();
-            if (statsd != null) {
-                return statsd.getData(key, callingUid);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to getData with statsd");
-            throw new IllegalStateException(e.getMessage(), e);
-        } finally {
-            wl.release();
-            Binder.restoreCallingIdentity(token);
-        }
-        throw new IllegalStateException("Failed to connect to statsd to getData");
-    }
-
-    @Override
-    public void addConfiguration(long configId, byte[] config, String packageName)
-            throws IllegalStateException {
-        enforceDumpAndUsageStatsPermission(packageName);
-        int callingUid = Binder.getCallingUid();
-        final long token = Binder.clearCallingIdentity();
-        try {
-            IStatsd statsd = waitForStatsd();
-            if (statsd != null) {
-                statsd.addConfiguration(configId, config, callingUid);
-                return;
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to addConfiguration with statsd");
-            throw new IllegalStateException(e.getMessage(), e);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-        throw new IllegalStateException("Failed to connect to statsd to addConfig");
-    }
-
-    @Override
-    public void removeConfiguration(long configId, String packageName)
-            throws IllegalStateException {
-        enforceDumpAndUsageStatsPermission(packageName);
-        int callingUid = Binder.getCallingUid();
-        final long token = Binder.clearCallingIdentity();
-        try {
-            IStatsd statsd = waitForStatsd();
-            if (statsd != null) {
-                statsd.removeConfiguration(configId, callingUid);
-                return;
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to removeConfiguration with statsd");
-            throw new IllegalStateException(e.getMessage(), e);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-        throw new IllegalStateException("Failed to connect to statsd to removeConfig");
-    }
-
-    void setStatsCompanionService(StatsCompanionService statsCompanionService) {
-        mStatsCompanionService = statsCompanionService;
-    }
-
-    /**
-     * Checks that the caller has both DUMP and PACKAGE_USAGE_STATS permissions. Also checks that
-     * the caller has USAGE_STATS_PERMISSION_OPS for the specified packageName if it is not null.
-     *
-     * @param packageName The packageName to check USAGE_STATS_PERMISSION_OPS.
-     */
-    private void enforceDumpAndUsageStatsPermission(@Nullable String packageName) {
-        int callingUid = Binder.getCallingUid();
-        int callingPid = Binder.getCallingPid();
-
-        if (callingPid == Process.myPid()) {
-            return;
-        }
-
-        mContext.enforceCallingPermission(Manifest.permission.DUMP, null);
-        mContext.enforceCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS, null);
-
-        if (packageName == null) {
-            return;
-        }
-        AppOpsManager appOpsManager = (AppOpsManager) mContext
-                .getSystemService(Context.APP_OPS_SERVICE);
-        switch (appOpsManager.noteOp(USAGE_STATS_PERMISSION_OPS,
-                Binder.getCallingUid(), packageName, null, null)) {
-            case AppOpsManager.MODE_ALLOWED:
-            case AppOpsManager.MODE_DEFAULT:
-                break;
-            default:
-                throw new SecurityException(
-                        String.format("UID %d / PID %d lacks app-op %s",
-                                callingUid, callingPid, USAGE_STATS_PERMISSION_OPS)
-                );
-        }
-    }
-
-    private void enforceRegisterStatsPullAtomPermission() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.REGISTER_STATS_PULL_ATOM,
-                "Need REGISTER_STATS_PULL_ATOM permission.");
-    }
-
-
-    /**
-     * Clients should call this if blocking until statsd to be ready is desired
-     *
-     * @return IStatsd object if statsd becomes ready within the timeout, null otherwise.
-     */
-    private IStatsd waitForStatsd() {
-        synchronized (mLock) {
-            if (mStatsd == null) {
-                try {
-                    mLock.wait(STATSD_TIMEOUT_MILLIS);
-                } catch (InterruptedException e) {
-                    Log.e(TAG, "wait for statsd interrupted");
-                }
-            }
-            return mStatsd;
-        }
-    }
-
-    /**
-     * Clients should call this to receive a reference to statsd.
-     *
-     * @return IStatsd object if statsd is ready, null otherwise.
-     */
-    private IStatsd getStatsdNonblocking() {
-        synchronized (mLock) {
-            return mStatsd;
-        }
-    }
-
-    /**
-     * Called from {@link StatsCompanionService}.
-     *
-     * Tells StatsManagerService that Statsd is ready and updates
-     * Statsd with the contents of our local cache.
-     */
-    void statsdReady(IStatsd statsd) {
-        synchronized (mLock) {
-            mStatsd = statsd;
-            mLock.notify();
-        }
-        sayHiToStatsd(statsd);
-    }
-
-    /**
-     * Called from {@link StatsCompanionService}.
-     *
-     * Tells StatsManagerService that Statsd is no longer ready
-     * and we should no longer make binder calls with statsd.
-     */
-    void statsdNotReady() {
-        synchronized (mLock) {
-            mStatsd = null;
-        }
-    }
-
-    private void sayHiToStatsd(IStatsd statsd) {
-        if (statsd == null) {
-            return;
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            registerAllPullers(statsd);
-            registerAllDataFetchOperations(statsd);
-            registerAllActiveConfigsChangedOperations(statsd);
-            registerAllBroadcastSubscribers(statsd);
-        } catch (RemoteException e) {
-            Log.e(TAG, "StatsManager failed to (re-)register data with statsd");
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    // Pre-condition: the Binder calling identity has already been cleared
-    private void registerAllPullers(IStatsd statsd) throws RemoteException {
-        // Since we do not want to make an IPC with the lock held, we first create a copy of the
-        // data with the lock held before iterating through the map.
-        ArrayMap<PullerKey, PullerValue> pullersCopy;
-        synchronized (mLock) {
-            pullersCopy = new ArrayMap<>(mPullers);
-        }
-
-        for (Map.Entry<PullerKey, PullerValue> entry : pullersCopy.entrySet()) {
-            PullerKey key = entry.getKey();
-            PullerValue value = entry.getValue();
-            statsd.registerPullAtomCallback(key.getUid(), key.getAtom(), value.getCoolDownMillis(),
-                    value.getTimeoutMillis(), value.getAdditiveFields(), value.getCallback());
-        }
-        statsd.allPullersFromBootRegistered();
-    }
-
-    // Pre-condition: the Binder calling identity has already been cleared
-    private void registerAllDataFetchOperations(IStatsd statsd) throws RemoteException {
-        // Since we do not want to make an IPC with the lock held, we first create a copy of the
-        // data with the lock held before iterating through the map.
-        ArrayMap<ConfigKey, PendingIntentRef> dataFetchCopy;
-        synchronized (mLock) {
-            dataFetchCopy = new ArrayMap<>(mDataFetchPirMap);
-        }
-
-        for (Map.Entry<ConfigKey, PendingIntentRef> entry : dataFetchCopy.entrySet()) {
-            ConfigKey key = entry.getKey();
-            statsd.setDataFetchOperation(key.getConfigId(), entry.getValue(), key.getUid());
-        }
-    }
-
-    // Pre-condition: the Binder calling identity has already been cleared
-    private void registerAllActiveConfigsChangedOperations(IStatsd statsd) throws RemoteException {
-        // Since we do not want to make an IPC with the lock held, we first create a copy of the
-        // data with the lock held before iterating through the map.
-        ArrayMap<Integer, PendingIntentRef> activeConfigsChangedCopy;
-        synchronized (mLock) {
-            activeConfigsChangedCopy = new ArrayMap<>(mActiveConfigsPirMap);
-        }
-
-        for (Map.Entry<Integer, PendingIntentRef> entry : activeConfigsChangedCopy.entrySet()) {
-            statsd.setActiveConfigsChangedOperation(entry.getValue(), entry.getKey());
-        }
-    }
-
-    // Pre-condition: the Binder calling identity has already been cleared
-    private void registerAllBroadcastSubscribers(IStatsd statsd) throws RemoteException {
-        // Since we do not want to make an IPC with the lock held, we first create a deep copy of
-        // the data with the lock held before iterating through the map.
-        ArrayMap<ConfigKey, ArrayMap<Long, PendingIntentRef>> broadcastSubscriberCopy =
-                new ArrayMap<>();
-        synchronized (mLock) {
-            for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry :
-                    mBroadcastSubscriberPirMap.entrySet()) {
-                broadcastSubscriberCopy.put(entry.getKey(), new ArrayMap(entry.getValue()));
-            }
-        }
-
-        for (Map.Entry<ConfigKey, ArrayMap<Long, PendingIntentRef>> entry :
-                mBroadcastSubscriberPirMap.entrySet()) {
-            ConfigKey configKey = entry.getKey();
-            for (Map.Entry<Long, PendingIntentRef> subscriberEntry : entry.getValue().entrySet()) {
-                statsd.setBroadcastSubscriber(configKey.getConfigId(), subscriberEntry.getKey(),
-                        subscriberEntry.getValue(), configKey.getUid());
-            }
-        }
-    }
-}
diff --git a/apex/statsd/statsd.rc b/apex/statsd/statsd.rc
deleted file mode 100644
index 605da2a..0000000
--- a/apex/statsd/statsd.rc
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 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.
-
-service statsd /apex/com.android.os.statsd/bin/statsd
-    class main
-    socket statsdw dgram+passcred 0222 statsd statsd
-    user statsd
-    group statsd log
-    writepid /dev/cpuset/system-background/tasks
diff --git a/apex/statsd/testing/Android.bp b/apex/statsd/testing/Android.bp
deleted file mode 100644
index a9cd0cc..0000000
--- a/apex/statsd/testing/Android.bp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2019 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.
-
-apex_test {
-    name: "test_com.android.os.statsd",
-    visibility: [
-        "//system/apex/tests",
-    ],
-    defaults: ["com.android.os.statsd-defaults"],
-    manifest: "test_manifest.json",
-    file_contexts: ":com.android.os.statsd-file_contexts",
-    // Test APEX, should never be installed
-    installable: false,
-}
diff --git a/apex/statsd/testing/test_manifest.json b/apex/statsd/testing/test_manifest.json
deleted file mode 100644
index 57343d3..0000000
--- a/apex/statsd/testing/test_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.os.statsd",
-  "version": 2147483647
-}
diff --git a/apex/statsd/tests/libstatspull/Android.bp b/apex/statsd/tests/libstatspull/Android.bp
deleted file mode 100644
index 05b3e04..0000000
--- a/apex/statsd/tests/libstatspull/Android.bp
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (C) 2019 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.
-
-android_test {
-    name: "LibStatsPullTests",
-    static_libs: [
-        "androidx.test.rules",
-        "platformprotoslite",
-        "statsdprotolite",
-        "truth-prebuilt",
-    ],
-    libs: [
-        "android.test.runner.stubs",
-        "android.test.base.stubs",
-    ],
-    jni_libs: [
-        "libstatspull_testhelper",
-    ],
-    srcs: [
-        "src/**/*.java",
-        "protos/**/*.proto",
-        ],
-    test_suites: [
-        "device-tests",
-        "mts",
-    ],
-    platform_apis: true,
-    privileged: true,
-    certificate: "platform",
-    compile_multilib: "both",
-}
-
-cc_library_shared {
-    name: "libstatspull_testhelper",
-    srcs: ["jni/stats_pull_helper.cpp"],
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-    shared_libs: [
-        "libbinder_ndk",
-        "statsd-aidl-ndk_platform",
-    ],
-    static_libs: [
-        "libstatspull_private",
-        "libstatssocket_private",
-        "libutils",
-        "libcutils",
-    ],
-}
diff --git a/apex/statsd/tests/libstatspull/AndroidManifest.xml b/apex/statsd/tests/libstatspull/AndroidManifest.xml
deleted file mode 100644
index 0c669b0..0000000
--- a/apex/statsd/tests/libstatspull/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.internal.os.statsd.libstats" >
-
-
-    <uses-permission android:name="android.permission.DUMP" />
-    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
-    <uses-permission android:name="android.permission.REGISTER_STATS_PULL_ATOM" />
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.internal.os.statsd.libstats"
-                     android:label="Tests for libstatspull">
-    </instrumentation>
-</manifest>
-
diff --git a/apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp b/apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp
deleted file mode 100644
index 166592d..0000000
--- a/apex/statsd/tests/libstatspull/jni/stats_pull_helper.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2019, 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.
- */
-
-#include <jni.h>
-#include <log/log.h>
-#include <stats_event.h>
-#include <stats_pull_atom_callback.h>
-
-#include <chrono>
-#include <thread>
-
-using std::this_thread::sleep_for;
-
-namespace {
-static int32_t sAtomTag;
-static int32_t sPullReturnVal;
-static int64_t sLatencyMillis;
-static int32_t sAtomsPerPull;
-static int32_t sNumPulls = 0;
-
-static AStatsManager_PullAtomCallbackReturn pullAtomCallback(int32_t atomTag, AStatsEventList* data,
-                                                             void* /*cookie*/) {
-    sNumPulls++;
-    sleep_for(std::chrono::milliseconds(sLatencyMillis));
-    for (int i = 0; i < sAtomsPerPull; i++) {
-        AStatsEvent* event = AStatsEventList_addStatsEvent(data);
-        AStatsEvent_setAtomId(event, atomTag);
-        AStatsEvent_writeInt64(event, (int64_t) sNumPulls);
-        AStatsEvent_build(event);
-    }
-    return sPullReturnVal;
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_internal_os_statsd_libstats_LibStatsPullTests_setStatsPuller(
-        JNIEnv* /*env*/, jobject /* this */, jint atomTag, jlong timeoutMillis,
-        jlong coolDownMillis, jint pullRetVal, jlong latencyMillis, int atomsPerPull) {
-    sAtomTag = atomTag;
-    sPullReturnVal = pullRetVal;
-    sLatencyMillis = latencyMillis;
-    sAtomsPerPull = atomsPerPull;
-    sNumPulls = 0;
-    AStatsManager_PullAtomMetadata* metadata = AStatsManager_PullAtomMetadata_obtain();
-    AStatsManager_PullAtomMetadata_setCoolDownMillis(metadata, coolDownMillis);
-    AStatsManager_PullAtomMetadata_setTimeoutMillis(metadata, timeoutMillis);
-
-    AStatsManager_setPullAtomCallback(sAtomTag, metadata, &pullAtomCallback, nullptr);
-    AStatsManager_PullAtomMetadata_release(metadata);
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_internal_os_statsd_libstats_LibStatsPullTests_clearStatsPuller(JNIEnv* /*env*/,
-                                                                                jobject /* this */,
-                                                                                jint /*atomTag*/) {
-    AStatsManager_clearPullAtomCallback(sAtomTag);
-}
-} // namespace
diff --git a/apex/statsd/tests/libstatspull/protos/test_atoms.proto b/apex/statsd/tests/libstatspull/protos/test_atoms.proto
deleted file mode 100644
index 56c1b53..0000000
--- a/apex/statsd/tests/libstatspull/protos/test_atoms.proto
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-syntax = "proto2";
-
-package com.android.internal.os.statsd.protos;
-
-option java_package = "com.android.internal.os.statsd.protos";
-option java_outer_classname = "TestAtoms";
-
-message PullCallbackAtomWrapper {
-  optional PullCallbackAtom pull_callback_atom = 150030;
-}
-
-message PullCallbackAtom {
-  optional int64 long_val = 1;
-}
-
-
-
diff --git a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java b/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java
deleted file mode 100644
index 6108a32..0000000
--- a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/LibStatsPullTests.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.internal.os.statsd.libstats;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.StatsManager;
-import android.content.Context;
-import android.util.Log;
-import android.util.StatsLog;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.PullAtomPackages;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.internal.os.statsd.protos.TestAtoms;
-import com.android.os.AtomsProto.Atom;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-/**
- * Test puller registration.
- */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class LibStatsPullTests {
-    private static final String LOG_TAG = LibStatsPullTests.class.getSimpleName();
-    private static final int SHORT_SLEEP_MILLIS = 250;
-    private static final int LONG_SLEEP_MILLIS = 1_000;
-    private Context mContext;
-    private static final int PULL_ATOM_TAG = 150030;
-    private static final int APP_BREADCRUMB_LABEL = 3;
-    private static int sPullReturnValue;
-    private static long sConfigId;
-    private static long sPullLatencyMillis;
-    private static long sPullTimeoutMillis;
-    private static long sCoolDownMillis;
-    private static int sAtomsPerPull;
-
-    static {
-        System.loadLibrary("statspull_testhelper");
-    }
-
-    /**
-     * Setup the tests. Initialize shared data.
-     */
-    @Before
-    public void setup() {
-        mContext = InstrumentationRegistry.getTargetContext();
-        assertThat(InstrumentationRegistry.getInstrumentation()).isNotNull();
-        sPullReturnValue = StatsManager.PULL_SUCCESS;
-        sPullLatencyMillis = 0;
-        sPullTimeoutMillis = 10_000L;
-        sCoolDownMillis = 1_000L;
-        sAtomsPerPull = 1;
-    }
-
-    /**
-     * Teardown the tests.
-     */
-    @After
-    public void tearDown() throws Exception {
-        clearStatsPuller(PULL_ATOM_TAG);
-        StatsManager statsManager = (StatsManager) mContext.getSystemService(
-                Context.STATS_MANAGER);
-        statsManager.removeConfig(sConfigId);
-    }
-
-    /**
-     * Tests adding a puller callback and that pulls complete successfully.
-     */
-    @Test
-    public void testPullAtomCallbackRegistration() throws Exception {
-        StatsManager statsManager = (StatsManager) mContext.getSystemService(
-                Context.STATS_MANAGER);
-        // Upload a config that captures that pulled atom.
-        createAndAddConfigToStatsd(statsManager);
-
-        // Add the puller.
-        setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
-                sPullLatencyMillis, sAtomsPerPull);
-        Thread.sleep(SHORT_SLEEP_MILLIS);
-        StatsLog.logStart(APP_BREADCRUMB_LABEL);
-        // Let the current bucket finish.
-        Thread.sleep(LONG_SLEEP_MILLIS);
-        List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
-        clearStatsPuller(PULL_ATOM_TAG);
-        assertThat(data.size()).isEqualTo(1);
-        TestAtoms.PullCallbackAtomWrapper atomWrapper = null;
-        try {
-            atomWrapper = TestAtoms.PullCallbackAtomWrapper.parser()
-                    .parseFrom(data.get(0).toByteArray());
-        } catch (Exception e) {
-            Log.e(LOG_TAG, "Failed to parse primitive atoms");
-        }
-        assertThat(atomWrapper).isNotNull();
-        assertThat(atomWrapper.hasPullCallbackAtom()).isTrue();
-        TestAtoms.PullCallbackAtom atom =
-                atomWrapper.getPullCallbackAtom();
-        assertThat(atom.getLongVal()).isEqualTo(1);
-    }
-
-    /**
-     * Tests that a failed pull is skipped.
-     */
-    @Test
-    public void testPullAtomCallbackFailure() throws Exception {
-        StatsManager statsManager = (StatsManager) mContext.getSystemService(
-                Context.STATS_MANAGER);
-        createAndAddConfigToStatsd(statsManager);
-        sPullReturnValue = StatsManager.PULL_SKIP;
-        // Add the puller.
-        setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
-                sPullLatencyMillis, sAtomsPerPull);
-        Thread.sleep(SHORT_SLEEP_MILLIS);
-        StatsLog.logStart(APP_BREADCRUMB_LABEL);
-        // Let the current bucket finish.
-        Thread.sleep(LONG_SLEEP_MILLIS);
-        List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
-        clearStatsPuller(PULL_ATOM_TAG);
-        assertThat(data.size()).isEqualTo(0);
-    }
-
-    /**
-     * Tests that a pull that times out is skipped.
-     */
-    @Test
-    public void testPullAtomCallbackTimeout() throws Exception {
-        StatsManager statsManager = (StatsManager) mContext.getSystemService(
-                Context.STATS_MANAGER);
-        createAndAddConfigToStatsd(statsManager);
-        // The puller will sleep for 1.5 sec.
-        sPullLatencyMillis = 1_500;
-        // 1 second timeout
-        sPullTimeoutMillis = 1_000;
-
-        // Add the puller.
-        setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
-                sPullLatencyMillis, sAtomsPerPull);
-        Thread.sleep(SHORT_SLEEP_MILLIS);
-        StatsLog.logStart(APP_BREADCRUMB_LABEL);
-        // Let the current bucket finish and the pull timeout.
-        Thread.sleep(sPullLatencyMillis * 2);
-        List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
-        clearStatsPuller(PULL_ATOM_TAG);
-        assertThat(data.size()).isEqualTo(0);
-    }
-
-    /**
-     * Tests that 2 pulls in quick succession use the cache instead of pulling again.
-     */
-    @Test
-    public void testPullAtomCallbackCache() throws Exception {
-        StatsManager statsManager = (StatsManager) mContext.getSystemService(
-                Context.STATS_MANAGER);
-        createAndAddConfigToStatsd(statsManager);
-
-        // Set the cooldown to 10 seconds
-        sCoolDownMillis = 10_000L;
-        // Add the puller.
-        setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
-                sPullLatencyMillis, sAtomsPerPull);
-
-        Thread.sleep(SHORT_SLEEP_MILLIS);
-        StatsLog.logStart(APP_BREADCRUMB_LABEL);
-        // Pull from cache.
-        StatsLog.logStart(APP_BREADCRUMB_LABEL);
-        Thread.sleep(LONG_SLEEP_MILLIS);
-        List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
-        clearStatsPuller(PULL_ATOM_TAG);
-        assertThat(data.size()).isEqualTo(2);
-        for (int i = 0; i < data.size(); i++) {
-            TestAtoms.PullCallbackAtomWrapper atomWrapper = null;
-            try {
-                atomWrapper = TestAtoms.PullCallbackAtomWrapper.parser()
-                        .parseFrom(data.get(i).toByteArray());
-            } catch (Exception e) {
-                Log.e(LOG_TAG, "Failed to parse primitive atoms");
-            }
-            assertThat(atomWrapper).isNotNull();
-            assertThat(atomWrapper.hasPullCallbackAtom()).isTrue();
-            TestAtoms.PullCallbackAtom atom =
-                    atomWrapper.getPullCallbackAtom();
-            assertThat(atom.getLongVal()).isEqualTo(1);
-        }
-    }
-
-    /**
-     * Tests that a pull that returns 1000 stats events works properly.
-     */
-    @Test
-    public void testPullAtomCallbackStress() throws Exception {
-        StatsManager statsManager = (StatsManager) mContext.getSystemService(
-                Context.STATS_MANAGER);
-        // Upload a config that captures that pulled atom.
-        createAndAddConfigToStatsd(statsManager);
-        sAtomsPerPull = 1000;
-        // Add the puller.
-        setStatsPuller(PULL_ATOM_TAG, sPullTimeoutMillis, sCoolDownMillis, sPullReturnValue,
-                sPullLatencyMillis, sAtomsPerPull);
-
-        Thread.sleep(SHORT_SLEEP_MILLIS);
-        StatsLog.logStart(APP_BREADCRUMB_LABEL);
-        // Let the current bucket finish.
-        Thread.sleep(LONG_SLEEP_MILLIS);
-        List<Atom> data = StatsConfigUtils.getGaugeMetricDataList(statsManager, sConfigId);
-        clearStatsPuller(PULL_ATOM_TAG);
-        assertThat(data.size()).isEqualTo(sAtomsPerPull);
-
-        for (int i = 0; i < data.size(); i++) {
-            TestAtoms.PullCallbackAtomWrapper atomWrapper = null;
-            try {
-                atomWrapper = TestAtoms.PullCallbackAtomWrapper.parser()
-                        .parseFrom(data.get(i).toByteArray());
-            } catch (Exception e) {
-                Log.e(LOG_TAG, "Failed to parse primitive atoms");
-            }
-            assertThat(atomWrapper).isNotNull();
-            assertThat(atomWrapper.hasPullCallbackAtom()).isTrue();
-            TestAtoms.PullCallbackAtom atom =
-                    atomWrapper.getPullCallbackAtom();
-            assertThat(atom.getLongVal()).isEqualTo(1);
-        }
-    }
-
-    private void createAndAddConfigToStatsd(StatsManager statsManager) throws Exception {
-        sConfigId = System.currentTimeMillis();
-        long triggerMatcherId = sConfigId + 10;
-        long pullerMatcherId = sConfigId + 11;
-        long metricId = sConfigId + 100;
-        StatsdConfig config = StatsConfigUtils.getSimpleTestConfig(sConfigId)
-                .addAtomMatcher(
-                        StatsConfigUtils.getAppBreadcrumbMatcher(triggerMatcherId,
-                                APP_BREADCRUMB_LABEL))
-                .addAtomMatcher(AtomMatcher.newBuilder()
-                        .setId(pullerMatcherId)
-                        .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder()
-                                .setAtomId(PULL_ATOM_TAG))
-                )
-                .addGaugeMetric(GaugeMetric.newBuilder()
-                        .setId(metricId)
-                        .setWhat(pullerMatcherId)
-                        .setTriggerEvent(triggerMatcherId)
-                        .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true))
-                        .setBucket(TimeUnit.CTS)
-                        .setSamplingType(GaugeMetric.SamplingType.FIRST_N_SAMPLES)
-                        .setMaxNumGaugeAtomsPerBucket(1000)
-                )
-                .addPullAtomPackages(PullAtomPackages.newBuilder()
-                        .setAtomId(PULL_ATOM_TAG)
-                        .addPackages(LibStatsPullTests.class.getPackage().getName()))
-                .build();
-        statsManager.addConfig(sConfigId, config.toByteArray());
-        assertThat(StatsConfigUtils.verifyValidConfigExists(statsManager, sConfigId)).isTrue();
-    }
-
-    private native void setStatsPuller(int atomTag, long timeoutMillis, long coolDownMillis,
-            int pullReturnVal, long latencyMillis, int atomPerPull);
-
-    private native void clearStatsPuller(int atomTag);
-}
-
diff --git a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java b/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java
deleted file mode 100644
index b5afb94..0000000
--- a/apex/statsd/tests/libstatspull/src/com/android/internal/os/statsd/libstats/StatsConfigUtils.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.internal.os.statsd.libstats;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.StatsManager;
-import android.util.Log;
-
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto.AppBreadcrumbReported;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.GaugeBucketInfo;
-import com.android.os.StatsLog.GaugeMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.os.StatsLog.StatsdStatsReport;
-import com.android.os.StatsLog.StatsdStatsReport.ConfigStats;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Util class for constructing statsd configs.
- */
-public class StatsConfigUtils {
-    public static final String TAG = "statsd.StatsConfigUtils";
-    public static final int SHORT_WAIT = 2_000; // 2 seconds.
-
-    /**
-     * @return An empty StatsdConfig in serialized proto format.
-     */
-    public static StatsdConfig.Builder getSimpleTestConfig(long configId) {
-        return StatsdConfig.newBuilder().setId(configId)
-                .addAllowedLogSource(StatsConfigUtils.class.getPackage().getName());
-    }
-
-
-    public static boolean verifyValidConfigExists(StatsManager statsManager, long configId) {
-        StatsdStatsReport report = null;
-        try {
-            report = StatsdStatsReport.parser().parseFrom(statsManager.getStatsMetadata());
-        } catch (Exception e) {
-            Log.e(TAG, "getMetadata failed", e);
-        }
-        assertThat(report).isNotNull();
-        boolean foundConfig = false;
-        for (ConfigStats configStats : report.getConfigStatsList()) {
-            if (configStats.getId() == configId && configStats.getIsValid()
-                    && configStats.getDeletionTimeSec() == 0) {
-                foundConfig = true;
-            }
-        }
-        return foundConfig;
-    }
-
-    public static AtomMatcher getAppBreadcrumbMatcher(long id, int label) {
-        return AtomMatcher.newBuilder()
-                .setId(id)
-                .setSimpleAtomMatcher(
-                        SimpleAtomMatcher.newBuilder()
-                                .setAtomId(Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER)
-                                .addFieldValueMatcher(FieldValueMatcher.newBuilder()
-                                        .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER)
-                                        .setEqInt(label)
-                                )
-                )
-                .build();
-    }
-
-    public static ConfigMetricsReport getConfigMetricsReport(StatsManager statsManager,
-            long configId) {
-        ConfigMetricsReportList reportList = null;
-        try {
-            reportList = ConfigMetricsReportList.parser()
-                    .parseFrom(statsManager.getReports(configId));
-        } catch (Exception e) {
-            Log.e(TAG, "getData failed", e);
-        }
-        assertThat(reportList).isNotNull();
-        assertThat(reportList.getReportsCount()).isEqualTo(1);
-        ConfigMetricsReport report = reportList.getReports(0);
-        assertThat(report.getDumpReportReason())
-                .isEqualTo(ConfigMetricsReport.DumpReportReason.GET_DATA_CALLED);
-        return report;
-
-    }
-    public static List<Atom> getGaugeMetricDataList(ConfigMetricsReport report) {
-        List<Atom> data = new ArrayList<>();
-        for (StatsLogReport metric : report.getMetricsList()) {
-            for (GaugeMetricData gaugeMetricData : metric.getGaugeMetrics().getDataList()) {
-                for (GaugeBucketInfo bucketInfo : gaugeMetricData.getBucketInfoList()) {
-                    for (Atom atom : bucketInfo.getAtomList()) {
-                        data.add(atom);
-                    }
-                }
-            }
-        }
-        return data;
-    }
-
-    public static List<Atom> getGaugeMetricDataList(StatsManager statsManager, long configId) {
-        ConfigMetricsReport report = getConfigMetricsReport(statsManager, configId);
-        return getGaugeMetricDataList(report);
-    }
-}
-
diff --git a/api/OWNERS b/api/OWNERS
new file mode 100644
index 0000000..88d0b61
--- /dev/null
+++ b/api/OWNERS
@@ -0,0 +1 @@
+per-file Android.bp = file:platform/build/soong:/OWNERS
diff --git a/cmds/am/OWNERS b/cmds/am/OWNERS
new file mode 100644
index 0000000..72c0a9e
--- /dev/null
+++ b/cmds/am/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/am/OWNERS
diff --git a/cmds/appops/OWNERS b/cmds/appops/OWNERS
new file mode 100644
index 0000000..999ea0e
--- /dev/null
+++ b/cmds/appops/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/permission/OWNERS
diff --git a/cmds/backup/OWNERS b/cmds/backup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/cmds/backup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/cmds/bmgr/OWNERS b/cmds/bmgr/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/cmds/bmgr/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/cmds/bu/OWNERS b/cmds/bu/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/cmds/bu/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/cmds/dpm/OWNERS b/cmds/dpm/OWNERS
new file mode 100644
index 0000000..e95633a
--- /dev/null
+++ b/cmds/dpm/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/admin/OWNERS
diff --git a/cmds/ime/OWNERS b/cmds/ime/OWNERS
new file mode 100644
index 0000000..5deb2ce
--- /dev/null
+++ b/cmds/ime/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/inputmethod/OWNERS
diff --git a/cmds/incident/OWNERS b/cmds/incident/OWNERS
new file mode 100644
index 0000000..f766115
--- /dev/null
+++ b/cmds/incident/OWNERS
@@ -0,0 +1 @@
+include /cmds/incidentd/OWNERS
diff --git a/cmds/input/OWNERS b/cmds/input/OWNERS
new file mode 100644
index 0000000..d701f23
--- /dev/null
+++ b/cmds/input/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/hardware/input/OWNERS
diff --git a/cmds/locksettings/OWNERS b/cmds/locksettings/OWNERS
new file mode 100644
index 0000000..0a8dc8c
--- /dev/null
+++ b/cmds/locksettings/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/locksettings/OWNERS
diff --git a/cmds/pm/OWNERS b/cmds/pm/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/cmds/pm/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/cmds/sm/OWNERS b/cmds/sm/OWNERS
new file mode 100644
index 0000000..6f9dbea
--- /dev/null
+++ b/cmds/sm/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/os/storage/OWNERS
diff --git a/cmds/statsd/.clang-format b/cmds/statsd/.clang-format
deleted file mode 100644
index cead3a0..0000000
--- a/cmds/statsd/.clang-format
+++ /dev/null
@@ -1,17 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: false
-AllowShortLoopsOnASingleLine: true
-BinPackArguments: true
-BinPackParameters: true
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-ContinuationIndentWidth: 8
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-AccessModifierOffset: -4
-IncludeCategories:
-  - Regex:    '^"Log\.h"'
-    Priority:    -1
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
deleted file mode 100644
index d225497..0000000
--- a/cmds/statsd/Android.bp
+++ /dev/null
@@ -1,447 +0,0 @@
-//
-// Copyright (C) 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.
-//
-
-cc_defaults {
-    name: "statsd_defaults",
-
-    srcs: [
-        "src/active_config_list.proto",
-        "src/anomaly/AlarmMonitor.cpp",
-        "src/anomaly/AlarmTracker.cpp",
-        "src/anomaly/AnomalyTracker.cpp",
-        "src/anomaly/DurationAnomalyTracker.cpp",
-        "src/anomaly/subscriber_util.cpp",
-        "src/condition/CombinationConditionTracker.cpp",
-        "src/condition/condition_util.cpp",
-        "src/condition/ConditionWizard.cpp",
-        "src/condition/SimpleConditionTracker.cpp",
-        "src/config/ConfigKey.cpp",
-        "src/config/ConfigListener.cpp",
-        "src/config/ConfigManager.cpp",
-        "src/experiment_ids.proto",
-        "src/external/Perfetto.cpp",
-        "src/external/PullResultReceiver.cpp",
-        "src/external/puller_util.cpp",
-        "src/external/StatsCallbackPuller.cpp",
-        "src/external/StatsPuller.cpp",
-        "src/external/StatsPullerManager.cpp",
-        "src/external/TrainInfoPuller.cpp",
-        "src/FieldValue.cpp",
-        "src/flags/flags.cpp",
-        "src/guardrail/StatsdStats.cpp",
-        "src/hash.cpp",
-        "src/HashableDimensionKey.cpp",
-        "src/logd/LogEvent.cpp",
-        "src/logd/LogEventQueue.cpp",
-        "src/matchers/CombinationAtomMatchingTracker.cpp",
-        "src/matchers/EventMatcherWizard.cpp",
-        "src/matchers/matcher_util.cpp",
-        "src/matchers/SimpleAtomMatchingTracker.cpp",
-        "src/metadata_util.cpp",
-        "src/metrics/CountMetricProducer.cpp",
-        "src/metrics/duration_helper/MaxDurationTracker.cpp",
-        "src/metrics/duration_helper/OringDurationTracker.cpp",
-        "src/metrics/DurationMetricProducer.cpp",
-        "src/metrics/EventMetricProducer.cpp",
-        "src/metrics/GaugeMetricProducer.cpp",
-        "src/metrics/MetricProducer.cpp",
-        "src/metrics/MetricsManager.cpp",
-        "src/metrics/parsing_utils/config_update_utils.cpp",
-        "src/metrics/parsing_utils/metrics_manager_util.cpp",
-        "src/metrics/ValueMetricProducer.cpp",
-        "src/packages/UidMap.cpp",
-        "src/shell/shell_config.proto",
-        "src/shell/ShellSubscriber.cpp",
-        "src/socket/StatsSocketListener.cpp",
-        "src/state/StateManager.cpp",
-        "src/state/StateTracker.cpp",
-        "src/stats_log_util.cpp",
-        "src/statscompanion_util.cpp",
-        "src/statsd_config.proto",
-        "src/statsd_metadata.proto",
-        "src/StatsLogProcessor.cpp",
-        "src/StatsService.cpp",
-        "src/storage/StorageManager.cpp",
-        "src/subscriber/IncidentdReporter.cpp",
-        "src/subscriber/SubscriberReporter.cpp",
-        "src/uid_data.proto",
-        "src/utils/MultiConditionTrigger.cpp",
-    ],
-
-    local_include_dirs: [
-        "src",
-    ],
-
-    static_libs: [
-        "libbase",
-        "libcutils",
-        "libgtest_prod",
-        "libprotoutil",
-        "libstatslog_statsd",
-        "libsysutils",
-        "libutils",
-        "server_configurable_flags",
-        "statsd-aidl-ndk_platform",
-    ],
-    shared_libs: [
-        "libbinder_ndk",
-        "libincident",
-        "liblog",
-    ],
-}
-
-genrule {
-    name: "statslog_statsd.h",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_statsd.h --module statsd --namespace android,os,statsd,util",
-    out: [
-        "statslog_statsd.h",
-    ],
-}
-
-genrule {
-    name: "statslog_statsd.cpp",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_statsd.cpp --module statsd --namespace android,os,statsd,util --importHeader statslog_statsd.h",
-    out: [
-        "statslog_statsd.cpp",
-    ],
-}
-
-genrule {
-    name: "statslog_statsdtest.h",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_statsdtest.h --module statsdtest --namespace android,os,statsd,util",
-    out: [
-        "statslog_statsdtest.h",
-    ],
-}
-
-genrule {
-    name: "statslog_statsdtest.cpp",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_statsdtest.cpp --module statsdtest --namespace android,os,statsd,util --importHeader statslog_statsdtest.h",
-    out: [
-        "statslog_statsdtest.cpp",
-    ],
-}
-
-cc_library_static {
-    name: "libstatslog_statsdtest",
-    generated_sources: ["statslog_statsdtest.cpp"],
-    generated_headers: ["statslog_statsdtest.h"],
-    export_generated_headers: ["statslog_statsdtest.h"],
-    shared_libs: [
-        "libstatssocket",
-        "libstatspull",
-    ],
-}
-
-cc_library_static {
-    name: "libstatslog_statsd",
-    generated_sources: ["statslog_statsd.cpp"],
-    generated_headers: ["statslog_statsd.h"],
-    export_generated_headers: ["statslog_statsd.h"],
-    apex_available: [
-        "com.android.os.statsd",
-        "test_com.android.os.statsd",
-    ],
-    shared_libs: [
-        "libstatssocket",
-        "libstatspull",
-    ],
-    export_shared_lib_headers: [
-        "libstatspull",
-    ],
-}
-
-// =========
-// statsd
-// =========
-
-cc_binary {
-    name: "statsd",
-    defaults: ["statsd_defaults"],
-
-    srcs: ["src/main.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-Wno-unused-parameter",
-        // optimize for size (protobuf glop can get big)
-        "-Os",
-        // "-g",
-        // "-O0",
-    ],
-
-    product_variables: {
-        eng: {
-            // Enable sanitizer ONLY on eng builds
-            //sanitize: {
-            //    address: true,
-            //},
-        },
-    },
-
-    proto: {
-        type: "lite",
-        static: true,
-    },
-    stl: "libc++_static",
-
-    shared_libs: [
-        "libstatssocket",
-    ],
-
-    apex_available: [
-        "com.android.os.statsd",
-        "test_com.android.os.statsd",
-    ],
-}
-
-// ==============
-// statsd_test
-// ==============
-
-cc_test {
-    name: "statsd_test",
-    defaults: ["statsd_defaults"],
-    test_suites: ["device-tests", "mts"],
-    test_config: "statsd_test.xml",
-
-    //TODO(b/153588990): Remove when the build system properly separates
-    //32bit and 64bit architectures.
-    compile_multilib: "both",
-    multilib: {
-        lib64: {
-            suffix: "64",
-        },
-        lib32: {
-            suffix: "32",
-        },
-    },
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-missing-field-initializers",
-        "-Wno-unused-variable",
-        "-Wno-unused-function",
-        "-Wno-unused-parameter",
-    ],
-
-    require_root: true,
-
-    srcs: [
-        // atom_field_options.proto needs field_options.proto, but that is
-        // not included in libprotobuf-cpp-lite, so compile it here.
-        ":libprotobuf-internal-protos",
-        ":libstats_internal_protos",
-
-        "src/shell/shell_data.proto",
-        "src/stats_log.proto",
-        "tests/AlarmMonitor_test.cpp",
-        "tests/anomaly/AlarmTracker_test.cpp",
-        "tests/anomaly/AnomalyTracker_test.cpp",
-        "tests/condition/CombinationConditionTracker_test.cpp",
-        "tests/condition/ConditionTimer_test.cpp",
-        "tests/condition/SimpleConditionTracker_test.cpp",
-        "tests/ConfigManager_test.cpp",
-        "tests/e2e/Alarm_e2e_test.cpp",
-        "tests/e2e/Anomaly_count_e2e_test.cpp",
-        "tests/e2e/Anomaly_duration_sum_e2e_test.cpp",
-        "tests/e2e/Attribution_e2e_test.cpp",
-        "tests/e2e/ConfigTtl_e2e_test.cpp",
-        "tests/e2e/ConfigUpdate_e2e_ab_test.cpp",
-        "tests/e2e/ConfigUpdate_e2e_test.cpp",
-        "tests/e2e/CountMetric_e2e_test.cpp",
-        "tests/e2e/DurationMetric_e2e_test.cpp",
-        "tests/e2e/GaugeMetric_e2e_pull_test.cpp",
-        "tests/e2e/GaugeMetric_e2e_push_test.cpp",
-        "tests/e2e/MetricActivation_e2e_test.cpp",
-        "tests/e2e/MetricConditionLink_e2e_test.cpp",
-        "tests/e2e/PartialBucket_e2e_test.cpp",
-        "tests/e2e/ValueMetric_pull_e2e_test.cpp",
-        "tests/e2e/WakelockDuration_e2e_test.cpp",
-        "tests/external/puller_util_test.cpp",
-        "tests/external/StatsCallbackPuller_test.cpp",
-        "tests/external/StatsPuller_test.cpp",
-        "tests/external/StatsPullerManager_test.cpp",
-        "tests/FieldValue_test.cpp",
-        "tests/guardrail/StatsdStats_test.cpp",
-        "tests/HashableDimensionKey_test.cpp",
-        "tests/indexed_priority_queue_test.cpp",
-        "tests/log_event/LogEventQueue_test.cpp",
-        "tests/LogEntryMatcher_test.cpp",
-        "tests/LogEvent_test.cpp",
-        "tests/metadata_util_test.cpp",
-        "tests/metrics/CountMetricProducer_test.cpp",
-        "tests/metrics/DurationMetricProducer_test.cpp",
-        "tests/metrics/EventMetricProducer_test.cpp",
-        "tests/metrics/GaugeMetricProducer_test.cpp",
-        "tests/metrics/MaxDurationTracker_test.cpp",
-        "tests/metrics/metrics_test_helper.cpp",
-        "tests/metrics/OringDurationTracker_test.cpp",
-        "tests/metrics/ValueMetricProducer_test.cpp",
-        "tests/metrics/parsing_utils/config_update_utils_test.cpp",
-        "tests/metrics/parsing_utils/metrics_manager_util_test.cpp",
-        "tests/MetricsManager_test.cpp",
-        "tests/shell/ShellSubscriber_test.cpp",
-        "tests/state/StateTracker_test.cpp",
-        "tests/statsd_test_util.cpp",
-        "tests/StatsLogProcessor_test.cpp",
-        "tests/StatsService_test.cpp",
-        "tests/storage/StorageManager_test.cpp",
-        "tests/UidMap_test.cpp",
-        "tests/utils/MultiConditionTrigger_test.cpp",
-    ],
-
-    static_libs: [
-        "libgmock",
-        "libplatformprotos",
-        "libstatslog_statsdtest",
-        "libstatssocket_private",
-    ],
-
-    proto: {
-        type: "lite",
-        include_dirs: [
-            "external/protobuf/src",
-            "frameworks/proto_logging/stats",
-        ],
-    },
-
-}
-
-//#############################
-// statsd micro benchmark
-//#############################
-
-cc_benchmark {
-    name: "statsd_benchmark",
-    defaults: ["statsd_defaults"],
-
-    srcs: [
-        // atom_field_options.proto needs field_options.proto, but that is
-        // not included in libprotobuf-cpp-lite, so compile it here.
-        ":libprotobuf-internal-protos",
-        ":libstats_internal_protos",
-
-        "benchmark/duration_metric_benchmark.cpp",
-        "benchmark/filter_value_benchmark.cpp",
-        "benchmark/get_dimensions_for_condition_benchmark.cpp",
-        "benchmark/hello_world_benchmark.cpp",
-        "benchmark/log_event_benchmark.cpp",
-        "benchmark/main.cpp",
-        "benchmark/metric_util.cpp",
-        "benchmark/stats_write_benchmark.cpp",
-        "src/stats_log.proto",
-    ],
-
-    proto: {
-        type: "lite",
-        include_dirs: [
-            "external/protobuf/src",
-            "frameworks/proto_logging/stats",
-        ],
-    },
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-unused-parameter",
-        "-Wno-unused-variable",
-        "-Wno-unused-function",
-
-        // Bug: http://b/29823425 Disable -Wvarargs for Clang update to r271374
-        "-Wno-varargs",
-    ],
-
-    static_libs: [
-        "libplatformprotos",
-        "libstatssocket_private",
-    ],
-
-    shared_libs: [
-        "libgtest_prod",
-        "libprotobuf-cpp-lite",
-        "libstatslog",
-    ],
-}
-
-// ====  java proto device library (for test only)  ==============================
-java_library {
-    name: "statsdprotolite",
-    sdk_version: "core_current",
-    proto: {
-        type: "lite",
-        include_dirs: [
-            "external/protobuf/src",
-            "frameworks/proto_logging/stats",
-        ],
-    },
-
-    srcs: [
-        ":libstats_atoms_proto",
-        "src/shell/shell_config.proto",
-        "src/shell/shell_data.proto",
-        "src/stats_log.proto",
-        "src/statsd_config.proto",
-    ],
-
-    static_libs: [
-        "platformprotoslite",
-    ],
-    // Protos have lots of MissingOverride and similar.
-    errorprone: {
-        javacflags: ["-XepDisableAllChecks"],
-    },
-}
-
-java_library {
-    name: "statsdprotonano",
-    sdk_version: "9",
-    proto: {
-        type: "nano",
-        output_params: ["store_unknown_fields=true"],
-        include_dirs: [
-            "external/protobuf/src",
-            "frameworks/proto_logging/stats",
-        ],
-    },
-    srcs: [
-        ":libstats_atoms_proto",
-        "src/shell/shell_config.proto",
-        "src/shell/shell_data.proto",
-        "src/stats_log.proto",
-        "src/statsd_config.proto",
-    ],
-    static_libs: [
-        "platformprotosnano",
-    ],
-    // Protos have lots of MissingOverride and similar.
-    errorprone: {
-        javacflags: ["-XepDisableAllChecks"],
-    },
-}
-
-// Filegroup for statsd config proto definition.
-filegroup {
-    name: "statsd-config-proto-def",
-    srcs: ["src/statsd_config.proto"],
-}
diff --git a/cmds/statsd/OWNERS b/cmds/statsd/OWNERS
deleted file mode 100644
index 4e4e119..0000000
--- a/cmds/statsd/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-baligh@google.com
diff --git a/cmds/statsd/TEST_MAPPING b/cmds/statsd/TEST_MAPPING
deleted file mode 100644
index a7a4cf1..0000000
--- a/cmds/statsd/TEST_MAPPING
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "presubmit" : [
-    {
-      "name" : "statsd_test"
-    }
-  ],
-
-  "postsubmit" : [
-    {
-      "name" : "CtsStatsdHostTestCases"
-    },
-    {
-      "name" : "GtsStatsdHostTestCases"
-    }
-  ]
-
-}
diff --git a/cmds/statsd/benchmark/duration_metric_benchmark.cpp b/cmds/statsd/benchmark/duration_metric_benchmark.cpp
deleted file mode 100644
index 2d315d9..0000000
--- a/cmds/statsd/benchmark/duration_metric_benchmark.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#include <vector>
-#include "benchmark/benchmark.h"
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-#include "metric_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-static StatsdConfig CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
-        DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
-    StatsdConfig config;
-    *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
-    *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
-    *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
-    *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
-    auto scheduledJobPredicate = CreateScheduledJobPredicate();
-    auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
-    dimensions->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
-    dimensions->add_child()->set_field(2);  // job name field.
-
-    auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
-    auto isSyncingPredicate = CreateIsSyncingPredicate();
-    auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
-    *syncDimension = CreateAttributionUidAndTagDimensions(android::util::SYNC_STATE_CHANGED,
-                                                          {Position::FIRST});
-    if (addExtraDimensionInCondition) {
-        syncDimension->add_child()->set_field(2 /* name field*/);
-    }
-
-    *config.add_predicate() = scheduledJobPredicate;
-    *config.add_predicate() = screenIsOffPredicate;
-    *config.add_predicate() = isSyncingPredicate;
-    auto combinationPredicate = config.add_predicate();
-    combinationPredicate->set_id(StringToId("CombinationPredicate"));
-    combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
-    addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
-    addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
-    auto metric = config.add_duration_metric();
-    metric->set_bucket(FIVE_MINUTES);
-    metric->set_id(StringToId("scheduledJob"));
-    metric->set_what(scheduledJobPredicate.id());
-    metric->set_condition(combinationPredicate->id());
-    metric->set_aggregation_type(aggregationType);
-    auto dimensionWhat = metric->mutable_dimensions_in_what();
-    dimensionWhat->set_field(android::util::SCHEDULED_JOB_STATE_CHANGED);
-    dimensionWhat->add_child()->set_field(2);  // job name field.
-    *metric->mutable_dimensions_in_condition() = CreateAttributionUidAndTagDimensions(
-            android::util::SYNC_STATE_CHANGED, {Position::FIRST});
-    return config;
-}
-
-static StatsdConfig CreateDurationMetricConfig_Link_AND_CombinationCondition(
-        DurationMetric::AggregationType aggregationType, bool addExtraDimensionInCondition) {
-    StatsdConfig config;
-    *config.add_atom_matcher() = CreateStartScheduledJobAtomMatcher();
-    *config.add_atom_matcher() = CreateFinishScheduledJobAtomMatcher();
-    *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
-    *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
-    auto scheduledJobPredicate = CreateScheduledJobPredicate();
-    auto dimensions = scheduledJobPredicate.mutable_simple_predicate()->mutable_dimensions();
-    *dimensions = CreateAttributionUidDimensions(
-                android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
-    dimensions->add_child()->set_field(2);  // job name field.
-
-    auto isSyncingPredicate = CreateIsSyncingPredicate();
-    auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
-    *syncDimension = CreateAttributionUidDimensions(
-            android::util::SYNC_STATE_CHANGED, {Position::FIRST});
-    if (addExtraDimensionInCondition) {
-        syncDimension->add_child()->set_field(2 /* name field*/);
-    }
-
-    auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
-    *config.add_predicate() = scheduledJobPredicate;
-    *config.add_predicate() = screenIsOffPredicate;
-    *config.add_predicate() = isSyncingPredicate;
-    auto combinationPredicate = config.add_predicate();
-    combinationPredicate->set_id(StringToId("CombinationPredicate"));
-    combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
-    addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
-    addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-
-    auto metric = config.add_duration_metric();
-    metric->set_bucket(FIVE_MINUTES);
-    metric->set_id(StringToId("scheduledJob"));
-    metric->set_what(scheduledJobPredicate.id());
-    metric->set_condition(combinationPredicate->id());
-    metric->set_aggregation_type(aggregationType);
-    *metric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
-            android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
-
-    auto links = metric->add_links();
-    links->set_condition(isSyncingPredicate.id());
-    *links->mutable_fields_in_what() =
-            CreateAttributionUidDimensions(
-                android::util::SCHEDULED_JOB_STATE_CHANGED, {Position::FIRST});
-    *links->mutable_fields_in_condition() =
-            CreateAttributionUidDimensions(android::util::SYNC_STATE_CHANGED, {Position::FIRST});
-    return config;
-}
-
-static void BM_DurationMetricNoLink(benchmark::State& state) {
-    ConfigKey cfgKey;
-    auto config = CreateDurationMetricConfig_NoLink_AND_CombinationCondition(
-            DurationMetric::SUM, false);
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 11,
-                                                   android::view::DISPLAY_STATE_OFF));
-    events.push_back(
-            CreateScreenStateChangedEvent(bucketStartTimeNs + 40, android::view::DISPLAY_STATE_ON));
-
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 102,
-                                                   android::view::DISPLAY_STATE_OFF));
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 450,
-                                                   android::view::DISPLAY_STATE_ON));
-
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 650,
-                                                   android::view::DISPLAY_STATE_OFF));
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 100,
-                                                   android::view::DISPLAY_STATE_ON));
-
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 640,
-                                                   android::view::DISPLAY_STATE_OFF));
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 650,
-                                                   android::view::DISPLAY_STATE_ON));
-
-    vector<int> attributionUids1 = {9999};
-    vector<string> attributionTags1 = {""};
-    events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 2, attributionUids1,
-                                                  attributionTags1, "job0"));
-    events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 101, attributionUids1,
-                                                   attributionTags1, "job0"));
-
-    events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 201, attributionUids1,
-                                                  attributionTags1, "job2"));
-    events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 500, attributionUids1,
-                                                   attributionTags1, "job2"));
-
-    vector<int> attributionUids2 = {8888};
-    events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 600, attributionUids2,
-                                                  attributionTags1, "job2"));
-    events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 850,
-                                                   attributionUids2, attributionTags1, "job2"));
-
-    events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 600,
-                                                  attributionUids2, attributionTags1, "job1"));
-    events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 900,
-                                                   attributionUids2, attributionTags1, "job1"));
-
-    vector<int> attributionUids3 = {111, 222, 222};
-    vector<string> attributionTags3 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 10, attributionUids3,
-                                          attributionTags3, "ReadEmail"));
-    events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 50, attributionUids3, attributionTags3,
-                                        "ReadEmail"));
-
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 200, attributionUids3,
-                                          attributionTags3, "ReadEmail"));
-    events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids3,
-                                        attributionTags3, "ReadEmail"));
-
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400, attributionUids3,
-                                          attributionTags3, "ReadDoc"));
-    events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids3,
-                                        attributionTags3, "ReadDoc"));
-
-    vector<int> attributionUids4 = {333, 222, 555};
-    vector<string> attributionTags4 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 401, attributionUids4,
-                                          attributionTags4, "ReadEmail"));
-    events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 700, attributionUids4,
-                                        attributionTags4, "ReadEmail"));
-    sortLogEventsByTimestamp(&events);
-
-    while (state.KeepRunning()) {
-        auto processor = CreateStatsLogProcessor(
-                bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
-        for (const auto& event : events) {
-            processor->OnLogEvent(event.get());
-        }
-    }
-}
-
-BENCHMARK(BM_DurationMetricNoLink);
-
-
-static void BM_DurationMetricLink(benchmark::State& state) {
-    ConfigKey cfgKey;
-    auto config = CreateDurationMetricConfig_Link_AND_CombinationCondition(
-        DurationMetric::SUM, false);
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 55,
-                                                   android::view::DISPLAY_STATE_OFF));
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 120,
-                                                   android::view::DISPLAY_STATE_ON));
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 121,
-                                                   android::view::DISPLAY_STATE_OFF));
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 450,
-                                                   android::view::DISPLAY_STATE_ON));
-
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 501,
-                                                   android::view::DISPLAY_STATE_OFF));
-    events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 100,
-                                                   android::view::DISPLAY_STATE_ON));
-
-    vector<int> attributionUids1 = {111};
-    vector<string> attributionTags1 = {"App1"};
-    events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 1, attributionUids1,
-                                                  attributionTags1, "job1"));
-    events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 101, attributionUids1,
-                                                   attributionTags1, "job1"));
-
-    vector<int> attributionUids2 = {333};
-    vector<string> attributionTags2 = {"App2"};
-    events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 201, attributionUids2,
-                                                  attributionTags2, "job2"));
-    events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + 500, attributionUids2,
-                                                   attributionTags2, "job2"));
-    events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + 600, attributionUids2,
-                                                  attributionTags2, "job2"));
-    events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 850,
-                                                   attributionUids2, attributionTags2, "job2"));
-
-    vector<int> attributionUids3 = {444};
-    vector<string> attributionTags3 = {"App3"};
-    events.push_back(CreateStartScheduledJobEvent(bucketStartTimeNs + bucketSizeNs - 2,
-                                                  attributionUids3, attributionTags3, "job3"));
-    events.push_back(CreateFinishScheduledJobEvent(bucketStartTimeNs + bucketSizeNs + 900,
-                                                   attributionUids3, attributionTags3, "job3"));
-
-    vector<int> attributionUids4 = {111, 222, 222};
-    vector<string> attributionTags4 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids4,
-                                          attributionTags4, "ReadEmail"));
-    events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 110, attributionUids4, attributionTags4,
-                                        "ReadEmail"));
-
-    vector<int> attributionUids5 = {333, 222, 555};
-    vector<string> attributionTags5 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 300, attributionUids5,
-                                          attributionTags5, "ReadEmail"));
-    events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 700, attributionUids5,
-                                        attributionTags5, "ReadEmail"));
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400, attributionUids5,
-                                          attributionTags5, "ReadDoc"));
-    events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids5,
-                                        attributionTags5, "ReadDoc"));
-
-    vector<int> attributionUids6 = {444, 222, 555};
-    vector<string> attributionTags6 = {"App3", "GMSCoreModule1", "GMSCoreModule2"};
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 550, attributionUids6,
-                                          attributionTags6, "ReadDoc"));
-    events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 800, attributionUids6, attributionTags6,
-                                        "ReadDoc"));
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids6,
-                                          attributionTags6, "ReadDoc"));
-    events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 700, attributionUids6,
-                                        attributionTags6, "ReadDoc"));
-    sortLogEventsByTimestamp(&events);
-
-    while (state.KeepRunning()) {
-        auto processor = CreateStatsLogProcessor(
-                bucketStartTimeNs / NS_PER_SEC, config, cfgKey);
-        for (const auto& event : events) {
-            processor->OnLogEvent(event.get());
-        }
-    }
-}
-
-BENCHMARK(BM_DurationMetricLink);
-
-}  //  namespace statsd
-}  //  namespace os
-}  //  namespace android
diff --git a/cmds/statsd/benchmark/filter_value_benchmark.cpp b/cmds/statsd/benchmark/filter_value_benchmark.cpp
deleted file mode 100644
index 743ccc4..0000000
--- a/cmds/statsd/benchmark/filter_value_benchmark.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#include <vector>
-
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "benchmark/benchmark.h"
-#include "logd/LogEvent.h"
-#include "metric_util.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-static void createLogEventAndMatcher(LogEvent* event, FieldMatcher* field_matcher) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, 1);
-    AStatsEvent_overwriteTimestamp(statsEvent, 100000);
-
-    std::vector<int> attributionUids = {100, 100};
-    std::vector<string> attributionTags = {"LOCATION", "LOCATION"};
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-
-    AStatsEvent_writeFloat(statsEvent, 3.2f);
-    AStatsEvent_writeString(statsEvent, "LOCATION");
-    AStatsEvent_writeInt64(statsEvent, 990);
-
-    parseStatsEventToLogEvent(statsEvent, event);
-
-    field_matcher->set_field(1);
-    auto child = field_matcher->add_child();
-    child->set_field(1);
-    child->set_position(FIRST);
-    child->add_child()->set_field(1);
-}
-
-static void BM_FilterValue(benchmark::State& state) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    FieldMatcher field_matcher;
-    createLogEventAndMatcher(&event, &field_matcher);
-
-    std::vector<Matcher> matchers;
-    translateFieldMatcher(field_matcher, &matchers);
-
-    while (state.KeepRunning()) {
-        HashableDimensionKey output;
-        filterValues(matchers, event.getValues(), &output);
-    }
-}
-
-BENCHMARK(BM_FilterValue);
-
-}  //  namespace statsd
-}  //  namespace os
-}  //  namespace android
diff --git a/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp b/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp
deleted file mode 100644
index 7a45565..0000000
--- a/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#include <vector>
-
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "benchmark/benchmark.h"
-#include "logd/LogEvent.h"
-#include "metric_util.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-static void createLogEventAndLink(LogEvent* event, Metric2Condition *link) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, 1);
-    AStatsEvent_overwriteTimestamp(statsEvent, 100000);
-
-    std::vector<int> attributionUids = {100, 100};
-    std::vector<string> attributionTags = {"LOCATION", "LOCATION"};
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-
-    AStatsEvent_writeFloat(statsEvent, 3.2f);
-    AStatsEvent_writeString(statsEvent, "LOCATION");
-    AStatsEvent_writeInt64(statsEvent, 990);
-
-    parseStatsEventToLogEvent(statsEvent, event);
-
-    link->conditionId = 1;
-
-    FieldMatcher field_matcher;
-    field_matcher.set_field(event->GetTagId());
-    auto child = field_matcher.add_child();
-    child->set_field(1);
-    child->set_position(FIRST);
-    child->add_child()->set_field(1);
-
-    translateFieldMatcher(field_matcher, &link->metricFields);
-    field_matcher.set_field(event->GetTagId() + 1);
-    translateFieldMatcher(field_matcher, &link->conditionFields);
-}
-
-static void BM_GetDimensionInCondition(benchmark::State& state) {
-    Metric2Condition link;
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createLogEventAndLink(&event, &link);
-
-    while (state.KeepRunning()) {
-        HashableDimensionKey output;
-        getDimensionForCondition(event.getValues(), link, &output);
-    }
-}
-
-BENCHMARK(BM_GetDimensionInCondition);
-
-
-}  //  namespace statsd
-}  //  namespace os
-}  //  namespace android
diff --git a/cmds/statsd/benchmark/hello_world_benchmark.cpp b/cmds/statsd/benchmark/hello_world_benchmark.cpp
deleted file mode 100644
index c732d39..0000000
--- a/cmds/statsd/benchmark/hello_world_benchmark.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#include "benchmark/benchmark.h"
-
-static void BM_StringCreation(benchmark::State& state) {
-    while (state.KeepRunning()) std::string empty_string;
-}
-// Register the function as a benchmark
-BENCHMARK(BM_StringCreation);
-
-// Define another benchmark
-static void BM_StringCopy(benchmark::State& state) {
-    std::string x = "hello";
-    while (state.KeepRunning()) std::string copy(x);
-}
-BENCHMARK(BM_StringCopy);
diff --git a/cmds/statsd/benchmark/log_event_benchmark.cpp b/cmds/statsd/benchmark/log_event_benchmark.cpp
deleted file mode 100644
index 057e00b..0000000
--- a/cmds/statsd/benchmark/log_event_benchmark.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#include <vector>
-#include "benchmark/benchmark.h"
-#include "logd/LogEvent.h"
-#include "stats_event.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static size_t createAndParseStatsEvent(uint8_t* msg) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeInt32(event, 2);
-    AStatsEvent_writeFloat(event, 2.0);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-    memcpy(msg, buf, size);
-    return size;
-}
-
-static void BM_LogEventCreation(benchmark::State& state) {
-    uint8_t msg[LOGGER_ENTRY_MAX_PAYLOAD];
-    size_t size = createAndParseStatsEvent(msg);
-    while (state.KeepRunning()) {
-        LogEvent event(/*uid=*/ 1000, /*pid=*/ 1001);
-        benchmark::DoNotOptimize(event.parseBuffer(msg, size));
-    }
-}
-BENCHMARK(BM_LogEventCreation);
-
-}  //  namespace statsd
-}  //  namespace os
-}  //  namespace android
diff --git a/cmds/statsd/benchmark/main.cpp b/cmds/statsd/benchmark/main.cpp
deleted file mode 100644
index 08921f3..0000000
--- a/cmds/statsd/benchmark/main.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include <benchmark/benchmark.h>
-
-BENCHMARK_MAIN();
diff --git a/cmds/statsd/benchmark/metric_util.cpp b/cmds/statsd/benchmark/metric_util.cpp
deleted file mode 100644
index 89fd3d9..0000000
--- a/cmds/statsd/benchmark/metric_util.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright (C) 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.
-
-#include "metric_util.h"
-
-#include "stats_event.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(atomId);
-    return atom_matcher;
-}
-
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
-                                                      ScheduledJobStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::SCHEDULED_JOB_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(3);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateStartScheduledJobAtomMatcher() {
-    return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
-                                                     ScheduledJobStateChanged::STARTED);
-}
-
-AtomMatcher CreateFinishScheduledJobAtomMatcher() {
-    return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
-                                                     ScheduledJobStateChanged::FINISHED);
-}
-
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::SCREEN_BRIGHTNESS_CHANGED);
-    return atom_matcher;
-}
-
-AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId("UidProcessStateChanged"));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::UID_PROCESS_STATE_CHANGED);
-    return atom_matcher;
-}
-
-AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
-                                                  WakelockStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::WAKELOCK_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(4);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateAcquireWakelockAtomMatcher() {
-    return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
-}
-
-AtomMatcher CreateReleaseWakelockAtomMatcher() {
-    return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
-}
-
-AtomMatcher CreateScreenStateChangedAtomMatcher(
-    const string& name, android::view::DisplayStateEnum state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::SCREEN_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(1);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateScreenTurnedOnAtomMatcher() {
-    return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-}
-
-AtomMatcher CreateScreenTurnedOffAtomMatcher() {
-    return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
-            ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-}
-
-AtomMatcher CreateSyncStateChangedAtomMatcher(
-    const string& name, SyncStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::SYNC_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(3);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateSyncStartAtomMatcher() {
-    return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
-}
-
-AtomMatcher CreateSyncEndAtomMatcher() {
-    return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
-}
-
-AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
-    const string& name, ActivityForegroundStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(4);  // Activity field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateMoveToBackgroundAtomMatcher() {
-    return CreateActivityForegroundStateChangedAtomMatcher(
-        "MoveToBackground", ActivityForegroundStateChanged::BACKGROUND);
-}
-
-AtomMatcher CreateMoveToForegroundAtomMatcher() {
-    return CreateActivityForegroundStateChangedAtomMatcher(
-        "MoveToForeground", ActivityForegroundStateChanged::FOREGROUND);
-}
-
-Predicate CreateScheduledJobPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
-    return predicate;
-}
-
-Predicate CreateBatterySaverModePredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("BatterySaverIsOn"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
-    return predicate;
-}
-
-Predicate CreateScreenIsOnPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("ScreenIsOn"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
-    return predicate;
-}
-
-Predicate CreateScreenIsOffPredicate() {
-    Predicate predicate;
-    predicate.set_id(1111123);
-    predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
-    return predicate;
-}
-
-Predicate CreateHoldingWakelockPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("HoldingWakelock"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
-    return predicate;
-}
-
-Predicate CreateIsSyncingPredicate() {
-    Predicate predicate;
-    predicate.set_id(33333333333333);
-    predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
-    return predicate;
-}
-
-Predicate CreateIsInBackgroundPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("IsInBackground"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("MoveToBackground"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("MoveToForeground"));
-    return predicate;
-}
-
-void addPredicateToPredicateCombination(const Predicate& predicate,
-                                        Predicate* combinationPredicate) {
-    combinationPredicate->mutable_combination()->add_predicate(predicate.id());
-}
-
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
-                                            const std::vector<Position>& positions) {
-    FieldMatcher dimensions;
-    dimensions.set_field(atomId);
-    for (const auto position : positions) {
-        auto child = dimensions.add_child();
-        child->set_field(1);
-        child->set_position(position);
-        child->add_child()->set_field(1);
-    }
-    return dimensions;
-}
-
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
-                                                 const std::vector<Position>& positions) {
-    FieldMatcher dimensions;
-    dimensions.set_field(atomId);
-    for (const auto position : positions) {
-        auto child = dimensions.add_child();
-        child->set_field(1);
-        child->set_position(position);
-        child->add_child()->set_field(1);
-        child->add_child()->set_field(2);
-    }
-    return dimensions;
-}
-
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
-    FieldMatcher dimensions;
-    dimensions.set_field(atomId);
-    for (const int field : fields) {
-        dimensions.add_child()->set_field(field);
-    }
-    return dimensions;
-}
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
-                      const vector<string>& attributionTags) {
-    vector<const char*> cTags(attributionTags.size());
-    for (int i = 0; i < cTags.size(); i++) {
-        cTags[i] = attributionTags[i].c_str();
-    }
-
-    AStatsEvent_writeAttributionChain(statsEvent,
-                                      reinterpret_cast<const uint32_t*>(attributionUids.data()),
-                                      cTags.data(), attributionUids.size());
-}
-
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
-    AStatsEvent_build(statsEvent);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    logEvent->parseBuffer(buf, size);
-
-    AStatsEvent_release(statsEvent);
-}
-
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
-        uint64_t timestampNs, const android::view::DisplayStateEnum state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-    AStatsEvent_writeInt32(statsEvent, state);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
-        const vector<int>& attributionUids, const vector<string>& attributionTags,
-        const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_writeString(statsEvent, jobName.c_str());
-    AStatsEvent_writeInt32(statsEvent, state);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
-                                                       const vector<int>& attributionUids,
-                                                       const vector<string>& attributionTags,
-                                                       const string& jobName) {
-    return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
-                                               ScheduledJobStateChanged::STARTED, timestampNs);
-}
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
-                                                        const vector<int>& attributionUids,
-                                                        const vector<string>& attributionTags,
-                                                        const string& jobName) {
-    return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
-                                               ScheduledJobStateChanged::FINISHED, timestampNs);
-}
-
-std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
-                                                      const vector<int>& attributionUids,
-                                                      const vector<string>& attributionTags,
-                                                      const string& name,
-                                                      const SyncStateChanged::State state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_writeString(statsEvent, name.c_str());
-    AStatsEvent_writeInt32(statsEvent, state);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
-                                               const vector<int>& attributionUids,
-                                               const vector<string>& attributionTags,
-                                               const string& name) {
-    return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
-                                       SyncStateChanged::ON);
-}
-
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
-                                             const vector<int>& attributionUids,
-                                             const vector<string>& attributionTags,
-                                             const string& name) {
-    return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
-                                       SyncStateChanged::OFF);
-}
-
-sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
-                                              const ConfigKey& key) {
-    sp<UidMap> uidMap = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    sp<StatsLogProcessor> processor =
-            new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-                                  timeBaseSec * NS_PER_SEC, [](const ConfigKey&) { return true; },
-                                  [](const int&, const vector<int64_t>&) { return true; });
-    processor->OnConfigUpdated(timeBaseSec * NS_PER_SEC, key, config);
-    return processor;
-}
-
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
-  std::sort(events->begin(), events->end(),
-            [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
-              return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
-            });
-}
-
-int64_t StringToId(const string& str) {
-    return static_cast<int64_t>(std::hash<std::string>()(str));
-}
-
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/benchmark/metric_util.h b/cmds/statsd/benchmark/metric_util.h
deleted file mode 100644
index 3efaa85..0000000
--- a/cmds/statsd/benchmark/metric_util.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (C) 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.
-
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "src/StatsLogProcessor.h"
-#include "src/logd/LogEvent.h"
-#include "stats_event.h"
-#include "statslog.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Create AtomMatcher proto to simply match a specific atom type.
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId);
-
-// Create AtomMatcher proto for scheduled job state changed.
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher();
-
-// Create AtomMatcher proto for starting a scheduled job.
-AtomMatcher CreateStartScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for a scheduled job is done.
-AtomMatcher CreateFinishScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for screen brightness state changed.
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher();
-
-// Create AtomMatcher proto for acquiring wakelock.
-AtomMatcher CreateAcquireWakelockAtomMatcher();
-
-// Create AtomMatcher proto for releasing wakelock.
-AtomMatcher CreateReleaseWakelockAtomMatcher() ;
-
-// Create AtomMatcher proto for screen turned on.
-AtomMatcher CreateScreenTurnedOnAtomMatcher();
-
-// Create AtomMatcher proto for screen turned off.
-AtomMatcher CreateScreenTurnedOffAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned on.
-AtomMatcher CreateSyncStartAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned off.
-AtomMatcher CreateSyncEndAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to background.
-AtomMatcher CreateMoveToBackgroundAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to foreground.
-AtomMatcher CreateMoveToForegroundAtomMatcher();
-
-// Create Predicate proto for screen is off.
-Predicate CreateScreenIsOffPredicate();
-
-// Create Predicate proto for a running scheduled job.
-Predicate CreateScheduledJobPredicate();
-
-// Create Predicate proto for holding wakelock.
-Predicate CreateHoldingWakelockPredicate();
-
-// Create a Predicate proto for app syncing.
-Predicate CreateIsSyncingPredicate();
-
-// Create a Predicate proto for app is in background.
-Predicate CreateIsInBackgroundPredicate();
-
-// Add a predicate to the predicate combination.
-void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination);
-
-// Create dimensions from primitive fields.
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields);
-
-// Create dimensions by attribution uid and tag.
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
-                                                  const std::vector<Position>& positions);
-
-// Create dimensions by attribution uid only.
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
-                                            const std::vector<Position>& positions);
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
-                      const vector<string>& attributionTags);
-
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent);
-
-// Create log event for screen state changed.
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
-        uint64_t timestampNs, const android::view::DisplayStateEnum state);
-
-// Create log event when scheduled job starts.
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
-                                                       const vector<int>& attributionUids,
-                                                       const vector<string>& attributionTags,
-                                                       const string& jobName);
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
-                                                        const vector<int>& attributionUids,
-                                                        const vector<string>& attributionTags,
-                                                        const string& jobName);
-
-// Create log event when the app sync starts.
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
-                                               const vector<int>& attributionUids,
-                                               const vector<string>& attributionTags,
-                                               const string& name);
-
-// Create log event when the app sync ends.
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
-                                             const vector<int>& attributionUids,
-                                             const vector<string>& attributionTags,
-                                             const string& name);
-
-// Create a statsd log event processor upon the start time in seconds, config and key.
-sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
-                                              const ConfigKey& key);
-
-// Util function to sort the log events by timestamp.
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
-
-int64_t StringToId(const string& str);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/benchmark/stats_write_benchmark.cpp b/cmds/statsd/benchmark/stats_write_benchmark.cpp
deleted file mode 100644
index f5a0cd5..0000000
--- a/cmds/statsd/benchmark/stats_write_benchmark.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#include "benchmark/benchmark.h"
-#include <statslog.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static void BM_StatsWrite(benchmark::State& state) {
-    const char* reason = "test";
-    int64_t boot_end_time = 1234567;
-    int64_t total_duration = 100;
-    int64_t bootloader_duration = 10;
-    int64_t time_since_last_boot = 99999999;
-    while (state.KeepRunning()) {
-        android::util::stats_write(
-                android::util::BOOT_SEQUENCE_REPORTED, reason, reason,
-                boot_end_time, total_duration, bootloader_duration, time_since_last_boot);
-        total_duration++;
-    }
-}
-BENCHMARK(BM_StatsWrite);
-
-}  //  namespace statsd
-}  //  namespace os
-}  //  namespace android
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
deleted file mode 100644
index c9ccfb9..0000000
--- a/cmds/statsd/src/FieldValue.cpp
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define DEBUG false
-#include "Log.h"
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "math.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
-    int32_t field = 0;
-    for (int32_t i = 0; i <= depth; i++) {
-        int32_t shiftBits = 8 * (kMaxLogDepth - i);
-        field |= (pos[i] << shiftBits);
-    }
-
-    if (includeDepth) {
-        field |= (depth << 24);
-    }
-    return field;
-}
-
-int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
-    return getEncodedField(mask, depth, false) | 0xff000000;
-}
-
-bool Field::matches(const Matcher& matcher) const {
-    if (mTag != matcher.mMatcher.getTag()) {
-        return false;
-    }
-    if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
-        return true;
-    }
-
-    if (matcher.hasAllPositionMatcher() &&
-        (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
-        return true;
-    }
-
-    return false;
-}
-
-void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
-                           std::vector<Matcher>* output) {
-    if (depth > kMaxLogDepth) {
-        ALOGE("depth > 2");
-        return;
-    }
-
-    pos[depth] = matcher.field();
-    mask[depth] = 0x7f;
-
-    if (matcher.has_position()) {
-        depth++;
-        if (depth > 2) {
-            return;
-        }
-        switch (matcher.position()) {
-            case Position::ALL:
-                pos[depth] = 0x00;
-                mask[depth] = 0x7f;
-                break;
-            case Position::ANY:
-                pos[depth] = 0;
-                mask[depth] = 0;
-                break;
-            case Position::FIRST:
-                pos[depth] = 1;
-                mask[depth] = 0x7f;
-                break;
-            case Position::LAST:
-                pos[depth] = 0x80;
-                mask[depth] = 0x80;
-                break;
-            case Position::POSITION_UNKNOWN:
-                pos[depth] = 0;
-                mask[depth] = 0;
-                break;
-        }
-    }
-
-    if (matcher.child_size() == 0) {
-        output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
-    } else {
-        for (const auto& child : matcher.child()) {
-            translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
-        }
-    }
-}
-
-void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
-    int pos[] = {1, 1, 1};
-    int mask[] = {0x7f, 0x7f, 0x7f};
-    int tag = matcher.field();
-    for (const auto& child : matcher.child()) {
-        translateFieldMatcher(tag, child, 0, pos, mask, output);
-    }
-}
-
-bool isAttributionUidField(const FieldValue& value) {
-    return isAttributionUidField(value.mField, value.mValue);
-}
-
-int32_t getUidIfExists(const FieldValue& value) {
-    // the field is uid field if the field is the uid field in attribution node
-    // or annotated as such in the atom
-    bool isUid = isAttributionUidField(value) || isUidField(value);
-    return isUid ? value.mValue.int_value : -1;
-}
-
-bool isAttributionUidField(const Field& field, const Value& value) {
-    int f = field.getField() & 0xff007f;
-    if (f == 0x10001 && value.getType() == INT) {
-        return true;
-    }
-    return false;
-}
-
-bool isUidField(const FieldValue& fieldValue) {
-    return fieldValue.mAnnotations.isUidField();
-}
-
-Value::Value(const Value& from) {
-    type = from.getType();
-    switch (type) {
-        case INT:
-            int_value = from.int_value;
-            break;
-        case LONG:
-            long_value = from.long_value;
-            break;
-        case FLOAT:
-            float_value = from.float_value;
-            break;
-        case DOUBLE:
-            double_value = from.double_value;
-            break;
-        case STRING:
-            str_value = from.str_value;
-            break;
-        case STORAGE:
-            storage_value = from.storage_value;
-            break;
-        default:
-            break;
-    }
-}
-
-std::string Value::toString() const {
-    switch (type) {
-        case INT:
-            return std::to_string(int_value) + "[I]";
-        case LONG:
-            return std::to_string(long_value) + "[L]";
-        case FLOAT:
-            return std::to_string(float_value) + "[F]";
-        case DOUBLE:
-            return std::to_string(double_value) + "[D]";
-        case STRING:
-            return str_value + "[S]";
-        case STORAGE:
-            return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
-        default:
-            return "[UNKNOWN]";
-    }
-}
-
-bool Value::isZero() const {
-    switch (type) {
-        case INT:
-            return int_value == 0;
-        case LONG:
-            return long_value == 0;
-        case FLOAT:
-            return fabs(float_value) <= std::numeric_limits<float>::epsilon();
-        case DOUBLE:
-            return fabs(double_value) <= std::numeric_limits<double>::epsilon();
-        case STRING:
-            return str_value.size() == 0;
-        case STORAGE:
-            return storage_value.size() == 0;
-        default:
-            return false;
-    }
-}
-
-bool Value::operator==(const Value& that) const {
-    if (type != that.getType()) return false;
-
-    switch (type) {
-        case INT:
-            return int_value == that.int_value;
-        case LONG:
-            return long_value == that.long_value;
-        case FLOAT:
-            return float_value == that.float_value;
-        case DOUBLE:
-            return double_value == that.double_value;
-        case STRING:
-            return str_value == that.str_value;
-        case STORAGE:
-            return storage_value == that.storage_value;
-        default:
-            return false;
-    }
-}
-
-bool Value::operator!=(const Value& that) const {
-    if (type != that.getType()) return true;
-    switch (type) {
-        case INT:
-            return int_value != that.int_value;
-        case LONG:
-            return long_value != that.long_value;
-        case FLOAT:
-            return float_value != that.float_value;
-        case DOUBLE:
-            return double_value != that.double_value;
-        case STRING:
-            return str_value != that.str_value;
-        case STORAGE:
-            return storage_value != that.storage_value;
-        default:
-            return false;
-    }
-}
-
-bool Value::operator<(const Value& that) const {
-    if (type != that.getType()) return type < that.getType();
-
-    switch (type) {
-        case INT:
-            return int_value < that.int_value;
-        case LONG:
-            return long_value < that.long_value;
-        case FLOAT:
-            return float_value < that.float_value;
-        case DOUBLE:
-            return double_value < that.double_value;
-        case STRING:
-            return str_value < that.str_value;
-        case STORAGE:
-            return storage_value < that.storage_value;
-        default:
-            return false;
-    }
-}
-
-bool Value::operator>(const Value& that) const {
-    if (type != that.getType()) return type > that.getType();
-
-    switch (type) {
-        case INT:
-            return int_value > that.int_value;
-        case LONG:
-            return long_value > that.long_value;
-        case FLOAT:
-            return float_value > that.float_value;
-        case DOUBLE:
-            return double_value > that.double_value;
-        case STRING:
-            return str_value > that.str_value;
-        case STORAGE:
-            return storage_value > that.storage_value;
-        default:
-            return false;
-    }
-}
-
-bool Value::operator>=(const Value& that) const {
-    if (type != that.getType()) return type >= that.getType();
-
-    switch (type) {
-        case INT:
-            return int_value >= that.int_value;
-        case LONG:
-            return long_value >= that.long_value;
-        case FLOAT:
-            return float_value >= that.float_value;
-        case DOUBLE:
-            return double_value >= that.double_value;
-        case STRING:
-            return str_value >= that.str_value;
-        case STORAGE:
-            return storage_value >= that.storage_value;
-        default:
-            return false;
-    }
-}
-
-Value Value::operator-(const Value& that) const {
-    Value v;
-    if (type != that.type) {
-        ALOGE("Can't operate on different value types, %d, %d", type, that.type);
-        return v;
-    }
-    if (type == STRING) {
-        ALOGE("Can't operate on string value type");
-        return v;
-    }
-
-    if (type == STORAGE) {
-        ALOGE("Can't operate on storage value type");
-        return v;
-    }
-
-    switch (type) {
-        case INT:
-            v.setInt(int_value - that.int_value);
-            break;
-        case LONG:
-            v.setLong(long_value - that.long_value);
-            break;
-        case FLOAT:
-            v.setFloat(float_value - that.float_value);
-            break;
-        case DOUBLE:
-            v.setDouble(double_value - that.double_value);
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-
-Value& Value::operator=(const Value& that) {
-    type = that.type;
-    switch (type) {
-        case INT:
-            int_value = that.int_value;
-            break;
-        case LONG:
-            long_value = that.long_value;
-            break;
-        case FLOAT:
-            float_value = that.float_value;
-            break;
-        case DOUBLE:
-            double_value = that.double_value;
-            break;
-        case STRING:
-            str_value = that.str_value;
-            break;
-        case STORAGE:
-            storage_value = that.storage_value;
-            break;
-        default:
-            break;
-    }
-    return *this;
-}
-
-Value& Value::operator+=(const Value& that) {
-    if (type != that.type) {
-        ALOGE("Can't operate on different value types, %d, %d", type, that.type);
-        return *this;
-    }
-    if (type == STRING) {
-        ALOGE("Can't operate on string value type");
-        return *this;
-    }
-    if (type == STORAGE) {
-        ALOGE("Can't operate on storage value type");
-        return *this;
-    }
-
-    switch (type) {
-        case INT:
-            int_value += that.int_value;
-            break;
-        case LONG:
-            long_value += that.long_value;
-            break;
-        case FLOAT:
-            float_value += that.float_value;
-            break;
-        case DOUBLE:
-            double_value += that.double_value;
-            break;
-        default:
-            break;
-    }
-    return *this;
-}
-
-double Value::getDouble() const {
-    switch (type) {
-        case INT:
-            return int_value;
-        case LONG:
-            return long_value;
-        case FLOAT:
-            return float_value;
-        case DOUBLE:
-            return double_value;
-        default:
-            return 0;
-    }
-}
-
-bool equalDimensions(const std::vector<Matcher>& dimension_a,
-                     const std::vector<Matcher>& dimension_b) {
-    bool eq = dimension_a.size() == dimension_b.size();
-    for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
-        if (dimension_b[i] != dimension_a[i]) {
-            eq = false;
-        }
-    }
-    return eq;
-}
-
-bool subsetDimensions(const std::vector<Matcher>& dimension_a,
-                      const std::vector<Matcher>& dimension_b) {
-    if (dimension_a.size() > dimension_b.size()) {
-        return false;
-    }
-    for (size_t i = 0; i < dimension_a.size(); ++i) {
-        bool found = false;
-        for (size_t j = 0; j < dimension_b.size(); ++j) {
-            if (dimension_a[i] == dimension_b[j]) {
-                found = true;
-            }
-        }
-        if (!found) {
-            return false;
-        }
-    }
-    return true;
-}
-
-bool HasPositionANY(const FieldMatcher& matcher) {
-    if (matcher.has_position() && matcher.position() == Position::ANY) {
-        return true;
-    }
-    for (const auto& child : matcher.child()) {
-        if (HasPositionANY(child)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool HasPositionALL(const FieldMatcher& matcher) {
-    if (matcher.has_position() && matcher.position() == Position::ALL) {
-        return true;
-    }
-    for (const auto& child : matcher.child()) {
-        if (HasPositionALL(child)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
deleted file mode 100644
index fd86e36..0000000
--- a/cmds/statsd/src/FieldValue.h
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "annotations.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class HashableDimensionKey;
-struct Matcher;
-struct Field;
-struct FieldValue;
-
-const int32_t kMaxLogDepth = 2;
-const int32_t kLastBitMask = 0x80;
-const int32_t kClearLastBitDeco = 0x7f;
-const int32_t kClearAllPositionMatcherMask = 0xffff00ff;
-
-enum Type { UNKNOWN, INT, LONG, FLOAT, DOUBLE, STRING, STORAGE };
-
-int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);
-
-int32_t encodeMatcherMask(int32_t mask[], int32_t depth);
-
-// Get the encoded field for a leaf with a [field] number at depth 0;
-inline int32_t getSimpleField(size_t field) {
-    return ((int32_t)field << 8 * 2);
-}
-
-/**
- * Field is a wrapper class for 2 integers that represents the field of a log element in its Atom
- * proto.
- * [mTag]: the atom id.
- * [mField]: encoded path from the root (atom) to leaf.
- *
- * For example:
- * WakeLockStateChanged {
- *    repeated AttributionNode = 1;
- *    int state = 2;
- *    string tag = 3;
- * }
- * Read from logd, the items are structured as below:
- * [[[1000, "tag"], [2000, "tag2"],], 2,"hello"]
- *
- * When we read through the list, we will encode each field in a 32bit integer.
- * 8bit segments   |--------|--------|--------|--------|
- *                    Depth   field0 [L]field1 [L]field1
- *
- *  The first 8 bits are the depth of the field. for example, the uid 1000 has depth 2.
- *  The following 3 8-bit are for the item's position at each level.
- *  The first bit of each 8bits field is reserved to mark if the item is the last item at that level
- *  this is to make matching easier later.
- *
- *  The above wakelock event is translated into FieldValue pairs.
- *  0x02010101->1000
- *  0x02010182->tag
- *  0x02018201->2000
- *  0x02018282->tag2
- *  0x00020000->2
- *  0x00030000->"hello"
- *
- *  This encoding is the building block for the later operations.
- *  Please see the definition for Matcher below to see how the matching is done.
- */
-struct Field {
-private:
-    int32_t mTag;
-    int32_t mField;
-
-public:
-    Field() {}
-
-    Field(int32_t tag, int32_t pos[], int32_t depth) : mTag(tag) {
-        mField = getEncodedField(pos, depth, true);
-    }
-
-    Field(const Field& from) : mTag(from.getTag()), mField(from.getField()) {
-    }
-
-    Field(int32_t tag, int32_t field) : mTag(tag), mField(field){};
-
-    inline void setField(int32_t field) {
-        mField = field;
-    }
-
-    inline void setTag(int32_t tag) {
-        mTag = tag;
-    }
-
-    inline void decorateLastPos(int32_t depth) {
-        int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
-        mField |= mask;
-    }
-
-    inline int32_t getTag() const {
-        return mTag;
-    }
-
-    inline int32_t getDepth() const {
-        return (mField >> 24);
-    }
-
-    inline int32_t getPath(int32_t depth) const {
-        if (depth > 2 || depth < 0) return 0;
-
-        int32_t field = (mField & 0x00ffffff);
-        int32_t mask = 0xffffffff;
-        return (field & (mask << 8 * (kMaxLogDepth - depth)));
-    }
-
-    inline int32_t getPrefix(int32_t depth) const {
-        if (depth == 0) return 0;
-        return getPath(depth - 1);
-    }
-
-    inline int32_t getField() const {
-        return mField;
-    }
-
-    inline int32_t getRawPosAtDepth(int32_t depth) const {
-        int32_t field = (mField & 0x00ffffff);
-        int32_t shift = 8 * (kMaxLogDepth - depth);
-        int32_t mask = 0xff << shift;
-
-        return (field & mask) >> shift;
-    }
-
-    inline int32_t getPosAtDepth(int32_t depth) const {
-        return getRawPosAtDepth(depth) & kClearLastBitDeco;
-    }
-
-    // Check if the first bit of the 8-bit segment for depth is 1
-    inline bool isLastPos(int32_t depth) const {
-        int32_t field = (mField & 0x00ffffff);
-        int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
-        return (field & mask) != 0;
-    }
-
-    // if the 8-bit segment is all 0's
-    inline bool isAnyPosMatcher(int32_t depth) const {
-        return getDepth() >= depth && getRawPosAtDepth(depth) == 0;
-    }
-    // if the 8bit is 0x80 (1000 0000)
-    inline bool isLastPosMatcher(int32_t depth) const {
-        return getDepth() >= depth && getRawPosAtDepth(depth) == kLastBitMask;
-    }
-
-    inline bool operator==(const Field& that) const {
-        return mTag == that.getTag() && mField == that.getField();
-    };
-
-    inline bool operator!=(const Field& that) const {
-        return mTag != that.getTag() || mField != that.getField();
-    };
-
-    bool operator<(const Field& that) const {
-        if (mTag != that.getTag()) {
-            return mTag < that.getTag();
-        }
-
-        if (mField != that.getField()) {
-            return mField < that.getField();
-        }
-
-        return false;
-    }
-
-    bool matches(const Matcher& that) const;
-};
-
-/**
- * Matcher represents a leaf matcher in the FieldMatcher in statsd_config.
- *
- * It contains all information needed to match one or more leaf node.
- * All information is encoded in a Field(2 ints) and a bit mask(1 int).
- *
- * For example, to match the first/any/last uid field in attribution chain in Atom 10,
- * we have the following FieldMatcher in statsd_config
- *    FieldMatcher {
- *        field:10
- *         FieldMatcher {
- *              field:1
- *              position: any/last/first
- *              FieldMatcher {
- *                  field:1
- *              }
- *          }
- *     }
- *
- * We translate the FieldMatcher into a Field, and mask
- * First: [Matcher Field] 0x02010101  [Mask]0xff7f7f7f
- * Last:  [Matcher Field] 0x02018001  [Mask]0xff7f807f
- * Any:   [Matcher Field] 0x02010001  [Mask]0xff7f007f
- * All:   [Matcher Field] 0x02010001  [Mask]0xff7f7f7f
- *
- * [To match a log Field with a Matcher] we apply the bit mask to the log Field and check if
- * the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are
- * equal. Nothing can beat the performance of this matching algorithm.
- *
- * TODO(b/110561213): ADD EXAMPLE HERE.
- */
-struct Matcher {
-    Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){};
-
-    const Field mMatcher;
-    const int32_t mMask;
-
-    inline const Field& getMatcher() const {
-        return mMatcher;
-    }
-
-    inline int32_t getMask() const {
-        return mMask;
-    }
-
-    inline int32_t getRawMaskAtDepth(int32_t depth) const {
-        int32_t field = (mMask & 0x00ffffff);
-        int32_t shift = 8 * (kMaxLogDepth - depth);
-        int32_t mask = 0xff << shift;
-
-        return (field & mask) >> shift;
-    }
-
-    bool hasAllPositionMatcher() const {
-        return mMatcher.getDepth() == 2 && getRawMaskAtDepth(1) == 0x7f;
-    }
-
-    bool hasAnyPositionMatcher(int* prefix) const {
-        if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(1) == 0) {
-            (*prefix) = mMatcher.getPrefix(1);
-            return true;
-        }
-        return false;
-    }
-
-    inline bool operator!=(const Matcher& that) const {
-        return mMatcher != that.getMatcher() || mMask != that.getMask();
-    }
-
-    inline bool operator==(const Matcher& that) const {
-        return mMatcher == that.mMatcher && mMask == that.mMask;
-    }
-};
-
-inline Matcher getSimpleMatcher(int32_t tag, size_t field) {
-    return Matcher(Field(tag, getSimpleField(field)), 0xff7f0000);
-}
-
-inline Matcher getFirstUidMatcher(int32_t atomId) {
-    int32_t pos[] = {1, 1, 1};
-    return Matcher(Field(atomId, pos, 2), 0xff7f7f7f);
-}
-
-/**
- * A wrapper for a union type to contain multiple types of values.
- *
- */
-struct Value {
-    Value() : type(UNKNOWN) {}
-
-    Value(int32_t v) {
-        int_value = v;
-        type = INT;
-    }
-
-    Value(int64_t v) {
-        long_value = v;
-        type = LONG;
-    }
-
-    Value(float v) {
-        float_value = v;
-        type = FLOAT;
-    }
-
-    Value(double v) {
-        double_value = v;
-        type = DOUBLE;
-    }
-
-    Value(const std::string& v) {
-        str_value = v;
-        type = STRING;
-    }
-
-    Value(const std::vector<uint8_t>& v) {
-        storage_value = v;
-        type = STORAGE;
-    }
-
-    void setInt(int32_t v) {
-        int_value = v;
-        type = INT;
-    }
-
-    void setLong(int64_t v) {
-        long_value = v;
-        type = LONG;
-    }
-
-    void setFloat(float v) {
-        float_value = v;
-        type = FLOAT;
-    }
-
-    void setDouble(double v) {
-        double_value = v;
-        type = DOUBLE;
-    }
-
-    union {
-        int32_t int_value;
-        int64_t long_value;
-        float float_value;
-        double double_value;
-    };
-    std::string str_value;
-    std::vector<uint8_t> storage_value;
-
-    Type type;
-
-    std::string toString() const;
-
-    bool isZero() const;
-
-    Type getType() const {
-        return type;
-    }
-
-    double getDouble() const;
-
-    Value(const Value& from);
-
-    bool operator==(const Value& that) const;
-    bool operator!=(const Value& that) const;
-
-    bool operator<(const Value& that) const;
-    bool operator>(const Value& that) const;
-    bool operator>=(const Value& that) const;
-    Value operator-(const Value& that) const;
-    Value& operator+=(const Value& that);
-    Value& operator=(const Value& that);
-};
-
-class Annotations {
-public:
-    Annotations() {
-        setNested(true);  // Nested = true by default
-    }
-
-    // This enum stores where particular annotations can be found in the
-    // bitmask. Note that these pos do not correspond to annotation ids.
-    enum {
-        NESTED_POS = 0x0,
-        PRIMARY_POS = 0x1,
-        EXCLUSIVE_POS = 0x2,
-        UID_POS = 0x3
-    };
-
-    inline void setNested(bool nested) { setBitmaskAtPos(NESTED_POS, nested); }
-
-    inline void setPrimaryField(bool primary) { setBitmaskAtPos(PRIMARY_POS, primary); }
-
-    inline void setExclusiveState(bool exclusive) { setBitmaskAtPos(EXCLUSIVE_POS, exclusive); }
-
-    inline void setUidField(bool isUid) { setBitmaskAtPos(UID_POS, isUid); }
-
-    // Default value = false
-    inline bool isNested() const { return getValueFromBitmask(NESTED_POS); }
-
-    // Default value = false
-    inline bool isPrimaryField() const { return getValueFromBitmask(PRIMARY_POS); }
-
-    // Default value = false
-    inline bool isExclusiveState() const { return getValueFromBitmask(EXCLUSIVE_POS); }
-
-    // Default value = false
-    inline bool isUidField() const { return getValueFromBitmask(UID_POS); }
-
-private:
-    inline void setBitmaskAtPos(int pos, bool value) {
-        mBooleanBitmask &= ~(1 << pos); // clear
-        mBooleanBitmask |= (value << pos); // set
-    }
-
-    inline bool getValueFromBitmask(int pos) const {
-        return (mBooleanBitmask >> pos) & 0x1;
-    }
-
-    // This is a bitmask over all annotations stored in boolean form. Because
-    // there are only 4 booleans, just one byte is required.
-    uint8_t mBooleanBitmask = 0;
-};
-
-/**
- * Represents a log item, or a dimension item (They are essentially the same).
- */
-struct FieldValue {
-    FieldValue() {}
-    FieldValue(const Field& field, const Value& value) : mField(field), mValue(value) {
-    }
-    bool operator==(const FieldValue& that) const {
-        return mField == that.mField && mValue == that.mValue;
-    }
-    bool operator!=(const FieldValue& that) const {
-        return mField != that.mField || mValue != that.mValue;
-    }
-    bool operator<(const FieldValue& that) const {
-        if (mField != that.mField) {
-            return mField < that.mField;
-        }
-
-        if (mValue != that.mValue) {
-            return mValue < that.mValue;
-        }
-
-        return false;
-    }
-
-    Field mField;
-    Value mValue;
-    Annotations mAnnotations;
-};
-
-bool HasPositionANY(const FieldMatcher& matcher);
-bool HasPositionALL(const FieldMatcher& matcher);
-
-bool isAttributionUidField(const FieldValue& value);
-
-/* returns uid if the field is uid field, or -1 if the field is not a uid field */
-int getUidIfExists(const FieldValue& value);
-
-void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output);
-
-bool isAttributionUidField(const Field& field, const Value& value);
-bool isUidField(const FieldValue& fieldValue);
-
-bool equalDimensions(const std::vector<Matcher>& dimension_a,
-                     const std::vector<Matcher>& dimension_b);
-
-// Returns true if dimension_a is a subset of dimension_b.
-bool subsetDimensions(const std::vector<Matcher>& dimension_a,
-                      const std::vector<Matcher>& dimension_b);
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
deleted file mode 100644
index eba66e0..0000000
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "HashableDimensionKey.h"
-#include "FieldValue.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::string;
-using std::vector;
-using android::base::StringPrintf;
-
-// These constants must be kept in sync with those in StatsDimensionsValue.java
-const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
-const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3;
-const static int STATS_DIMENSIONS_VALUE_LONG_TYPE = 4;
-// const static int STATS_DIMENSIONS_VALUE_BOOL_TYPE = 5; (commented out because
-// unused -- statsd does not correctly support bool types)
-const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6;
-const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7;
-
-/**
- * Recursive helper function that populates a parent StatsDimensionsValueParcel
- * with children StatsDimensionsValueParcels.
- *
- * \param parent parcel that will be populated with children
- * \param childDepth depth of children FieldValues
- * \param childPrefix expected FieldValue prefix of children
- * \param dims vector of FieldValues stored by HashableDimensionKey
- * \param index position in dims to start reading children from
- */
-static void populateStatsDimensionsValueParcelChildren(StatsDimensionsValueParcel& parent,
-                                                       int childDepth, int childPrefix,
-                                                       const vector<FieldValue>& dims,
-                                                       size_t& index) {
-    if (childDepth > 2) {
-        ALOGE("Depth > 2 not supported by StatsDimensionsValueParcel.");
-        return;
-    }
-
-    while (index < dims.size()) {
-        const FieldValue& dim = dims[index];
-        int fieldDepth = dim.mField.getDepth();
-        int fieldPrefix = dim.mField.getPrefix(childDepth);
-
-        StatsDimensionsValueParcel child;
-        child.field = dim.mField.getPosAtDepth(childDepth);
-
-        if (fieldDepth == childDepth && fieldPrefix == childPrefix) {
-            switch (dim.mValue.getType()) {
-                case INT:
-                    child.valueType = STATS_DIMENSIONS_VALUE_INT_TYPE;
-                    child.intValue = dim.mValue.int_value;
-                    break;
-                case LONG:
-                    child.valueType = STATS_DIMENSIONS_VALUE_LONG_TYPE;
-                    child.longValue = dim.mValue.long_value;
-                    break;
-                case FLOAT:
-                    child.valueType = STATS_DIMENSIONS_VALUE_FLOAT_TYPE;
-                    child.floatValue = dim.mValue.float_value;
-                    break;
-                case STRING:
-                    child.valueType = STATS_DIMENSIONS_VALUE_STRING_TYPE;
-                    child.stringValue = dim.mValue.str_value;
-                    break;
-                default:
-                    ALOGE("Encountered FieldValue with unsupported value type.");
-                    break;
-            }
-            index++;
-            parent.tupleValue.push_back(child);
-        } else if (fieldDepth > childDepth && fieldPrefix == childPrefix) {
-            // This FieldValue is not a child of the current parent, but it is
-            // an indirect descendant. Thus, create a direct child of TUPLE_TYPE
-            // and recurse to parcel the indirect descendants.
-            child.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
-            populateStatsDimensionsValueParcelChildren(child, childDepth + 1,
-                                                       dim.mField.getPrefix(childDepth + 1), dims,
-                                                       index);
-            parent.tupleValue.push_back(child);
-        } else {
-            return;
-        }
-    }
-}
-
-StatsDimensionsValueParcel HashableDimensionKey::toStatsDimensionsValueParcel() const {
-    StatsDimensionsValueParcel root;
-    if (mValues.size() == 0) {
-        return root;
-    }
-
-    root.field = mValues[0].mField.getTag();
-    root.valueType = STATS_DIMENSIONS_VALUE_TUPLE_TYPE;
-
-    // Children of the root correspond to top-level (depth = 0) FieldValues.
-    int childDepth = 0;
-    int childPrefix = 0;
-    size_t index = 0;
-    populateStatsDimensionsValueParcelChildren(root, childDepth, childPrefix, mValues, index);
-
-    return root;
-}
-
-android::hash_t hashDimension(const HashableDimensionKey& value) {
-    android::hash_t hash = 0;
-    for (const auto& fieldValue : value.getValues()) {
-        hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mField.getField()));
-        hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mField.getTag()));
-        hash = android::JenkinsHashMix(hash, android::hash_type((int)fieldValue.mValue.getType()));
-        switch (fieldValue.mValue.getType()) {
-            case INT:
-                hash = android::JenkinsHashMix(hash,
-                                               android::hash_type(fieldValue.mValue.int_value));
-                break;
-            case LONG:
-                hash = android::JenkinsHashMix(hash,
-                                               android::hash_type(fieldValue.mValue.long_value));
-                break;
-            case STRING:
-                hash = android::JenkinsHashMix(hash, static_cast<uint32_t>(std::hash<std::string>()(
-                                                             fieldValue.mValue.str_value)));
-                break;
-            case FLOAT: {
-                hash = android::JenkinsHashMix(hash,
-                                               android::hash_type(fieldValue.mValue.float_value));
-                break;
-            }
-            default:
-                break;
-        }
-    }
-    return JenkinsHashWhiten(hash);
-}
-
-bool filterValues(const Matcher& matcherField, const vector<FieldValue>& values,
-                  FieldValue* output) {
-    for (const auto& value : values) {
-        if (value.mField.matches(matcherField)) {
-            (*output) = value;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool filterValues(const vector<Matcher>& matcherFields, const vector<FieldValue>& values,
-                  HashableDimensionKey* output) {
-    size_t num_matches = 0;
-    for (const auto& value : values) {
-        for (size_t i = 0; i < matcherFields.size(); ++i) {
-            const auto& matcher = matcherFields[i];
-            if (value.mField.matches(matcher)) {
-                output->addValue(value);
-                output->mutableValue(num_matches)->mField.setTag(value.mField.getTag());
-                output->mutableValue(num_matches)->mField.setField(
-                    value.mField.getField() & matcher.mMask);
-                num_matches++;
-            }
-        }
-    }
-    return num_matches > 0;
-}
-
-bool filterPrimaryKey(const std::vector<FieldValue>& values, HashableDimensionKey* output) {
-    size_t num_matches = 0;
-    const int32_t simpleFieldMask = 0xff7f0000;
-    const int32_t attributionUidFieldMask = 0xff7f7f7f;
-    for (const auto& value : values) {
-        if (value.mAnnotations.isPrimaryField()) {
-            output->addValue(value);
-            output->mutableValue(num_matches)->mField.setTag(value.mField.getTag());
-            const int32_t mask =
-                    isAttributionUidField(value) ? attributionUidFieldMask : simpleFieldMask;
-            output->mutableValue(num_matches)->mField.setField(value.mField.getField() & mask);
-            num_matches++;
-        }
-    }
-    return num_matches > 0;
-}
-
-void filterGaugeValues(const std::vector<Matcher>& matcherFields,
-                       const std::vector<FieldValue>& values, std::vector<FieldValue>* output) {
-    for (const auto& field : matcherFields) {
-        for (const auto& value : values) {
-            if (value.mField.matches(field)) {
-                output->push_back(value);
-            }
-        }
-    }
-}
-
-void getDimensionForCondition(const std::vector<FieldValue>& eventValues,
-                              const Metric2Condition& links,
-                              HashableDimensionKey* conditionDimension) {
-    // Get the dimension first by using dimension from what.
-    filterValues(links.metricFields, eventValues, conditionDimension);
-
-    size_t count = conditionDimension->getValues().size();
-    if (count != links.conditionFields.size()) {
-        return;
-    }
-
-    for (size_t i = 0; i < count; i++) {
-        conditionDimension->mutableValue(i)->mField.setField(
-                links.conditionFields[i].mMatcher.getField());
-        conditionDimension->mutableValue(i)->mField.setTag(
-                links.conditionFields[i].mMatcher.getTag());
-    }
-}
-
-void getDimensionForState(const std::vector<FieldValue>& eventValues, const Metric2State& link,
-                          HashableDimensionKey* statePrimaryKey) {
-    // First, get the dimension from the event using the "what" fields from the
-    // MetricStateLinks.
-    filterValues(link.metricFields, eventValues, statePrimaryKey);
-
-    // Then check that the statePrimaryKey size equals the number of state fields
-    size_t count = statePrimaryKey->getValues().size();
-    if (count != link.stateFields.size()) {
-        return;
-    }
-
-    // For each dimension Value in the statePrimaryKey, set the field and tag
-    // using the state atom fields from MetricStateLinks.
-    for (size_t i = 0; i < count; i++) {
-        statePrimaryKey->mutableValue(i)->mField.setField(link.stateFields[i].mMatcher.getField());
-        statePrimaryKey->mutableValue(i)->mField.setTag(link.stateFields[i].mMatcher.getTag());
-    }
-}
-
-bool containsLinkedStateValues(const HashableDimensionKey& whatKey,
-                               const HashableDimensionKey& primaryKey,
-                               const vector<Metric2State>& stateLinks, const int32_t stateAtomId) {
-    if (whatKey.getValues().size() < primaryKey.getValues().size()) {
-        ALOGE("Contains linked values false: whatKey is too small");
-        return false;
-    }
-
-    for (const auto& primaryValue : primaryKey.getValues()) {
-        bool found = false;
-        for (const auto& whatValue : whatKey.getValues()) {
-            if (linked(stateLinks, stateAtomId, primaryValue.mField, whatValue.mField) &&
-                primaryValue.mValue == whatValue.mValue) {
-                found = true;
-                break;
-            }
-        }
-        if (!found) {
-            return false;
-        }
-    }
-    return true;
-}
-
-bool linked(const vector<Metric2State>& stateLinks, const int32_t stateAtomId,
-            const Field& stateField, const Field& metricField) {
-    for (auto stateLink : stateLinks) {
-        if (stateLink.stateAtomId != stateAtomId) {
-            continue;
-        }
-
-        for (size_t i = 0; i < stateLink.stateFields.size(); i++) {
-            if (stateLink.stateFields[i].mMatcher == stateField &&
-                stateLink.metricFields[i].mMatcher == metricField) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-bool LessThan(const vector<FieldValue>& s1, const vector<FieldValue>& s2) {
-    if (s1.size() != s2.size()) {
-        return s1.size() < s2.size();
-    }
-
-    size_t count = s1.size();
-    for (size_t i = 0; i < count; i++) {
-        if (s1[i] != s2[i]) {
-            return s1[i] < s2[i];
-        }
-    }
-    return false;
-}
-
-bool HashableDimensionKey::operator!=(const HashableDimensionKey& that) const {
-    return !((*this) == that);
-}
-
-bool HashableDimensionKey::operator==(const HashableDimensionKey& that) const {
-    if (mValues.size() != that.getValues().size()) {
-        return false;
-    }
-    size_t count = mValues.size();
-    for (size_t i = 0; i < count; i++) {
-        if (mValues[i] != (that.getValues())[i]) {
-            return false;
-        }
-    }
-    return true;
-};
-
-bool HashableDimensionKey::operator<(const HashableDimensionKey& that) const {
-    return LessThan(getValues(), that.getValues());
-};
-
-bool HashableDimensionKey::contains(const HashableDimensionKey& that) const {
-    if (mValues.size() < that.getValues().size()) {
-        return false;
-    }
-
-    if (mValues.size() == that.getValues().size()) {
-        return (*this) == that;
-    }
-
-    for (const auto& value : that.getValues()) {
-        bool found = false;
-        for (const auto& myValue : mValues) {
-            if (value.mField == myValue.mField && value.mValue == myValue.mValue) {
-                found = true;
-                break;
-            }
-        }
-        if (!found) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-string HashableDimensionKey::toString() const {
-    std::string output;
-    for (const auto& value : mValues) {
-        output += StringPrintf("(%d)%#x->%s ", value.mField.getTag(), value.mField.getField(),
-                               value.mValue.toString().c_str());
-    }
-    return output;
-}
-
-bool MetricDimensionKey::operator==(const MetricDimensionKey& that) const {
-    return mDimensionKeyInWhat == that.getDimensionKeyInWhat() &&
-           mStateValuesKey == that.getStateValuesKey();
-};
-
-string MetricDimensionKey::toString() const {
-    return mDimensionKeyInWhat.toString() + mStateValuesKey.toString();
-}
-
-bool MetricDimensionKey::operator<(const MetricDimensionKey& that) const {
-    if (mDimensionKeyInWhat < that.getDimensionKeyInWhat()) {
-        return true;
-    } else if (that.getDimensionKeyInWhat() < mDimensionKeyInWhat) {
-        return false;
-    }
-
-    return mStateValuesKey < that.getStateValuesKey();
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h
deleted file mode 100644
index bd01100..0000000
--- a/cmds/statsd/src/HashableDimensionKey.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <aidl/android/os/StatsDimensionsValueParcel.h>
-#include <utils/JenkinsHash.h>
-#include <vector>
-#include "android-base/stringprintf.h"
-#include "FieldValue.h"
-#include "logd/LogEvent.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using ::aidl::android::os::StatsDimensionsValueParcel;
-
-struct Metric2Condition {
-    int64_t conditionId;
-    std::vector<Matcher> metricFields;
-    std::vector<Matcher> conditionFields;
-};
-
-struct Metric2State {
-    int32_t stateAtomId;
-    std::vector<Matcher> metricFields;
-    std::vector<Matcher> stateFields;
-};
-
-class HashableDimensionKey {
-public:
-    explicit HashableDimensionKey(const std::vector<FieldValue>& values) {
-        mValues = values;
-    }
-
-    HashableDimensionKey() {};
-
-    HashableDimensionKey(const HashableDimensionKey& that) : mValues(that.getValues()){};
-
-    inline void addValue(const FieldValue& value) {
-        mValues.push_back(value);
-    }
-
-    inline const std::vector<FieldValue>& getValues() const {
-        return mValues;
-    }
-
-    inline std::vector<FieldValue>* mutableValues() {
-        return &mValues;
-    }
-
-    inline FieldValue* mutableValue(size_t i) {
-        if (i >= 0 && i < mValues.size()) {
-            return &(mValues[i]);
-        }
-        return nullptr;
-    }
-
-    StatsDimensionsValueParcel toStatsDimensionsValueParcel() const;
-
-    std::string toString() const;
-
-    bool operator!=(const HashableDimensionKey& that) const;
-
-    bool operator==(const HashableDimensionKey& that) const;
-
-    bool operator<(const HashableDimensionKey& that) const;
-
-    bool contains(const HashableDimensionKey& that) const;
-
-private:
-    std::vector<FieldValue> mValues;
-};
-
-class MetricDimensionKey {
-public:
-    explicit MetricDimensionKey(const HashableDimensionKey& dimensionKeyInWhat,
-                                const HashableDimensionKey& stateValuesKey)
-        : mDimensionKeyInWhat(dimensionKeyInWhat), mStateValuesKey(stateValuesKey){};
-
-    MetricDimensionKey(){};
-
-    MetricDimensionKey(const MetricDimensionKey& that)
-        : mDimensionKeyInWhat(that.getDimensionKeyInWhat()),
-          mStateValuesKey(that.getStateValuesKey()){};
-
-    MetricDimensionKey& operator=(const MetricDimensionKey& from) = default;
-
-    std::string toString() const;
-
-    inline const HashableDimensionKey& getDimensionKeyInWhat() const {
-        return mDimensionKeyInWhat;
-    }
-
-    inline const HashableDimensionKey& getStateValuesKey() const {
-        return mStateValuesKey;
-    }
-
-    inline HashableDimensionKey* getMutableStateValuesKey() {
-        return &mStateValuesKey;
-    }
-
-    inline void setStateValuesKey(const HashableDimensionKey& key) {
-        mStateValuesKey = key;
-    }
-
-    bool hasStateValuesKey() const {
-        return mStateValuesKey.getValues().size() > 0;
-    }
-
-    bool operator==(const MetricDimensionKey& that) const;
-
-    bool operator<(const MetricDimensionKey& that) const;
-
-private:
-    HashableDimensionKey mDimensionKeyInWhat;
-    HashableDimensionKey mStateValuesKey;
-};
-
-android::hash_t hashDimension(const HashableDimensionKey& key);
-
-/**
- * Returns true if a FieldValue field matches the matcher field.
- * The value of the FieldValue is output.
- */
-bool filterValues(const Matcher& matcherField, const std::vector<FieldValue>& values,
-                  FieldValue* output);
-
-/**
- * Creating HashableDimensionKeys from FieldValues using matcher.
- *
- * This function may make modifications to the Field if the matcher has Position=FIRST,LAST or ALL
- * in it. This is because: for example, when we create dimension from last uid in attribution chain,
- * In one event, uid 1000 is at position 5 and it's the last
- * In another event, uid 1000 is at position 6, and it's the last
- * these 2 events should be mapped to the same dimension.  So we will remove the original position
- * from the dimension key for the uid field (by applying 0x80 bit mask).
- */
-bool filterValues(const std::vector<Matcher>& matcherFields, const std::vector<FieldValue>& values,
-                  HashableDimensionKey* output);
-
-/**
- * Creating HashableDimensionKeys from State Primary Keys in FieldValues.
- *
- * This function may make modifications to the Field if the matcher has Position=FIRST,LAST or ALL
- * in it. This is because: for example, when we create dimension from last uid in attribution chain,
- * In one event, uid 1000 is at position 5 and it's the last
- * In another event, uid 1000 is at position 6, and it's the last
- * these 2 events should be mapped to the same dimension.  So we will remove the original position
- * from the dimension key for the uid field (by applying 0x80 bit mask).
- */
-bool filterPrimaryKey(const std::vector<FieldValue>& values, HashableDimensionKey* output);
-
-/**
- * Filter the values from FieldValues using the matchers.
- *
- * In contrast to the above function, this function will not do any modification to the original
- * data. Considering it as taking a snapshot on the atom event.
- */
-void filterGaugeValues(const std::vector<Matcher>& matchers, const std::vector<FieldValue>& values,
-                       std::vector<FieldValue>* output);
-
-void getDimensionForCondition(const std::vector<FieldValue>& eventValues,
-                              const Metric2Condition& links,
-                              HashableDimensionKey* conditionDimension);
-
-/**
- * Get dimension values using metric's "what" fields and fill statePrimaryKey's
- * mField information using "state" fields.
- */
-void getDimensionForState(const std::vector<FieldValue>& eventValues, const Metric2State& link,
-                          HashableDimensionKey* statePrimaryKey);
-
-/**
- * Returns true if the primaryKey values are a subset of the whatKey values.
- * The values from the primaryKey come from the state atom, so we need to
- * check that a link exists between the state atom field and what atom field.
- *
- * Example:
- * whatKey = [Atom: 10, {uid: 1005, wakelock_name: "compose"}]
- * statePrimaryKey = [Atom: 27, {uid: 1005}]
- * Returns true IF one of the Metric2State links Atom 10's uid to Atom 27's uid
- *
- * Example:
- * whatKey = [Atom: 10, {uid: 1005, wakelock_name: "compose"}]
- * statePrimaryKey = [Atom: 59, {uid: 1005, package_name: "system"}]
- * Returns false
- */
-bool containsLinkedStateValues(const HashableDimensionKey& whatKey,
-                               const HashableDimensionKey& primaryKey,
-                               const std::vector<Metric2State>& stateLinks,
-                               const int32_t stateAtomId);
-
-/**
- * Returns true if there is a Metric2State link that links the stateField and
- * the metricField (they are equal fields from different atoms).
- */
-bool linked(const std::vector<Metric2State>& stateLinks, const int32_t stateAtomId,
-            const Field& stateField, const Field& metricField);
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-namespace std {
-
-using android::os::statsd::HashableDimensionKey;
-using android::os::statsd::MetricDimensionKey;
-
-template <>
-struct hash<HashableDimensionKey> {
-    std::size_t operator()(const HashableDimensionKey& key) const {
-        return hashDimension(key);
-    }
-};
-
-template <>
-struct hash<MetricDimensionKey> {
-    std::size_t operator()(const MetricDimensionKey& key) const {
-        android::hash_t hash = hashDimension(key.getDimensionKeyInWhat());
-        hash = android::JenkinsHashMix(hash, hashDimension(key.getStateValuesKey()));
-        return android::JenkinsHashWhiten(hash);
-    }
-};
-}  // namespace std
diff --git a/cmds/statsd/src/Log.h b/cmds/statsd/src/Log.h
deleted file mode 100644
index 87f4cba..0000000
--- a/cmds/statsd/src/Log.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * This file must be included at the top of the file. Other header files
- * occasionally include log.h, and if LOG_TAG isn't set when that happens
- * we'll get a preprocesser error when we try to define it here.
- */
-
-#pragma once
-
-#define LOG_TAG "statsd"
-
-#include <log/log.h>
-
-// Use the local value to turn on/off debug logs instead of using log.tag. properties.
-// The advantage is that in production compiler can remove the logging code if the local
-// DEBUG/VERBOSE is false.
-#define VLOG(...) \
-    if (DEBUG) ALOGD(__VA_ARGS__);
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
deleted file mode 100644
index c5d9f54..0000000
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ /dev/null
@@ -1,1147 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsLogProcessor.h"
-
-#include <android-base/file.h>
-#include <cutils/multiuser.h>
-#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
-#include <frameworks/base/cmds/statsd/src/experiment_ids.pb.h>
-
-#include "StatsService.h"
-#include "android-base/stringprintf.h"
-#include "external/StatsPullerManager.h"
-#include "flags/flags.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "metrics/CountMetricProducer.h"
-#include "state/StateManager.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "statslog_statsd.h"
-#include "storage/StorageManager.h"
-
-using namespace android;
-using android::base::StringPrintf;
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for ConfigMetricsReportList
-const int FIELD_ID_CONFIG_KEY = 1;
-const int FIELD_ID_REPORTS = 2;
-// for ConfigKey
-const int FIELD_ID_UID = 1;
-const int FIELD_ID_ID = 2;
-// for ConfigMetricsReport
-// const int FIELD_ID_METRICS = 1; // written in MetricsManager.cpp
-const int FIELD_ID_UID_MAP = 2;
-const int FIELD_ID_LAST_REPORT_ELAPSED_NANOS = 3;
-const int FIELD_ID_CURRENT_REPORT_ELAPSED_NANOS = 4;
-const int FIELD_ID_LAST_REPORT_WALL_CLOCK_NANOS = 5;
-const int FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS = 6;
-const int FIELD_ID_DUMP_REPORT_REASON = 8;
-const int FIELD_ID_STRINGS = 9;
-
-// for ActiveConfigList
-const int FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG = 1;
-
-// for permissions checks
-constexpr const char* kPermissionDump = "android.permission.DUMP";
-constexpr const char* kPermissionUsage = "android.permission.PACKAGE_USAGE_STATS";
-
-#define NS_PER_HOUR 3600 * NS_PER_SEC
-
-#define STATS_ACTIVE_METRIC_DIR "/data/misc/stats-active-metric"
-#define STATS_METADATA_DIR "/data/misc/stats-metadata"
-
-// Cool down period for writing data to disk to avoid overwriting files.
-#define WRITE_DATA_COOL_DOWN_SEC 5
-
-StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap,
-                                     const sp<StatsPullerManager>& pullerManager,
-                                     const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                                     const sp<AlarmMonitor>& periodicAlarmMonitor,
-                                     const int64_t timeBaseNs,
-                                     const std::function<bool(const ConfigKey&)>& sendBroadcast,
-                                     const std::function<bool(
-                                            const int&, const vector<int64_t>&)>& activateBroadcast)
-    : mUidMap(uidMap),
-      mPullerManager(pullerManager),
-      mAnomalyAlarmMonitor(anomalyAlarmMonitor),
-      mPeriodicAlarmMonitor(periodicAlarmMonitor),
-      mSendBroadcast(sendBroadcast),
-      mSendActivationBroadcast(activateBroadcast),
-      mTimeBaseNs(timeBaseNs),
-      mLargestTimestampSeen(0),
-      mLastTimestampSeen(0) {
-    mPullerManager->ForceClearPullerCache();
-    StateManager::getInstance().updateLogSources(uidMap);
-}
-
-StatsLogProcessor::~StatsLogProcessor() {
-}
-
-static void flushProtoToBuffer(ProtoOutputStream& proto, vector<uint8_t>* outData) {
-    outData->clear();
-    outData->resize(proto.size());
-    size_t pos = 0;
-    sp<android::util::ProtoReader> reader = proto.data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(&((*outData)[pos]), reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-}
-
-void StatsLogProcessor::processFiredAnomalyAlarmsLocked(
-        const int64_t& timestampNs,
-        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
-    for (const auto& itr : mMetricsManagers) {
-        itr.second->onAnomalyAlarmFired(timestampNs, alarmSet);
-    }
-}
-void StatsLogProcessor::onPeriodicAlarmFired(
-        const int64_t& timestampNs,
-        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
-
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    for (const auto& itr : mMetricsManagers) {
-        itr.second->onPeriodicAlarmFired(timestampNs, alarmSet);
-    }
-}
-
-void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
-    if (std::pair<int, int> indexRange; event->hasAttributionChain(&indexRange)) {
-        vector<FieldValue>* const fieldValues = event->getMutableValues();
-        for (int i = indexRange.first; i <= indexRange.second; i++) {
-            FieldValue& fieldValue = fieldValues->at(i);
-            if (isAttributionUidField(fieldValue)) {
-                const int hostUid = mUidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
-                fieldValue.mValue.setInt(hostUid);
-            }
-        }
-    } else {
-        int uidFieldIndex = event->getUidFieldIndex();
-        if (uidFieldIndex != -1) {
-           Value& value = (*event->getMutableValues())[uidFieldIndex].mValue;
-           const int hostUid = mUidMap->getHostUidOrSelf(value.int_value);
-           value.setInt(hostUid);
-        }
-    }
-}
-
-void StatsLogProcessor::onIsolatedUidChangedEventLocked(const LogEvent& event) {
-    status_t err = NO_ERROR, err2 = NO_ERROR, err3 = NO_ERROR;
-    bool is_create = event.GetBool(3, &err);
-    auto parent_uid = int(event.GetLong(1, &err2));
-    auto isolated_uid = int(event.GetLong(2, &err3));
-    if (err == NO_ERROR && err2 == NO_ERROR && err3 == NO_ERROR) {
-        if (is_create) {
-            mUidMap->assignIsolatedUid(isolated_uid, parent_uid);
-        } else {
-            mUidMap->removeIsolatedUid(isolated_uid);
-        }
-    } else {
-        ALOGE("Failed to parse uid in the isolated uid change event.");
-    }
-}
-
-void StatsLogProcessor::onBinaryPushStateChangedEventLocked(LogEvent* event) {
-    pid_t pid = event->GetPid();
-    uid_t uid = event->GetUid();
-    if (!checkPermissionForIds(kPermissionDump, pid, uid) ||
-        !checkPermissionForIds(kPermissionUsage, pid, uid)) {
-        return;
-    }
-    // The Get* functions don't modify the status on success, they only write in
-    // failure statuses, so we can use one status variable for all calls then
-    // check if it is no longer NO_ERROR.
-    status_t err = NO_ERROR;
-    InstallTrainInfo trainInfo;
-    trainInfo.trainName = string(event->GetString(1 /*train name field id*/, &err));
-    trainInfo.trainVersionCode = event->GetLong(2 /*train version field id*/, &err);
-    trainInfo.requiresStaging = event->GetBool(3 /*requires staging field id*/, &err);
-    trainInfo.rollbackEnabled = event->GetBool(4 /*rollback enabled field id*/, &err);
-    trainInfo.requiresLowLatencyMonitor =
-            event->GetBool(5 /*requires low latency monitor field id*/, &err);
-    trainInfo.status = int32_t(event->GetLong(6 /*state field id*/, &err));
-    std::vector<uint8_t> trainExperimentIdBytes =
-            event->GetStorage(7 /*experiment ids field id*/, &err);
-    bool is_rollback = event->GetBool(10 /*is rollback field id*/, &err);
-
-    if (err != NO_ERROR) {
-        ALOGE("Failed to parse fields in binary push state changed log event");
-        return;
-    }
-    ExperimentIds trainExperimentIds;
-    if (!trainExperimentIds.ParseFromArray(trainExperimentIdBytes.data(),
-                                           trainExperimentIdBytes.size())) {
-        ALOGE("Failed to parse experimentids in binary push state changed.");
-        return;
-    }
-    trainInfo.experimentIds = {trainExperimentIds.experiment_id().begin(),
-                               trainExperimentIds.experiment_id().end()};
-
-    // Update the train info on disk and get any data the logevent is missing.
-    getAndUpdateTrainInfoOnDisk(is_rollback, &trainInfo);
-
-    std::vector<uint8_t> trainExperimentIdProto;
-    writeExperimentIdsToProto(trainInfo.experimentIds, &trainExperimentIdProto);
-    int32_t userId = multiuser_get_user_id(uid);
-
-    event->updateValue(2 /*train version field id*/, trainInfo.trainVersionCode, LONG);
-    event->updateValue(7 /*experiment ids field id*/, trainExperimentIdProto, STORAGE);
-    event->updateValue(8 /*user id field id*/, userId, INT);
-
-    // If this event is a rollback event, then the following bits in the event
-    // are invalid and we will need to update them with the values we pulled
-    // from disk.
-    if (is_rollback) {
-        int bit = trainInfo.requiresStaging ? 1 : 0;
-        event->updateValue(3 /*requires staging field id*/, bit, INT);
-        bit = trainInfo.rollbackEnabled ? 1 : 0;
-        event->updateValue(4 /*rollback enabled field id*/, bit, INT);
-        bit = trainInfo.requiresLowLatencyMonitor ? 1 : 0;
-        event->updateValue(5 /*requires low latency monitor field id*/, bit, INT);
-    }
-}
-
-void StatsLogProcessor::getAndUpdateTrainInfoOnDisk(bool is_rollback,
-                                                    InstallTrainInfo* trainInfo) {
-    // If the train name is empty, we don't know which train to attribute the
-    // event to, so return early.
-    if (trainInfo->trainName.empty()) {
-        return;
-    }
-    bool readTrainInfoSuccess = false;
-    InstallTrainInfo trainInfoOnDisk;
-    readTrainInfoSuccess = StorageManager::readTrainInfo(trainInfo->trainName, trainInfoOnDisk);
-
-    bool resetExperimentIds = false;
-    if (readTrainInfoSuccess) {
-        // Keep the old train version if we received an empty version.
-        if (trainInfo->trainVersionCode == -1) {
-            trainInfo->trainVersionCode = trainInfoOnDisk.trainVersionCode;
-        } else if (trainInfo->trainVersionCode != trainInfoOnDisk.trainVersionCode) {
-            // Reset experiment ids if we receive a new non-empty train version.
-            resetExperimentIds = true;
-        }
-
-        // Reset if we received a different experiment id.
-        if (!trainInfo->experimentIds.empty() &&
-            (trainInfoOnDisk.experimentIds.empty() ||
-             trainInfo->experimentIds.at(0) != trainInfoOnDisk.experimentIds[0])) {
-            resetExperimentIds = true;
-        }
-    }
-
-    // Find the right experiment IDs
-    if ((!resetExperimentIds || is_rollback) && readTrainInfoSuccess) {
-        trainInfo->experimentIds = trainInfoOnDisk.experimentIds;
-    }
-
-    if (!trainInfo->experimentIds.empty()) {
-        int64_t firstId = trainInfo->experimentIds.at(0);
-        auto& ids = trainInfo->experimentIds;
-        switch (trainInfo->status) {
-            case android::os::statsd::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALL_SUCCESS:
-                if (find(ids.begin(), ids.end(), firstId + 1) == ids.end()) {
-                    ids.push_back(firstId + 1);
-                }
-                break;
-            case android::os::statsd::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_INITIATED:
-                if (find(ids.begin(), ids.end(), firstId + 2) == ids.end()) {
-                    ids.push_back(firstId + 2);
-                }
-                break;
-            case android::os::statsd::util::BINARY_PUSH_STATE_CHANGED__STATE__INSTALLER_ROLLBACK_SUCCESS:
-                if (find(ids.begin(), ids.end(), firstId + 3) == ids.end()) {
-                    ids.push_back(firstId + 3);
-                }
-                break;
-        }
-    }
-
-    // If this event is a rollback event, the following fields are invalid and
-    // need to be replaced by the fields stored to disk.
-    if (is_rollback) {
-        trainInfo->requiresStaging = trainInfoOnDisk.requiresStaging;
-        trainInfo->rollbackEnabled = trainInfoOnDisk.rollbackEnabled;
-        trainInfo->requiresLowLatencyMonitor = trainInfoOnDisk.requiresLowLatencyMonitor;
-    }
-
-    StorageManager::writeTrainInfo(*trainInfo);
-}
-
-void StatsLogProcessor::onWatchdogRollbackOccurredLocked(LogEvent* event) {
-    pid_t pid = event->GetPid();
-    uid_t uid = event->GetUid();
-    if (!checkPermissionForIds(kPermissionDump, pid, uid) ||
-        !checkPermissionForIds(kPermissionUsage, pid, uid)) {
-        return;
-    }
-    // The Get* functions don't modify the status on success, they only write in
-    // failure statuses, so we can use one status variable for all calls then
-    // check if it is no longer NO_ERROR.
-    status_t err = NO_ERROR;
-    int32_t rollbackType = int32_t(event->GetInt(1 /*rollback type field id*/, &err));
-    string packageName = string(event->GetString(2 /*package name field id*/, &err));
-
-    if (err != NO_ERROR) {
-        ALOGE("Failed to parse fields in watchdog rollback occurred log event");
-        return;
-    }
-
-    vector<int64_t> experimentIds =
-        processWatchdogRollbackOccurred(rollbackType, packageName);
-    vector<uint8_t> experimentIdProto;
-    writeExperimentIdsToProto(experimentIds, &experimentIdProto);
-
-    event->updateValue(6 /*experiment ids field id*/, experimentIdProto, STORAGE);
-}
-
-vector<int64_t> StatsLogProcessor::processWatchdogRollbackOccurred(const int32_t rollbackTypeIn,
-                                                                    const string& packageNameIn) {
-    // If the package name is empty, we can't attribute it to any train, so
-    // return early.
-    if (packageNameIn.empty()) {
-      return vector<int64_t>();
-    }
-    bool readTrainInfoSuccess = false;
-    InstallTrainInfo trainInfoOnDisk;
-    // We use the package name of the event as the train name.
-    readTrainInfoSuccess = StorageManager::readTrainInfo(packageNameIn, trainInfoOnDisk);
-
-    if (!readTrainInfoSuccess) {
-        return vector<int64_t>();
-    }
-
-    if (trainInfoOnDisk.experimentIds.empty()) {
-        return vector<int64_t>();
-    }
-
-    int64_t firstId = trainInfoOnDisk.experimentIds[0];
-    auto& ids = trainInfoOnDisk.experimentIds;
-    switch (rollbackTypeIn) {
-      case android::os::statsd::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE:
-            if (find(ids.begin(), ids.end(), firstId + 4) == ids.end()) {
-                ids.push_back(firstId + 4);
-            }
-            StorageManager::writeTrainInfo(trainInfoOnDisk);
-            break;
-      case android::os::statsd::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS:
-            if (find(ids.begin(), ids.end(), firstId + 5) == ids.end()) {
-                ids.push_back(firstId + 5);
-            }
-            StorageManager::writeTrainInfo(trainInfoOnDisk);
-            break;
-    }
-
-    return trainInfoOnDisk.experimentIds;
-}
-
-void StatsLogProcessor::resetConfigs() {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    resetConfigsLocked(getElapsedRealtimeNs());
-}
-
-void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs) {
-    std::vector<ConfigKey> configKeys;
-    for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
-        configKeys.push_back(it->first);
-    }
-    resetConfigsLocked(timestampNs, configKeys);
-}
-
-void StatsLogProcessor::OnLogEvent(LogEvent* event) {
-    OnLogEvent(event, getElapsedRealtimeNs());
-}
-
-void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-
-    // Tell StatsdStats about new event
-    const int64_t eventElapsedTimeNs = event->GetElapsedTimestampNs();
-    int atomId = event->GetTagId();
-    StatsdStats::getInstance().noteAtomLogged(atomId, eventElapsedTimeNs / NS_PER_SEC);
-    if (!event->isValid()) {
-        StatsdStats::getInstance().noteAtomError(atomId);
-        return;
-    }
-
-    // Hard-coded logic to update train info on disk and fill in any information
-    // this log event may be missing.
-    if (atomId == android::os::statsd::util::BINARY_PUSH_STATE_CHANGED) {
-        onBinaryPushStateChangedEventLocked(event);
-    }
-
-    // Hard-coded logic to update experiment ids on disk for certain rollback
-    // types and fill the rollback atom with experiment ids
-    if (atomId == android::os::statsd::util::WATCHDOG_ROLLBACK_OCCURRED) {
-        onWatchdogRollbackOccurredLocked(event);
-    }
-
-    if (mPrintAllLogs) {
-        ALOGI("%s", event->ToString().c_str());
-    }
-    resetIfConfigTtlExpiredLocked(eventElapsedTimeNs);
-
-    // Hard-coded logic to update the isolated uid's in the uid-map.
-    // The field numbers need to be currently updated by hand with atoms.proto
-    if (atomId == android::os::statsd::util::ISOLATED_UID_CHANGED) {
-        onIsolatedUidChangedEventLocked(*event);
-    } else {
-        // Map the isolated uid to host uid if necessary.
-        mapIsolatedUidToHostUidIfNecessaryLocked(event);
-    }
-
-    StateManager::getInstance().onLogEvent(*event);
-
-    if (mMetricsManagers.empty()) {
-        return;
-    }
-
-    bool fireAlarm = false;
-    {
-        std::lock_guard<std::mutex> anomalyLock(mAnomalyAlarmMutex);
-        if (mNextAnomalyAlarmTime != 0 &&
-            MillisToNano(mNextAnomalyAlarmTime) <= elapsedRealtimeNs) {
-            mNextAnomalyAlarmTime = 0;
-            VLOG("informing anomaly alarm at time %lld", (long long)elapsedRealtimeNs);
-            fireAlarm = true;
-        }
-    }
-    if (fireAlarm) {
-        informAnomalyAlarmFiredLocked(NanoToMillis(elapsedRealtimeNs));
-    }
-
-    int64_t curTimeSec = getElapsedRealtimeSec();
-    if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) {
-        mPullerManager->ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC);
-        mLastPullerCacheClearTimeSec = curTimeSec;
-    }
-
-    std::unordered_set<int> uidsWithActiveConfigsChanged;
-    std::unordered_map<int, std::vector<int64_t>> activeConfigsPerUid;
-    // pass the event to metrics managers.
-    for (auto& pair : mMetricsManagers) {
-        int uid = pair.first.GetUid();
-        int64_t configId = pair.first.GetId();
-        bool isPrevActive = pair.second->isActive();
-        pair.second->onLogEvent(*event);
-        bool isCurActive = pair.second->isActive();
-        // Map all active configs by uid.
-        if (isCurActive) {
-            auto activeConfigs = activeConfigsPerUid.find(uid);
-            if (activeConfigs != activeConfigsPerUid.end()) {
-                activeConfigs->second.push_back(configId);
-            } else {
-                vector<int64_t> newActiveConfigs;
-                newActiveConfigs.push_back(configId);
-                activeConfigsPerUid[uid] = newActiveConfigs;
-            }
-        }
-        // The activation state of this config changed.
-        if (isPrevActive != isCurActive) {
-            VLOG("Active status changed for uid  %d", uid);
-            uidsWithActiveConfigsChanged.insert(uid);
-            StatsdStats::getInstance().noteActiveStatusChanged(pair.first, isCurActive);
-        }
-        flushIfNecessaryLocked(pair.first, *(pair.second));
-    }
-
-    // Don't use the event timestamp for the guardrail.
-    for (int uid : uidsWithActiveConfigsChanged) {
-        // Send broadcast so that receivers can pull data.
-        auto lastBroadcastTime = mLastActivationBroadcastTimes.find(uid);
-        if (lastBroadcastTime != mLastActivationBroadcastTimes.end()) {
-            if (elapsedRealtimeNs - lastBroadcastTime->second <
-                StatsdStats::kMinActivationBroadcastPeriodNs) {
-                StatsdStats::getInstance().noteActivationBroadcastGuardrailHit(uid);
-                VLOG("StatsD would've sent an activation broadcast but the rate limit stopped us.");
-                return;
-            }
-        }
-        auto activeConfigs = activeConfigsPerUid.find(uid);
-        if (activeConfigs != activeConfigsPerUid.end()) {
-            if (mSendActivationBroadcast(uid, activeConfigs->second)) {
-                VLOG("StatsD sent activation notice for uid %d", uid);
-                mLastActivationBroadcastTimes[uid] = elapsedRealtimeNs;
-            }
-        } else {
-            std::vector<int64_t> emptyActiveConfigs;
-            if (mSendActivationBroadcast(uid, emptyActiveConfigs)) {
-                VLOG("StatsD sent EMPTY activation notice for uid %d", uid);
-                mLastActivationBroadcastTimes[uid] = elapsedRealtimeNs;
-            }
-        }
-    }
-}
-
-void StatsLogProcessor::GetActiveConfigs(const int uid, vector<int64_t>& outActiveConfigs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    GetActiveConfigsLocked(uid, outActiveConfigs);
-}
-
-void StatsLogProcessor::GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs) {
-    outActiveConfigs.clear();
-    for (auto& pair : mMetricsManagers) {
-        if (pair.first.GetUid() == uid && pair.second->isActive()) {
-            outActiveConfigs.push_back(pair.first.GetId());
-        }
-    }
-}
-
-void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
-                                        const StatsdConfig& config) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    WriteDataToDiskLocked(key, timestampNs, CONFIG_UPDATED, NO_TIME_CONSTRAINTS);
-    bool modularUpdate = getFlagBool(PARTIAL_CONFIG_UPDATE_FLAG, "false");
-    OnConfigUpdatedLocked(timestampNs, key, config, modularUpdate);
-}
-
-void StatsLogProcessor::OnConfigUpdatedLocked(const int64_t timestampNs, const ConfigKey& key,
-                                              const StatsdConfig& config, bool modularUpdate) {
-    VLOG("Updated configuration for key %s", key.ToString().c_str());
-    // Create new config if this is not a modular update or if this is a new config.
-    const auto& it = mMetricsManagers.find(key);
-    bool configValid = false;
-    if (!modularUpdate || it == mMetricsManagers.end()) {
-        sp<MetricsManager> newMetricsManager =
-                new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
-                                   mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
-        configValid = newMetricsManager->isConfigValid();
-        if (configValid) {
-            newMetricsManager->init();
-            mUidMap->OnConfigUpdated(key);
-            newMetricsManager->refreshTtl(timestampNs);
-            mMetricsManagers[key] = newMetricsManager;
-            VLOG("StatsdConfig valid");
-        }
-    } else {
-        // Preserve the existing MetricsManager, update necessary components and metadata in place.
-        configValid = it->second->updateConfig(config, mTimeBaseNs, timestampNs,
-                                               mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
-        if (configValid) {
-            mUidMap->OnConfigUpdated(key);
-        }
-    }
-    if (!configValid) {
-        // If there is any error in the config, don't use it.
-        // Remove any existing config with the same key.
-        ALOGE("StatsdConfig NOT valid");
-        mMetricsManagers.erase(key);
-    }
-}
-
-size_t StatsLogProcessor::GetMetricsSize(const ConfigKey& key) const {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    auto it = mMetricsManagers.find(key);
-    if (it == mMetricsManagers.end()) {
-        ALOGW("Config source %s does not exist", key.ToString().c_str());
-        return 0;
-    }
-    return it->second->byteSize();
-}
-
-void StatsLogProcessor::dumpStates(int out, bool verbose) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    FILE* fout = fdopen(out, "w");
-    if (fout == NULL) {
-        return;
-    }
-    fprintf(fout, "MetricsManager count: %lu\n", (unsigned long)mMetricsManagers.size());
-    for (auto metricsManager : mMetricsManagers) {
-        metricsManager.second->dumpStates(fout, verbose);
-    }
-
-    fclose(fout);
-}
-
-/*
- * onDumpReport dumps serialized ConfigMetricsReportList into proto.
- */
-void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
-                                     const bool include_current_partial_bucket,
-                                     const bool erase_data,
-                                     const DumpReportReason dumpReportReason,
-                                     const DumpLatency dumpLatency,
-                                     ProtoOutputStream* proto) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-
-    // Start of ConfigKey.
-    uint64_t configKeyToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
-    proto->write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
-    proto->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
-    proto->end(configKeyToken);
-    // End of ConfigKey.
-
-    bool keepFile = false;
-    auto it = mMetricsManagers.find(key);
-    if (it != mMetricsManagers.end() && it->second->shouldPersistLocalHistory()) {
-        keepFile = true;
-    }
-
-    // Then, check stats-data directory to see there's any file containing
-    // ConfigMetricsReport from previous shutdowns to concatenate to reports.
-    StorageManager::appendConfigMetricsReport(
-            key, proto, erase_data && !keepFile /* should remove file after appending it */,
-            dumpReportReason == ADB_DUMP /*if caller is adb*/);
-
-    if (it != mMetricsManagers.end()) {
-        // This allows another broadcast to be sent within the rate-limit period if we get close to
-        // filling the buffer again soon.
-        mLastBroadcastTimes.erase(key);
-
-        vector<uint8_t> buffer;
-        onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket,
-                                    erase_data, dumpReportReason, dumpLatency,
-                                    false /* is this data going to be saved on disk */, &buffer);
-        proto->write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS,
-                     reinterpret_cast<char*>(buffer.data()), buffer.size());
-    } else {
-        ALOGW("Config source %s does not exist", key.ToString().c_str());
-    }
-}
-
-/*
- * onDumpReport dumps serialized ConfigMetricsReportList into outData.
- */
-void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
-                                     const bool include_current_partial_bucket,
-                                     const bool erase_data,
-                                     const DumpReportReason dumpReportReason,
-                                     const DumpLatency dumpLatency,
-                                     vector<uint8_t>* outData) {
-    ProtoOutputStream proto;
-    onDumpReport(key, dumpTimeStampNs, include_current_partial_bucket, erase_data,
-                 dumpReportReason, dumpLatency, &proto);
-
-    if (outData != nullptr) {
-        flushProtoToBuffer(proto, outData);
-        VLOG("output data size %zu", outData->size());
-    }
-
-    StatsdStats::getInstance().noteMetricsReportSent(key, proto.size());
-}
-
-/*
- * onConfigMetricsReportLocked dumps serialized ConfigMetricsReport into outData.
- */
-void StatsLogProcessor::onConfigMetricsReportLocked(
-        const ConfigKey& key, const int64_t dumpTimeStampNs,
-        const bool include_current_partial_bucket, const bool erase_data,
-        const DumpReportReason dumpReportReason, const DumpLatency dumpLatency,
-        const bool dataSavedOnDisk, vector<uint8_t>* buffer) {
-    // We already checked whether key exists in mMetricsManagers in
-    // WriteDataToDisk.
-    auto it = mMetricsManagers.find(key);
-    if (it == mMetricsManagers.end()) {
-        return;
-    }
-    int64_t lastReportTimeNs = it->second->getLastReportTimeNs();
-    int64_t lastReportWallClockNs = it->second->getLastReportWallClockNs();
-
-    std::set<string> str_set;
-
-    ProtoOutputStream tempProto;
-    // First, fill in ConfigMetricsReport using current data on memory, which
-    // starts from filling in StatsLogReport's.
-    it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
-                             dumpLatency, &str_set, &tempProto);
-
-    // Fill in UidMap if there is at least one metric to report.
-    // This skips the uid map if it's an empty config.
-    if (it->second->getNumMetrics() > 0) {
-        uint64_t uidMapToken = tempProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UID_MAP);
-        mUidMap->appendUidMap(
-                dumpTimeStampNs, key, it->second->hashStringInReport() ? &str_set : nullptr,
-                it->second->versionStringsInReport(), it->second->installerInReport(), &tempProto);
-        tempProto.end(uidMapToken);
-    }
-
-    // Fill in the timestamps.
-    tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_LAST_REPORT_ELAPSED_NANOS,
-                    (long long)lastReportTimeNs);
-    tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_ELAPSED_NANOS,
-                    (long long)dumpTimeStampNs);
-    tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_LAST_REPORT_WALL_CLOCK_NANOS,
-                    (long long)lastReportWallClockNs);
-    tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS,
-                    (long long)getWallClockNs());
-    // Dump report reason
-    tempProto.write(FIELD_TYPE_INT32 | FIELD_ID_DUMP_REPORT_REASON, dumpReportReason);
-
-    for (const auto& str : str_set) {
-        tempProto.write(FIELD_TYPE_STRING | FIELD_COUNT_REPEATED | FIELD_ID_STRINGS, str);
-    }
-
-    flushProtoToBuffer(tempProto, buffer);
-
-    // save buffer to disk if needed
-    if (erase_data && !dataSavedOnDisk && it->second->shouldPersistLocalHistory()) {
-        VLOG("save history to disk");
-        string file_name = StorageManager::getDataHistoryFileName((long)getWallClockSec(),
-                                                                  key.GetUid(), key.GetId());
-        StorageManager::writeFile(file_name.c_str(), buffer->data(), buffer->size());
-    }
-}
-
-void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs,
-                                           const std::vector<ConfigKey>& configs) {
-    for (const auto& key : configs) {
-        StatsdConfig config;
-        if (StorageManager::readConfigFromDisk(key, &config)) {
-            // Force a full update when resetting a config.
-            OnConfigUpdatedLocked(timestampNs, key, config, /*modularUpdate=*/false);
-            StatsdStats::getInstance().noteConfigReset(key);
-        } else {
-            ALOGE("Failed to read backup config from disk for : %s", key.ToString().c_str());
-            auto it = mMetricsManagers.find(key);
-            if (it != mMetricsManagers.end()) {
-                it->second->refreshTtl(timestampNs);
-            }
-        }
-    }
-}
-
-void StatsLogProcessor::resetIfConfigTtlExpiredLocked(const int64_t timestampNs) {
-    std::vector<ConfigKey> configKeysTtlExpired;
-    for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
-        if (it->second != nullptr && !it->second->isInTtl(timestampNs)) {
-            configKeysTtlExpired.push_back(it->first);
-        }
-    }
-    if (configKeysTtlExpired.size() > 0) {
-        WriteDataToDiskLocked(CONFIG_RESET, NO_TIME_CONSTRAINTS);
-        resetConfigsLocked(timestampNs, configKeysTtlExpired);
-    }
-}
-
-void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    auto it = mMetricsManagers.find(key);
-    if (it != mMetricsManagers.end()) {
-        WriteDataToDiskLocked(key, getElapsedRealtimeNs(), CONFIG_REMOVED,
-                              NO_TIME_CONSTRAINTS);
-        mMetricsManagers.erase(it);
-        mUidMap->OnConfigRemoved(key);
-    }
-    StatsdStats::getInstance().noteConfigRemoved(key);
-
-    mLastBroadcastTimes.erase(key);
-
-    int uid = key.GetUid();
-    bool lastConfigForUid = true;
-    for (auto it : mMetricsManagers) {
-        if (it.first.GetUid() == uid) {
-            lastConfigForUid = false;
-            break;
-        }
-    }
-    if (lastConfigForUid) {
-        mLastActivationBroadcastTimes.erase(uid);
-    }
-
-    if (mMetricsManagers.empty()) {
-        mPullerManager->ForceClearPullerCache();
-    }
-}
-
-void StatsLogProcessor::flushIfNecessaryLocked(const ConfigKey& key,
-                                               MetricsManager& metricsManager) {
-    int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
-    auto lastCheckTime = mLastByteSizeTimes.find(key);
-    if (lastCheckTime != mLastByteSizeTimes.end()) {
-        if (elapsedRealtimeNs - lastCheckTime->second < StatsdStats::kMinByteSizeCheckPeriodNs) {
-            return;
-        }
-    }
-
-    // We suspect that the byteSize() computation is expensive, so we set a rate limit.
-    size_t totalBytes = metricsManager.byteSize();
-    mLastByteSizeTimes[key] = elapsedRealtimeNs;
-    bool requestDump = false;
-    if (totalBytes > StatsdStats::kMaxMetricsBytesPerConfig) {
-        // Too late. We need to start clearing data.
-        metricsManager.dropData(elapsedRealtimeNs);
-        StatsdStats::getInstance().noteDataDropped(key, totalBytes);
-        VLOG("StatsD had to toss out metrics for %s", key.ToString().c_str());
-    } else if ((totalBytes > StatsdStats::kBytesPerConfigTriggerGetData) ||
-               (mOnDiskDataConfigs.find(key) != mOnDiskDataConfigs.end())) {
-        // Request to send a broadcast if:
-        // 1. in memory data > threshold   OR
-        // 2. config has old data report on disk.
-        requestDump = true;
-    }
-
-    if (requestDump) {
-        // Send broadcast so that receivers can pull data.
-        auto lastBroadcastTime = mLastBroadcastTimes.find(key);
-        if (lastBroadcastTime != mLastBroadcastTimes.end()) {
-            if (elapsedRealtimeNs - lastBroadcastTime->second <
-                    StatsdStats::kMinBroadcastPeriodNs) {
-                VLOG("StatsD would've sent a broadcast but the rate limit stopped us.");
-                return;
-            }
-        }
-        if (mSendBroadcast(key)) {
-            mOnDiskDataConfigs.erase(key);
-            VLOG("StatsD triggered data fetch for %s", key.ToString().c_str());
-            mLastBroadcastTimes[key] = elapsedRealtimeNs;
-            StatsdStats::getInstance().noteBroadcastSent(key);
-        }
-    }
-}
-
-void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key,
-                                              const int64_t timestampNs,
-                                              const DumpReportReason dumpReportReason,
-                                              const DumpLatency dumpLatency) {
-    if (mMetricsManagers.find(key) == mMetricsManagers.end() ||
-        !mMetricsManagers.find(key)->second->shouldWriteToDisk()) {
-        return;
-    }
-    vector<uint8_t> buffer;
-    onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/,
-                                true /* erase_data */, dumpReportReason, dumpLatency, true,
-                                &buffer);
-    string file_name =
-            StorageManager::getDataFileName((long)getWallClockSec(), key.GetUid(), key.GetId());
-    StorageManager::writeFile(file_name.c_str(), buffer.data(), buffer.size());
-
-    // We were able to write the ConfigMetricsReport to disk, so we should trigger collection ASAP.
-    mOnDiskDataConfigs.insert(key);
-}
-
-void StatsLogProcessor::SaveActiveConfigsToDisk(int64_t currentTimeNs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    const int64_t timeNs = getElapsedRealtimeNs();
-    // Do not write to disk if we already have in the last few seconds.
-    if (static_cast<unsigned long long> (timeNs) <
-            mLastActiveMetricsWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
-        ALOGI("Statsd skipping writing active metrics to disk. Already wrote data in last %d seconds",
-                WRITE_DATA_COOL_DOWN_SEC);
-        return;
-    }
-    mLastActiveMetricsWriteNs = timeNs;
-
-    ProtoOutputStream proto;
-    WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, DEVICE_SHUTDOWN, &proto);
-
-    string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
-    StorageManager::deleteFile(file_name.c_str());
-    android::base::unique_fd fd(
-            open(file_name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR));
-    if (fd == -1) {
-        ALOGE("Attempt to write %s but failed", file_name.c_str());
-        return;
-    }
-    proto.flush(fd.get());
-}
-
-void StatsLogProcessor::SaveMetadataToDisk(int64_t currentWallClockTimeNs,
-                                           int64_t systemElapsedTimeNs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    // Do not write to disk if we already have in the last few seconds.
-    if (static_cast<unsigned long long> (systemElapsedTimeNs) <
-            mLastMetadataWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
-        ALOGI("Statsd skipping writing metadata to disk. Already wrote data in last %d seconds",
-                WRITE_DATA_COOL_DOWN_SEC);
-        return;
-    }
-    mLastMetadataWriteNs = systemElapsedTimeNs;
-
-    metadata::StatsMetadataList metadataList;
-    WriteMetadataToProtoLocked(
-            currentWallClockTimeNs, systemElapsedTimeNs, &metadataList);
-
-    string file_name = StringPrintf("%s/metadata", STATS_METADATA_DIR);
-    StorageManager::deleteFile(file_name.c_str());
-
-    if (metadataList.stats_metadata_size() == 0) {
-        // Skip the write if we have nothing to write.
-        return;
-    }
-
-    std::string data;
-    metadataList.SerializeToString(&data);
-    StorageManager::writeFile(file_name.c_str(), data.c_str(), data.size());
-}
-
-void StatsLogProcessor::WriteMetadataToProto(int64_t currentWallClockTimeNs,
-                                             int64_t systemElapsedTimeNs,
-                                             metadata::StatsMetadataList* metadataList) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    WriteMetadataToProtoLocked(currentWallClockTimeNs, systemElapsedTimeNs, metadataList);
-}
-
-void StatsLogProcessor::WriteMetadataToProtoLocked(int64_t currentWallClockTimeNs,
-                                                   int64_t systemElapsedTimeNs,
-                                                   metadata::StatsMetadataList* metadataList) {
-    for (const auto& pair : mMetricsManagers) {
-        const sp<MetricsManager>& metricsManager = pair.second;
-        metadata::StatsMetadata* statsMetadata = metadataList->add_stats_metadata();
-        bool metadataWritten = metricsManager->writeMetadataToProto(currentWallClockTimeNs,
-                systemElapsedTimeNs, statsMetadata);
-        if (!metadataWritten) {
-            metadataList->mutable_stats_metadata()->RemoveLast();
-        }
-    }
-}
-
-void StatsLogProcessor::LoadMetadataFromDisk(int64_t currentWallClockTimeNs,
-                                             int64_t systemElapsedTimeNs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    string file_name = StringPrintf("%s/metadata", STATS_METADATA_DIR);
-    int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
-    if (-1 == fd) {
-        VLOG("Attempt to read %s but failed", file_name.c_str());
-        StorageManager::deleteFile(file_name.c_str());
-        return;
-    }
-    string content;
-    if (!android::base::ReadFdToString(fd, &content)) {
-        ALOGE("Attempt to read %s but failed", file_name.c_str());
-        close(fd);
-        StorageManager::deleteFile(file_name.c_str());
-        return;
-    }
-
-    close(fd);
-
-    metadata::StatsMetadataList statsMetadataList;
-    if (!statsMetadataList.ParseFromString(content)) {
-        ALOGE("Attempt to read %s but failed; failed to metadata", file_name.c_str());
-        StorageManager::deleteFile(file_name.c_str());
-        return;
-    }
-    SetMetadataStateLocked(statsMetadataList, currentWallClockTimeNs, systemElapsedTimeNs);
-    StorageManager::deleteFile(file_name.c_str());
-}
-
-void StatsLogProcessor::SetMetadataState(const metadata::StatsMetadataList& statsMetadataList,
-                                         int64_t currentWallClockTimeNs,
-                                         int64_t systemElapsedTimeNs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    SetMetadataStateLocked(statsMetadataList, currentWallClockTimeNs, systemElapsedTimeNs);
-}
-
-void StatsLogProcessor::SetMetadataStateLocked(
-        const metadata::StatsMetadataList& statsMetadataList,
-        int64_t currentWallClockTimeNs,
-        int64_t systemElapsedTimeNs) {
-    for (const metadata::StatsMetadata& metadata : statsMetadataList.stats_metadata()) {
-        ConfigKey key(metadata.config_key().uid(), metadata.config_key().config_id());
-        auto it = mMetricsManagers.find(key);
-        if (it == mMetricsManagers.end()) {
-            ALOGE("No config found for configKey %s", key.ToString().c_str());
-            continue;
-        }
-        VLOG("Setting metadata %s", key.ToString().c_str());
-        it->second->loadMetadata(metadata, currentWallClockTimeNs, systemElapsedTimeNs);
-    }
-    VLOG("Successfully loaded %d metadata.", statsMetadataList.stats_metadata_size());
-}
-
-void StatsLogProcessor::WriteActiveConfigsToProtoOutputStream(
-        int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, reason, proto);
-}
-
-void StatsLogProcessor::WriteActiveConfigsToProtoOutputStreamLocked(
-        int64_t currentTimeNs,  const DumpReportReason reason, ProtoOutputStream* proto) {
-    for (const auto& pair : mMetricsManagers) {
-        const sp<MetricsManager>& metricsManager = pair.second;
-        uint64_t configToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                     FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG);
-        metricsManager->writeActiveConfigToProtoOutputStream(currentTimeNs, reason, proto);
-        proto->end(configToken);
-    }
-}
-void StatsLogProcessor::LoadActiveConfigsFromDisk() {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
-    int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
-    if (-1 == fd) {
-        VLOG("Attempt to read %s but failed", file_name.c_str());
-        StorageManager::deleteFile(file_name.c_str());
-        return;
-    }
-    string content;
-    if (!android::base::ReadFdToString(fd, &content)) {
-        ALOGE("Attempt to read %s but failed", file_name.c_str());
-        close(fd);
-        StorageManager::deleteFile(file_name.c_str());
-        return;
-    }
-
-    close(fd);
-
-    ActiveConfigList activeConfigList;
-    if (!activeConfigList.ParseFromString(content)) {
-        ALOGE("Attempt to read %s but failed; failed to load active configs", file_name.c_str());
-        StorageManager::deleteFile(file_name.c_str());
-        return;
-    }
-    // Passing in mTimeBaseNs only works as long as we only load from disk is when statsd starts.
-    SetConfigsActiveStateLocked(activeConfigList, mTimeBaseNs);
-    StorageManager::deleteFile(file_name.c_str());
-}
-
-void StatsLogProcessor::SetConfigsActiveState(const ActiveConfigList& activeConfigList,
-                                                    int64_t currentTimeNs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    SetConfigsActiveStateLocked(activeConfigList, currentTimeNs);
-}
-
-void StatsLogProcessor::SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
-                                                    int64_t currentTimeNs) {
-    for (int i = 0; i < activeConfigList.config_size(); i++) {
-        const auto& config = activeConfigList.config(i);
-        ConfigKey key(config.uid(), config.id());
-        auto it = mMetricsManagers.find(key);
-        if (it == mMetricsManagers.end()) {
-            ALOGE("No config found for config %s", key.ToString().c_str());
-            continue;
-        }
-        VLOG("Setting active config %s", key.ToString().c_str());
-        it->second->loadActiveConfig(config, currentTimeNs);
-    }
-    VLOG("Successfully loaded %d active configs.", activeConfigList.config_size());
-}
-
-void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
-                                              const DumpLatency dumpLatency) {
-    const int64_t timeNs = getElapsedRealtimeNs();
-    // Do not write to disk if we already have in the last few seconds.
-    // This is to avoid overwriting files that would have the same name if we
-    //   write twice in the same second.
-    if (static_cast<unsigned long long> (timeNs) <
-            mLastWriteTimeNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
-        ALOGI("Statsd skipping writing data to disk. Already wrote data in last %d seconds",
-                WRITE_DATA_COOL_DOWN_SEC);
-        return;
-    }
-    mLastWriteTimeNs = timeNs;
-    for (auto& pair : mMetricsManagers) {
-        WriteDataToDiskLocked(pair.first, timeNs, dumpReportReason, dumpLatency);
-    }
-}
-
-void StatsLogProcessor::WriteDataToDisk(const DumpReportReason dumpReportReason,
-                                        const DumpLatency dumpLatency) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    WriteDataToDiskLocked(dumpReportReason, dumpLatency);
-}
-
-void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    mPullerManager->OnAlarmFired(timestampNs);
-}
-
-int64_t StatsLogProcessor::getLastReportTimeNs(const ConfigKey& key) {
-    auto it = mMetricsManagers.find(key);
-    if (it == mMetricsManagers.end()) {
-        return 0;
-    } else {
-        return it->second->getLastReportTimeNs();
-    }
-}
-
-void StatsLogProcessor::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk,
-                                         const int uid, const int64_t version) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    VLOG("Received app upgrade");
-    StateManager::getInstance().notifyAppChanged(apk, mUidMap);
-    for (const auto& it : mMetricsManagers) {
-        it.second->notifyAppUpgrade(eventTimeNs, apk, uid, version);
-    }
-}
-
-void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk,
-                                         const int uid) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    VLOG("Received app removed");
-    StateManager::getInstance().notifyAppChanged(apk, mUidMap);
-    for (const auto& it : mMetricsManagers) {
-        it.second->notifyAppRemoved(eventTimeNs, apk, uid);
-    }
-}
-
-void StatsLogProcessor::onUidMapReceived(const int64_t& eventTimeNs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    VLOG("Received uid map");
-    StateManager::getInstance().updateLogSources(mUidMap);
-    for (const auto& it : mMetricsManagers) {
-        it.second->onUidMapReceived(eventTimeNs);
-    }
-}
-
-void StatsLogProcessor::onStatsdInitCompleted(const int64_t& elapsedTimeNs) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    VLOG("Received boot completed signal");
-    for (const auto& it : mMetricsManagers) {
-        it.second->onStatsdInitCompleted(elapsedTimeNs);
-    }
-}
-
-void StatsLogProcessor::noteOnDiskData(const ConfigKey& key) {
-    std::lock_guard<std::mutex> lock(mMetricsMutex);
-    mOnDiskDataConfigs.insert(key);
-}
-
-void StatsLogProcessor::setAnomalyAlarm(const int64_t elapsedTimeMillis) {
-    std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex);
-    mNextAnomalyAlarmTime = elapsedTimeMillis;
-}
-
-void StatsLogProcessor::cancelAnomalyAlarm() {
-    std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex);
-    mNextAnomalyAlarmTime = 0;
-}
-
-void StatsLogProcessor::informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis) {
-    VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
-    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
-            mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(elapsedTimeMillis / 1000));
-    if (alarmSet.size() > 0) {
-        VLOG("Found periodic alarm fired.");
-        processFiredAnomalyAlarmsLocked(MillisToNano(elapsedTimeMillis), alarmSet);
-    } else {
-        ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
deleted file mode 100644
index a320b2f..0000000
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include "config/ConfigListener.h"
-#include "logd/LogEvent.h"
-#include "metrics/MetricsManager.h"
-#include "packages/UidMap.h"
-#include "external/StatsPullerManager.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
-
-#include <stdio.h>
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-class StatsLogProcessor : public ConfigListener, public virtual PackageInfoListener {
-public:
-    StatsLogProcessor(const sp<UidMap>& uidMap, const sp<StatsPullerManager>& pullerManager,
-                      const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                      const sp<AlarmMonitor>& subscriberTriggerAlarmMonitor,
-                      const int64_t timeBaseNs,
-                      const std::function<bool(const ConfigKey&)>& sendBroadcast,
-                      const std::function<bool(const int&,
-                                               const vector<int64_t>&)>& sendActivationBroadcast);
-    virtual ~StatsLogProcessor();
-
-    void OnLogEvent(LogEvent* event);
-
-    void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
-                         const StatsdConfig& config);
-    void OnConfigRemoved(const ConfigKey& key);
-
-    size_t GetMetricsSize(const ConfigKey& key) const;
-
-    void GetActiveConfigs(const int uid, vector<int64_t>& outActiveConfigs);
-
-    void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
-                      const bool include_current_partial_bucket, const bool erase_data,
-                      const DumpReportReason dumpReportReason,
-                      const DumpLatency dumpLatency,
-                      vector<uint8_t>* outData);
-    void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
-                      const bool include_current_partial_bucket, const bool erase_data,
-                      const DumpReportReason dumpReportReason,
-                      const DumpLatency dumpLatency,
-                      ProtoOutputStream* proto);
-
-    /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
-    void onPeriodicAlarmFired(
-            const int64_t& timestampNs,
-            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
-
-    /* Flushes data to disk. Data on memory will be gone after written to disk. */
-    void WriteDataToDisk(const DumpReportReason dumpReportReason,
-                         const DumpLatency dumpLatency);
-
-    /* Persist configs containing metrics with active activations to disk. */
-    void SaveActiveConfigsToDisk(int64_t currentTimeNs);
-
-    /* Writes the current active status/ttl for all configs and metrics to ProtoOutputStream. */
-    void WriteActiveConfigsToProtoOutputStream(
-            int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
-    /* Load configs containing metrics with active activations from disk. */
-    void LoadActiveConfigsFromDisk();
-
-    /* Persist metadata for configs and metrics to disk. */
-    void SaveMetadataToDisk(int64_t currentWallClockTimeNs, int64_t systemElapsedTimeNs);
-
-    /* Writes the statsd metadata for all configs and metrics to StatsMetadataList. */
-    void WriteMetadataToProto(int64_t currentWallClockTimeNs,
-                              int64_t systemElapsedTimeNs,
-                              metadata::StatsMetadataList* metadataList);
-
-    /* Load stats metadata for configs and metrics from disk. */
-    void LoadMetadataFromDisk(int64_t currentWallClockTimeNs,
-                              int64_t systemElapsedTimeNs);
-
-    /* Sets the metadata for all configs and metrics */
-    void SetMetadataState(const metadata::StatsMetadataList& statsMetadataList,
-                          int64_t currentWallClockTimeNs,
-                          int64_t systemElapsedTimeNs);
-
-    /* Sets the active status/ttl for all configs and metrics to the status in ActiveConfigList. */
-    void SetConfigsActiveState(const ActiveConfigList& activeConfigList, int64_t currentTimeNs);
-
-    /* Notify all MetricsManagers of app upgrades */
-    void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
-                          const int64_t version) override;
-
-    /* Notify all MetricsManagers of app removals */
-    void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid) override;
-
-    /* Notify all MetricsManagers of uid map snapshots received */
-    void onUidMapReceived(const int64_t& eventTimeNs) override;
-
-    /* Notify all metrics managers of boot completed
-     * This will force a bucket split when the boot is finished.
-     */
-    void onStatsdInitCompleted(const int64_t& elapsedTimeNs);
-
-    // Reset all configs.
-    void resetConfigs();
-
-    inline sp<UidMap> getUidMap() {
-        return mUidMap;
-    }
-
-    void dumpStates(int outFd, bool verbose);
-
-    void informPullAlarmFired(const int64_t timestampNs);
-
-    int64_t getLastReportTimeNs(const ConfigKey& key);
-
-    inline void setPrintLogs(bool enabled) {
-        std::lock_guard<std::mutex> lock(mMetricsMutex);
-        mPrintAllLogs = enabled;
-    }
-
-    // Add a specific config key to the possible configs to dump ASAP.
-    void noteOnDiskData(const ConfigKey& key);
-
-    void setAnomalyAlarm(const int64_t timeMillis);
-
-    void cancelAnomalyAlarm();
-
-private:
-    // For testing only.
-    inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
-        return mAnomalyAlarmMonitor;
-    }
-
-    inline sp<AlarmMonitor> getPeriodicAlarmMonitor() const {
-        return mPeriodicAlarmMonitor;
-    }
-
-    mutable mutex mMetricsMutex;
-
-    // Guards mNextAnomalyAlarmTime. A separate mutex is needed because alarms are set/cancelled
-    // in the onLogEvent code path, which is locked by mMetricsMutex.
-    // DO NOT acquire mMetricsMutex while holding mAnomalyAlarmMutex. This can lead to a deadlock.
-    mutable mutex mAnomalyAlarmMutex;
-
-    std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers;
-
-    std::unordered_map<ConfigKey, int64_t> mLastBroadcastTimes;
-
-    // Last time we sent a broadcast to this uid that the active configs had changed.
-    std::unordered_map<int, int64_t> mLastActivationBroadcastTimes;
-
-    // Tracks when we last checked the bytes consumed for each config key.
-    std::unordered_map<ConfigKey, int64_t> mLastByteSizeTimes;
-
-    // Tracks which config keys has metric reports on disk
-    std::set<ConfigKey> mOnDiskDataConfigs;
-
-    sp<UidMap> mUidMap;  // Reference to the UidMap to lookup app name and version for each uid.
-
-    sp<StatsPullerManager> mPullerManager;  // Reference to StatsPullerManager
-
-    sp<AlarmMonitor> mAnomalyAlarmMonitor;
-
-    sp<AlarmMonitor> mPeriodicAlarmMonitor;
-
-    void OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs);
-
-    void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
-
-    void OnConfigUpdatedLocked(const int64_t currentTimestampNs, const ConfigKey& key,
-                               const StatsdConfig& config, bool modularUpdate);
-
-    void GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs);
-
-    void WriteActiveConfigsToProtoOutputStreamLocked(
-            int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
-    void SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
-                                     int64_t currentTimeNs);
-
-    void SetMetadataStateLocked(const metadata::StatsMetadataList& statsMetadataList,
-                                int64_t currentWallClockTimeNs,
-                                int64_t systemElapsedTimeNs);
-
-    void WriteMetadataToProtoLocked(int64_t currentWallClockTimeNs,
-                                    int64_t systemElapsedTimeNs,
-                                    metadata::StatsMetadataList* metadataList);
-
-    void WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
-                               const DumpLatency dumpLatency);
-
-    void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs,
-                               const DumpReportReason dumpReportReason,
-                               const DumpLatency dumpLatency);
-
-    void onConfigMetricsReportLocked(
-            const ConfigKey& key, const int64_t dumpTimeStampNs,
-            const bool include_current_partial_bucket, const bool erase_data,
-            const DumpReportReason dumpReportReason, const DumpLatency dumpLatency,
-            /*if dataSavedToDisk is true, it indicates the caller will write the data to disk
-             (e.g., before reboot). So no need to further persist local history.*/
-            const bool dataSavedToDisk, vector<uint8_t>* proto);
-
-    /* Check if we should send a broadcast if approaching memory limits and if we're over, we
-     * actually delete the data. */
-    void flushIfNecessaryLocked(const ConfigKey& key, MetricsManager& metricsManager);
-
-    // Maps the isolated uid in the log event to host uid if the log event contains uid fields.
-    void mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const;
-
-    // Handler over the isolated uid change event.
-    void onIsolatedUidChangedEventLocked(const LogEvent& event);
-
-    // Handler over the binary push state changed event.
-    void onBinaryPushStateChangedEventLocked(LogEvent* event);
-
-    // Handler over the watchdog rollback occurred event.
-    void onWatchdogRollbackOccurredLocked(LogEvent* event);
-
-    // Updates train info on disk based on binary push state changed info and
-    // write disk info into parameters.
-    void getAndUpdateTrainInfoOnDisk(bool is_rollback, InstallTrainInfo* trainInfoIn);
-
-    // Gets experiment ids on disk for associated train and updates them
-    // depending on rollback type. Then writes them back to disk and returns
-    // them.
-    std::vector<int64_t> processWatchdogRollbackOccurred(const int32_t rollbackTypeIn,
-                                                          const string& packageName);
-
-    // Reset all configs.
-    void resetConfigsLocked(const int64_t timestampNs);
-    // Reset the specified configs.
-    void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs);
-
-    // An anomaly alarm should have fired.
-    // Check with anomaly alarm manager to find the alarms and process the result.
-    void informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis);
-
-    /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
-    void processFiredAnomalyAlarmsLocked(
-            const int64_t& timestampNs,
-            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
-
-    // Function used to send a broadcast so that receiver for the config key can call getData
-    // to retrieve the stored data.
-    std::function<bool(const ConfigKey& key)> mSendBroadcast;
-
-    // Function used to send a broadcast so that receiver can be notified of which configs
-    // are currently active.
-    std::function<bool(const int& uid, const vector<int64_t>& configIds)> mSendActivationBroadcast;
-
-    const int64_t mTimeBaseNs;
-
-    // Largest timestamp of the events that we have processed.
-    int64_t mLargestTimestampSeen = 0;
-
-    int64_t mLastTimestampSeen = 0;
-
-    int64_t mLastPullerCacheClearTimeSec = 0;
-
-    // Last time we wrote data to disk.
-    int64_t mLastWriteTimeNs = 0;
-
-    // Last time we wrote active metrics to disk.
-    int64_t mLastActiveMetricsWriteNs = 0;
-
-    //Last time we wrote metadata to disk.
-    int64_t mLastMetadataWriteNs = 0;
-
-    // The time for the next anomaly alarm for alerts.
-    int64_t mNextAnomalyAlarmTime = 0;
-
-    bool mPrintAllLogs = false;
-
-    FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs);
-    FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize);
-    FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast);
-    FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
-    FRIEND_TEST(StatsLogProcessorTest, InvalidConfigRemoved);
-    FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
-    FRIEND_TEST(StatsLogProcessorTest,
-            TestActivationOnBootMultipleActivationsDifferentActivationTypes);
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-
-    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
-    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
-    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3);
-    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1);
-    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2);
-    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3);
-    FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1);
-    FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2);
-    FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
-    FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
-    FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
-    FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents);
-
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-
-    FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
-    FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
-
-    FRIEND_TEST(ConfigUpdateE2eAbTest, TestHashStrings);
-    FRIEND_TEST(ConfigUpdateE2eAbTest, TestUidMapVersionStringInstaller);
-    FRIEND_TEST(ConfigUpdateE2eAbTest, TestConfigTtl);
-
-    FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
-    FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
-    FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
-    FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
-    FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
-
-    FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
-    FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
-    FRIEND_TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
-
-    FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
-    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
-    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
-    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
deleted file mode 100644
index 68c2dd5..0000000
--- a/cmds/statsd/src/StatsService.cpp
+++ /dev/null
@@ -1,1312 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsService.h"
-#include "stats_log_util.h"
-#include "android-base/stringprintf.h"
-#include "config/ConfigKey.h"
-#include "config/ConfigManager.h"
-#include "guardrail/StatsdStats.h"
-#include "storage/StorageManager.h"
-#include "subscriber/SubscriberReporter.h"
-
-#include <android-base/file.h>
-#include <android-base/strings.h>
-#include <cutils/multiuser.h>
-#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
-#include <frameworks/base/cmds/statsd/src/uid_data.pb.h>
-#include <private/android_filesystem_config.h>
-#include <statslog_statsd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/system_properties.h>
-#include <unistd.h>
-#include <utils/String16.h>
-
-using namespace android;
-
-using android::base::StringPrintf;
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_MESSAGE;
-
-using Status = ::ndk::ScopedAStatus;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-constexpr const char* kPermissionDump = "android.permission.DUMP";
-
-constexpr const char* kPermissionRegisterPullAtom = "android.permission.REGISTER_STATS_PULL_ATOM";
-
-#define STATS_SERVICE_DIR "/data/misc/stats-service"
-
-// for StatsDataDumpProto
-const int FIELD_ID_REPORTS_LIST = 1;
-
-static Status exception(int32_t code, const std::string& msg) {
-    ALOGE("%s (%d)", msg.c_str(), code);
-    return Status::fromExceptionCodeWithMessage(code, msg.c_str());
-}
-
-static bool checkPermission(const char* permission) {
-    pid_t pid = AIBinder_getCallingPid();
-    uid_t uid = AIBinder_getCallingUid();
-    return checkPermissionForIds(permission, pid, uid);
-}
-
-Status checkUid(uid_t expectedUid) {
-    uid_t uid = AIBinder_getCallingUid();
-    if (uid == expectedUid || uid == AID_ROOT) {
-        return Status::ok();
-    } else {
-        return exception(EX_SECURITY,
-                         StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
-    }
-}
-
-#define ENFORCE_UID(uid) {                                        \
-    Status status = checkUid((uid));                              \
-    if (!status.isOk()) {                                         \
-        return status;                                            \
-    }                                                             \
-}
-
-StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue)
-    : mAnomalyAlarmMonitor(new AlarmMonitor(
-              MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
-              [this](const shared_ptr<IStatsCompanionService>& /*sc*/, int64_t timeMillis) {
-                  mProcessor->setAnomalyAlarm(timeMillis);
-                  StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
-              },
-              [this](const shared_ptr<IStatsCompanionService>& /*sc*/) {
-                  mProcessor->cancelAnomalyAlarm();
-                  StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
-              })),
-      mPeriodicAlarmMonitor(new AlarmMonitor(
-              MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
-              [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) {
-                  if (sc != nullptr) {
-                      sc->setAlarmForSubscriberTriggering(timeMillis);
-                      StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
-                  }
-              },
-              [](const shared_ptr<IStatsCompanionService>& sc) {
-                  if (sc != nullptr) {
-                      sc->cancelAlarmForSubscriberTriggering();
-                      StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
-                  }
-              })),
-      mEventQueue(queue),
-      mBootCompleteTrigger({kBootCompleteTag, kUidMapReceivedTag, kAllPullersRegisteredTag},
-                           [this]() { mProcessor->onStatsdInitCompleted(getElapsedRealtimeNs()); }),
-      mStatsCompanionServiceDeathRecipient(
-              AIBinder_DeathRecipient_new(StatsService::statsCompanionServiceDied)) {
-    mUidMap = UidMap::getInstance();
-    mPullerManager = new StatsPullerManager();
-    StatsPuller::SetUidMap(mUidMap);
-    mConfigManager = new ConfigManager();
-    mProcessor = new StatsLogProcessor(
-            mUidMap, mPullerManager, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor,
-            getElapsedRealtimeNs(),
-            [this](const ConfigKey& key) {
-                shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
-                if (receiver == nullptr) {
-                    VLOG("Could not find a broadcast receiver for %s", key.ToString().c_str());
-                    return false;
-                } else if (receiver->sendDataBroadcast(
-                           mProcessor->getLastReportTimeNs(key)).isOk()) {
-                    return true;
-                } else {
-                    VLOG("Failed to send a broadcast for receiver %s", key.ToString().c_str());
-                    return false;
-                }
-            },
-            [this](const int& uid, const vector<int64_t>& activeConfigs) {
-                shared_ptr<IPendingIntentRef> receiver =
-                    mConfigManager->GetActiveConfigsChangedReceiver(uid);
-                if (receiver == nullptr) {
-                    VLOG("Could not find receiver for uid %d", uid);
-                    return false;
-                } else if (receiver->sendActiveConfigsChangedBroadcast(activeConfigs).isOk()) {
-                    VLOG("StatsService::active configs broadcast succeeded for uid %d" , uid);
-                    return true;
-                } else {
-                    VLOG("StatsService::active configs broadcast failed for uid %d" , uid);
-                    return false;
-                }
-            });
-
-    mUidMap->setListener(mProcessor);
-    mConfigManager->AddListener(mProcessor);
-
-    init_system_properties();
-
-    if (mEventQueue != nullptr) {
-        std::thread pushedEventThread([this] { readLogs(); });
-        pushedEventThread.detach();
-    }
-}
-
-StatsService::~StatsService() {
-}
-
-/* Runs on a dedicated thread to process pushed events. */
-void StatsService::readLogs() {
-    // Read forever..... long live statsd
-    while (1) {
-        // Block until an event is available.
-        auto event = mEventQueue->waitPop();
-        // Pass it to StatsLogProcess to all configs/metrics
-        // At this point, the LogEventQueue is not blocked, so that the socketListener
-        // can read events from the socket and write to buffer to avoid data drop.
-        mProcessor->OnLogEvent(event.get());
-        // The ShellSubscriber is only used by shell for local debugging.
-        if (mShellSubscriber != nullptr) {
-            mShellSubscriber->onLogEvent(*event);
-        }
-    }
-}
-
-void StatsService::init_system_properties() {
-    mEngBuild = false;
-    const prop_info* buildType = __system_property_find("ro.build.type");
-    if (buildType != NULL) {
-        __system_property_read_callback(buildType, init_build_type_callback, this);
-    }
-}
-
-void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value,
-                                            uint32_t serial) {
-    if (0 == strcmp("eng", value) || 0 == strcmp("userdebug", value)) {
-        reinterpret_cast<StatsService*>(cookie)->mEngBuild = true;
-    }
-}
-
-/**
- * Write data from statsd.
- * Format for statsdStats:  adb shell dumpsys stats --metadata [-v] [--proto]
- * Format for data report:  adb shell dumpsys stats [anything other than --metadata] [--proto]
- * Anything ending in --proto will be in proto format.
- * Anything without --metadata as the first argument will be report information.
- *     (bugreports call "adb shell dumpsys stats --dump-priority NORMAL -a --proto")
- * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>.
- */
-status_t StatsService::dump(int fd, const char** args, uint32_t numArgs) {
-    if (!checkPermission(kPermissionDump)) {
-        return PERMISSION_DENIED;
-    }
-
-    int lastArg = numArgs - 1;
-    bool asProto = false;
-    if (lastArg >= 0 && string(args[lastArg]) == "--proto") { // last argument
-        asProto = true;
-        lastArg--;
-    }
-    if (numArgs > 0 && string(args[0]) == "--metadata") { // first argument
-        // Request is to dump statsd stats.
-        bool verbose = false;
-        if (lastArg >= 0 && string(args[lastArg]) == "-v") {
-            verbose = true;
-            lastArg--;
-        }
-        dumpStatsdStats(fd, verbose, asProto);
-    } else {
-        // Request is to dump statsd report data.
-        if (asProto) {
-            dumpIncidentSection(fd);
-        } else {
-            dprintf(fd, "Non-proto format of stats data dump not available; see proto version.\n");
-        }
-    }
-
-    return NO_ERROR;
-}
-
-/**
- * Write debugging data about statsd in text or proto format.
- */
-void StatsService::dumpStatsdStats(int out, bool verbose, bool proto) {
-    if (proto) {
-        vector<uint8_t> data;
-        StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats.
-        for (size_t i = 0; i < data.size(); i ++) {
-            dprintf(out, "%c", data[i]);
-        }
-    } else {
-        StatsdStats::getInstance().dumpStats(out);
-        mProcessor->dumpStates(out, verbose);
-    }
-}
-
-/**
- * Write stats report data in StatsDataDumpProto incident section format.
- */
-void StatsService::dumpIncidentSection(int out) {
-    ProtoOutputStream proto;
-    for (const ConfigKey& configKey : mConfigManager->GetAllConfigKeys()) {
-        uint64_t reportsListToken =
-                proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS_LIST);
-        // Don't include the current bucket to avoid skipping buckets.
-        // If we need to include the current bucket later, consider changing to NO_TIME_CONSTRAINTS
-        // or other alternatives to avoid skipping buckets for pulled metrics.
-        mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(),
-                                 false /* includeCurrentBucket */, false /* erase_data */,
-                                 ADB_DUMP,
-                                 FAST,
-                                 &proto);
-        proto.end(reportsListToken);
-        proto.flush(out);
-        proto.clear();
-    }
-}
-
-/**
- * Implementation of the adb shell cmd stats command.
- */
-status_t StatsService::handleShellCommand(int in, int out, int err, const char** argv,
-                                          uint32_t argc) {
-    uid_t uid = AIBinder_getCallingUid();
-    if (uid != AID_ROOT && uid != AID_SHELL) {
-        return PERMISSION_DENIED;
-    }
-
-    Vector<String8> utf8Args;
-    utf8Args.setCapacity(argc);
-    for (uint32_t i = 0; i < argc; i++) {
-        utf8Args.push(String8(argv[i]));
-    }
-
-    if (argc >= 1) {
-        // adb shell cmd stats config ...
-        if (!utf8Args[0].compare(String8("config"))) {
-            return cmd_config(in, out, err, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("print-uid-map"))) {
-            return cmd_print_uid_map(out, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("dump-report"))) {
-            return cmd_dump_report(out, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("pull-source")) && argc > 1) {
-            return cmd_print_pulled_metrics(out, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("send-broadcast"))) {
-            return cmd_trigger_broadcast(out, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("print-stats"))) {
-            return cmd_print_stats(out, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("meminfo"))) {
-            return cmd_dump_memory_info(out);
-        }
-
-        if (!utf8Args[0].compare(String8("write-to-disk"))) {
-            return cmd_write_data_to_disk(out);
-        }
-
-        if (!utf8Args[0].compare(String8("log-app-breadcrumb"))) {
-            return cmd_log_app_breadcrumb(out, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("log-binary-push"))) {
-            return cmd_log_binary_push(out, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("clear-puller-cache"))) {
-            return cmd_clear_puller_cache(out);
-        }
-
-        if (!utf8Args[0].compare(String8("print-logs"))) {
-            return cmd_print_logs(out, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("send-active-configs"))) {
-            return cmd_trigger_active_config_broadcast(out, utf8Args);
-        }
-
-        if (!utf8Args[0].compare(String8("data-subscribe"))) {
-            {
-                std::lock_guard<std::mutex> lock(mShellSubscriberMutex);
-                if (mShellSubscriber == nullptr) {
-                    mShellSubscriber = new ShellSubscriber(mUidMap, mPullerManager);
-                }
-            }
-            int timeoutSec = -1;
-            if (argc >= 2) {
-                timeoutSec = atoi(utf8Args[1].c_str());
-            }
-            mShellSubscriber->startNewSubscription(in, out, timeoutSec);
-            return NO_ERROR;
-        }
-    }
-
-    print_cmd_help(out);
-    return NO_ERROR;
-}
-
-void StatsService::print_cmd_help(int out) {
-    dprintf(out,
-            "usage: adb shell cmd stats print-stats-log [tag_required] "
-            "[timestamp_nsec_optional]\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats meminfo\n");
-    dprintf(out, "\n");
-    dprintf(out, "  Prints the malloc debug information. You need to run the following first: \n");
-    dprintf(out, "   # adb shell stop\n");
-    dprintf(out, "   # adb shell setprop libc.debug.malloc.program statsd \n");
-    dprintf(out, "   # adb shell setprop libc.debug.malloc.options backtrace \n");
-    dprintf(out, "   # adb shell start\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats print-uid-map [PKG]\n");
-    dprintf(out, "\n");
-    dprintf(out, "  Prints the UID, app name, version mapping.\n");
-    dprintf(out, "  PKG           Optional package name to print the uids of the package\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats pull-source ATOM_TAG [PACKAGE] \n");
-    dprintf(out, "\n");
-    dprintf(out, "  Prints the output of a pulled atom\n");
-    dprintf(out, "  UID           The atom to pull\n");
-    dprintf(out, "  PACKAGE       The package to pull from. Default is AID_SYSTEM\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats write-to-disk \n");
-    dprintf(out, "\n");
-    dprintf(out, "  Flushes all data on memory to disk.\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats log-app-breadcrumb [UID] LABEL STATE\n");
-    dprintf(out, "  Writes an AppBreadcrumbReported event to the statslog buffer.\n");
-    dprintf(out, "  UID           The uid to use. It is only possible to pass a UID\n");
-    dprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
-    dprintf(out, "                uid is used.\n");
-    dprintf(out, "  LABEL         Integer in [0, 15], as per atoms.proto.\n");
-    dprintf(out, "  STATE         Integer in [0, 3], as per atoms.proto.\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out,
-            "usage: adb shell cmd stats log-binary-push NAME VERSION STAGING ROLLBACK_ENABLED "
-            "LOW_LATENCY STATE EXPERIMENT_IDS\n");
-    dprintf(out, "  Log a binary push state changed event.\n");
-    dprintf(out, "  NAME                The train name.\n");
-    dprintf(out, "  VERSION             The train version code.\n");
-    dprintf(out, "  STAGING             If this train requires a restart.\n");
-    dprintf(out, "  ROLLBACK_ENABLED    If rollback should be enabled for this install.\n");
-    dprintf(out, "  LOW_LATENCY         If the train requires low latency monitoring.\n");
-    dprintf(out, "  STATE               The status of the train push.\n");
-    dprintf(out, "                      Integer value of the enum in atoms.proto.\n");
-    dprintf(out, "  EXPERIMENT_IDS      Comma separated list of experiment ids.\n");
-    dprintf(out, "                      Leave blank for none.\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats config remove [UID] [NAME]\n");
-    dprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n");
-    dprintf(out, "\n");
-    dprintf(out, "  Adds, updates or removes a configuration. The proto should be in\n");
-    dprintf(out, "  wire-encoded protobuf format and passed via stdin. If no UID and name is\n");
-    dprintf(out, "  provided, then all configs will be removed from memory and disk.\n");
-    dprintf(out, "\n");
-    dprintf(out, "  UID           The uid to use. It is only possible to pass the UID\n");
-    dprintf(out, "                parameter on eng builds. If UID is omitted the calling\n");
-    dprintf(out, "                uid is used.\n");
-    dprintf(out, "  NAME          The per-uid name to use\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n              *Note: If both UID and NAME are omitted then all configs will\n");
-    dprintf(out, "\n                     be removed from memory and disk!\n");
-    dprintf(out, "\n");
-    dprintf(out,
-            "usage: adb shell cmd stats dump-report [UID] NAME [--keep_data] "
-            "[--include_current_bucket] [--proto]\n");
-    dprintf(out, "  Dump all metric data for a configuration.\n");
-    dprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
-    dprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
-    dprintf(out, "                calling uid is used.\n");
-    dprintf(out, "  NAME          The name of the configuration\n");
-    dprintf(out, "  --keep_data   Do NOT erase the data upon dumping it.\n");
-    dprintf(out, "  --proto       Print proto binary.\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats send-broadcast [UID] NAME\n");
-    dprintf(out, "  Send a broadcast that triggers the subscriber to fetch metrics.\n");
-    dprintf(out, "  UID           The uid of the configuration. It is only possible to pass\n");
-    dprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
-    dprintf(out, "                calling uid is used.\n");
-    dprintf(out, "  NAME          The name of the configuration\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out,
-            "usage: adb shell cmd stats send-active-configs [--uid=UID] [--configs] "
-            "[NAME1] [NAME2] [NAME3..]\n");
-    dprintf(out, "  Send a broadcast that informs the subscriber of the current active configs.\n");
-    dprintf(out, "  --uid=UID     The uid of the configurations. It is only possible to pass\n");
-    dprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
-    dprintf(out, "                calling uid is used.\n");
-    dprintf(out, "  --configs     Send the list of configs in the name list instead of\n");
-    dprintf(out, "                the currently active configs\n");
-    dprintf(out, "  NAME LIST     List of configuration names to be included in the broadcast.\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats print-stats\n");
-    dprintf(out, "  Prints some basic stats.\n");
-    dprintf(out, "  --proto       Print proto binary instead of string format.\n");
-    dprintf(out, "\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats clear-puller-cache\n");
-    dprintf(out, "  Clear cached puller data.\n");
-    dprintf(out, "\n");
-    dprintf(out, "usage: adb shell cmd stats print-logs\n");
-    dprintf(out, "  Requires root privileges.\n");
-    dprintf(out, "  Can be disabled by calling adb shell cmd stats print-logs 0\n");
-}
-
-status_t StatsService::cmd_trigger_broadcast(int out, Vector<String8>& args) {
-    string name;
-    bool good = false;
-    int uid;
-    const int argCount = args.size();
-    if (argCount == 2) {
-        // Automatically pick the UID
-        uid = AIBinder_getCallingUid();
-        name.assign(args[1].c_str(), args[1].size());
-        good = true;
-    } else if (argCount == 3) {
-        good = getUidFromArgs(args, 1, uid);
-        if (!good) {
-            dprintf(out, "Invalid UID. Note that the metrics can only be dumped for "
-                         "other UIDs on eng or userdebug builds.\n");
-        }
-        name.assign(args[2].c_str(), args[2].size());
-    }
-    if (!good) {
-        print_cmd_help(out);
-        return UNKNOWN_ERROR;
-    }
-    ConfigKey key(uid, StrToInt64(name));
-    shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetConfigReceiver(key);
-    if (receiver == nullptr) {
-        VLOG("Could not find receiver for %s, %s", args[1].c_str(), args[2].c_str());
-        return UNKNOWN_ERROR;
-    } else if (receiver->sendDataBroadcast(mProcessor->getLastReportTimeNs(key)).isOk()) {
-        VLOG("StatsService::trigger broadcast succeeded to %s, %s", args[1].c_str(),
-             args[2].c_str());
-    } else {
-        VLOG("StatsService::trigger broadcast failed to %s, %s", args[1].c_str(), args[2].c_str());
-        return UNKNOWN_ERROR;
-    }
-    return NO_ERROR;
-}
-
-status_t StatsService::cmd_trigger_active_config_broadcast(int out, Vector<String8>& args) {
-    const int argCount = args.size();
-    int uid;
-    vector<int64_t> configIds;
-    if (argCount == 1) {
-        // Automatically pick the uid and send a broadcast that has no active configs.
-        uid = AIBinder_getCallingUid();
-        mProcessor->GetActiveConfigs(uid, configIds);
-    } else {
-        int curArg = 1;
-        if(args[curArg].find("--uid=") == 0) {
-            string uidArgStr(args[curArg].c_str());
-            string uidStr = uidArgStr.substr(6);
-            if (!getUidFromString(uidStr.c_str(), uid)) {
-                dprintf(out, "Invalid UID. Note that the config can only be set for "
-                             "other UIDs on eng or userdebug builds.\n");
-                return UNKNOWN_ERROR;
-            }
-            curArg++;
-        } else {
-            uid = AIBinder_getCallingUid();
-        }
-        if (curArg == argCount || args[curArg] != "--configs") {
-            VLOG("Reached end of args, or specify configs not set. Sending actual active configs,");
-            mProcessor->GetActiveConfigs(uid, configIds);
-        } else {
-            // Flag specified, use the given list of configs.
-            curArg++;
-            for (int i = curArg; i < argCount; i++) {
-                char* endp;
-                int64_t configID = strtoll(args[i].c_str(), &endp, 10);
-                if (endp == args[i].c_str() || *endp != '\0') {
-                    dprintf(out, "Error parsing config ID.\n");
-                    return UNKNOWN_ERROR;
-                }
-                VLOG("Adding config id %ld", static_cast<long>(configID));
-                configIds.push_back(configID);
-            }
-        }
-    }
-    shared_ptr<IPendingIntentRef> receiver = mConfigManager->GetActiveConfigsChangedReceiver(uid);
-    if (receiver == nullptr) {
-        VLOG("Could not find receiver for uid %d", uid);
-        return UNKNOWN_ERROR;
-    } else if (receiver->sendActiveConfigsChangedBroadcast(configIds).isOk()) {
-        VLOG("StatsService::trigger active configs changed broadcast succeeded for uid %d" , uid);
-    } else {
-        VLOG("StatsService::trigger active configs changed broadcast failed for uid %d", uid);
-        return UNKNOWN_ERROR;
-    }
-    return NO_ERROR;
-}
-
-status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& args) {
-    const int argCount = args.size();
-    if (argCount >= 2) {
-        if (args[1] == "update" || args[1] == "remove") {
-            bool good = false;
-            int uid = -1;
-            string name;
-
-            if (argCount == 3) {
-                // Automatically pick the UID
-                uid = AIBinder_getCallingUid();
-                name.assign(args[2].c_str(), args[2].size());
-                good = true;
-            } else if (argCount == 4) {
-                good = getUidFromArgs(args, 2, uid);
-                if (!good) {
-                    dprintf(err, "Invalid UID. Note that the config can only be set for "
-                                 "other UIDs on eng or userdebug builds.\n");
-                }
-                name.assign(args[3].c_str(), args[3].size());
-            } else if (argCount == 2 && args[1] == "remove") {
-                good = true;
-            }
-
-            if (!good) {
-                // If arg parsing failed, print the help text and return an error.
-                print_cmd_help(out);
-                return UNKNOWN_ERROR;
-            }
-
-            if (args[1] == "update") {
-                char* endp;
-                int64_t configID = strtoll(name.c_str(), &endp, 10);
-                if (endp == name.c_str() || *endp != '\0') {
-                    dprintf(err, "Error parsing config ID.\n");
-                    return UNKNOWN_ERROR;
-                }
-
-                // Read stream into buffer.
-                string buffer;
-                if (!android::base::ReadFdToString(in, &buffer)) {
-                    dprintf(err, "Error reading stream for StatsConfig.\n");
-                    return UNKNOWN_ERROR;
-                }
-
-                // Parse buffer.
-                StatsdConfig config;
-                if (!config.ParseFromString(buffer)) {
-                    dprintf(err, "Error parsing proto stream for StatsConfig.\n");
-                    return UNKNOWN_ERROR;
-                }
-
-                // Add / update the config.
-                mConfigManager->UpdateConfig(ConfigKey(uid, configID), config);
-            } else {
-                if (argCount == 2) {
-                    cmd_remove_all_configs(out);
-                } else {
-                    // Remove the config.
-                    mConfigManager->RemoveConfig(ConfigKey(uid, StrToInt64(name)));
-                }
-            }
-
-            return NO_ERROR;
-        }
-    }
-    print_cmd_help(out);
-    return UNKNOWN_ERROR;
-}
-
-status_t StatsService::cmd_dump_report(int out, const Vector<String8>& args) {
-    if (mProcessor != nullptr) {
-        int argCount = args.size();
-        bool good = false;
-        bool proto = false;
-        bool includeCurrentBucket = false;
-        bool eraseData = true;
-        int uid;
-        string name;
-        if (!std::strcmp("--proto", args[argCount-1].c_str())) {
-            proto = true;
-            argCount -= 1;
-        }
-        if (!std::strcmp("--include_current_bucket", args[argCount-1].c_str())) {
-            includeCurrentBucket = true;
-            argCount -= 1;
-        }
-        if (!std::strcmp("--keep_data", args[argCount-1].c_str())) {
-            eraseData = false;
-            argCount -= 1;
-        }
-        if (argCount == 2) {
-            // Automatically pick the UID
-            uid = AIBinder_getCallingUid();
-            name.assign(args[1].c_str(), args[1].size());
-            good = true;
-        } else if (argCount == 3) {
-            good = getUidFromArgs(args, 1, uid);
-            if (!good) {
-                dprintf(out, "Invalid UID. Note that the metrics can only be dumped for "
-                             "other UIDs on eng or userdebug builds.\n");
-            }
-            name.assign(args[2].c_str(), args[2].size());
-        }
-        if (good) {
-            vector<uint8_t> data;
-            mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
-                                     includeCurrentBucket, eraseData, ADB_DUMP,
-                                     NO_TIME_CONSTRAINTS,
-                                     &data);
-            if (proto) {
-                for (size_t i = 0; i < data.size(); i ++) {
-                    dprintf(out, "%c", data[i]);
-                }
-            } else {
-                dprintf(out, "Non-proto stats data dump not currently supported.\n");
-            }
-            return android::OK;
-        } else {
-            // If arg parsing failed, print the help text and return an error.
-            print_cmd_help(out);
-            return UNKNOWN_ERROR;
-        }
-    } else {
-        dprintf(out, "Log processor does not exist...\n");
-        return UNKNOWN_ERROR;
-    }
-}
-
-status_t StatsService::cmd_print_stats(int out, const Vector<String8>& args) {
-    int argCount = args.size();
-    bool proto = false;
-    if (!std::strcmp("--proto", args[argCount-1].c_str())) {
-        proto = true;
-        argCount -= 1;
-    }
-    StatsdStats& statsdStats = StatsdStats::getInstance();
-    if (proto) {
-        vector<uint8_t> data;
-        statsdStats.dumpStats(&data, false); // does not reset statsdStats.
-        for (size_t i = 0; i < data.size(); i ++) {
-            dprintf(out, "%c", data[i]);
-        }
-
-    } else {
-        vector<ConfigKey> configs = mConfigManager->GetAllConfigKeys();
-        for (const ConfigKey& key : configs) {
-            dprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(),
-                    mProcessor->GetMetricsSize(key));
-        }
-        statsdStats.dumpStats(out);
-    }
-    return NO_ERROR;
-}
-
-status_t StatsService::cmd_print_uid_map(int out, const Vector<String8>& args) {
-    if (args.size() > 1) {
-        string pkg;
-        pkg.assign(args[1].c_str(), args[1].size());
-        auto uids = mUidMap->getAppUid(pkg);
-        dprintf(out, "%s -> [ ", pkg.c_str());
-        for (const auto& uid : uids) {
-            dprintf(out, "%d ", uid);
-        }
-        dprintf(out, "]\n");
-    } else {
-        mUidMap->printUidMap(out);
-    }
-    return NO_ERROR;
-}
-
-status_t StatsService::cmd_write_data_to_disk(int out) {
-    dprintf(out, "Writing data to disk\n");
-    mProcessor->WriteDataToDisk(ADB_DUMP, NO_TIME_CONSTRAINTS);
-    return NO_ERROR;
-}
-
-status_t StatsService::cmd_log_app_breadcrumb(int out, const Vector<String8>& args) {
-    bool good = false;
-    int32_t uid;
-    int32_t label;
-    int32_t state;
-    const int argCount = args.size();
-    if (argCount == 3) {
-        // Automatically pick the UID
-        uid = AIBinder_getCallingUid();
-        label = atoi(args[1].c_str());
-        state = atoi(args[2].c_str());
-        good = true;
-    } else if (argCount == 4) {
-        good = getUidFromArgs(args, 1, uid);
-        if (!good) {
-            dprintf(out,
-                    "Invalid UID. Note that selecting a UID for writing AppBreadcrumb can only be "
-                    "done for other UIDs on eng or userdebug builds.\n");
-        }
-        label = atoi(args[2].c_str());
-        state = atoi(args[3].c_str());
-    }
-    if (good) {
-        dprintf(out, "Logging AppBreadcrumbReported(%d, %d, %d) to statslog.\n", uid, label, state);
-        android::os::statsd::util::stats_write(
-                android::os::statsd::util::APP_BREADCRUMB_REPORTED, uid, label, state);
-    } else {
-        print_cmd_help(out);
-        return UNKNOWN_ERROR;
-    }
-    return NO_ERROR;
-}
-
-status_t StatsService::cmd_log_binary_push(int out, const Vector<String8>& args) {
-    // Security checks are done in the sendBinaryPushStateChanged atom.
-    const int argCount = args.size();
-    if (argCount != 7 && argCount != 8) {
-        dprintf(out, "Incorrect number of argument supplied\n");
-        return UNKNOWN_ERROR;
-    }
-    string trainName = string(args[1].c_str());
-    int64_t trainVersion = strtoll(args[2].c_str(), nullptr, 10);
-    int32_t state = atoi(args[6].c_str());
-    vector<int64_t> experimentIds;
-    if (argCount == 8) {
-        vector<string> experimentIdsString = android::base::Split(string(args[7].c_str()), ",");
-        for (string experimentIdString : experimentIdsString) {
-            int64_t experimentId = strtoll(experimentIdString.c_str(), nullptr, 10);
-            experimentIds.push_back(experimentId);
-        }
-    }
-    dprintf(out, "Logging BinaryPushStateChanged\n");
-    vector<uint8_t> experimentIdBytes;
-    writeExperimentIdsToProto(experimentIds, &experimentIdBytes);
-    LogEvent event(trainName, trainVersion, args[3], args[4], args[5], state, experimentIdBytes, 0);
-    mProcessor->OnLogEvent(&event);
-    return NO_ERROR;
-}
-
-status_t StatsService::cmd_print_pulled_metrics(int out, const Vector<String8>& args) {
-    int s = atoi(args[1].c_str());
-    vector<int32_t> uids;
-    if (args.size() > 2) {
-        string package = string(args[2].c_str());
-        auto it = UidMap::sAidToUidMapping.find(package);
-        if (it != UidMap::sAidToUidMapping.end()) {
-            uids.push_back(it->second);
-        } else {
-            set<int32_t> uids_set = mUidMap->getAppUid(package);
-            uids.insert(uids.end(), uids_set.begin(), uids_set.end());
-        }
-    } else {
-        uids.push_back(AID_SYSTEM);
-    }
-    vector<shared_ptr<LogEvent>> stats;
-    if (mPullerManager->Pull(s, uids, getElapsedRealtimeNs(), &stats)) {
-        for (const auto& it : stats) {
-            dprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
-        }
-        dprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size());
-        return NO_ERROR;
-    }
-    return UNKNOWN_ERROR;
-}
-
-status_t StatsService::cmd_remove_all_configs(int out) {
-    dprintf(out, "Removing all configs...\n");
-    VLOG("StatsService::cmd_remove_all_configs was called");
-    mConfigManager->RemoveAllConfigs();
-    StorageManager::deleteAllFiles(STATS_SERVICE_DIR);
-    return NO_ERROR;
-}
-
-status_t StatsService::cmd_dump_memory_info(int out) {
-    dprintf(out, "meminfo not available.\n");
-    return NO_ERROR;
-}
-
-status_t StatsService::cmd_clear_puller_cache(int out) {
-    VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i",
-            AIBinder_getCallingPid(), AIBinder_getCallingUid());
-    if (checkPermission(kPermissionDump)) {
-        int cleared = mPullerManager->ForceClearPullerCache();
-        dprintf(out, "Puller removed %d cached data!\n", cleared);
-        return NO_ERROR;
-    } else {
-        return PERMISSION_DENIED;
-    }
-}
-
-status_t StatsService::cmd_print_logs(int out, const Vector<String8>& args) {
-    Status status = checkUid(AID_ROOT);
-    if (!status.isOk()) {
-        return PERMISSION_DENIED;
-    }
-
-    VLOG("StatsService::cmd_print_logs with pid %i, uid %i", AIBinder_getCallingPid(),
-         AIBinder_getCallingUid());
-    bool enabled = true;
-    if (args.size() >= 2) {
-        enabled = atoi(args[1].c_str()) != 0;
-    }
-    mProcessor->setPrintLogs(enabled);
-    return NO_ERROR;
-}
-
-bool StatsService::getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid) {
-    return getUidFromString(args[uidArgIndex].c_str(), uid);
-}
-
-bool StatsService::getUidFromString(const char* s, int32_t& uid) {
-    if (*s == '\0') {
-        return false;
-    }
-    char* endc = NULL;
-    int64_t longUid = strtol(s, &endc, 0);
-    if (*endc != '\0') {
-        return false;
-    }
-    int32_t goodUid = static_cast<int32_t>(longUid);
-    if (longUid < 0 || static_cast<uint64_t>(longUid) != static_cast<uid_t>(goodUid)) {
-        return false;  // It was not of uid_t type.
-    }
-    uid = goodUid;
-
-    int32_t callingUid = AIBinder_getCallingUid();
-    return mEngBuild // UserDebug/EngBuild are allowed to impersonate uids.
-            || (callingUid == goodUid) // Anyone can 'impersonate' themselves.
-            || (callingUid == AID_ROOT && goodUid == AID_SHELL); // ROOT can impersonate SHELL.
-}
-
-Status StatsService::informAllUidData(const ScopedFileDescriptor& fd) {
-    ENFORCE_UID(AID_SYSTEM);
-    // Read stream into buffer.
-    string buffer;
-    if (!android::base::ReadFdToString(fd.get(), &buffer)) {
-        return exception(EX_ILLEGAL_ARGUMENT, "Failed to read all data from the pipe.");
-    }
-
-    // Parse buffer.
-    UidData uidData;
-    if (!uidData.ParseFromString(buffer)) {
-        return exception(EX_ILLEGAL_ARGUMENT, "Error parsing proto stream for UidData.");
-    }
-
-    vector<String16> versionStrings;
-    vector<String16> installers;
-    vector<String16> packageNames;
-    vector<int32_t> uids;
-    vector<int64_t> versions;
-
-    const auto numEntries = uidData.app_info_size();
-    versionStrings.reserve(numEntries);
-    installers.reserve(numEntries);
-    packageNames.reserve(numEntries);
-    uids.reserve(numEntries);
-    versions.reserve(numEntries);
-
-    for (const auto& appInfo: uidData.app_info()) {
-        packageNames.emplace_back(String16(appInfo.package_name().c_str()));
-        uids.push_back(appInfo.uid());
-        versions.push_back(appInfo.version());
-        versionStrings.emplace_back(String16(appInfo.version_string().c_str()));
-        installers.emplace_back(String16(appInfo.installer().c_str()));
-    }
-
-    mUidMap->updateMap(getElapsedRealtimeNs(),
-                       uids,
-                       versions,
-                       versionStrings,
-                       packageNames,
-                       installers);
-
-    mBootCompleteTrigger.markComplete(kUidMapReceivedTag);
-    VLOG("StatsService::informAllUidData UidData proto parsed successfully.");
-    return Status::ok();
-}
-
-Status StatsService::informOnePackage(const string& app, int32_t uid, int64_t version,
-                                      const string& versionString, const string& installer) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::informOnePackage was called");
-    String16 utf16App = String16(app.c_str());
-    String16 utf16VersionString = String16(versionString.c_str());
-    String16 utf16Installer = String16(installer.c_str());
-
-    mUidMap->updateApp(getElapsedRealtimeNs(), utf16App, uid, version, utf16VersionString,
-                       utf16Installer);
-    return Status::ok();
-}
-
-Status StatsService::informOnePackageRemoved(const string& app, int32_t uid) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::informOnePackageRemoved was called");
-    String16 utf16App = String16(app.c_str());
-    mUidMap->removeApp(getElapsedRealtimeNs(), utf16App, uid);
-    mConfigManager->RemoveConfigs(uid);
-    return Status::ok();
-}
-
-Status StatsService::informAlarmForSubscriberTriggeringFired() {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
-    int64_t currentTimeSec = getElapsedRealtimeSec();
-    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
-            mPeriodicAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
-    if (alarmSet.size() > 0) {
-        VLOG("Found periodic alarm fired.");
-        mProcessor->onPeriodicAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet);
-    } else {
-        ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled.");
-    }
-    return Status::ok();
-}
-
-Status StatsService::informPollAlarmFired() {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::informPollAlarmFired was called");
-    mProcessor->informPullAlarmFired(getElapsedRealtimeNs());
-    VLOG("StatsService::informPollAlarmFired succeeded");
-    return Status::ok();
-}
-
-Status StatsService::systemRunning() {
-    ENFORCE_UID(AID_SYSTEM);
-
-    // When system_server is up and running, schedule the dropbox task to run.
-    VLOG("StatsService::systemRunning");
-    sayHiToStatsCompanion();
-    return Status::ok();
-}
-
-Status StatsService::informDeviceShutdown() {
-    ENFORCE_UID(AID_SYSTEM);
-    VLOG("StatsService::informDeviceShutdown");
-    mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST);
-    mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
-    mProcessor->SaveMetadataToDisk(getWallClockNs(), getElapsedRealtimeNs());
-    return Status::ok();
-}
-
-void StatsService::sayHiToStatsCompanion() {
-    shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
-    if (statsCompanion != nullptr) {
-        VLOG("Telling statsCompanion that statsd is ready");
-        statsCompanion->statsdReady();
-    } else {
-        VLOG("Could not access statsCompanion");
-    }
-}
-
-Status StatsService::statsCompanionReady() {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::statsCompanionReady was called");
-    shared_ptr<IStatsCompanionService> statsCompanion = getStatsCompanionService();
-    if (statsCompanion == nullptr) {
-        return exception(EX_NULL_POINTER,
-                         "StatsCompanion unavailable despite it contacting statsd.");
-    }
-    VLOG("StatsService::statsCompanionReady linking to statsCompanion.");
-    AIBinder_linkToDeath(statsCompanion->asBinder().get(),
-                         mStatsCompanionServiceDeathRecipient.get(), this);
-    mPullerManager->SetStatsCompanionService(statsCompanion);
-    mAnomalyAlarmMonitor->setStatsCompanionService(statsCompanion);
-    mPeriodicAlarmMonitor->setStatsCompanionService(statsCompanion);
-    return Status::ok();
-}
-
-Status StatsService::bootCompleted() {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::bootCompleted was called");
-    mBootCompleteTrigger.markComplete(kBootCompleteTag);
-    return Status::ok();
-}
-
-void StatsService::Startup() {
-    mConfigManager->Startup();
-    mProcessor->LoadActiveConfigsFromDisk();
-    mProcessor->LoadMetadataFromDisk(getWallClockNs(), getElapsedRealtimeNs());
-}
-
-void StatsService::Terminate() {
-    ALOGI("StatsService::Terminating");
-    if (mProcessor != nullptr) {
-        mProcessor->WriteDataToDisk(TERMINATION_SIGNAL_RECEIVED, FAST);
-        mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
-        mProcessor->SaveMetadataToDisk(getWallClockNs(), getElapsedRealtimeNs());
-    }
-}
-
-// Test only interface!!!
-void StatsService::OnLogEvent(LogEvent* event) {
-    mProcessor->OnLogEvent(event);
-    if (mShellSubscriber != nullptr) {
-        mShellSubscriber->onLogEvent(*event);
-    }
-}
-
-Status StatsService::getData(int64_t key, const int32_t callingUid, vector<uint8_t>* output) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::getData with Uid %i", callingUid);
-    ConfigKey configKey(callingUid, key);
-    // The dump latency does not matter here since we do not include the current bucket, we do not
-    // need to pull any new data anyhow.
-    mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
-                             true /* erase_data */, GET_DATA_CALLED, FAST, output);
-    return Status::ok();
-}
-
-Status StatsService::getMetadata(vector<uint8_t>* output) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters.
-    return Status::ok();
-}
-
-Status StatsService::addConfiguration(int64_t key, const vector <uint8_t>& config,
-                                      const int32_t callingUid) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    if (addConfigurationChecked(callingUid, key, config)) {
-        return Status::ok();
-    } else {
-        return exception(EX_ILLEGAL_ARGUMENT, "Could not parse malformatted StatsdConfig.");
-    }
-}
-
-bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config) {
-    ConfigKey configKey(uid, key);
-    StatsdConfig cfg;
-    if (config.size() > 0) {  // If the config is empty, skip parsing.
-        if (!cfg.ParseFromArray(&config[0], config.size())) {
-            return false;
-        }
-    }
-    mConfigManager->UpdateConfig(configKey, cfg);
-    return true;
-}
-
-Status StatsService::removeDataFetchOperation(int64_t key,
-                                              const int32_t callingUid) {
-    ENFORCE_UID(AID_SYSTEM);
-    ConfigKey configKey(callingUid, key);
-    mConfigManager->RemoveConfigReceiver(configKey);
-    return Status::ok();
-}
-
-Status StatsService::setDataFetchOperation(int64_t key,
-                                           const shared_ptr<IPendingIntentRef>& pir,
-                                           const int32_t callingUid) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    ConfigKey configKey(callingUid, key);
-    mConfigManager->SetConfigReceiver(configKey, pir);
-    if (StorageManager::hasConfigMetricsReport(configKey)) {
-        VLOG("StatsService::setDataFetchOperation marking configKey %s to dump reports on disk",
-             configKey.ToString().c_str());
-        mProcessor->noteOnDiskData(configKey);
-    }
-    return Status::ok();
-}
-
-Status StatsService::setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir,
-                                                      const int32_t callingUid,
-                                                      vector<int64_t>* output) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    mConfigManager->SetActiveConfigsChangedReceiver(callingUid, pir);
-    if (output != nullptr) {
-        mProcessor->GetActiveConfigs(callingUid, *output);
-    } else {
-        ALOGW("StatsService::setActiveConfigsChanged output was nullptr");
-    }
-    return Status::ok();
-}
-
-Status StatsService::removeActiveConfigsChangedOperation(const int32_t callingUid) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    mConfigManager->RemoveActiveConfigsChangedReceiver(callingUid);
-    return Status::ok();
-}
-
-Status StatsService::removeConfiguration(int64_t key, const int32_t callingUid) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    ConfigKey configKey(callingUid, key);
-    mConfigManager->RemoveConfig(configKey);
-    return Status::ok();
-}
-
-Status StatsService::setBroadcastSubscriber(int64_t configId,
-                                            int64_t subscriberId,
-                                            const shared_ptr<IPendingIntentRef>& pir,
-                                            const int32_t callingUid) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::setBroadcastSubscriber called.");
-    ConfigKey configKey(callingUid, configId);
-    SubscriberReporter::getInstance()
-            .setBroadcastSubscriber(configKey, subscriberId, pir);
-    return Status::ok();
-}
-
-Status StatsService::unsetBroadcastSubscriber(int64_t configId,
-                                              int64_t subscriberId,
-                                              const int32_t callingUid) {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::unsetBroadcastSubscriber called.");
-    ConfigKey configKey(callingUid, configId);
-    SubscriberReporter::getInstance()
-            .unsetBroadcastSubscriber(configKey, subscriberId);
-    return Status::ok();
-}
-
-Status StatsService::allPullersFromBootRegistered() {
-    ENFORCE_UID(AID_SYSTEM);
-
-    VLOG("StatsService::allPullersFromBootRegistered was called");
-    mBootCompleteTrigger.markComplete(kAllPullersRegisteredTag);
-    return Status::ok();
-}
-
-Status StatsService::registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownMillis,
-                                              int64_t timeoutMillis,
-                                              const std::vector<int32_t>& additiveFields,
-                                              const shared_ptr<IPullAtomCallback>& pullerCallback) {
-    ENFORCE_UID(AID_SYSTEM);
-    VLOG("StatsService::registerPullAtomCallback called.");
-    mPullerManager->RegisterPullAtomCallback(uid, atomTag, MillisToNano(coolDownMillis),
-                                             MillisToNano(timeoutMillis), additiveFields,
-                                             pullerCallback);
-    return Status::ok();
-}
-
-Status StatsService::registerNativePullAtomCallback(
-        int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
-        const std::vector<int32_t>& additiveFields,
-        const shared_ptr<IPullAtomCallback>& pullerCallback) {
-    if (!checkPermission(kPermissionRegisterPullAtom)) {
-        return exception(
-                EX_SECURITY,
-                StringPrintf("Uid %d does not have the %s permission when registering atom %d",
-                             AIBinder_getCallingUid(), kPermissionRegisterPullAtom, atomTag));
-    }
-    VLOG("StatsService::registerNativePullAtomCallback called.");
-    int32_t uid = AIBinder_getCallingUid();
-    mPullerManager->RegisterPullAtomCallback(uid, atomTag, MillisToNano(coolDownMillis),
-                                             MillisToNano(timeoutMillis), additiveFields,
-                                             pullerCallback);
-    return Status::ok();
-}
-
-Status StatsService::unregisterPullAtomCallback(int32_t uid, int32_t atomTag) {
-    ENFORCE_UID(AID_SYSTEM);
-    VLOG("StatsService::unregisterPullAtomCallback called.");
-    mPullerManager->UnregisterPullAtomCallback(uid, atomTag);
-    return Status::ok();
-}
-
-Status StatsService::unregisterNativePullAtomCallback(int32_t atomTag) {
-    if (!checkPermission(kPermissionRegisterPullAtom)) {
-        return exception(
-                EX_SECURITY,
-                StringPrintf("Uid %d does not have the %s permission when unregistering atom %d",
-                             AIBinder_getCallingUid(), kPermissionRegisterPullAtom, atomTag));
-    }
-    VLOG("StatsService::unregisterNativePullAtomCallback called.");
-    int32_t uid = AIBinder_getCallingUid();
-    mPullerManager->UnregisterPullAtomCallback(uid, atomTag);
-    return Status::ok();
-}
-
-Status StatsService::getRegisteredExperimentIds(std::vector<int64_t>* experimentIdsOut) {
-    ENFORCE_UID(AID_SYSTEM);
-    // TODO: add verifier permission
-
-    experimentIdsOut->clear();
-    // Read the latest train info
-    vector<InstallTrainInfo> trainInfoList = StorageManager::readAllTrainInfo();
-    if (trainInfoList.empty()) {
-        // No train info means no experiment IDs, return an empty list
-        return Status::ok();
-    }
-
-    // Copy the experiment IDs to the out vector
-    for (InstallTrainInfo& trainInfo : trainInfoList) {
-        experimentIdsOut->insert(experimentIdsOut->end(),
-                                 trainInfo.experimentIds.begin(),
-                                 trainInfo.experimentIds.end());
-    }
-    return Status::ok();
-}
-
-void StatsService::statsCompanionServiceDied(void* cookie) {
-    auto thiz = static_cast<StatsService*>(cookie);
-    thiz->statsCompanionServiceDiedImpl();
-}
-
-void StatsService::statsCompanionServiceDiedImpl() {
-    ALOGW("statscompanion service died");
-    StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
-    if (mProcessor != nullptr) {
-        ALOGW("Reset statsd upon system server restarts.");
-        int64_t systemServerRestartNs = getElapsedRealtimeNs();
-        ProtoOutputStream activeConfigsProto;
-        mProcessor->WriteActiveConfigsToProtoOutputStream(systemServerRestartNs,
-                STATSCOMPANION_DIED, &activeConfigsProto);
-        metadata::StatsMetadataList metadataList;
-        mProcessor->WriteMetadataToProto(getWallClockNs(),
-                systemServerRestartNs, &metadataList);
-        mProcessor->WriteDataToDisk(STATSCOMPANION_DIED, FAST);
-        mProcessor->resetConfigs();
-
-        std::string serializedActiveConfigs;
-        if (activeConfigsProto.serializeToString(&serializedActiveConfigs)) {
-            ActiveConfigList activeConfigs;
-            if (activeConfigs.ParseFromString(serializedActiveConfigs)) {
-                mProcessor->SetConfigsActiveState(activeConfigs, systemServerRestartNs);
-            }
-        }
-        mProcessor->SetMetadataState(metadataList, getWallClockNs(), systemServerRestartNs);
-    }
-    mAnomalyAlarmMonitor->setStatsCompanionService(nullptr);
-    mPeriodicAlarmMonitor->setStatsCompanionService(nullptr);
-    mPullerManager->SetStatsCompanionService(nullptr);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
deleted file mode 100644
index 479f4e8..0000000
--- a/cmds/statsd/src/StatsService.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef STATS_SERVICE_H
-#define STATS_SERVICE_H
-
-#include <aidl/android/os/BnStatsd.h>
-#include <aidl/android/os/IPendingIntentRef.h>
-#include <aidl/android/os/IPullAtomCallback.h>
-#include <gtest/gtest_prod.h>
-#include <utils/Looper.h>
-
-#include <mutex>
-
-#include "StatsLogProcessor.h"
-#include "anomaly/AlarmMonitor.h"
-#include "config/ConfigManager.h"
-#include "external/StatsPullerManager.h"
-#include "logd/LogEventQueue.h"
-#include "packages/UidMap.h"
-#include "shell/ShellSubscriber.h"
-#include "statscompanion_util.h"
-#include "utils/MultiConditionTrigger.h"
-
-using namespace android;
-using namespace android::os;
-using namespace std;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnStatsd;
-using aidl::android::os::IPendingIntentRef;
-using aidl::android::os::IPullAtomCallback;
-using ::ndk::ScopedAIBinder_DeathRecipient;
-using ::ndk::ScopedFileDescriptor;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsService : public BnStatsd {
-public:
-    StatsService(const sp<Looper>& handlerLooper, std::shared_ptr<LogEventQueue> queue);
-    virtual ~StatsService();
-
-    /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */
-    const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5;
-
-    virtual status_t dump(int fd, const char** args, uint32_t numArgs) override;
-    virtual status_t handleShellCommand(int in, int out, int err, const char** argv,
-                                        uint32_t argc) override;
-
-    virtual Status systemRunning();
-    virtual Status statsCompanionReady();
-    virtual Status bootCompleted();
-    virtual Status informPollAlarmFired();
-    virtual Status informAlarmForSubscriberTriggeringFired();
-
-    virtual Status informAllUidData(const ScopedFileDescriptor& fd);
-    virtual Status informOnePackage(const string& app, int32_t uid, int64_t version,
-                                    const string& versionString, const string& installer);
-    virtual Status informOnePackageRemoved(const string& app, int32_t uid);
-    virtual Status informDeviceShutdown();
-
-    /**
-     * Called right before we start processing events.
-     */
-    void Startup();
-
-    /**
-     * Called when terminiation signal received.
-     */
-    void Terminate();
-
-    /**
-     * Test ONLY interface. In real world, StatsService reads from LogEventQueue.
-     */
-    virtual void OnLogEvent(LogEvent* event);
-
-    /**
-     * Binder call for clients to request data for this configuration key.
-     */
-    virtual Status getData(int64_t key,
-                           const int32_t callingUid,
-                           vector<uint8_t>* output) override;
-
-
-    /**
-     * Binder call for clients to get metadata across all configs in statsd.
-     */
-    virtual Status getMetadata(vector<uint8_t>* output) override;
-
-
-    /**
-     * Binder call to let clients send a configuration and indicate they're interested when they
-     * should requestData for this configuration.
-     */
-    virtual Status addConfiguration(int64_t key,
-                                    const vector<uint8_t>& config,
-                                    const int32_t callingUid) override;
-
-    /**
-     * Binder call to let clients register the data fetch operation for a configuration.
-     */
-    virtual Status setDataFetchOperation(int64_t key,
-                                         const shared_ptr<IPendingIntentRef>& pir,
-                                         const int32_t callingUid) override;
-
-    /**
-     * Binder call to remove the data fetch operation for the specified config key.
-     */
-    virtual Status removeDataFetchOperation(int64_t key,
-                                            const int32_t callingUid) override;
-
-    /**
-     * Binder call to let clients register the active configs changed operation.
-     */
-    virtual Status setActiveConfigsChangedOperation(const shared_ptr<IPendingIntentRef>& pir,
-                                                    const int32_t callingUid,
-                                                    vector<int64_t>* output) override;
-
-    /**
-     * Binder call to remove the active configs changed operation for the specified package..
-     */
-    virtual Status removeActiveConfigsChangedOperation(const int32_t callingUid) override;
-    /**
-     * Binder call to allow clients to remove the specified configuration.
-     */
-    virtual Status removeConfiguration(int64_t key,
-                                       const int32_t callingUid) override;
-
-    /**
-     * Binder call to associate the given config's subscriberId with the given pendingIntentRef.
-     */
-    virtual Status setBroadcastSubscriber(int64_t configId,
-                                          int64_t subscriberId,
-                                          const shared_ptr<IPendingIntentRef>& pir,
-                                          const int32_t callingUid) override;
-
-    /**
-     * Binder call to unassociate the given config's subscriberId with any pendingIntentRef.
-     */
-    virtual Status unsetBroadcastSubscriber(int64_t configId,
-                                            int64_t subscriberId,
-                                            const int32_t callingUid) override;
-
-    /** Inform statsCompanion that statsd is ready. */
-    virtual void sayHiToStatsCompanion();
-
-    /**
-     * Binder call to notify statsd that all pullers from boot have been registered.
-     */
-    virtual Status allPullersFromBootRegistered();
-
-    /**
-     * Binder call to register a callback function for a pulled atom.
-     */
-    virtual Status registerPullAtomCallback(
-            int32_t uid, int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
-            const std::vector<int32_t>& additiveFields,
-            const shared_ptr<IPullAtomCallback>& pullerCallback) override;
-
-    /**
-     * Binder call to register a callback function for a pulled atom.
-     */
-    virtual Status registerNativePullAtomCallback(
-            int32_t atomTag, int64_t coolDownMillis, int64_t timeoutMillis,
-            const std::vector<int32_t>& additiveFields,
-            const shared_ptr<IPullAtomCallback>& pullerCallback) override;
-
-    /**
-     * Binder call to unregister any existing callback for the given uid and atom.
-     */
-    virtual Status unregisterPullAtomCallback(int32_t uid, int32_t atomTag) override;
-
-    /**
-     * Binder call to unregister any existing callback for the given atom and calling uid.
-     */
-    virtual Status unregisterNativePullAtomCallback(int32_t atomTag) override;
-
-    /**
-     * Binder call to get registered experiment IDs.
-     */
-    virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut);
-
-private:
-    /**
-     * Load system properties at init.
-     */
-    void init_system_properties();
-
-    /**
-     * Helper for loading system properties.
-     */
-    static void init_build_type_callback(void* cookie, const char* name, const char* value,
-                                         uint32_t serial);
-
-    /**
-     * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto.
-     */
-    void dumpIncidentSection(int outFd);
-
-    /**
-     * Text or proto output of statsdStats dumpsys.
-     */
-    void dumpStatsdStats(int outFd, bool verbose, bool proto);
-
-    /**
-     * Print usage information for the commands
-     */
-    void print_cmd_help(int out);
-
-    /* Runs on its dedicated thread to process pushed stats event from socket. */
-    void readLogs();
-
-    /**
-     * Trigger a broadcast.
-     */
-    status_t cmd_trigger_broadcast(int outFd, Vector<String8>& args);
-
-
-    /**
-     * Trigger an active configs changed broadcast.
-     */
-    status_t cmd_trigger_active_config_broadcast(int outFd, Vector<String8>& args);
-
-    /**
-     * Handle the config sub-command.
-     */
-    status_t cmd_config(int inFd, int outFd, int err, Vector<String8>& args);
-
-    /**
-     * Prints some basic stats to std out.
-     */
-    status_t cmd_print_stats(int outFd, const Vector<String8>& args);
-
-    /**
-     * Print the event log.
-     */
-    status_t cmd_dump_report(int outFd, const Vector<String8>& args);
-
-    /**
-     * Print the mapping of uids to package names.
-     */
-    status_t cmd_print_uid_map(int outFd, const Vector<String8>& args);
-
-    /**
-     * Flush the data to disk.
-     */
-    status_t cmd_write_data_to_disk(int outFd);
-
-    /**
-     * Write an AppBreadcrumbReported event to the StatsLog buffer, as if calling
-     * StatsLog.write(APP_BREADCRUMB_REPORTED).
-     */
-    status_t cmd_log_app_breadcrumb(int outFd, const Vector<String8>& args);
-
-    /**
-     * Write an BinaryPushStateChanged event, as if calling StatsLog.logBinaryPushStateChanged().
-     */
-    status_t cmd_log_binary_push(int outFd, const Vector<String8>& args);
-
-    /**
-     * Print contents of a pulled metrics source.
-     */
-    status_t cmd_print_pulled_metrics(int outFd, const Vector<String8>& args);
-
-    /**
-     * Removes all configs stored on disk and on memory.
-     */
-    status_t cmd_remove_all_configs(int outFd);
-
-    /*
-     * Dump memory usage by statsd.
-     */
-    status_t cmd_dump_memory_info(int outFd);
-
-    /*
-     * Clear all puller cached data
-     */
-    status_t cmd_clear_puller_cache(int outFd);
-
-    /**
-     * Print all stats logs received to logcat.
-     */
-    status_t cmd_print_logs(int outFd, const Vector<String8>& args);
-
-    /**
-     * Writes the value of args[uidArgIndex] into uid.
-     * Returns whether the uid is reasonable (type uid_t) and whether
-     * 1. it is equal to the calling uid, or
-     * 2. the device is mEngBuild, or
-     * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL).
-     */
-    bool getUidFromArgs(const Vector<String8>& args, size_t uidArgIndex, int32_t& uid);
-
-    /**
-     * Writes the value of uidSting into uid.
-     * Returns whether the uid is reasonable (type uid_t) and whether
-     * 1. it is equal to the calling uid, or
-     * 2. the device is mEngBuild, or
-     * 3. the caller is AID_ROOT and the uid is AID_SHELL (i.e. ROOT can impersonate SHELL).
-     */
-     bool getUidFromString(const char* uidString, int32_t& uid);
-
-    /**
-     * Adds a configuration after checking permissions and obtaining UID from binder call.
-     */
-    bool addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config);
-
-    /**
-     * Update a configuration.
-     */
-    void set_config(int uid, const string& name, const StatsdConfig& config);
-
-    /**
-     * Death recipient callback that is called when StatsCompanionService dies.
-     * The cookie is a pointer to a StatsService object.
-     */
-    static void statsCompanionServiceDied(void* cookie);
-
-    /**
-     * Implementation of statsCompanionServiceDied.
-     */
-    void statsCompanionServiceDiedImpl();
-
-    /**
-     * Tracks the uid <--> package name mapping.
-     */
-    sp<UidMap> mUidMap;
-
-    /**
-     * Fetches external metrics
-     */
-    sp<StatsPullerManager> mPullerManager;
-
-    /**
-     * Tracks the configurations that have been passed to statsd.
-     */
-    sp<ConfigManager> mConfigManager;
-
-    /**
-     * The metrics recorder.
-     */
-    sp<StatsLogProcessor> mProcessor;
-
-    /**
-     * The alarm monitor for anomaly detection.
-     */
-    const sp<AlarmMonitor> mAnomalyAlarmMonitor;
-
-    /**
-     * The alarm monitor for alarms to directly trigger subscriber.
-     */
-    const sp<AlarmMonitor> mPeriodicAlarmMonitor;
-
-    /**
-     * Whether this is an eng build.
-     */
-    bool mEngBuild;
-
-    sp<ShellSubscriber> mShellSubscriber;
-
-    /**
-     * Mutex for setting the shell subscriber
-     */
-    mutable mutex mShellSubscriberMutex;
-    std::shared_ptr<LogEventQueue> mEventQueue;
-
-    MultiConditionTrigger mBootCompleteTrigger;
-    static const inline string kBootCompleteTag = "BOOT_COMPLETE";
-    static const inline string kUidMapReceivedTag = "UID_MAP";
-    static const inline string kAllPullersRegisteredTag = "PULLERS_REGISTERED";
-
-    ScopedAIBinder_DeathRecipient mStatsCompanionServiceDeathRecipient;
-
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-    FRIEND_TEST(StatsServiceTest, TestAddConfig_simple);
-    FRIEND_TEST(StatsServiceTest, TestAddConfig_empty);
-    FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid);
-    FRIEND_TEST(StatsServiceTest, TestGetUidFromArgs);
-    FRIEND_TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp);
-    FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot);
-    FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade);
-    FRIEND_TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval);
-    FRIEND_TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit);
-    FRIEND_TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket);
-    FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket);
-    FRIEND_TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket);
-    FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket);
-    FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket);
-    FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket);
-
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // STATS_SERVICE_H
diff --git a/cmds/statsd/src/active_config_list.proto b/cmds/statsd/src/active_config_list.proto
deleted file mode 100644
index 9929833..0000000
--- a/cmds/statsd/src/active_config_list.proto
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_multiple_files = true;
-option java_outer_classname = "ActiveConfigProto";
-
-message ActiveEventActivation {
-    optional int32 atom_matcher_index = 1;
-
-    // Time left in activation. When this proto is loaded after device boot,
-    // the activation should be set to active for this duration.
-    // This field will only be set when the state is ACTIVE
-    optional int64 remaining_ttl_nanos = 2;
-
-    enum State {
-        UNNKNOWN = 0;
-        // This metric should activate for remaining_ttl_nanos when we load the activations.
-        ACTIVE = 1;
-        // When we load the activations, this metric should activate on next boot for the tll
-        // specified in the config.
-        ACTIVATE_ON_BOOT = 2;
-    }
-    optional State state = 3;
-}
-
-message ActiveMetric {
-    optional int64 id = 1;
-    repeated ActiveEventActivation activation = 2;
-}
-
-message ActiveConfig {
-    optional int64 id = 1;
-    optional int32 uid = 2;
-    repeated ActiveMetric metric = 3;
-}
-
-// all configs and their metrics on device.
-message ActiveConfigList {
-    repeated ActiveConfig config = 1;
-}
diff --git a/cmds/statsd/src/annotations.h b/cmds/statsd/src/annotations.h
deleted file mode 100644
index cf7f543..0000000
--- a/cmds/statsd/src/annotations.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const uint8_t ANNOTATION_ID_IS_UID = 1;
-const uint8_t ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2;
-const uint8_t ANNOTATION_ID_PRIMARY_FIELD = 3;
-const uint8_t ANNOTATION_ID_EXCLUSIVE_STATE = 4;
-const uint8_t ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5;
-const uint8_t ANNOTATION_ID_TRIGGER_STATE_RESET = 7;
-const uint8_t ANNOTATION_ID_STATE_NESTED = 8;
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.cpp b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
deleted file mode 100644
index b632d04..0000000
--- a/cmds/statsd/src/anomaly/AlarmMonitor.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false
-#include "Log.h"
-
-#include "anomaly/AlarmMonitor.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AlarmMonitor::AlarmMonitor(
-        uint32_t minDiffToUpdateRegisteredAlarmTimeSec,
-        const std::function<void(const shared_ptr<IStatsCompanionService>&, int64_t)>& updateAlarm,
-        const std::function<void(const shared_ptr<IStatsCompanionService>&)>& cancelAlarm)
-    : mRegisteredAlarmTimeSec(0),
-      mMinUpdateTimeSec(minDiffToUpdateRegisteredAlarmTimeSec),
-      mUpdateAlarm(updateAlarm),
-      mCancelAlarm(cancelAlarm) {}
-
-AlarmMonitor::~AlarmMonitor() {}
-
-void AlarmMonitor::setStatsCompanionService(
-        shared_ptr<IStatsCompanionService> statsCompanionService) {
-    std::lock_guard<std::mutex> lock(mLock);
-    shared_ptr<IStatsCompanionService> tmpForLock = mStatsCompanionService;
-    mStatsCompanionService = statsCompanionService;
-    if (statsCompanionService == nullptr) {
-        VLOG("Erasing link to statsCompanionService");
-        return;
-    }
-    VLOG("Creating link to statsCompanionService");
-    const sp<const InternalAlarm> top = mPq.top();
-    if (top != nullptr) {
-        updateRegisteredAlarmTime_l(top->timestampSec);
-    }
-}
-
-void AlarmMonitor::add(sp<const InternalAlarm> alarm) {
-    std::lock_guard<std::mutex> lock(mLock);
-    if (alarm == nullptr) {
-        ALOGW("Asked to add a null alarm.");
-        return;
-    }
-    if (alarm->timestampSec < 1) {
-        // forbidden since a timestamp 0 is used to indicate no alarm registered
-        ALOGW("Asked to add a 0-time alarm.");
-        return;
-    }
-    // TODO(b/110563466): Ensure that refractory period is respected.
-    VLOG("Adding alarm with time %u", alarm->timestampSec);
-    mPq.push(alarm);
-    if (mRegisteredAlarmTimeSec < 1 ||
-        alarm->timestampSec + mMinUpdateTimeSec < mRegisteredAlarmTimeSec) {
-        updateRegisteredAlarmTime_l(alarm->timestampSec);
-    }
-}
-
-void AlarmMonitor::remove(sp<const InternalAlarm> alarm) {
-    std::lock_guard<std::mutex> lock(mLock);
-    if (alarm == nullptr) {
-        ALOGW("Asked to remove a null alarm.");
-        return;
-    }
-    VLOG("Removing alarm with time %u", alarm->timestampSec);
-    bool wasPresent = mPq.remove(alarm);
-    if (!wasPresent) return;
-    if (mPq.empty()) {
-        VLOG("Queue is empty. Cancel any alarm.");
-        cancelRegisteredAlarmTime_l();
-        return;
-    }
-    uint32_t soonestAlarmTimeSec = mPq.top()->timestampSec;
-    VLOG("Soonest alarm is %u", soonestAlarmTimeSec);
-    if (soonestAlarmTimeSec > mRegisteredAlarmTimeSec + mMinUpdateTimeSec) {
-        updateRegisteredAlarmTime_l(soonestAlarmTimeSec);
-    }
-}
-
-// More efficient than repeatedly calling remove(mPq.top()) since it batches the
-// updates to the registered alarm.
-unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> AlarmMonitor::popSoonerThan(
-        uint32_t timestampSec) {
-    VLOG("Removing alarms with time <= %u", timestampSec);
-    unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> oldAlarms;
-    std::lock_guard<std::mutex> lock(mLock);
-
-    for (sp<const InternalAlarm> t = mPq.top(); t != nullptr && t->timestampSec <= timestampSec;
-        t = mPq.top()) {
-        oldAlarms.insert(t);
-        mPq.pop();  // remove t
-    }
-    // Always update registered alarm time (if anything has changed).
-    if (!oldAlarms.empty()) {
-        if (mPq.empty()) {
-            VLOG("Queue is empty. Cancel any alarm.");
-            cancelRegisteredAlarmTime_l();
-        } else {
-            // Always update the registered alarm in this case (unlike remove()).
-            updateRegisteredAlarmTime_l(mPq.top()->timestampSec);
-        }
-    }
-    return oldAlarms;
-}
-
-void AlarmMonitor::updateRegisteredAlarmTime_l(uint32_t timestampSec) {
-    VLOG("Updating reg alarm time to %u", timestampSec);
-    mRegisteredAlarmTimeSec = timestampSec;
-    mUpdateAlarm(mStatsCompanionService, secToMs(mRegisteredAlarmTimeSec));
-}
-
-void AlarmMonitor::cancelRegisteredAlarmTime_l() {
-    VLOG("Cancelling reg alarm.");
-    mRegisteredAlarmTimeSec = 0;
-    mCancelAlarm(mStatsCompanionService);
-}
-
-int64_t AlarmMonitor::secToMs(uint32_t timeSec) {
-    return ((int64_t)timeSec) * 1000;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.h b/cmds/statsd/src/anomaly/AlarmMonitor.h
deleted file mode 100644
index 5c34e38..0000000
--- a/cmds/statsd/src/anomaly/AlarmMonitor.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "anomaly/indexed_priority_queue.h"
-
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <utils/RefBase.h>
-
-#include <unordered_set>
-#include <vector>
-
-using namespace android;
-
-using aidl::android::os::IStatsCompanionService;
-using std::function;
-using std::shared_ptr;
-using std::unordered_set;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Represents an alarm, associated with some aggregate metric, holding a
- * projected time at which the metric is expected to exceed its anomaly
- * threshold.
- * Timestamps are in seconds since epoch in a uint32, so will fail in year 2106.
- */
-struct InternalAlarm : public RefBase {
-    explicit InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) {
-    }
-
-    const uint32_t timestampSec;
-
-    /** InternalAlarm a is smaller (higher priority) than b if its timestamp is sooner. */
-    struct SmallerTimestamp {
-        bool operator()(sp<const InternalAlarm> a, sp<const InternalAlarm> b) const {
-            return (a->timestampSec < b->timestampSec);
-        }
-    };
-};
-
-/**
- * Manages internal alarms that may get registered with the AlarmManager.
- */
-class AlarmMonitor : public RefBase {
-public:
-    /**
-     * @param minDiffToUpdateRegisteredAlarmTimeSec If the soonest alarm differs
-     * from the registered alarm by more than this amount, update the registered
-     * alarm.
-     */
-    AlarmMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec,
-                 const function<void(const shared_ptr<IStatsCompanionService>&, int64_t)>&
-                         updateAlarm,
-                 const function<void(const shared_ptr<IStatsCompanionService>&)>& cancelAlarm);
-    ~AlarmMonitor();
-
-    /**
-     * Tells AnomalyMonitor what IStatsCompanionService to use and, if
-     * applicable, immediately registers an existing alarm with it.
-     * If nullptr, AnomalyMonitor will continue to add/remove alarms, but won't
-     * update IStatsCompanionService (until such time as it is set non-null).
-     */
-    void setStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService);
-
-    /**
-     * Adds the given alarm (reference) to the queue.
-     */
-    void add(sp<const InternalAlarm> alarm);
-
-    /**
-     * Removes the given alarm (reference) from the queue.
-     * Note that alarm comparison is reference-based; if another alarm exists
-     * with the same timestampSec, that alarm will still remain in the queue.
-     */
-    void remove(sp<const InternalAlarm> alarm);
-
-    /**
-     * Returns and removes all alarms whose timestamp <= the given timestampSec.
-     * Always updates the registered alarm if return is non-empty.
-     */
-    unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> popSoonerThan(
-            uint32_t timestampSec);
-
-    /**
-     * Returns the projected alarm timestamp that is registered with
-     * StatsCompanionService. This may not be equal to the soonest alarm,
-     * but should be within minDiffToUpdateRegisteredAlarmTimeSec of it.
-     */
-    uint32_t getRegisteredAlarmTimeSec() const {
-        return mRegisteredAlarmTimeSec;
-    }
-
-private:
-    std::mutex mLock;
-
-    /**
-     * Timestamp (seconds since epoch) of the alarm registered with
-     * StatsCompanionService. This, in general, may not be equal to the soonest
-     * alarm stored in mPq, but should be within minUpdateTimeSec of it.
-     * A value of 0 indicates that no alarm is currently registered.
-     */
-    uint32_t mRegisteredAlarmTimeSec;
-
-    /**
-     * Priority queue of alarms, prioritized by soonest alarm.timestampSec.
-     */
-    indexed_priority_queue<InternalAlarm, InternalAlarm::SmallerTimestamp> mPq;
-
-    /**
-     * Binder interface for communicating with StatsCompanionService.
-     */
-    shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr;
-
-    /**
-     * Amount by which the soonest projected alarm must differ from
-     * mRegisteredAlarmTimeSec before updateRegisteredAlarmTime_l is called.
-     */
-    uint32_t mMinUpdateTimeSec;
-
-    /**
-     * Updates the alarm registered with StatsCompanionService to the given time.
-     * Also correspondingly updates mRegisteredAlarmTimeSec.
-     */
-    void updateRegisteredAlarmTime_l(uint32_t timestampSec);
-
-    /**
-     * Cancels the alarm registered with StatsCompanionService.
-     * Also correspondingly sets mRegisteredAlarmTimeSec to 0.
-     */
-    void cancelRegisteredAlarmTime_l();
-
-    /** Converts uint32 timestamp in seconds to a Java long in msec. */
-    int64_t secToMs(uint32_t timeSec);
-
-    // Callback function to update the alarm via StatsCompanionService.
-    std::function<void(const shared_ptr<IStatsCompanionService>, int64_t)> mUpdateAlarm;
-
-    // Callback function to cancel the alarm via StatsCompanionService.
-    std::function<void(const shared_ptr<IStatsCompanionService>)> mCancelAlarm;
-
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp
deleted file mode 100644
index 6d9beb8..0000000
--- a/cmds/statsd/src/anomaly/AlarmTracker.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "anomaly/AlarmTracker.h"
-#include "anomaly/subscriber_util.h"
-#include "HashableDimensionKey.h"
-#include "stats_util.h"
-#include "storage/StorageManager.h"
-
-#include <time.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AlarmTracker::AlarmTracker(const int64_t startMillis,
-                           const int64_t currentMillis,
-                           const Alarm& alarm, const ConfigKey& configKey,
-                           const sp<AlarmMonitor>& alarmMonitor)
-    : mAlarmConfig(alarm),
-      mConfigKey(configKey),
-      mAlarmMonitor(alarmMonitor) {
-    VLOG("AlarmTracker() called");
-    mAlarmSec = (startMillis + mAlarmConfig.offset_millis()) / MS_PER_SEC;
-    // startMillis is the time statsd is created. We need to find the 1st alarm timestamp after
-    // the config is added to statsd.
-    mAlarmSec = findNextAlarmSec(currentMillis / MS_PER_SEC);  // round up
-    mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
-    VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
-    if (mAlarmMonitor != nullptr) {
-        mAlarmMonitor->add(mInternalAlarm);
-    }
-}
-
-AlarmTracker::~AlarmTracker() {
-    VLOG("~AlarmTracker() called");
-    if (mInternalAlarm != nullptr && mAlarmMonitor != nullptr) {
-        mAlarmMonitor->remove(mInternalAlarm);
-    }
-}
-
-void AlarmTracker::addSubscription(const Subscription& subscription) {
-    mSubscriptions.push_back(subscription);
-}
-
-int64_t AlarmTracker::findNextAlarmSec(int64_t currentTimeSec) {
-    if (currentTimeSec < mAlarmSec) {
-        return mAlarmSec;
-    }
-    int64_t periodsForward =
-        ((currentTimeSec - mAlarmSec) * MS_PER_SEC) / mAlarmConfig.period_millis() + 1;
-    return mAlarmSec + periodsForward * mAlarmConfig.period_millis() / MS_PER_SEC;
-}
-
-void AlarmTracker::informAlarmsFired(
-        const int64_t& timestampNs,
-        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
-    if (firedAlarms.empty() || mInternalAlarm == nullptr ||
-        firedAlarms.find(mInternalAlarm) == firedAlarms.end()) {
-        return;
-    }
-    if (!mSubscriptions.empty()) {
-        VLOG("AlarmTracker triggers the subscribers.");
-        triggerSubscribers(mAlarmConfig.id(), 0 /*metricId N/A*/, DEFAULT_METRIC_DIMENSION_KEY,
-                           0 /* metricValue N/A */, mConfigKey, mSubscriptions);
-    }
-    firedAlarms.erase(mInternalAlarm);
-    mAlarmSec = findNextAlarmSec((timestampNs-1) / NS_PER_SEC + 1); // round up
-    mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
-    VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
-    if (mAlarmMonitor != nullptr) {
-        mAlarmMonitor->add(mInternalAlarm);
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h
deleted file mode 100644
index 406086d..0000000
--- a/cmds/statsd/src/anomaly/AlarmTracker.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-
-#include "AlarmMonitor.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alarm
-
-#include <stdlib.h>
-#include <utils/RefBase.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class AlarmTracker : public virtual RefBase {
-public:
-    AlarmTracker(const int64_t startMillis,
-                 const int64_t currentMillis,
-                 const Alarm& alarm, const ConfigKey& configKey,
-                 const sp<AlarmMonitor>& subscriberAlarmMonitor);
-
-    virtual ~AlarmTracker();
-
-    void onAlarmFired();
-
-    void addSubscription(const Subscription& subscription);
-
-    void informAlarmsFired(const int64_t& timestampNs,
-            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms);
-
-protected:
-    // For test only. Returns the alarm timestamp in seconds. Otherwise returns 0.
-    inline int32_t getAlarmTimestampSec() const {
-        return mInternalAlarm == nullptr ? 0 : mInternalAlarm->timestampSec;
-    }
-
-    int64_t findNextAlarmSec(int64_t currentTimeMillis);
-
-    // statsd_config.proto Alarm message that defines this tracker.
-    const Alarm mAlarmConfig;
-
-    // A reference to the Alarm's config key.
-    const ConfigKey mConfigKey;
-
-    // The subscriptions that depend on this alarm.
-    std::vector<Subscription> mSubscriptions;
-
-    // Alarm monitor.
-    sp<AlarmMonitor> mAlarmMonitor;
-
-    // The current expected alarm time in seconds.
-    int64_t mAlarmSec;
-
-    // The current alarm.
-    sp<const InternalAlarm> mInternalAlarm;
-
-    FRIEND_TEST(AlarmTrackerTest, TestTriggerTimestamp);
-    FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlarms);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
deleted file mode 100644
index 6aa410b..0000000
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "AnomalyTracker.h"
-#include "external/Perfetto.h"
-#include "guardrail/StatsdStats.h"
-#include "metadata_util.h"
-#include "stats_log_util.h"
-#include "subscriber_util.h"
-#include "subscriber/IncidentdReporter.h"
-#include "subscriber/SubscriberReporter.h"
-
-#include <inttypes.h>
-#include <statslog_statsd.h>
-#include <time.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-AnomalyTracker::AnomalyTracker(const Alert& alert, const ConfigKey& configKey)
-        : mAlert(alert), mConfigKey(configKey), mNumOfPastBuckets(mAlert.num_buckets() - 1) {
-    VLOG("AnomalyTracker() called");
-    resetStorage();  // initialization
-}
-
-AnomalyTracker::~AnomalyTracker() {
-    VLOG("~AnomalyTracker() called");
-}
-
-void AnomalyTracker::onConfigUpdated() {
-    mSubscriptions.clear();
-}
-
-void AnomalyTracker::resetStorage() {
-    VLOG("resetStorage() called.");
-    mPastBuckets.clear();
-    // Excludes the current bucket.
-    mPastBuckets.resize(mNumOfPastBuckets);
-    mSumOverPastBuckets.clear();
-}
-
-size_t AnomalyTracker::index(int64_t bucketNum) const {
-    if (bucketNum < 0) {
-        ALOGE("index() was passed a negative bucket number (%lld)!", (long long)bucketNum);
-    }
-    return bucketNum % mNumOfPastBuckets;
-}
-
-void AnomalyTracker::advanceMostRecentBucketTo(const int64_t& bucketNum) {
-    VLOG("advanceMostRecentBucketTo() called.");
-    if (mNumOfPastBuckets <= 0) {
-        return;
-    }
-    if (bucketNum <= mMostRecentBucketNum) {
-        ALOGW("Cannot advance buckets backwards (bucketNum=%lld but mMostRecentBucketNum=%lld)",
-              (long long)bucketNum, (long long)mMostRecentBucketNum);
-        return;
-    }
-    // If in the future (i.e. buckets are ancient), just empty out all past info.
-    if (bucketNum >= mMostRecentBucketNum + mNumOfPastBuckets) {
-        resetStorage();
-        mMostRecentBucketNum = bucketNum;
-        return;
-    }
-
-    // Clear out space by emptying out old mPastBuckets[i] values and update mSumOverPastBuckets.
-    for (int64_t i = mMostRecentBucketNum + 1; i <= bucketNum; i++) {
-        const int idx = index(i);
-        subtractBucketFromSum(mPastBuckets[idx]);
-        mPastBuckets[idx] = nullptr;  // release (but not clear) the old bucket.
-    }
-    mMostRecentBucketNum = bucketNum;
-}
-
-void AnomalyTracker::addPastBucket(const MetricDimensionKey& key,
-                                   const int64_t& bucketValue,
-                                   const int64_t& bucketNum) {
-    VLOG("addPastBucket(bucketValue) called.");
-    if (mNumOfPastBuckets == 0 ||
-        bucketNum < 0 || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets) {
-        return;
-    }
-
-    const int bucketIndex = index(bucketNum);
-    if (bucketNum <= mMostRecentBucketNum && (mPastBuckets[bucketIndex] != nullptr)) {
-        // We need to insert into an already existing past bucket.
-        std::shared_ptr<DimToValMap>& bucket = mPastBuckets[bucketIndex];
-        auto itr = bucket->find(key);
-        if (itr != bucket->end()) {
-            // Old entry already exists; update it.
-            subtractValueFromSum(key, itr->second);
-            itr->second = bucketValue;
-        } else {
-            bucket->insert({key, bucketValue});
-        }
-        mSumOverPastBuckets[key] += bucketValue;
-    } else {
-        // Bucket does not exist yet (in future or was never made), so we must make it.
-        std::shared_ptr<DimToValMap> bucket = std::make_shared<DimToValMap>();
-        bucket->insert({key, bucketValue});
-        addPastBucket(bucket, bucketNum);
-    }
-}
-
-void AnomalyTracker::addPastBucket(std::shared_ptr<DimToValMap> bucket,
-                                   const int64_t& bucketNum) {
-    VLOG("addPastBucket(bucket) called.");
-    if (mNumOfPastBuckets == 0 ||
-            bucketNum < 0 || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets) {
-        return;
-    }
-
-    if (bucketNum <= mMostRecentBucketNum) {
-        // We are updating an old bucket, not adding a new one.
-        subtractBucketFromSum(mPastBuckets[index(bucketNum)]);
-    } else {
-        // Clear space for the new bucket to be at bucketNum.
-        advanceMostRecentBucketTo(bucketNum);
-    }
-    mPastBuckets[index(bucketNum)] = bucket;
-    addBucketToSum(bucket);
-}
-
-void AnomalyTracker::subtractBucketFromSum(const shared_ptr<DimToValMap>& bucket) {
-    if (bucket == nullptr) {
-        return;
-    }
-    for (const auto& keyValuePair : *bucket) {
-        subtractValueFromSum(keyValuePair.first, keyValuePair.second);
-    }
-}
-
-
-void AnomalyTracker::subtractValueFromSum(const MetricDimensionKey& key,
-                                          const int64_t& bucketValue) {
-    auto itr = mSumOverPastBuckets.find(key);
-    if (itr == mSumOverPastBuckets.end()) {
-        return;
-    }
-    itr->second -= bucketValue;
-    if (itr->second == 0) {
-        mSumOverPastBuckets.erase(itr);
-    }
-}
-
-void AnomalyTracker::addBucketToSum(const shared_ptr<DimToValMap>& bucket) {
-    if (bucket == nullptr) {
-        return;
-    }
-    // For each dimension present in the bucket, add its value to its corresponding sum.
-    for (const auto& keyValuePair : *bucket) {
-        mSumOverPastBuckets[keyValuePair.first] += keyValuePair.second;
-    }
-}
-
-int64_t AnomalyTracker::getPastBucketValue(const MetricDimensionKey& key,
-                                           const int64_t& bucketNum) const {
-    if (bucketNum < 0 || mMostRecentBucketNum < 0
-            || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets
-            || bucketNum > mMostRecentBucketNum) {
-        return 0;
-    }
-
-    const auto& bucket = mPastBuckets[index(bucketNum)];
-    if (bucket == nullptr) {
-        return 0;
-    }
-    const auto& itr = bucket->find(key);
-    return itr == bucket->end() ? 0 : itr->second;
-}
-
-int64_t AnomalyTracker::getSumOverPastBuckets(const MetricDimensionKey& key) const {
-    const auto& itr = mSumOverPastBuckets.find(key);
-    if (itr != mSumOverPastBuckets.end()) {
-        return itr->second;
-    }
-    return 0;
-}
-
-bool AnomalyTracker::detectAnomaly(const int64_t& currentBucketNum,
-                                   const MetricDimensionKey& key,
-                                   const int64_t& currentBucketValue) {
-
-    // currentBucketNum should be the next bucket after pastBuckets. If not, advance so that it is.
-    if (currentBucketNum > mMostRecentBucketNum + 1) {
-        advanceMostRecentBucketTo(currentBucketNum - 1);
-    }
-    return mAlert.has_trigger_if_sum_gt() &&
-           getSumOverPastBuckets(key) + currentBucketValue > mAlert.trigger_if_sum_gt();
-}
-
-void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, int64_t metricId,
-                                    const MetricDimensionKey& key, int64_t metricValue) {
-    // TODO(b/110563466): Why receive timestamp? RefractoryPeriod should always be based on
-    // real time right now.
-    if (isInRefractoryPeriod(timestampNs, key)) {
-        VLOG("Skipping anomaly declaration since within refractory period");
-        return;
-    }
-    if (mAlert.has_refractory_period_secs()) {
-        mRefractoryPeriodEndsSec[key] = ((timestampNs + NS_PER_SEC - 1) / NS_PER_SEC) // round up
-                                        + mAlert.refractory_period_secs();
-        // TODO(b/110563466): If we had access to the bucket_size_millis, consider
-        // calling resetStorage()
-        // if (mAlert.refractory_period_secs() > mNumOfPastBuckets * bucketSizeNs) {resetStorage();}
-    }
-
-    if (!mSubscriptions.empty()) {
-        ALOGI("An anomaly (%" PRId64 ") %s has occurred! Informing subscribers.",
-                mAlert.id(), key.toString().c_str());
-        informSubscribers(key, metricId, metricValue);
-    } else {
-        ALOGI("An anomaly has occurred! (But no subscriber for that alert.)");
-    }
-
-    StatsdStats::getInstance().noteAnomalyDeclared(mConfigKey, mAlert.id());
-
-    // TODO(b/110564268): This should also take in the const MetricDimensionKey& key?
-    util::stats_write(util::ANOMALY_DETECTED, mConfigKey.GetUid(),
-                      mConfigKey.GetId(), mAlert.id());
-}
-
-void AnomalyTracker::detectAndDeclareAnomaly(const int64_t& timestampNs,
-                                             const int64_t& currBucketNum, int64_t metricId,
-                                             const MetricDimensionKey& key,
-                                             const int64_t& currentBucketValue) {
-    if (detectAnomaly(currBucketNum, key, currentBucketValue)) {
-        declareAnomaly(timestampNs, metricId, key, currentBucketValue);
-    }
-}
-
-bool AnomalyTracker::isInRefractoryPeriod(const int64_t& timestampNs,
-                                          const MetricDimensionKey& key) const {
-    const auto& it = mRefractoryPeriodEndsSec.find(key);
-    if (it != mRefractoryPeriodEndsSec.end()) {
-        return timestampNs < (it->second *  (int64_t)NS_PER_SEC);
-    }
-    return false;
-}
-
-std::pair<bool, uint64_t> AnomalyTracker::getProtoHash() const {
-    string serializedAlert;
-    if (!mAlert.SerializeToString(&serializedAlert)) {
-        ALOGW("Unable to serialize alert %lld", (long long)mAlert.id());
-        return {false, 0};
-    }
-    return {true, Hash64(serializedAlert)};
-}
-
-void AnomalyTracker::informSubscribers(const MetricDimensionKey& key, int64_t metric_id,
-                                       int64_t metricValue) {
-    triggerSubscribers(mAlert.id(), metric_id, key, metricValue, mConfigKey, mSubscriptions);
-}
-
-bool AnomalyTracker::writeAlertMetadataToProto(int64_t currentWallClockTimeNs,
-                                               int64_t systemElapsedTimeNs,
-                                               metadata::AlertMetadata* alertMetadata) {
-    bool metadataWritten = false;
-
-    if (mRefractoryPeriodEndsSec.empty()) {
-        return false;
-    }
-
-    for (const auto& it: mRefractoryPeriodEndsSec) {
-        // Do not write the timestamp to disk if it has already expired
-        if (it.second < systemElapsedTimeNs / NS_PER_SEC) {
-            continue;
-        }
-
-        metadataWritten = true;
-        if (alertMetadata->alert_dim_keyed_data_size() == 0) {
-            alertMetadata->set_alert_id(mAlert.id());
-        }
-
-        metadata::AlertDimensionKeyedData* keyedData = alertMetadata->add_alert_dim_keyed_data();
-        // We convert and write the refractory_end_sec to wall clock time because we do not know
-        // when statsd will start again.
-        int32_t refractoryEndWallClockSec = (int32_t) ((currentWallClockTimeNs / NS_PER_SEC) +
-                (it.second - systemElapsedTimeNs / NS_PER_SEC));
-
-        keyedData->set_last_refractory_ends_sec(refractoryEndWallClockSec);
-        writeMetricDimensionKeyToMetadataDimensionKey(
-                it.first, keyedData->mutable_dimension_key());
-    }
-
-    return metadataWritten;
-}
-
-void AnomalyTracker::loadAlertMetadata(
-        const metadata::AlertMetadata& alertMetadata,
-        int64_t currentWallClockTimeNs,
-        int64_t systemElapsedTimeNs) {
-    for (const metadata::AlertDimensionKeyedData& keyedData :
-            alertMetadata.alert_dim_keyed_data()) {
-        if ((uint64_t) keyedData.last_refractory_ends_sec() < currentWallClockTimeNs / NS_PER_SEC) {
-            // Do not update the timestamp if it has already expired.
-            continue;
-        }
-        MetricDimensionKey metricKey = loadMetricDimensionKeyFromProto(
-                keyedData.dimension_key());
-        int32_t refractoryPeriodEndsSec = (int32_t) keyedData.last_refractory_ends_sec() -
-                currentWallClockTimeNs / NS_PER_SEC + systemElapsedTimeNs / NS_PER_SEC;
-        mRefractoryPeriodEndsSec[metricKey] = refractoryPeriodEndsSec;
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h
deleted file mode 100644
index 9a578ee..0000000
--- a/cmds/statsd/src/anomaly/AnomalyTracker.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include <stdlib.h>
-#include <utils/RefBase.h>
-
-#include "AlarmMonitor.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"    // Alert
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"  // AlertMetadata
-#include "hash.h"
-#include "stats_util.h"  // HashableDimensionKey and DimToValMap
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::shared_ptr;
-using std::unordered_map;
-
-// Does NOT allow negative values.
-class AnomalyTracker : public virtual RefBase {
-public:
-    AnomalyTracker(const Alert& alert, const ConfigKey& configKey);
-
-    virtual ~AnomalyTracker();
-
-    // Reset appropriate state on a config update. Clear subscriptions so they can be reset.
-    void onConfigUpdated();
-
-    // Add subscriptions that depend on this alert.
-    void addSubscription(const Subscription& subscription) {
-        mSubscriptions.push_back(subscription);
-    }
-
-    // Adds a bucket for the given bucketNum (index starting at 0).
-    // If a bucket for bucketNum already exists, it will be replaced.
-    // Also, advances to bucketNum (if not in the past), effectively filling any intervening
-    // buckets with 0s.
-    void addPastBucket(std::shared_ptr<DimToValMap> bucket, const int64_t& bucketNum);
-
-    // Inserts (or replaces) the bucket entry for the given bucketNum at the given key to be the
-    // given bucketValue. If the bucket does not exist, it will be created.
-    // Also, advances to bucketNum (if not in the past), effectively filling any intervening
-    // buckets with 0s.
-    void addPastBucket(const MetricDimensionKey& key, const int64_t& bucketValue,
-                       const int64_t& bucketNum);
-
-    // Returns true if, based on past buckets plus the new currentBucketValue (which generally
-    // represents the partially-filled current bucket), an anomaly has happened.
-    // Also advances to currBucketNum-1.
-    bool detectAnomaly(const int64_t& currBucketNum, const MetricDimensionKey& key,
-                       const int64_t& currentBucketValue);
-
-    // Informs incidentd about the detected alert.
-    void declareAnomaly(const int64_t& timestampNs, int64_t metricId, const MetricDimensionKey& key,
-                        int64_t metricValue);
-
-    // Detects if, based on past buckets plus the new currentBucketValue (which generally
-    // represents the partially-filled current bucket), an anomaly has happened, and if so,
-    // declares an anomaly and informs relevant subscribers.
-    // Also advances to currBucketNum-1.
-    void detectAndDeclareAnomaly(const int64_t& timestampNs, const int64_t& currBucketNum,
-                                 int64_t metricId, const MetricDimensionKey& key,
-                                 const int64_t& currentBucketValue);
-
-    // Init the AlarmMonitor which is shared across anomaly trackers.
-    virtual void setAlarmMonitor(const sp<AlarmMonitor>& alarmMonitor) {
-        return; // Base AnomalyTracker class has no need for the AlarmMonitor.
-    }
-
-    // Returns the sum of all past bucket values for the given dimension key.
-    int64_t getSumOverPastBuckets(const MetricDimensionKey& key) const;
-
-    // Returns the value for a past bucket, or 0 if that bucket doesn't exist.
-    int64_t getPastBucketValue(const MetricDimensionKey& key, const int64_t& bucketNum) const;
-
-    // Returns the anomaly threshold set in the configuration.
-    inline int64_t getAnomalyThreshold() const {
-        return mAlert.trigger_if_sum_gt();
-    }
-
-    // Returns the refractory period ending timestamp (in seconds) for the given key.
-    // Before this moment, any detected anomaly will be ignored.
-    // If there is no stored refractory period ending timestamp, returns 0.
-    uint32_t getRefractoryPeriodEndsSec(const MetricDimensionKey& key) const {
-        const auto& it = mRefractoryPeriodEndsSec.find(key);
-        return it != mRefractoryPeriodEndsSec.end() ? it->second : 0;
-    }
-
-    // Returns the (constant) number of past buckets this anomaly tracker can store.
-    inline int getNumOfPastBuckets() const {
-        return mNumOfPastBuckets;
-    }
-
-    std::pair<bool, uint64_t> getProtoHash() const;
-
-    // Sets an alarm for the given timestamp.
-    // Replaces previous alarm if one already exists.
-    virtual void startAlarm(const MetricDimensionKey& dimensionKey, const int64_t& eventTime) {
-        return;  // The base AnomalyTracker class doesn't have alarms.
-    }
-
-    // Stops the alarm.
-    // If it should have already fired, but hasn't yet (e.g. because the AlarmManager is delayed),
-    // declare the anomaly now.
-    virtual void stopAlarm(const MetricDimensionKey& dimensionKey, const int64_t& timestampNs) {
-        return;  // The base AnomalyTracker class doesn't have alarms.
-    }
-
-    // Stop all the alarms owned by this tracker. Does not declare any anomalies.
-    virtual void cancelAllAlarms() {
-        return;  // The base AnomalyTracker class doesn't have alarms.
-    }
-
-    // Declares an anomaly for each alarm in firedAlarms that belongs to this AnomalyTracker,
-    // and removes it from firedAlarms. Does NOT remove the alarm from the AlarmMonitor.
-    virtual void informAlarmsFired(const int64_t& timestampNs,
-            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
-        return; // The base AnomalyTracker class doesn't have alarms.
-    }
-
-    // Writes metadata of the alert (refractory_period_end_sec) to AlertMetadata.
-    // Returns true if at least one element is written to alertMetadata.
-    bool writeAlertMetadataToProto(
-            int64_t currentWallClockTimeNs,
-            int64_t systemElapsedTimeNs, metadata::AlertMetadata* alertMetadata);
-
-    void loadAlertMetadata(
-            const metadata::AlertMetadata& alertMetadata,
-            int64_t currentWallClockTimeNs,
-            int64_t systemElapsedTimeNs);
-
-protected:
-    // For testing only.
-    // Returns the alarm timestamp in seconds for the query dimension if it exists. Otherwise
-    // returns 0.
-    virtual uint32_t getAlarmTimestampSec(const MetricDimensionKey& dimensionKey) const {
-        return 0;   // The base AnomalyTracker class doesn't have alarms.
-    }
-
-    // statsd_config.proto Alert message that defines this tracker.
-    const Alert mAlert;
-
-    // The subscriptions that depend on this alert.
-    std::vector<Subscription> mSubscriptions;
-
-    // A reference to the Alert's config key.
-    const ConfigKey mConfigKey;
-
-    // Number of past buckets. One less than the total number of buckets needed
-    // for the anomaly detection (since the current bucket is not in the past).
-    const int mNumOfPastBuckets;
-
-    // Values for each of the past mNumOfPastBuckets buckets. Always of size mNumOfPastBuckets.
-    // mPastBuckets[i] can be null, meaning that no data is present in that bucket.
-    std::vector<shared_ptr<DimToValMap>> mPastBuckets;
-
-    // Cached sum over all existing buckets in mPastBuckets.
-    // Its buckets never contain entries of 0.
-    DimToValMap mSumOverPastBuckets;
-
-    // The bucket number of the last added bucket.
-    int64_t mMostRecentBucketNum = -1;
-
-    // Map from each dimension to the timestamp that its refractory period (if this anomaly was
-    // declared for that dimension) ends, in seconds. From this moment and onwards, anomalies
-    // can be declared again.
-    // Entries may be, but are not guaranteed to be, removed after the period is finished.
-    unordered_map<MetricDimensionKey, uint32_t> mRefractoryPeriodEndsSec;
-
-    // Advances mMostRecentBucketNum to bucketNum, deleting any data that is now too old.
-    // Specifically, since it is now too old, removes the data for
-    //   [mMostRecentBucketNum - mNumOfPastBuckets + 1, bucketNum - mNumOfPastBuckets].
-    void advanceMostRecentBucketTo(const int64_t& bucketNum);
-
-    // Add the information in the given bucket to mSumOverPastBuckets.
-    void addBucketToSum(const shared_ptr<DimToValMap>& bucket);
-
-    // Subtract the information in the given bucket from mSumOverPastBuckets
-    // and remove any items with value 0.
-    void subtractBucketFromSum(const shared_ptr<DimToValMap>& bucket);
-
-    // From mSumOverPastBuckets[key], subtracts bucketValue, removing it if it is now 0.
-    void subtractValueFromSum(const MetricDimensionKey& key, const int64_t& bucketValue);
-
-    // Returns true if in the refractory period, else false.
-    bool isInRefractoryPeriod(const int64_t& timestampNs, const MetricDimensionKey& key) const;
-
-    // Calculates the corresponding bucket index within the circular array.
-    // Requires bucketNum >= 0.
-    size_t index(int64_t bucketNum) const;
-
-    // Resets all bucket data. For use when all the data gets stale.
-    virtual void resetStorage();
-
-    // Informs the subscribers (incidentd, perfetto, broadcasts, etc) that an anomaly has occurred.
-    void informSubscribers(const MetricDimensionKey& key, int64_t metricId, int64_t metricValue);
-
-    FRIEND_TEST(AnomalyTrackerTest, TestConsecutiveBuckets);
-    FRIEND_TEST(AnomalyTrackerTest, TestSparseBuckets);
-    FRIEND_TEST(GaugeMetricProducerTest, TestAnomalyDetection);
-    FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlerts);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
deleted file mode 100644
index 2b56810..0000000
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "DurationAnomalyTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-DurationAnomalyTracker::DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey,
-                                               const sp<AlarmMonitor>& alarmMonitor)
-        : AnomalyTracker(alert, configKey), mAlarmMonitor(alarmMonitor) {
-    VLOG("DurationAnomalyTracker() called");
-}
-
-DurationAnomalyTracker::~DurationAnomalyTracker() {
-    VLOG("~DurationAnomalyTracker() called");
-    cancelAllAlarms();
-}
-
-void DurationAnomalyTracker::startAlarm(const MetricDimensionKey& dimensionKey,
-                                        const int64_t& timestampNs) {
-    // Alarms are stored in secs. Must round up, since if it fires early, it is ignored completely.
-    uint32_t timestampSec = static_cast<uint32_t>((timestampNs -1) / NS_PER_SEC) + 1; // round up
-    if (isInRefractoryPeriod(timestampNs, dimensionKey)) {
-        VLOG("Not setting anomaly alarm since it would fall in the refractory period.");
-        return;
-    }
-
-    auto itr = mAlarms.find(dimensionKey);
-    if (itr != mAlarms.end() && mAlarmMonitor != nullptr) {
-        mAlarmMonitor->remove(itr->second);
-    }
-
-    sp<const InternalAlarm> alarm = new InternalAlarm{timestampSec};
-    mAlarms[dimensionKey] = alarm;
-    if (mAlarmMonitor != nullptr) {
-        mAlarmMonitor->add(alarm);
-    }
-}
-
-void DurationAnomalyTracker::stopAlarm(const MetricDimensionKey& dimensionKey,
-                                       const int64_t& timestampNs) {
-    const auto itr = mAlarms.find(dimensionKey);
-    if (itr == mAlarms.end()) {
-        return;
-    }
-
-    // If the alarm is set in the past but hasn't fired yet (due to lag), catch it now.
-    if (itr->second != nullptr && timestampNs >= (int64_t)NS_PER_SEC * itr->second->timestampSec) {
-        declareAnomaly(timestampNs, mAlert.metric_id(), dimensionKey,
-                       mAlert.trigger_if_sum_gt() + (timestampNs / NS_PER_SEC) -
-                               itr->second->timestampSec);
-    }
-    if (mAlarmMonitor != nullptr) {
-        mAlarmMonitor->remove(itr->second);
-    }
-    mAlarms.erase(dimensionKey);
-}
-
-void DurationAnomalyTracker::cancelAllAlarms() {
-    if (mAlarmMonitor != nullptr) {
-        for (const auto& itr : mAlarms) {
-            mAlarmMonitor->remove(itr.second);
-        }
-    }
-    mAlarms.clear();
-}
-
-void DurationAnomalyTracker::informAlarmsFired(const int64_t& timestampNs,
-        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
-
-    if (firedAlarms.empty() || mAlarms.empty()) return;
-    // Find the intersection of firedAlarms and mAlarms.
-    // The for loop is inefficient, since it loops over all keys, but that's okay since it is very
-    // seldomly called. The alternative would be having InternalAlarms store information about the
-    // DurationAnomalyTracker and key, but that's a lot of data overhead to speed up something that
-    // is rarely ever called.
-    unordered_map<MetricDimensionKey, sp<const InternalAlarm>> matchedAlarms;
-    for (const auto& kv : mAlarms) {
-        if (firedAlarms.count(kv.second) > 0) {
-            matchedAlarms.insert({kv.first, kv.second});
-        }
-    }
-
-    // Now declare each of these alarms to have fired.
-    for (const auto& kv : matchedAlarms) {
-        declareAnomaly(
-                timestampNs, mAlert.metric_id(), kv.first,
-                mAlert.trigger_if_sum_gt() + (timestampNs / NS_PER_SEC) - kv.second->timestampSec);
-        mAlarms.erase(kv.first);
-        firedAlarms.erase(kv.second);  // No one else can also own it, so we're done with it.
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
deleted file mode 100644
index 4641914..0000000
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "AlarmMonitor.h"
-#include "AnomalyTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-
-class DurationAnomalyTracker : public virtual AnomalyTracker {
-public:
-    DurationAnomalyTracker(const Alert& alert, const ConfigKey& configKey,
-                           const sp<AlarmMonitor>& alarmMonitor);
-
-    virtual ~DurationAnomalyTracker();
-
-    // Sets an alarm for the given timestamp.
-    // Replaces previous alarm if one already exists.
-    void startAlarm(const MetricDimensionKey& dimensionKey, const int64_t& eventTime) override;
-
-    // Stops the alarm.
-    // If it should have already fired, but hasn't yet (e.g. because the AlarmManager is delayed),
-    // declare the anomaly now.
-    void stopAlarm(const MetricDimensionKey& dimensionKey, const int64_t& timestampNs) override;
-
-    // Stop all the alarms owned by this tracker. Does not declare any anomalies.
-    void cancelAllAlarms() override;
-
-    // Declares an anomaly for each alarm in firedAlarms that belongs to this DurationAnomalyTracker
-    // and removes it from firedAlarms. The AlarmMonitor is not informed.
-    // Note that this will generally be called from a different thread from the other functions;
-    // the caller is responsible for thread safety.
-    void informAlarmsFired(const int64_t& timestampNs,
-            unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) override;
-
-protected:
-    // Returns the alarm timestamp in seconds for the query dimension if it exists. Otherwise
-    // returns 0.
-    uint32_t getAlarmTimestampSec(const MetricDimensionKey& dimensionKey) const override {
-        auto it = mAlarms.find(dimensionKey);
-        return it == mAlarms.end() ? 0 : it->second->timestampSec;
-    }
-
-    // The alarms owned by this tracker. The alarm monitor also shares the alarm pointers when they
-    // are still active.
-    std::unordered_map<MetricDimensionKey, sp<const InternalAlarm>> mAlarms;
-
-    // Anomaly alarm monitor.
-    sp<AlarmMonitor> mAlarmMonitor;
-
-    FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
-    FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
-    FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
-    FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyDetection);
-    FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp);
-    FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/indexed_priority_queue.h b/cmds/statsd/src/anomaly/indexed_priority_queue.h
deleted file mode 100644
index 99882d0..0000000
--- a/cmds/statsd/src/anomaly/indexed_priority_queue.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <utils/RefBase.h>
-#include <unordered_map>
-#include <vector>
-
-using namespace android;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/** Defines a hash function for sp<const AA>, returning the hash of the underlying pointer. */
-template <class AA>
-struct SpHash {
-    size_t operator()(const sp<const AA>& k) const {
-        return std::hash<const AA*>()(k.get());
-    }
-};
-
-/**
- * Min priority queue for generic type AA.
- * Unlike a regular priority queue, this class is also capable of removing interior elements.
- * @tparam Comparator must implement [bool operator()(sp<const AA> a, sp<const AA> b)], returning
- *    whether a should be closer to the top of the queue than b.
- */
-template <class AA, class Comparator>
-class indexed_priority_queue {
-public:
-    indexed_priority_queue();
-    /** Adds a into the priority queue. If already present or a==nullptr, does nothing. */
-    void push(sp<const AA> a);
-    /*
-     * Removes a from the priority queue. If not present or a==nullptr, does nothing.
-     * Returns true if a had been present (and is now removed), else false.
-     */
-    bool remove(sp<const AA> a);
-    /** Removes the top element, if there is one. */
-    void pop();
-    /** Removes all elements. */
-    void clear();
-    /** Returns whether priority queue contains a (not just a copy of a, but a itself). */
-    bool contains(sp<const AA> a) const;
-    /** Returns min element. Returns nullptr iff empty(). */
-    sp<const AA> top() const;
-    /** Returns number of elements in priority queue. */
-    size_t size() const {
-        return pq.size() - 1;
-    }  // pq is 1-indexed
-    /** Returns true iff priority queue is empty. */
-    bool empty() const {
-        return size() < 1;
-    }
-
-private:
-    /** Vector representing a min-heap (1-indexed, with nullptr at 0). */
-    std::vector<sp<const AA>> pq;
-    /** Mapping of each element in pq to its index in pq (i.e. the inverse of a=pq[i]). */
-    std::unordered_map<sp<const AA>, size_t, SpHash<AA>> indices;
-
-    void init();
-    void sift_up(size_t idx);
-    void sift_down(size_t idx);
-    /** Returns whether pq[idx1] is considered higher than pq[idx2], according to Comparator. */
-    bool higher(size_t idx1, size_t idx2) const;
-    void swap_indices(size_t i, size_t j);
-};
-
-// Implementation must be done in this file due to use of template.
-
-template <class AA, class Comparator>
-indexed_priority_queue<AA, Comparator>::indexed_priority_queue() {
-    init();
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::push(sp<const AA> a) {
-    if (a == nullptr) return;
-    if (contains(a)) return;
-    pq.push_back(a);
-    size_t idx = size();  // index of last element since 1-indexed
-    indices.insert({a, idx});
-    sift_up(idx);  // get the pq back in order
-}
-
-template <class AA, class Comparator>
-bool indexed_priority_queue<AA, Comparator>::remove(sp<const AA> a) {
-    if (a == nullptr) return false;
-    if (!contains(a)) return false;
-    size_t idx = indices[a];
-    if (idx >= pq.size()) {
-        return false;
-    }
-    if (idx == size()) {  // if a is the last element, i.e. at index idx == size() == (pq.size()-1)
-        pq.pop_back();
-        indices.erase(a);
-        return true;
-    }
-    // move last element (guaranteed not to be at idx) to idx, then delete a
-    sp<const AA> last_a = pq.back();
-    pq[idx] = last_a;
-    pq.pop_back();
-    indices[last_a] = idx;
-    indices.erase(a);
-
-    // get the heap back in order (since the element at idx is not in order)
-    sift_up(idx);
-    sift_down(idx);
-
-    return true;
-}
-
-// The same as, but slightly more efficient than, remove(top()).
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::pop() {
-    sp<const AA> a = top();
-    if (a == nullptr) return;
-    const size_t idx = 1;
-    if (idx == size()) {  // if a is the last element
-        pq.pop_back();
-        indices.erase(a);
-        return;
-    }
-    // move last element (guaranteed not to be at idx) to idx, then delete a
-    sp<const AA> last_a = pq.back();
-    pq[idx] = last_a;
-    pq.pop_back();
-    indices[last_a] = idx;
-    indices.erase(a);
-
-    // get the heap back in order (since the element at idx is not in order)
-    sift_down(idx);
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::clear() {
-    pq.clear();
-    indices.clear();
-    init();
-}
-
-template <class AA, class Comparator>
-sp<const AA> indexed_priority_queue<AA, Comparator>::top() const {
-    if (empty()) return nullptr;
-    return pq[1];
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::init() {
-    pq.push_back(nullptr);         // so that pq is 1-indexed.
-    indices.insert({nullptr, 0});  // just to be consistent with pq.
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::sift_up(size_t idx) {
-    while (idx > 1) {
-        size_t parent = idx / 2;
-        if (higher(idx, parent))
-            swap_indices(idx, parent);
-        else
-            break;
-        idx = parent;
-    }
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::sift_down(size_t idx) {
-    while (2 * idx <= size()) {
-        size_t child = 2 * idx;
-        if (child < size() && higher(child + 1, child)) child++;
-        if (higher(child, idx))
-            swap_indices(child, idx);
-        else
-            break;
-        idx = child;
-    }
-}
-
-template <class AA, class Comparator>
-bool indexed_priority_queue<AA, Comparator>::higher(size_t idx1, size_t idx2) const {
-    if (!(0u < idx1 && idx1 < pq.size() && 0u < idx2 && idx2 < pq.size())) {
-        return false;  // got to do something.
-    }
-    return Comparator()(pq[idx1], pq[idx2]);
-}
-
-template <class AA, class Comparator>
-bool indexed_priority_queue<AA, Comparator>::contains(sp<const AA> a) const {
-    if (a == nullptr) return false;  // publicly, we pretend that nullptr is not actually in pq.
-    return indices.count(a) > 0;
-}
-
-template <class AA, class Comparator>
-void indexed_priority_queue<AA, Comparator>::swap_indices(size_t i, size_t j) {
-    if (!(0u < i && i < pq.size() && 0u < j && j < pq.size())) {
-        return;
-    }
-    sp<const AA> val_i = pq[i];
-    sp<const AA> val_j = pq[j];
-    pq[i] = val_j;
-    pq[j] = val_i;
-    indices[val_i] = j;
-    indices[val_j] = i;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp
deleted file mode 100644
index 5a4a41d..0000000
--- a/cmds/statsd/src/anomaly/subscriber_util.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "external/Perfetto.h"
-#include "subscriber/IncidentdReporter.h"
-#include "subscriber/SubscriberReporter.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void triggerSubscribers(int64_t ruleId, int64_t metricId, const MetricDimensionKey& dimensionKey,
-                        int64_t metricValue, const ConfigKey& configKey,
-                        const std::vector<Subscription>& subscriptions) {
-    VLOG("informSubscribers called.");
-    if (subscriptions.empty()) {
-        VLOG("No Subscriptions were associated.");
-        return;
-    }
-
-    for (const Subscription& subscription : subscriptions) {
-        if (subscription.probability_of_informing() < 1
-                && ((float)rand() / (float)RAND_MAX) >= subscription.probability_of_informing()) {
-            // Note that due to float imprecision, 0.0 and 1.0 might not truly mean never/always.
-            // The config writer was advised to use -0.1 and 1.1 for never/always.
-            ALOGI("Fate decided that a subscriber would not be informed.");
-            continue;
-        }
-        switch (subscription.subscriber_information_case()) {
-            case Subscription::SubscriberInformationCase::kIncidentdDetails:
-                if (!GenerateIncidentReport(subscription.incidentd_details(), ruleId, metricId,
-                                            dimensionKey, metricValue, configKey)) {
-                    ALOGW("Failed to generate incident report.");
-                }
-                break;
-            case Subscription::SubscriberInformationCase::kPerfettoDetails:
-                if (!CollectPerfettoTraceAndUploadToDropbox(subscription.perfetto_details(),
-                                                            subscription.id(), ruleId, configKey)) {
-                    ALOGW("Failed to generate perfetto traces.");
-                }
-                break;
-            case Subscription::SubscriberInformationCase::kBroadcastSubscriberDetails:
-                SubscriberReporter::getInstance().alertBroadcastSubscriber(configKey, subscription,
-                                                                           dimensionKey);
-                break;
-            default:
-                break;
-        }
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/anomaly/subscriber_util.h b/cmds/statsd/src/anomaly/subscriber_util.h
deleted file mode 100644
index 1df3c89..0000000
--- a/cmds/statsd/src/anomaly/subscriber_util.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-#include "HashableDimensionKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void triggerSubscribers(const int64_t ruleId, const int64_t metricId,
-                        const MetricDimensionKey& dimensionKey, int64_t metricValue,
-                        const ConfigKey& configKey, const std::vector<Subscription>& subscriptions);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
deleted file mode 100644
index 4574b2e..0000000
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-#include "CombinationConditionTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-using std::vector;
-
-CombinationConditionTracker::CombinationConditionTracker(const int64_t& id, const int index,
-                                                         const uint64_t protoHash)
-    : ConditionTracker(id, index, protoHash) {
-    VLOG("creating CombinationConditionTracker %lld", (long long)mConditionId);
-}
-
-CombinationConditionTracker::~CombinationConditionTracker() {
-    VLOG("~CombinationConditionTracker() %lld", (long long)mConditionId);
-}
-
-bool CombinationConditionTracker::init(const vector<Predicate>& allConditionConfig,
-                                       const vector<sp<ConditionTracker>>& allConditionTrackers,
-                                       const unordered_map<int64_t, int>& conditionIdIndexMap,
-                                       vector<bool>& stack,
-                                       vector<ConditionState>& conditionCache) {
-    VLOG("Combination predicate init() %lld", (long long)mConditionId);
-    if (mInitialized) {
-        // All the children are guaranteed to be initialized, but the recursion is needed to
-        // fill the conditionCache properly, since another combination condition or metric
-        // might rely on this. The recursion is needed to compute the current condition.
-
-        // Init is called instead of isConditionMet so that the ConditionKey can be filled with the
-        // default key for sliced conditions, since we do not know all indirect descendants here.
-        for (const int childIndex : mChildren) {
-            if (conditionCache[childIndex] == ConditionState::kNotEvaluated) {
-                allConditionTrackers[childIndex]->init(allConditionConfig, allConditionTrackers,
-                                                       conditionIdIndexMap, stack, conditionCache);
-            }
-        }
-        conditionCache[mIndex] =
-                evaluateCombinationCondition(mChildren, mLogicalOperation, conditionCache);
-        return true;
-    }
-
-    // mark this node as visited in the recursion stack.
-    stack[mIndex] = true;
-
-    Predicate_Combination combinationCondition = allConditionConfig[mIndex].combination();
-
-    if (!combinationCondition.has_operation()) {
-        return false;
-    }
-    mLogicalOperation = combinationCondition.operation();
-
-    if (mLogicalOperation == LogicalOperation::NOT && combinationCondition.predicate_size() != 1) {
-        return false;
-    }
-
-    for (auto child : combinationCondition.predicate()) {
-        auto it = conditionIdIndexMap.find(child);
-
-        if (it == conditionIdIndexMap.end()) {
-            ALOGW("Predicate %lld not found in the config", (long long)child);
-            return false;
-        }
-
-        int childIndex = it->second;
-        const auto& childTracker = allConditionTrackers[childIndex];
-        // if the child is a visited node in the recursion -> circle detected.
-        if (stack[childIndex]) {
-            ALOGW("Circle detected!!!");
-            return false;
-        }
-
-        bool initChildSucceeded = childTracker->init(allConditionConfig, allConditionTrackers,
-                                                     conditionIdIndexMap, stack, conditionCache);
-
-        if (!initChildSucceeded) {
-            ALOGW("Child initialization failed %lld ", (long long)child);
-            return false;
-        } else {
-            VLOG("Child initialization success %lld ", (long long)child);
-        }
-
-        if (allConditionTrackers[childIndex]->isSliced()) {
-            setSliced(true);
-            mSlicedChildren.push_back(childIndex);
-        } else {
-            mUnSlicedChildren.push_back(childIndex);
-        }
-        mChildren.push_back(childIndex);
-        mTrackerIndex.insert(childTracker->getAtomMatchingTrackerIndex().begin(),
-                             childTracker->getAtomMatchingTrackerIndex().end());
-    }
-
-    mUnSlicedPartCondition =
-            evaluateCombinationCondition(mUnSlicedChildren, mLogicalOperation, conditionCache);
-    conditionCache[mIndex] =
-            evaluateCombinationCondition(mChildren, mLogicalOperation, conditionCache);
-
-    // unmark this node in the recursion stack.
-    stack[mIndex] = false;
-
-    mInitialized = true;
-
-    return true;
-}
-
-bool CombinationConditionTracker::onConfigUpdated(
-        const vector<Predicate>& allConditionProtos, const int index,
-        const vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& conditionTrackerMap) {
-    ConditionTracker::onConfigUpdated(allConditionProtos, index, allConditionTrackers,
-                                      atomMatchingTrackerMap, conditionTrackerMap);
-    mTrackerIndex.clear();
-    mChildren.clear();
-    mUnSlicedChildren.clear();
-    mSlicedChildren.clear();
-    Predicate_Combination combinationCondition = allConditionProtos[mIndex].combination();
-
-    for (const int64_t child : combinationCondition.predicate()) {
-        const auto& it = conditionTrackerMap.find(child);
-
-        if (it == conditionTrackerMap.end()) {
-            ALOGW("Predicate %lld not found in the config", (long long)child);
-            return false;
-        }
-
-        int childIndex = it->second;
-        const sp<ConditionTracker>& childTracker = allConditionTrackers[childIndex];
-
-        // Ensures that the child's tracker indices are updated.
-        if (!childTracker->onConfigUpdated(allConditionProtos, childIndex, allConditionTrackers,
-                                           atomMatchingTrackerMap, conditionTrackerMap)) {
-            ALOGW("Child update failed %lld ", (long long)child);
-            return false;
-        }
-
-        if (allConditionTrackers[childIndex]->isSliced()) {
-            mSlicedChildren.push_back(childIndex);
-        } else {
-            mUnSlicedChildren.push_back(childIndex);
-        }
-        mChildren.push_back(childIndex);
-        mTrackerIndex.insert(childTracker->getAtomMatchingTrackerIndex().begin(),
-                             childTracker->getAtomMatchingTrackerIndex().end());
-    }
-    return true;
-}
-
-void CombinationConditionTracker::isConditionMet(
-        const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
-        const bool isPartialLink,
-        vector<ConditionState>& conditionCache) const {
-    // So far, this is fine as there is at most one child having sliced output.
-    for (const int childIndex : mChildren) {
-        if (conditionCache[childIndex] == ConditionState::kNotEvaluated) {
-            allConditions[childIndex]->isConditionMet(conditionParameters, allConditions,
-                                                      isPartialLink,
-                                                      conditionCache);
-        }
-    }
-    conditionCache[mIndex] =
-            evaluateCombinationCondition(mChildren, mLogicalOperation, conditionCache);
-}
-
-void CombinationConditionTracker::evaluateCondition(
-        const LogEvent& event, const std::vector<MatchingState>& eventMatcherValues,
-        const std::vector<sp<ConditionTracker>>& mAllConditions,
-        std::vector<ConditionState>& nonSlicedConditionCache,
-        std::vector<bool>& conditionChangedCache) {
-    // value is up to date.
-    if (nonSlicedConditionCache[mIndex] != ConditionState::kNotEvaluated) {
-        return;
-    }
-
-    for (const int childIndex : mChildren) {
-        // So far, this is fine as there is at most one child having sliced output.
-        if (nonSlicedConditionCache[childIndex] == ConditionState::kNotEvaluated) {
-            const sp<ConditionTracker>& child = mAllConditions[childIndex];
-            child->evaluateCondition(event, eventMatcherValues, mAllConditions,
-                                     nonSlicedConditionCache, conditionChangedCache);
-        }
-    }
-
-    ConditionState newCondition =
-            evaluateCombinationCondition(mChildren, mLogicalOperation, nonSlicedConditionCache);
-    if (!mSliced) {
-        bool nonSlicedChanged = (mUnSlicedPartCondition != newCondition);
-        mUnSlicedPartCondition = newCondition;
-
-        nonSlicedConditionCache[mIndex] = mUnSlicedPartCondition;
-        conditionChangedCache[mIndex] = nonSlicedChanged;
-    } else {
-        mUnSlicedPartCondition = evaluateCombinationCondition(mUnSlicedChildren, mLogicalOperation,
-                                                              nonSlicedConditionCache);
-
-        for (const int childIndex : mChildren) {
-            // If any of the sliced condition in children condition changes, the combination
-            // condition may be changed too.
-            if (conditionChangedCache[childIndex]) {
-                conditionChangedCache[mIndex] = true;
-                break;
-            }
-        }
-        nonSlicedConditionCache[mIndex] = newCondition;
-        VLOG("CombinationPredicate %lld sliced may changed? %d", (long long)mConditionId,
-            conditionChangedCache[mIndex] == true);
-    }
-}
-
-bool CombinationConditionTracker::equalOutputDimensions(
-        const std::vector<sp<ConditionTracker>>& allConditions,
-        const vector<Matcher>& dimensions) const {
-    if (mSlicedChildren.size() != 1 ||
-        mSlicedChildren.front() >= (int)allConditions.size() ||
-        mLogicalOperation != LogicalOperation::AND) {
-        return false;
-    }
-    const sp<ConditionTracker>& slicedChild = allConditions.at(mSlicedChildren.front());
-    return slicedChild->equalOutputDimensions(allConditions, dimensions);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h
deleted file mode 100644
index d355146..0000000
--- a/cmds/statsd/src/condition/CombinationConditionTracker.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef COMBINATION_CONDITION_TRACKER_H
-#define COMBINATION_CONDITION_TRACKER_H
-
-#include "ConditionTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class CombinationConditionTracker : public ConditionTracker {
-public:
-    CombinationConditionTracker(const int64_t& id, const int index, const uint64_t protoHash);
-
-    ~CombinationConditionTracker();
-
-    bool init(const std::vector<Predicate>& allConditionConfig,
-              const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-              const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
-              std::vector<ConditionState>& conditionCache) override;
-
-    bool onConfigUpdated(const std::vector<Predicate>& allConditionProtos, const int index,
-                         const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-                         const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                         const std::unordered_map<int64_t, int>& conditionTrackerMap) override;
-
-    void evaluateCondition(const LogEvent& event,
-                           const std::vector<MatchingState>& eventMatcherValues,
-                           const std::vector<sp<ConditionTracker>>& mAllConditions,
-                           std::vector<ConditionState>& conditionCache,
-                           std::vector<bool>& changedCache) override;
-
-    void isConditionMet(const ConditionKey& conditionParameters,
-                        const std::vector<sp<ConditionTracker>>& allConditions,
-                        const bool isPartialLink,
-                        std::vector<ConditionState>& conditionCache) const override;
-
-    // Only one child predicate can have dimension.
-    const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
-            const std::vector<sp<ConditionTracker>>& allConditions) const override {
-        for (const auto& child : mChildren) {
-            auto result = allConditions[child]->getChangedToTrueDimensions(allConditions);
-            if (result != nullptr) {
-                return result;
-            }
-        }
-        return nullptr;
-    }
-
-    // Only one child predicate can have dimension.
-    const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
-            const std::vector<sp<ConditionTracker>>& allConditions) const override {
-        for (const auto& child : mChildren) {
-            auto result = allConditions[child]->getChangedToFalseDimensions(allConditions);
-            if (result != nullptr) {
-                return result;
-            }
-        }
-        return nullptr;
-    }
-
-    bool IsSimpleCondition() const  override { return false; }
-
-    bool IsChangedDimensionTrackable() const  override {
-        return mLogicalOperation == LogicalOperation::AND && mSlicedChildren.size() == 1;
-    }
-
-    bool equalOutputDimensions(
-        const std::vector<sp<ConditionTracker>>& allConditions,
-        const vector<Matcher>& dimensions) const override;
-
-    const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(
-            const std::vector<sp<ConditionTracker>>& allConditions) const override {
-        if (mSlicedChildren.size() == 1) {
-            return allConditions[mSlicedChildren.front()]->getSlicedDimensionMap(allConditions);
-        }
-        return nullptr;
-    }
-
-private:
-    LogicalOperation mLogicalOperation;
-
-    // Store index of the children Predicates.
-    // We don't store string name of the Children, because we want to get rid of the hash map to
-    // map the name to object. We don't want to store smart pointers to children, because it
-    // increases the risk of circular dependency and memory leak.
-    std::vector<int> mChildren;
-
-    std::vector<int> mSlicedChildren;
-    std::vector<int> mUnSlicedChildren;
-
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateConditions);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // COMBINATION_CONDITION_TRACKER_H
diff --git a/cmds/statsd/src/condition/ConditionTimer.h b/cmds/statsd/src/condition/ConditionTimer.h
deleted file mode 100644
index 1fbe252..0000000
--- a/cmds/statsd/src/condition/ConditionTimer.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include <stdint.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * A simple stopwatch to time the duration of condition being true.
- *
- * The owner of the stopwatch (MetricProducer) is responsible to notify the stopwatch when condition
- * changes (start/pause), and when to start a new bucket (a new lap basically). All timestamps
- * should be elapsedRealTime in nano seconds.
- *
- * Keep the timer simple and inline everything. This class is *NOT* thread safe. Caller is
- * responsible for thread safety.
- */
-class ConditionTimer {
-public:
-    explicit ConditionTimer(bool initCondition, int64_t bucketStartNs) : mCondition(initCondition) {
-        if (initCondition) {
-            mLastConditionChangeTimestampNs = bucketStartNs;
-        }
-    };
-
-    // Tracks how long the condition has been stayed true in the *current* bucket.
-    // When a new bucket is created, this value will be reset to 0.
-    int64_t mTimerNs = 0;
-
-    // Last elapsed real timestamp when condition changed.
-    int64_t mLastConditionChangeTimestampNs = 0;
-
-    bool mCondition = false;
-
-    int64_t newBucketStart(int64_t nextBucketStartNs) {
-        if (mCondition) {
-            // Normally, the next bucket happens after the last condition
-            // change. In this case, add the time between the condition becoming
-            // true to the next bucket start time.
-            // Otherwise, the next bucket start time is before the last
-            // condition change time, this means that the condition was false at
-            // the bucket boundary before the condition became true, so the
-            // timer should not get updated and the last condition change time
-            // remains as is.
-            if (nextBucketStartNs >= mLastConditionChangeTimestampNs) {
-                mTimerNs += (nextBucketStartNs - mLastConditionChangeTimestampNs);
-                mLastConditionChangeTimestampNs = nextBucketStartNs;
-            }
-        } else if (mLastConditionChangeTimestampNs > nextBucketStartNs) {
-            // The next bucket start time is before the last condition change
-            // time, this means that the condition was true at the bucket
-            // boundary before the condition became false, so adjust the timer
-            // to match how long the condition was true to the bucket boundary.
-            // This means remove the amount the condition stayed true in the
-            // next bucket from the current bucket.
-            mTimerNs -= (mLastConditionChangeTimestampNs - nextBucketStartNs);
-        }
-
-        int64_t temp = mTimerNs;
-        mTimerNs = 0;
-
-        if (!mCondition && (mLastConditionChangeTimestampNs > nextBucketStartNs)) {
-            // The next bucket start time is before the last condition change
-            // time, this means that the condition was true at the bucket
-            // boundary and remained true in the next bucket up to the condition
-            // change to false, so adjust the timer to match how long the
-            // condition stayed true in the next bucket (now the current bucket).
-            mTimerNs = mLastConditionChangeTimestampNs - nextBucketStartNs;
-        }
-        return temp;
-    }
-
-    void onConditionChanged(bool newCondition, int64_t timestampNs) {
-        if (newCondition == mCondition) {
-            return;
-        }
-        mCondition = newCondition;
-        if (newCondition == false) {
-            mTimerNs += (timestampNs - mLastConditionChangeTimestampNs);
-        }
-        mLastConditionChangeTimestampNs = timestampNs;
-    }
-
-    FRIEND_TEST(ConditionTimerTest, TestTimer_Inital_False);
-    FRIEND_TEST(ConditionTimerTest, TestTimer_Inital_True);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h
deleted file mode 100644
index 7af022a..0000000
--- a/cmds/statsd/src/condition/ConditionTracker.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "condition/condition_util.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/AtomMatchingTracker.h"
-#include "matchers/matcher_util.h"
-
-#include <utils/RefBase.h>
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class ConditionTracker : public virtual RefBase {
-public:
-    ConditionTracker(const int64_t& id, const int index, const uint64_t protoHash)
-        : mConditionId(id),
-          mIndex(index),
-          mInitialized(false),
-          mTrackerIndex(),
-          mUnSlicedPartCondition(ConditionState::kUnknown),
-          mSliced(false),
-          mProtoHash(protoHash){};
-
-    virtual ~ConditionTracker(){};
-
-    // Initialize this ConditionTracker. This initialization is done recursively (DFS). It can also
-    // be done in the constructor, but we do it separately because (1) easy to return a bool to
-    // indicate whether the initialization is successful. (2) makes unit test easier.
-    // This function can also be called on config updates, in which case it does nothing other than
-    // fill the condition cache with the current condition.
-    // allConditionConfig: the list of all Predicate config from statsd_config.
-    // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
-    //                       need to call init() on child conditions)
-    // conditionIdIndexMap: the mapping from condition id to its index.
-    // stack: a bit map to keep track which nodes have been visited on the stack in the recursion.
-    // conditionCache: tracks initial conditions of all ConditionTrackers. returns the
-    //                        current condition if called on a config update.
-    virtual bool init(const std::vector<Predicate>& allConditionConfig,
-                      const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-                      const std::unordered_map<int64_t, int>& conditionIdIndexMap,
-                      std::vector<bool>& stack, std::vector<ConditionState>& conditionCache) = 0;
-
-    // Update appropriate state on config updates. Primarily, all indices need to be updated.
-    // This predicate and all of its children are guaranteed to be preserved across the update.
-    // This function is recursive and will call onConfigUpdated on child conditions. It does not
-    // manage cycle detection since all preserved conditions should not have any cycles.
-    //
-    // allConditionProtos: the new predicates.
-    // index: the new index of this tracker in allConditionProtos and allConditionTrackers.
-    // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
-    //                       need to call onConfigUpdated() on child conditions)
-    // atomMatchingTrackerMap: map of atom matcher id to index after the config update.
-    // conditionTrackerMap: map of condition tracker id to index after the config update.
-    // returns whether or not the update is successful.
-    virtual bool onConfigUpdated(const std::vector<Predicate>& allConditionProtos, const int index,
-                                 const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-                                 const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                                 const std::unordered_map<int64_t, int>& conditionTrackerMap) {
-        mIndex = index;
-        return true;
-    }
-
-    // evaluate current condition given the new event.
-    // event: the new log event
-    // eventMatcherValues: the results of the AtomMatchingTrackers. AtomMatchingTrackers always
-    //                     process event before ConditionTrackers, because ConditionTracker depends
-    //                     on AtomMatchingTrackers.
-    // mAllConditions: the list of all ConditionTracker
-    // conditionCache: the cached non-sliced condition of the ConditionTrackers for this new event.
-    // conditionChanged: the bit map to record whether the condition has changed.
-    //                   If the condition has dimension, then any sub condition changes will report
-    //                   conditionChanged.
-    virtual void evaluateCondition(const LogEvent& event,
-                                   const std::vector<MatchingState>& eventMatcherValues,
-                                   const std::vector<sp<ConditionTracker>>& mAllConditions,
-                                   std::vector<ConditionState>& conditionCache,
-                                   std::vector<bool>& conditionChanged) = 0;
-
-    // Query the condition with parameters.
-    // [conditionParameters]: a map from condition name to the HashableDimensionKey to query the
-    //                       condition.
-    // [allConditions]: all condition trackers. This is needed because the condition evaluation is
-    //                  done recursively
-    // [isPartialLink]: true if the link specified by 'conditionParameters' contains all the fields
-    //                  in the condition tracker output dimension.
-    // [conditionCache]: the cache holding the condition evaluation values.
-    virtual void isConditionMet(
-            const ConditionKey& conditionParameters,
-            const std::vector<sp<ConditionTracker>>& allConditions,
-            const bool isPartialLink,
-            std::vector<ConditionState>& conditionCache) const = 0;
-
-    // return the list of AtomMatchingTracker index that this ConditionTracker uses.
-    virtual const std::set<int>& getAtomMatchingTrackerIndex() const {
-        return mTrackerIndex;
-    }
-
-    virtual void setSliced(bool sliced) {
-        mSliced = mSliced | sliced;
-    }
-
-    inline bool isSliced() const {
-        return mSliced;
-    }
-
-    virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
-            const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
-    virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
-            const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
-
-    inline int64_t getConditionId() const {
-        return mConditionId;
-    }
-
-    inline uint64_t getProtoHash() const {
-        return mProtoHash;
-    }
-
-    virtual const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(
-            const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
-
-    virtual bool IsChangedDimensionTrackable() const = 0;
-
-    virtual bool IsSimpleCondition() const = 0;
-
-    virtual bool equalOutputDimensions(
-        const std::vector<sp<ConditionTracker>>& allConditions,
-        const vector<Matcher>& dimensions) const = 0;
-
-    // Return the current condition state of the unsliced part of the condition.
-    inline ConditionState getUnSlicedPartConditionState() const  {
-        return mUnSlicedPartCondition;
-    }
-
-protected:
-    const int64_t mConditionId;
-
-    // the index of this condition in the manager's condition list.
-    int mIndex;
-
-    // if it's properly initialized.
-    bool mInitialized;
-
-    // the list of AtomMatchingTracker index that this ConditionTracker uses.
-    std::set<int> mTrackerIndex;
-
-    // This variable is only used for CombinationConditionTrackers.
-    // SimpleConditionTrackers technically don't have an unsliced part because
-    // they are either sliced or unsliced.
-    //
-    // CombinationConditionTrackers have multiple children ConditionTrackers
-    // that can be a mixture of sliced or unsliced. This tracks the
-    // condition of the unsliced part of the combination condition.
-    ConditionState mUnSlicedPartCondition;
-
-    bool mSliced;
-
-    // Hash of the Predicate's proto bytes from StatsdConfig.
-    // Used to determine if the definition of this condition has changed across a config update.
-    const uint64_t mProtoHash;
-
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateConditions);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/condition/ConditionWizard.cpp b/cmds/statsd/src/condition/ConditionWizard.cpp
deleted file mode 100644
index c542032..0000000
--- a/cmds/statsd/src/condition/ConditionWizard.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-#include "ConditionWizard.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-ConditionState ConditionWizard::query(const int index, const ConditionKey& parameters,
-                                      const bool isPartialLink) {
-    vector<ConditionState> cache(mAllConditions.size(), ConditionState::kNotEvaluated);
-
-    mAllConditions[index]->isConditionMet(
-        parameters, mAllConditions, isPartialLink,
-        cache);
-    return cache[index];
-}
-
-const set<HashableDimensionKey>* ConditionWizard::getChangedToTrueDimensions(
-        const int index) const {
-    return mAllConditions[index]->getChangedToTrueDimensions(mAllConditions);
-}
-
-const set<HashableDimensionKey>* ConditionWizard::getChangedToFalseDimensions(
-        const int index) const {
-    return mAllConditions[index]->getChangedToFalseDimensions(mAllConditions);
-}
-
-bool ConditionWizard::IsChangedDimensionTrackable(const int index) {
-    if (index >= 0 && index < (int)mAllConditions.size()) {
-        return mAllConditions[index]->IsChangedDimensionTrackable();
-    } else {
-        return false;
-    }
-}
-
-bool ConditionWizard::IsSimpleCondition(const int index) {
-    if (index >= 0 && index < (int)mAllConditions.size()) {
-        return mAllConditions[index]->IsSimpleCondition();
-    } else {
-        return false;
-    }
-}
-
-bool ConditionWizard::equalOutputDimensions(const int index, const vector<Matcher>& dimensions) {
-    if (index >= 0 && index < (int)mAllConditions.size()) {
-        return mAllConditions[index]->equalOutputDimensions(mAllConditions, dimensions);
-    } else {
-        return false;
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/condition/ConditionWizard.h b/cmds/statsd/src/condition/ConditionWizard.h
deleted file mode 100644
index 43db94c..0000000
--- a/cmds/statsd/src/condition/ConditionWizard.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef CONDITION_WIZARD_H
-#define CONDITION_WIZARD_H
-
-#include "ConditionTracker.h"
-#include "condition_util.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Held by MetricProducer, to query a condition state with input defined in MetricConditionLink.
-class ConditionWizard : public virtual android::RefBase {
-public:
-    ConditionWizard(){};  // for testing
-    explicit ConditionWizard(std::vector<sp<ConditionTracker>>& conditionTrackers)
-        : mAllConditions(conditionTrackers){};
-
-    virtual ~ConditionWizard(){};
-
-    // Query condition state, for a ConditionTracker at [conditionIndex], with [conditionParameters]
-    // [conditionParameters] mapping from condition name to the HashableDimensionKey to query the
-    //                       condition.
-    // The ConditionTracker at [conditionIndex] can be a CombinationConditionTracker. In this case,
-    // the conditionParameters contains the parameters for it's children SimpleConditionTrackers.
-    virtual ConditionState query(const int conditionIndex, const ConditionKey& conditionParameters,
-                                 const bool isPartialLink);
-
-    virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(const int index) const;
-    virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
-            const int index) const;
-    bool equalOutputDimensions(const int index, const vector<Matcher>& dimensions);
-
-    bool IsChangedDimensionTrackable(const int index);
-    bool IsSimpleCondition(const int index);
-
-    ConditionState getUnSlicedPartConditionState(const int index) {
-        return mAllConditions[index]->getUnSlicedPartConditionState();
-    }
-
-    const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(const int index) const {
-        return mAllConditions[index]->getSlicedDimensionMap(mAllConditions);
-    }
-
-private:
-    std::vector<sp<ConditionTracker>> mAllConditions;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#endif  // CONDITION_WIZARD_H
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
deleted file mode 100644
index 1dcc8f9..0000000
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "SimpleConditionTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-
-SimpleConditionTracker::SimpleConditionTracker(
-        const ConfigKey& key, const int64_t& id, const uint64_t protoHash, const int index,
-        const SimplePredicate& simplePredicate,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap)
-    : ConditionTracker(id, index, protoHash),
-      mConfigKey(key),
-      mContainANYPositionInInternalDimensions(false) {
-    VLOG("creating SimpleConditionTracker %lld", (long long)mConditionId);
-    mCountNesting = simplePredicate.count_nesting();
-
-    setMatcherIndices(simplePredicate, atomMatchingTrackerMap);
-
-    if (simplePredicate.has_dimensions()) {
-        translateFieldMatcher(simplePredicate.dimensions(), &mOutputDimensions);
-        if (mOutputDimensions.size() > 0) {
-            mSliced = true;
-        }
-        mContainANYPositionInInternalDimensions = HasPositionANY(simplePredicate.dimensions());
-    }
-
-    if (simplePredicate.initial_value() == SimplePredicate_InitialValue_FALSE) {
-        mInitialValue = ConditionState::kFalse;
-    } else {
-        mInitialValue = ConditionState::kUnknown;
-    }
-
-    mInitialized = true;
-}
-
-SimpleConditionTracker::~SimpleConditionTracker() {
-    VLOG("~SimpleConditionTracker()");
-}
-
-bool SimpleConditionTracker::init(const vector<Predicate>& allConditionConfig,
-                                  const vector<sp<ConditionTracker>>& allConditionTrackers,
-                                  const unordered_map<int64_t, int>& conditionIdIndexMap,
-                                  vector<bool>& stack, vector<ConditionState>& conditionCache) {
-    // SimpleConditionTracker does not have dependency on other conditions, thus we just return
-    // if the initialization was successful.
-    ConditionKey conditionKey;
-    if (mSliced) {
-        conditionKey[mConditionId] = DEFAULT_DIMENSION_KEY;
-    }
-    isConditionMet(conditionKey, allConditionTrackers, mSliced, conditionCache);
-    return mInitialized;
-}
-
-bool SimpleConditionTracker::onConfigUpdated(
-        const vector<Predicate>& allConditionProtos, const int index,
-        const vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& conditionTrackerMap) {
-    ConditionTracker::onConfigUpdated(allConditionProtos, index, allConditionTrackers,
-                                      atomMatchingTrackerMap, conditionTrackerMap);
-    setMatcherIndices(allConditionProtos[index].simple_predicate(), atomMatchingTrackerMap);
-    return true;
-}
-
-void SimpleConditionTracker::setMatcherIndices(
-        const SimplePredicate& simplePredicate,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap) {
-    mTrackerIndex.clear();
-    if (simplePredicate.has_start()) {
-        auto pair = atomMatchingTrackerMap.find(simplePredicate.start());
-        if (pair == atomMatchingTrackerMap.end()) {
-            ALOGW("Start matcher %lld not found in the config", (long long)simplePredicate.start());
-            return;
-        }
-        mStartLogMatcherIndex = pair->second;
-        mTrackerIndex.insert(mStartLogMatcherIndex);
-    } else {
-        mStartLogMatcherIndex = -1;
-    }
-
-    if (simplePredicate.has_stop()) {
-        auto pair = atomMatchingTrackerMap.find(simplePredicate.stop());
-        if (pair == atomMatchingTrackerMap.end()) {
-            ALOGW("Stop matcher %lld not found in the config", (long long)simplePredicate.stop());
-            return;
-        }
-        mStopLogMatcherIndex = pair->second;
-        mTrackerIndex.insert(mStopLogMatcherIndex);
-    } else {
-        mStopLogMatcherIndex = -1;
-    }
-
-    if (simplePredicate.has_stop_all()) {
-        auto pair = atomMatchingTrackerMap.find(simplePredicate.stop_all());
-        if (pair == atomMatchingTrackerMap.end()) {
-            ALOGW("Stop all matcher %lld found in the config",
-                  (long long)simplePredicate.stop_all());
-            return;
-        }
-        mStopAllLogMatcherIndex = pair->second;
-        mTrackerIndex.insert(mStopAllLogMatcherIndex);
-    } else {
-        mStopAllLogMatcherIndex = -1;
-    }
-}
-
-void SimpleConditionTracker::dumpState() {
-    VLOG("%lld DUMP:", (long long)mConditionId);
-    for (const auto& pair : mSlicedConditionState) {
-        VLOG("\t%s : %d", pair.first.toString().c_str(), pair.second);
-    }
-
-    VLOG("Changed to true keys: \n");
-    for (const auto& key : mLastChangedToTrueDimensions) {
-        VLOG("%s", key.toString().c_str());
-    }
-    VLOG("Changed to false keys: \n");
-    for (const auto& key : mLastChangedToFalseDimensions) {
-        VLOG("%s", key.toString().c_str());
-    }
-}
-
-void SimpleConditionTracker::handleStopAll(std::vector<ConditionState>& conditionCache,
-                                           std::vector<bool>& conditionChangedCache) {
-    // Unless the default condition is false, and there was nothing started, otherwise we have
-    // triggered a condition change.
-    conditionChangedCache[mIndex] =
-            (mInitialValue == ConditionState::kFalse && mSlicedConditionState.empty()) ? false
-                                                                                           : true;
-
-    for (const auto& cond : mSlicedConditionState) {
-        if (cond.second > 0) {
-            mLastChangedToFalseDimensions.insert(cond.first);
-        }
-    }
-
-    // After StopAll, we know everything has stopped. From now on, default condition is false.
-    mInitialValue = ConditionState::kFalse;
-    mSlicedConditionState.clear();
-    conditionCache[mIndex] = ConditionState::kFalse;
-}
-
-bool SimpleConditionTracker::hitGuardRail(const HashableDimensionKey& newKey) {
-    if (!mSliced || mSlicedConditionState.find(newKey) != mSlicedConditionState.end()) {
-        // if the condition is not sliced or the key is not new, we are good!
-        return false;
-    }
-    // 1. Report the tuple count if the tuple count > soft limit
-    if (mSlicedConditionState.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
-        size_t newTupleCount = mSlicedConditionState.size() + 1;
-        StatsdStats::getInstance().noteConditionDimensionSize(mConfigKey, mConditionId, newTupleCount);
-        // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
-        if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
-            ALOGE("Predicate %lld dropping data for dimension key %s",
-                (long long)mConditionId, newKey.toString().c_str());
-            return true;
-        }
-    }
-    return false;
-}
-
-void SimpleConditionTracker::handleConditionEvent(const HashableDimensionKey& outputKey,
-                                                  bool matchStart, ConditionState* conditionCache,
-                                                  bool* conditionChangedCache) {
-    bool changed = false;
-    auto outputIt = mSlicedConditionState.find(outputKey);
-    ConditionState newCondition;
-    if (hitGuardRail(outputKey)) {
-        (*conditionChangedCache) = false;
-        // Tells the caller it's evaluated.
-        (*conditionCache) = ConditionState::kUnknown;
-        return;
-    }
-    if (outputIt == mSlicedConditionState.end()) {
-        // We get a new output key.
-        newCondition = matchStart ? ConditionState::kTrue : ConditionState::kFalse;
-        if (matchStart && mInitialValue != ConditionState::kTrue) {
-            mSlicedConditionState[outputKey] = 1;
-            changed = true;
-            mLastChangedToTrueDimensions.insert(outputKey);
-        } else if (mInitialValue != ConditionState::kFalse) {
-            // it's a stop and we don't have history about it.
-            // If the default condition is not false, it means this stop is valuable to us.
-            mSlicedConditionState[outputKey] = 0;
-            mLastChangedToFalseDimensions.insert(outputKey);
-            changed = true;
-        }
-    } else {
-        // we have history about this output key.
-        auto& startedCount = outputIt->second;
-        // assign the old value first.
-        newCondition = startedCount > 0 ? ConditionState::kTrue : ConditionState::kFalse;
-        if (matchStart) {
-            if (startedCount == 0) {
-                mLastChangedToTrueDimensions.insert(outputKey);
-                // This condition for this output key will change from false -> true
-                changed = true;
-            }
-
-            // it's ok to do ++ here, even if we don't count nesting. The >1 counts will be treated
-            // as 1 if not counting nesting.
-            startedCount++;
-            newCondition = ConditionState::kTrue;
-        } else {
-            // This is a stop event.
-            if (startedCount > 0) {
-                if (mCountNesting) {
-                    startedCount--;
-                    if (startedCount == 0) {
-                        newCondition = ConditionState::kFalse;
-                    }
-                } else {
-                    // not counting nesting, so ignore the number of starts, stop now.
-                    startedCount = 0;
-                    newCondition = ConditionState::kFalse;
-                }
-                // if everything has stopped for this output key, condition true -> false;
-                if (startedCount == 0) {
-                    mLastChangedToFalseDimensions.insert(outputKey);
-                    changed = true;
-                }
-            }
-
-            // if default condition is false, it means we don't need to keep the false values.
-            if (mInitialValue == ConditionState::kFalse && startedCount == 0) {
-                mSlicedConditionState.erase(outputIt);
-                VLOG("erase key %s", outputKey.toString().c_str());
-            }
-        }
-    }
-
-    // dump all dimensions for debugging
-    if (DEBUG) {
-        dumpState();
-    }
-
-    (*conditionChangedCache) = changed;
-    (*conditionCache) = newCondition;
-
-    VLOG("SimplePredicate %lld nonSlicedChange? %d", (long long)mConditionId,
-         conditionChangedCache[mIndex] == true);
-}
-
-void SimpleConditionTracker::evaluateCondition(
-        const LogEvent& event,
-        const vector<MatchingState>& eventMatcherValues,
-        const vector<sp<ConditionTracker>>& mAllConditions,
-        vector<ConditionState>& conditionCache,
-        vector<bool>& conditionChangedCache) {
-    if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
-        // it has been evaluated.
-        VLOG("Yes, already evaluated, %lld %d",
-            (long long)mConditionId, conditionCache[mIndex]);
-        return;
-    }
-    mLastChangedToTrueDimensions.clear();
-    mLastChangedToFalseDimensions.clear();
-
-    if (mStopAllLogMatcherIndex >= 0 && mStopAllLogMatcherIndex < int(eventMatcherValues.size()) &&
-        eventMatcherValues[mStopAllLogMatcherIndex] == MatchingState::kMatched) {
-        handleStopAll(conditionCache, conditionChangedCache);
-        return;
-    }
-
-    int matchedState = -1;
-    // Note: The order to evaluate the following start, stop, stop_all matters.
-    // The priority of overwrite is stop_all > stop > start.
-    if (mStartLogMatcherIndex >= 0 &&
-        eventMatcherValues[mStartLogMatcherIndex] == MatchingState::kMatched) {
-        matchedState = 1;
-    }
-
-    if (mStopLogMatcherIndex >= 0 &&
-        eventMatcherValues[mStopLogMatcherIndex] == MatchingState::kMatched) {
-        matchedState = 0;
-    }
-
-    if (matchedState < 0) {
-        // The event doesn't match this condition. So we just report existing condition values.
-        conditionChangedCache[mIndex] = false;
-        if (mSliced) {
-            // if the condition result is sliced. The overall condition is true if any of the sliced
-            // condition is true
-            conditionCache[mIndex] = mInitialValue;
-            for (const auto& slicedCondition : mSlicedConditionState) {
-                if (slicedCondition.second > 0) {
-                    conditionCache[mIndex] = ConditionState::kTrue;
-                    break;
-                }
-            }
-        } else {
-            const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
-            if (itr == mSlicedConditionState.end()) {
-                // condition not sliced, but we haven't seen the matched start or stop yet. so
-                // return initial value.
-                conditionCache[mIndex] = mInitialValue;
-            } else {
-                // return the cached condition.
-                conditionCache[mIndex] =
-                        itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
-            }
-        }
-        return;
-    }
-
-    ConditionState overallState = mInitialValue;
-    bool overallChanged = false;
-
-    if (mOutputDimensions.size() == 0) {
-        handleConditionEvent(DEFAULT_DIMENSION_KEY, matchedState == 1, &overallState,
-                             &overallChanged);
-    } else if (!mContainANYPositionInInternalDimensions) {
-        HashableDimensionKey outputValue;
-        filterValues(mOutputDimensions, event.getValues(), &outputValue);
-
-        // If this event has multiple nodes in the attribution chain,  this log event probably will
-        // generate multiple dimensions. If so, we will find if the condition changes for any
-        // dimension and ask the corresponding metric producer to verify whether the actual sliced
-        // condition has changed or not.
-        // A high level assumption is that a predicate is either sliced or unsliced. We will never
-        // have both sliced and unsliced version of a predicate.
-        handleConditionEvent(outputValue, matchedState == 1, &overallState, &overallChanged);
-    } else {
-        ALOGE("The condition tracker should not be sliced by ANY position matcher.");
-    }
-    conditionCache[mIndex] = overallState;
-    conditionChangedCache[mIndex] = overallChanged;
-}
-
-void SimpleConditionTracker::isConditionMet(
-        const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
-        const bool isPartialLink,
-        vector<ConditionState>& conditionCache) const {
-
-    if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
-        // it has been evaluated.
-        VLOG("Yes, already evaluated, %lld %d",
-            (long long)mConditionId, conditionCache[mIndex]);
-        return;
-    }
-    const auto pair = conditionParameters.find(mConditionId);
-
-    if (pair == conditionParameters.end()) {
-        ConditionState conditionState = ConditionState::kNotEvaluated;
-        conditionState = conditionState | mInitialValue;
-        if (!mSliced) {
-            const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
-            if (itr != mSlicedConditionState.end()) {
-                ConditionState sliceState =
-                    itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
-                conditionState = conditionState | sliceState;
-            }
-        }
-        conditionCache[mIndex] = conditionState;
-        return;
-    }
-
-    ConditionState conditionState = ConditionState::kNotEvaluated;
-    const HashableDimensionKey& key = pair->second;
-    if (isPartialLink) {
-        // For unseen key, check whether the require dimensions are subset of sliced condition
-        // output.
-        conditionState = conditionState | mInitialValue;
-        for (const auto& slice : mSlicedConditionState) {
-            ConditionState sliceState =
-                slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
-            if (slice.first.contains(key)) {
-                conditionState = conditionState | sliceState;
-            }
-        }
-    } else {
-        auto startedCountIt = mSlicedConditionState.find(key);
-        conditionState = conditionState | mInitialValue;
-        if (startedCountIt != mSlicedConditionState.end()) {
-            ConditionState sliceState =
-                startedCountIt->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
-            conditionState = conditionState | sliceState;
-        }
-
-    }
-    conditionCache[mIndex] = conditionState;
-    VLOG("Predicate %lld return %d", (long long)mConditionId, conditionCache[mIndex]);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h
deleted file mode 100644
index 2fbc8a7..0000000
--- a/cmds/statsd/src/condition/SimpleConditionTracker.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef SIMPLE_CONDITION_TRACKER_H
-#define SIMPLE_CONDITION_TRACKER_H
-
-#include <gtest/gtest_prod.h>
-#include "ConditionTracker.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class SimpleConditionTracker : public ConditionTracker {
-public:
-    SimpleConditionTracker(const ConfigKey& key, const int64_t& id, const uint64_t protoHash,
-                           const int index, const SimplePredicate& simplePredicate,
-                           const std::unordered_map<int64_t, int>& atomMatchingTrackerMap);
-
-    ~SimpleConditionTracker();
-
-    bool init(const std::vector<Predicate>& allConditionConfig,
-              const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-              const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
-              std::vector<ConditionState>& conditionCache) override;
-
-    bool onConfigUpdated(const std::vector<Predicate>& allConditionProtos, const int index,
-                         const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-                         const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                         const std::unordered_map<int64_t, int>& conditionTrackerMap) override;
-
-    void evaluateCondition(const LogEvent& event,
-                           const std::vector<MatchingState>& eventMatcherValues,
-                           const std::vector<sp<ConditionTracker>>& mAllConditions,
-                           std::vector<ConditionState>& conditionCache,
-                           std::vector<bool>& changedCache) override;
-
-    void isConditionMet(const ConditionKey& conditionParameters,
-                        const std::vector<sp<ConditionTracker>>& allConditions,
-                        const bool isPartialLink,
-                        std::vector<ConditionState>& conditionCache) const override;
-
-    virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
-            const std::vector<sp<ConditionTracker>>& allConditions) const {
-        if (mSliced) {
-            return &mLastChangedToTrueDimensions;
-        } else {
-            return nullptr;
-        }
-    }
-
-    virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
-            const std::vector<sp<ConditionTracker>>& allConditions) const {
-        if (mSliced) {
-            return &mLastChangedToFalseDimensions;
-        } else {
-            return nullptr;
-        }
-    }
-
-    const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(
-            const std::vector<sp<ConditionTracker>>& allConditions) const override {
-        return &mSlicedConditionState;
-    }
-
-    bool IsChangedDimensionTrackable() const  override { return true; }
-
-    bool IsSimpleCondition() const  override { return true; }
-
-    bool equalOutputDimensions(
-        const std::vector<sp<ConditionTracker>>& allConditions,
-        const vector<Matcher>& dimensions) const override {
-            return equalDimensions(mOutputDimensions, dimensions);
-    }
-
-private:
-    const ConfigKey mConfigKey;
-    // The index of the LogEventMatcher which defines the start.
-    int mStartLogMatcherIndex;
-
-    // The index of the LogEventMatcher which defines the end.
-    int mStopLogMatcherIndex;
-
-    // if the start end needs to be nested.
-    bool mCountNesting;
-
-    // The index of the LogEventMatcher which defines the stop all.
-    int mStopAllLogMatcherIndex;
-
-    ConditionState mInitialValue;
-
-    std::vector<Matcher> mOutputDimensions;
-
-    bool mContainANYPositionInInternalDimensions;
-
-    std::set<HashableDimensionKey> mLastChangedToTrueDimensions;
-    std::set<HashableDimensionKey> mLastChangedToFalseDimensions;
-
-    std::map<HashableDimensionKey, int> mSlicedConditionState;
-
-    void setMatcherIndices(const SimplePredicate& predicate,
-                           const std::unordered_map<int64_t, int>& logTrackerMap);
-
-    void handleStopAll(std::vector<ConditionState>& conditionCache,
-                       std::vector<bool>& changedCache);
-
-    void handleConditionEvent(const HashableDimensionKey& outputKey, bool matchStart,
-                              ConditionState* conditionCache, bool* changedCache);
-
-    bool hitGuardRail(const HashableDimensionKey& newKey);
-
-    void dumpState();
-
-    FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedCondition);
-    FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim);
-    FRIEND_TEST(SimpleConditionTrackerTest, TestStopAll);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateConditions);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // SIMPLE_CONDITION_TRACKER_H
diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp
deleted file mode 100644
index 60b8c53..0000000
--- a/cmds/statsd/src/condition/condition_util.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "Log.h"
-
-#include "condition_util.h"
-
-#include "../matchers/matcher_util.h"
-#include "ConditionTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-
-ConditionState evaluateCombinationCondition(const std::vector<int>& children,
-                                            const LogicalOperation& operation,
-                                            const std::vector<ConditionState>& conditionCache) {
-    ConditionState newCondition;
-
-    bool hasUnknown = false;
-    bool hasFalse = false;
-    bool hasTrue = false;
-
-    for (auto childIndex : children) {
-        ConditionState childState = conditionCache[childIndex];
-        if (childState == ConditionState::kUnknown) {
-            hasUnknown = true;
-            break;
-        }
-        if (childState == ConditionState::kFalse) {
-            hasFalse = true;
-        }
-        if (childState == ConditionState::kTrue) {
-            hasTrue = true;
-        }
-    }
-
-    // If any child condition is in unknown state, the condition is unknown too.
-    if (hasUnknown) {
-        return ConditionState::kUnknown;
-    }
-
-    switch (operation) {
-        case LogicalOperation::AND: {
-            newCondition = hasFalse ? ConditionState::kFalse : ConditionState::kTrue;
-            break;
-        }
-        case LogicalOperation::OR: {
-            newCondition = hasTrue ? ConditionState::kTrue : ConditionState::kFalse;
-            break;
-        }
-        case LogicalOperation::NOT:
-            newCondition = children.empty() ? ConditionState::kUnknown :
-                              ((conditionCache[children[0]] == ConditionState::kFalse) ?
-                                  ConditionState::kTrue : ConditionState::kFalse);
-            break;
-        case LogicalOperation::NAND:
-            newCondition = hasFalse ? ConditionState::kTrue : ConditionState::kFalse;
-            break;
-        case LogicalOperation::NOR:
-            newCondition = hasTrue ? ConditionState::kFalse : ConditionState::kTrue;
-            break;
-        case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
-            newCondition = ConditionState::kFalse;
-            break;
-    }
-    return newCondition;
-}
-
-ConditionState operator|(ConditionState l, ConditionState r) {
-    return l >= r ? l : r;
-}
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/condition/condition_util.h b/cmds/statsd/src/condition/condition_util.h
deleted file mode 100644
index fed90ec..0000000
--- a/cmds/statsd/src/condition/condition_util.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef CONDITION_UTIL_H
-#define CONDITION_UTIL_H
-
-#include <vector>
-#include "../matchers/matcher_util.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-enum ConditionState {
-    kNotEvaluated = -2,
-    kUnknown = -1,
-    kFalse = 0,
-    kTrue = 1,
-};
-
-ConditionState operator|(ConditionState l, ConditionState r);
-
-ConditionState evaluateCombinationCondition(const std::vector<int>& children,
-                                            const LogicalOperation& operation,
-                                            const std::vector<ConditionState>& conditionCache);
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#endif  // CONDITION_UTIL_H
diff --git a/cmds/statsd/src/config/ConfigKey.cpp b/cmds/statsd/src/config/ConfigKey.cpp
deleted file mode 100644
index 4a2bd27..0000000
--- a/cmds/statsd/src/config/ConfigKey.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "config/ConfigKey.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-ConfigKey::ConfigKey() {
-}
-
-ConfigKey::ConfigKey(const ConfigKey& that) : mId(that.mId), mUid(that.mUid) {
-}
-
-ConfigKey::ConfigKey(int uid, const int64_t& id) : mId(id), mUid(uid) {
-}
-
-ConfigKey::~ConfigKey() {
-}
-
-string ConfigKey::ToString() const {
-    string s;
-    s += "(" + std::to_string(mUid) + " " + std::to_string(mId) + ")";
-    return s;
-}
-
-
-int64_t StrToInt64(const string& str) {
-    char* endp;
-    int64_t value;
-    value = strtoll(str.c_str(), &endp, 0);
-    if (endp == str.c_str() || *endp != '\0') {
-        value = 0;
-    }
-    return value;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/config/ConfigKey.h b/cmds/statsd/src/config/ConfigKey.h
deleted file mode 100644
index 4cc9393..0000000
--- a/cmds/statsd/src/config/ConfigKey.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::hash;
-using std::string;
-
-/**
- * Uniquely identifies a configuration.
- */
-class ConfigKey {
-public:
-    ConfigKey();
-    ConfigKey(const ConfigKey& that);
-    ConfigKey(int uid, const int64_t& id);
-    ~ConfigKey();
-
-    inline int GetUid() const {
-        return mUid;
-    }
-    inline const int64_t& GetId() const {
-        return mId;
-    }
-
-    inline bool operator<(const ConfigKey& that) const {
-        if (mUid < that.mUid) {
-            return true;
-        }
-        if (mUid > that.mUid) {
-            return false;
-        }
-        return mId < that.mId;
-    };
-
-    inline bool operator==(const ConfigKey& that) const {
-        return mUid == that.mUid && mId == that.mId;
-    };
-
-    string ToString() const;
-
-private:
-    int64_t mId;
-    int mUid;
-};
-
-int64_t StrToInt64(const string& str);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-/**
- * A hash function for ConfigKey so it can be used for unordered_map/set.
- * Unfortunately this has to go in std namespace because C++ is fun!
- */
-namespace std {
-
-using android::os::statsd::ConfigKey;
-
-template <>
-struct hash<ConfigKey> {
-    std::size_t operator()(const ConfigKey& key) const {
-        return (7 * key.GetUid()) ^ ((hash<long long>()(key.GetId())));
-    }
-};
-
-}  // namespace std
diff --git a/cmds/statsd/src/config/ConfigListener.cpp b/cmds/statsd/src/config/ConfigListener.cpp
deleted file mode 100644
index 21a3f16..0000000
--- a/cmds/statsd/src/config/ConfigListener.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "config/ConfigListener.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-ConfigListener::ConfigListener() {
-}
-
-ConfigListener::~ConfigListener() {
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/config/ConfigListener.h b/cmds/statsd/src/config/ConfigListener.h
deleted file mode 100644
index dcd5e52..0000000
--- a/cmds/statsd/src/config/ConfigListener.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-
-#include <utils/RefBase.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::RefBase;
-
-/**
- * Callback for different subsystems inside statsd to implement to find out
- * when a configuration has been added, updated or removed.
- */
-class ConfigListener : public virtual RefBase {
-public:
-    ConfigListener();
-    virtual ~ConfigListener();
-
-    /**
-     * A configuration was added or updated.
-     */
-    virtual void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
-                                 const StatsdConfig& config) = 0;
-
-    /**
-     * A configuration was removed.
-     */
-    virtual void OnConfigRemoved(const ConfigKey& key) = 0;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
deleted file mode 100644
index 13020e0..0000000
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "config/ConfigManager.h"
-#include "storage/StorageManager.h"
-
-#include "guardrail/StatsdStats.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "stats_log_util.h"
-
-#include <stdio.h>
-#include <vector>
-#include "android-base/stringprintf.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::pair;
-using std::string;
-using std::vector;
-
-#define STATS_SERVICE_DIR "/data/misc/stats-service"
-
-using android::base::StringPrintf;
-using std::unique_ptr;
-
-struct ConfigReceiverDeathCookie {
-    ConfigReceiverDeathCookie(const wp<ConfigManager>& configManager, const ConfigKey& configKey,
-                              const shared_ptr<IPendingIntentRef>& pir) :
-            mConfigManager(configManager), mConfigKey(configKey), mPir(pir) {
-    }
-
-    wp<ConfigManager> mConfigManager;
-    ConfigKey mConfigKey;
-    shared_ptr<IPendingIntentRef> mPir;
-};
-
-void ConfigManager::configReceiverDied(void* cookie) {
-    auto cookie_ = static_cast<ConfigReceiverDeathCookie*>(cookie);
-    sp<ConfigManager> thiz = cookie_->mConfigManager.promote();
-    if (!thiz) {
-        return;
-    }
-
-    ConfigKey& configKey = cookie_->mConfigKey;
-    shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
-
-    // Erase the mapping from the config key to the config receiver (pir) if the
-    // mapping still exists.
-    lock_guard<mutex> lock(thiz->mMutex);
-    auto it = thiz->mConfigReceivers.find(configKey);
-    if (it != thiz->mConfigReceivers.end() && it->second == pir) {
-        thiz->mConfigReceivers.erase(configKey);
-    }
-
-    // The death recipient corresponding to this specific pir can never be
-    // triggered again, so free up resources.
-    delete cookie_;
-}
-
-struct ActiveConfigChangedReceiverDeathCookie {
-    ActiveConfigChangedReceiverDeathCookie(const wp<ConfigManager>& configManager, const int uid,
-                                           const shared_ptr<IPendingIntentRef>& pir) :
-            mConfigManager(configManager), mUid(uid), mPir(pir) {
-    }
-
-    wp<ConfigManager> mConfigManager;
-    int mUid;
-    shared_ptr<IPendingIntentRef> mPir;
-};
-
-void ConfigManager::activeConfigChangedReceiverDied(void* cookie) {
-    auto cookie_ = static_cast<ActiveConfigChangedReceiverDeathCookie*>(cookie);
-    sp<ConfigManager> thiz = cookie_->mConfigManager.promote();
-    if (!thiz) {
-        return;
-    }
-
-    int uid = cookie_->mUid;
-    shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
-
-    // Erase the mapping from the config key to the active config changed
-    // receiver (pir) if the mapping still exists.
-    lock_guard<mutex> lock(thiz->mMutex);
-    auto it = thiz->mActiveConfigsChangedReceivers.find(uid);
-    if (it != thiz->mActiveConfigsChangedReceivers.end() && it->second == pir) {
-        thiz->mActiveConfigsChangedReceivers.erase(uid);
-    }
-
-    // The death recipient corresponding to this specific pir can never
-    // be triggered again, so free up resources.
-    delete cookie_;
-}
-
-ConfigManager::ConfigManager() :
-    mConfigReceiverDeathRecipient(AIBinder_DeathRecipient_new(configReceiverDied)),
-    mActiveConfigChangedReceiverDeathRecipient(
-            AIBinder_DeathRecipient_new(activeConfigChangedReceiverDied)) {
-}
-
-ConfigManager::~ConfigManager() {
-}
-
-void ConfigManager::Startup() {
-    map<ConfigKey, StatsdConfig> configsFromDisk;
-    StorageManager::readConfigFromDisk(configsFromDisk);
-    for (const auto& pair : configsFromDisk) {
-        UpdateConfig(pair.first, pair.second);
-    }
-}
-
-void ConfigManager::StartupForTest() {
-    // No-op function to avoid reading configs from disks for tests.
-}
-
-void ConfigManager::AddListener(const sp<ConfigListener>& listener) {
-    lock_guard<mutex> lock(mMutex);
-    mListeners.push_back(listener);
-}
-
-void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& config) {
-    vector<sp<ConfigListener>> broadcastList;
-    {
-        lock_guard <mutex> lock(mMutex);
-
-        const int numBytes = config.ByteSize();
-        vector<uint8_t> buffer(numBytes);
-        config.SerializeToArray(&buffer[0], numBytes);
-
-        auto uidIt = mConfigs.find(key.GetUid());
-        // GuardRail: Limit the number of configs per uid.
-        if (uidIt != mConfigs.end()) {
-            auto it = uidIt->second.find(key);
-            if (it == uidIt->second.end() &&
-                uidIt->second.size() >= StatsdStats::kMaxConfigCountPerUid) {
-                ALOGE("ConfigManager: uid %d has exceeded the config count limit", key.GetUid());
-                return;
-            }
-        }
-
-        // Check if it's a duplicate config.
-        if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end() &&
-            StorageManager::hasIdenticalConfig(key, buffer)) {
-            // This is a duplicate config.
-            ALOGI("ConfigManager This is a duplicate config %s", key.ToString().c_str());
-            // Update saved file on disk. We still update timestamp of file when
-            // there exists a duplicate configuration to avoid garbage collection.
-            update_saved_configs_locked(key, buffer, numBytes);
-            return;
-        }
-
-        // Update saved file on disk.
-        update_saved_configs_locked(key, buffer, numBytes);
-
-        // Add to set.
-        mConfigs[key.GetUid()].insert(key);
-
-        for (const sp<ConfigListener>& listener : mListeners) {
-            broadcastList.push_back(listener);
-        }
-    }
-
-    const int64_t timestampNs = getElapsedRealtimeNs();
-    // Tell everyone
-    for (const sp<ConfigListener>& listener : broadcastList) {
-        listener->OnConfigUpdated(timestampNs, key, config);
-    }
-}
-
-void ConfigManager::SetConfigReceiver(const ConfigKey& key,
-                                      const shared_ptr<IPendingIntentRef>& pir) {
-    lock_guard<mutex> lock(mMutex);
-    mConfigReceivers[key] = pir;
-    AIBinder_linkToDeath(pir->asBinder().get(), mConfigReceiverDeathRecipient.get(),
-                         new ConfigReceiverDeathCookie(this, key, pir));
-}
-
-void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
-    lock_guard<mutex> lock(mMutex);
-    mConfigReceivers.erase(key);
-}
-
-void ConfigManager::SetActiveConfigsChangedReceiver(const int uid,
-                                                    const shared_ptr<IPendingIntentRef>& pir) {
-    {
-        lock_guard<mutex> lock(mMutex);
-        mActiveConfigsChangedReceivers[uid] = pir;
-    }
-    AIBinder_linkToDeath(pir->asBinder().get(), mActiveConfigChangedReceiverDeathRecipient.get(),
-                         new ActiveConfigChangedReceiverDeathCookie(this, uid, pir));
-}
-
-void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid) {
-    lock_guard<mutex> lock(mMutex);
-    mActiveConfigsChangedReceivers.erase(uid);
-}
-
-void ConfigManager::RemoveConfig(const ConfigKey& key) {
-    vector<sp<ConfigListener>> broadcastList;
-    {
-        lock_guard <mutex> lock(mMutex);
-
-        auto uid = key.GetUid();
-        auto uidIt = mConfigs.find(uid);
-        if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
-            // Remove from map
-            uidIt->second.erase(key);
-
-            for (const sp<ConfigListener>& listener : mListeners) {
-                broadcastList.push_back(listener);
-            }
-        }
-
-        // Remove from disk. There can still be a lingering file on disk so we check
-        // whether or not the config was on memory.
-        remove_saved_configs(key);
-    }
-
-    for (const sp<ConfigListener>& listener:broadcastList) {
-        listener->OnConfigRemoved(key);
-    }
-}
-
-void ConfigManager::remove_saved_configs(const ConfigKey& key) {
-    string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
-    StorageManager::deleteSuffixedFiles(STATS_SERVICE_DIR, suffix.c_str());
-}
-
-void ConfigManager::RemoveConfigs(int uid) {
-    vector<ConfigKey> removed;
-    vector<sp<ConfigListener>> broadcastList;
-    {
-        lock_guard <mutex> lock(mMutex);
-
-        auto uidIt = mConfigs.find(uid);
-        if (uidIt == mConfigs.end()) {
-            return;
-        }
-
-        for (auto it = uidIt->second.begin(); it != uidIt->second.end(); ++it) {
-            // Remove from map
-                remove_saved_configs(*it);
-                removed.push_back(*it);
-        }
-
-        mConfigs.erase(uidIt);
-
-        for (const sp<ConfigListener>& listener : mListeners) {
-            broadcastList.push_back(listener);
-        }
-    }
-
-    // Remove separately so if they do anything in the callback they can't mess up our iteration.
-    for (auto& key : removed) {
-        // Tell everyone
-        for (const sp<ConfigListener>& listener:broadcastList) {
-            listener->OnConfigRemoved(key);
-        }
-    }
-}
-
-void ConfigManager::RemoveAllConfigs() {
-    vector<ConfigKey> removed;
-    vector<sp<ConfigListener>> broadcastList;
-    {
-        lock_guard <mutex> lock(mMutex);
-
-        for (auto uidIt = mConfigs.begin(); uidIt != mConfigs.end();) {
-            for (auto it = uidIt->second.begin(); it != uidIt->second.end();) {
-                // Remove from map
-                removed.push_back(*it);
-                it = uidIt->second.erase(it);
-            }
-            uidIt = mConfigs.erase(uidIt);
-        }
-
-        for (const sp<ConfigListener>& listener : mListeners) {
-            broadcastList.push_back(listener);
-        }
-    }
-
-    // Remove separately so if they do anything in the callback they can't mess up our iteration.
-    for (auto& key : removed) {
-        // Tell everyone
-        for (const sp<ConfigListener>& listener:broadcastList) {
-            listener->OnConfigRemoved(key);
-        }
-    }
-}
-
-vector<ConfigKey> ConfigManager::GetAllConfigKeys() const {
-    lock_guard<mutex> lock(mMutex);
-
-    vector<ConfigKey> ret;
-    for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
-        for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
-            ret.push_back(*it);
-        }
-    }
-    return ret;
-}
-
-const shared_ptr<IPendingIntentRef> ConfigManager::GetConfigReceiver(const ConfigKey& key) const {
-    lock_guard<mutex> lock(mMutex);
-
-    auto it = mConfigReceivers.find(key);
-    if (it == mConfigReceivers.end()) {
-        return nullptr;
-    } else {
-        return it->second;
-    }
-}
-
-const shared_ptr<IPendingIntentRef> ConfigManager::GetActiveConfigsChangedReceiver(const int uid)
-        const {
-    lock_guard<mutex> lock(mMutex);
-
-    auto it = mActiveConfigsChangedReceivers.find(uid);
-    if (it == mActiveConfigsChangedReceivers.end()) {
-        return nullptr;
-    } else {
-        return it->second;
-    }
-}
-
-void ConfigManager::Dump(FILE* out) {
-    lock_guard<mutex> lock(mMutex);
-
-    fprintf(out, "CONFIGURATIONS\n");
-    fprintf(out, "     uid name\n");
-    for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
-        for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
-            fprintf(out, "  %6d %lld\n", it->GetUid(), (long long)it->GetId());
-            auto receiverIt = mConfigReceivers.find(*it);
-            if (receiverIt != mConfigReceivers.end()) {
-                fprintf(out, "    -> received by PendingIntent as binder\n");
-            }
-        }
-    }
-}
-
-void ConfigManager::update_saved_configs_locked(const ConfigKey& key,
-                                                const vector<uint8_t>& buffer,
-                                                const int numBytes) {
-    // If there is a pre-existing config with same key we should first delete it.
-    remove_saved_configs(key);
-
-    // Then we save the latest config.
-    string file_name =
-        StringPrintf("%s/%ld_%d_%lld", STATS_SERVICE_DIR, time(nullptr),
-                     key.GetUid(), (long long)key.GetId());
-    StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
deleted file mode 100644
index bef057f..0000000
--- a/cmds/statsd/src/config/ConfigManager.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-#include "config/ConfigListener.h"
-
-#include <aidl/android/os/IPendingIntentRef.h>
-#include <mutex>
-#include <string>
-
-#include <stdio.h>
-
-using aidl::android::os::IPendingIntentRef;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Keeps track of which configurations have been set from various sources.
- */
-class ConfigManager : public virtual android::RefBase {
-public:
-    ConfigManager();
-    virtual ~ConfigManager();
-
-    /**
-     * Initialize ConfigListener by reading from disk and get updates.
-     */
-    void Startup();
-
-    /*
-     * No-op initializer for tests.
-     */
-    void StartupForTest();
-
-    /**
-     * Someone else wants to know about the configs.
-     */
-    void AddListener(const sp<ConfigListener>& listener);
-
-    /**
-     * A configuration was added or updated.
-     *
-     * Reports this to listeners.
-     */
-    void UpdateConfig(const ConfigKey& key, const StatsdConfig& data);
-
-    /**
-     * Sets the broadcast receiver for a configuration key.
-     */
-    void SetConfigReceiver(const ConfigKey& key, const shared_ptr<IPendingIntentRef>& pir);
-
-    /**
-     * Returns the package name and class name representing the broadcast receiver for this config.
-     */
-    const shared_ptr<IPendingIntentRef> GetConfigReceiver(const ConfigKey& key) const;
-
-    /**
-     * Returns all config keys registered.
-     */
-    std::vector<ConfigKey> GetAllConfigKeys() const;
-
-    /**
-     * Erase any broadcast receiver associated with this config key.
-     */
-    void RemoveConfigReceiver(const ConfigKey& key);
-
-    /**
-     * Sets the broadcast receiver that is notified whenever the list of active configs
-     * changes for this uid.
-     */
-    void SetActiveConfigsChangedReceiver(const int uid, const shared_ptr<IPendingIntentRef>& pir);
-
-    /**
-     * Returns the broadcast receiver for active configs changed for this uid.
-     */
-
-    const shared_ptr<IPendingIntentRef> GetActiveConfigsChangedReceiver(const int uid) const;
-
-    /**
-     * Erase any active configs changed broadcast receiver associated with this uid.
-     */
-    void RemoveActiveConfigsChangedReceiver(const int uid);
-
-    /**
-     * A configuration was removed.
-     *
-     * Reports this to listeners.
-     */
-    void RemoveConfig(const ConfigKey& key);
-
-    /**
-     * Remove all of the configs for the given uid.
-     */
-    void RemoveConfigs(int uid);
-
-    /**
-     * Remove all of the configs from memory.
-     */
-    void RemoveAllConfigs();
-
-    /**
-     * Text dump of our state for debugging.
-     */
-    void Dump(FILE* out);
-
-private:
-    mutable std::mutex mMutex;
-
-    /**
-     * Save the configs to disk.
-     */
-    void update_saved_configs_locked(const ConfigKey& key,
-                                     const std::vector<uint8_t>& buffer,
-                                     const int numBytes);
-
-    /**
-     * Remove saved configs from disk.
-     */
-    void remove_saved_configs(const ConfigKey& key);
-
-    /**
-     * Maps from uid to the config keys that have been set.
-     */
-    std::map<int, std::set<ConfigKey>> mConfigs;
-
-    /**
-     * Each config key can be subscribed by up to one receiver, specified as IPendingIntentRef.
-     */
-    std::map<ConfigKey, shared_ptr<IPendingIntentRef>> mConfigReceivers;
-
-    /**
-     * Each uid can be subscribed by up to one receiver to notify that the list of active configs
-     * for this uid has changed. The receiver is specified as IPendingIntentRef.
-     */
-     std::map<int, shared_ptr<IPendingIntentRef>> mActiveConfigsChangedReceivers;
-
-    /**
-     * The ConfigListeners that will be told about changes.
-     */
-    std::vector<sp<ConfigListener>> mListeners;
-
-    // Death recipients that are triggered when the host process holding an
-    // IPendingIntentRef dies.
-    ::ndk::ScopedAIBinder_DeathRecipient mConfigReceiverDeathRecipient;
-    ::ndk::ScopedAIBinder_DeathRecipient mActiveConfigChangedReceiverDeathRecipient;
-
-    /**
-     * Death recipient callback that is called when a config receiver dies.
-     * The cookie is a pointer to a ConfigReceiverDeathCookie.
-     */
-    static void configReceiverDied(void* cookie);
-
-    /**
-     * Death recipient callback that is called when an active config changed
-     * receiver dies. The cookie is a pointer to an
-     * ActiveConfigChangedReceiverDeathCookie.
-     */
-    static void activeConfigChangedReceiverDied(void* cookie);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/experiment_ids.proto b/cmds/statsd/src/experiment_ids.proto
deleted file mode 100644
index c203631..0000000
--- a/cmds/statsd/src/experiment_ids.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.internal.os";
-option java_outer_classname = "ExperimentIdsProto";
-
-// StatsLogProcessor uses the proto to parse experiment ids from
-// BinaryPushStateChanged atoms. This needs to be in sync with
-// TrainExperimentIds in atoms.proto.
-message ExperimentIds {
-    repeated int64 experiment_id = 1;
-}
diff --git a/cmds/statsd/src/external/Perfetto.cpp b/cmds/statsd/src/external/Perfetto.cpp
deleted file mode 100644
index 85b660e..0000000
--- a/cmds/statsd/src/external/Perfetto.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "config/ConfigKey.h"
-#include "Log.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alert
-
-#include <android-base/unique_fd.h>
-#include <inttypes.h>
-#include <sys/wait.h>
-
-#include <string>
-
-namespace {
-const char kDropboxTag[] = "perfetto";
-}
-
-namespace android {
-namespace os {
-namespace statsd {
-
-bool CollectPerfettoTraceAndUploadToDropbox(const PerfettoDetails& config,
-                                            int64_t subscription_id,
-                                            int64_t alert_id,
-                                            const ConfigKey& configKey) {
-    VLOG("Starting trace collection through perfetto");
-
-    if (!config.has_trace_config()) {
-        ALOGE("The perfetto trace config is empty, aborting");
-        return false;
-    }
-
-    char subscriptionId[25];
-    char alertId[25];
-    char configId[25];
-    char configUid[25];
-    snprintf(subscriptionId, sizeof(subscriptionId), "%" PRId64, subscription_id);
-    snprintf(alertId, sizeof(alertId), "%" PRId64, alert_id);
-    snprintf(configId, sizeof(configId), "%" PRId64, configKey.GetId());
-    snprintf(configUid, sizeof(configUid), "%d", configKey.GetUid());
-
-    android::base::unique_fd readPipe;
-    android::base::unique_fd writePipe;
-    if (!android::base::Pipe(&readPipe, &writePipe)) {
-        ALOGE("pipe() failed while calling the Perfetto client: %s", strerror(errno));
-        return false;
-    }
-
-    pid_t pid = fork();
-    if (pid < 0) {
-        ALOGE("fork() failed while calling the Perfetto client: %s", strerror(errno));
-        return false;
-    }
-
-    if (pid == 0) {
-        // Child process.
-
-        // No malloc calls or library calls after this point. Remember that even
-        // ALOGx (aka android_printLog()) can use dynamic memory for vsprintf().
-
-        writePipe.reset();  // Close the write end (owned by the main process).
-
-        // Replace stdin with |readPipe| so the main process can write into it.
-        if (dup2(readPipe.get(), STDIN_FILENO) < 0) _exit(1);
-        readPipe.reset();
-
-        // Replace stdout/stderr with /dev/null and close any other file
-        // descriptor. This is to avoid SELinux complaining about perfetto
-        // trying to access files accidentally left open by statsd (i.e. files
-        // that have been opened without the O_CLOEXEC flag).
-        int devNullFd = open("/dev/null", O_RDWR | O_CLOEXEC);
-        if (dup2(devNullFd, STDOUT_FILENO) < 0) _exit(2);
-        if (dup2(devNullFd, STDERR_FILENO) < 0) _exit(3);
-        close(devNullFd);
-        for (int i = 0; i < 1024; i++) {
-            if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO) close(i);
-        }
-
-        execl("/system/bin/perfetto", "perfetto", "--background", "--config", "-", "--dropbox",
-              kDropboxTag, "--alert-id", alertId, "--config-id", configId, "--config-uid",
-              configUid, "--subscription-id", subscriptionId, nullptr);
-
-        // execl() doesn't return in case of success, if we get here something
-        // failed.
-        _exit(4);
-    }
-
-    // Main process.
-
-    readPipe.reset();  // Close the read end (owned by the child process).
-
-    // Using fdopen() because fwrite() has the right logic to chunking write()
-    // over a pipe (see __sfvwrite()).
-    FILE* writePipeStream = android::base::Fdopen(std::move(writePipe), "wb");
-    if (!writePipeStream) {
-        ALOGE("fdopen() failed while calling the Perfetto client: %s", strerror(errno));
-        return false;
-    }
-
-    const std::string& cfgProto = config.trace_config();
-    size_t bytesWritten = fwrite(cfgProto.data(), 1, cfgProto.size(), writePipeStream);
-    fclose(writePipeStream);
-    if (bytesWritten != cfgProto.size() || cfgProto.size() == 0) {
-        ALOGE("fwrite() failed (ret: %zd) while calling the Perfetto client: %s", bytesWritten,
-              strerror(errno));
-        return false;
-    }
-
-    // This does NOT wait for the full duration of the trace. It just waits until
-    // the process has read the config from stdin and detached.
-    int childStatus = 0;
-    waitpid(pid, &childStatus, 0);
-    if (!WIFEXITED(childStatus) || WEXITSTATUS(childStatus) != 0) {
-        ALOGE("Child process failed (0x%x) while calling the Perfetto client", childStatus);
-        return false;
-    }
-
-    VLOG("CollectPerfettoTraceAndUploadToDropbox() succeeded");
-    return true;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/Perfetto.h b/cmds/statsd/src/external/Perfetto.h
deleted file mode 100644
index 095782a..0000000
--- a/cmds/statsd/src/external/Perfetto.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class ConfigKey;
-class PerfettoDetails;  // Declared in statsd_config.pb.h
-
-// Starts the collection of a Perfetto trace with the given |config|.
-// The trace is uploaded to Dropbox by the perfetto cmdline util once done.
-// This method returns immediately after passing the config and does NOT wait
-// for the full duration of the trace.
-bool CollectPerfettoTraceAndUploadToDropbox(const PerfettoDetails& config,
-                                            int64_t subscription_id,
-                                            int64_t alert_id,
-                                            const ConfigKey& configKey);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/PullDataReceiver.h b/cmds/statsd/src/external/PullDataReceiver.h
deleted file mode 100644
index dd5c0cf..0000000
--- a/cmds/statsd/src/external/PullDataReceiver.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PullDataReceiver : virtual public RefBase{
- public:
-  virtual ~PullDataReceiver() {}
-  /**
-   * @param data The pulled data.
-   * @param pullSuccess Whether the pull succeeded. If the pull does not succeed, the data for the
-   * bucket should be invalidated.
-   * @param originalPullTimeNs This is when all the pulls have been initiated (elapsed time).
-   */
-  virtual void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data, 
-                            bool pullSuccess, int64_t originalPullTimeNs) = 0;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/PullResultReceiver.cpp b/cmds/statsd/src/external/PullResultReceiver.cpp
deleted file mode 100644
index 8aa4792..0000000
--- a/cmds/statsd/src/external/PullResultReceiver.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#include "PullResultReceiver.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-PullResultReceiver::PullResultReceiver(
-        std::function<void(int32_t, bool, const vector<StatsEventParcel>&)> pullFinishCb)
-    : pullFinishCallback(std::move(pullFinishCb)) {
-}
-
-Status PullResultReceiver::pullFinished(int32_t atomTag, bool success,
-                                        const vector<StatsEventParcel>& output) {
-    pullFinishCallback(atomTag, success, output);
-    return Status::ok();
-}
-
-PullResultReceiver::~PullResultReceiver() {
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/PullResultReceiver.h b/cmds/statsd/src/external/PullResultReceiver.h
deleted file mode 100644
index ceaae80..0000000
--- a/cmds/statsd/src/external/PullResultReceiver.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#include <aidl/android/os/BnPullAtomResultReceiver.h>
-#include <aidl/android/util/StatsEventParcel.h>
-
-using namespace std;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnPullAtomResultReceiver;
-using aidl::android::util::StatsEventParcel;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PullResultReceiver : public BnPullAtomResultReceiver {
-public:
-    PullResultReceiver(function<void(int32_t, bool, const vector<StatsEventParcel>&)>
-                               pullFinishCallback);
-    ~PullResultReceiver();
-
-    /**
-     * Binder call for finishing a pull.
-     */
-    Status pullFinished(int32_t atomTag, bool success,
-                        const vector<StatsEventParcel>& output) override;
-
-private:
-    function<void(int32_t, bool, const vector<StatsEventParcel>&)> pullFinishCallback;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/PullUidProvider.h b/cmds/statsd/src/external/PullUidProvider.h
deleted file mode 100644
index 2318c50..0000000
--- a/cmds/statsd/src/external/PullUidProvider.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PullUidProvider : virtual public RefBase {
-public:
-    virtual ~PullUidProvider() {}
-
-    /**
-     * @param atomId The atom for which to get the uids.
-     */
-    virtual vector<int32_t> getPullAtomUids(int32_t atomId) = 0;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.cpp b/cmds/statsd/src/external/StatsCallbackPuller.cpp
deleted file mode 100644
index 78e6f09..0000000
--- a/cmds/statsd/src/external/StatsCallbackPuller.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsCallbackPuller.h"
-#include "PullResultReceiver.h"
-#include "StatsPullerManager.h"
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-
-#include <aidl/android/util/StatsEventParcel.h>
-
-using namespace std;
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsCallbackPuller::StatsCallbackPuller(int tagId, const shared_ptr<IPullAtomCallback>& callback,
-                                         const int64_t coolDownNs, int64_t timeoutNs,
-                                         const vector<int> additiveFields)
-    : StatsPuller(tagId, coolDownNs, timeoutNs, additiveFields), mCallback(callback) {
-    VLOG("StatsCallbackPuller created for tag %d", tagId);
-}
-
-bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
-    VLOG("StatsCallbackPuller called for tag %d", mTagId);
-    if(mCallback == nullptr) {
-        ALOGW("No callback registered");
-        return false;
-    }
-
-    // Shared variables needed in the result receiver.
-    shared_ptr<mutex> cv_mutex = make_shared<mutex>();
-    shared_ptr<condition_variable> cv = make_shared<condition_variable>();
-    shared_ptr<bool> pullFinish = make_shared<bool>(false);
-    shared_ptr<bool> pullSuccess = make_shared<bool>(false);
-    shared_ptr<vector<shared_ptr<LogEvent>>> sharedData =
-            make_shared<vector<shared_ptr<LogEvent>>>();
-
-    shared_ptr<PullResultReceiver> resultReceiver = SharedRefBase::make<PullResultReceiver>(
-            [cv_mutex, cv, pullFinish, pullSuccess, sharedData](
-                    int32_t atomTag, bool success, const vector<StatsEventParcel>& output) {
-                // This is the result of the pull, executing in a statsd binder thread.
-                // The pull could have taken a long time, and we should only modify
-                // data (the output param) if the pointer is in scope and the pull did not time out.
-                {
-                    lock_guard<mutex> lk(*cv_mutex);
-                    for (const StatsEventParcel& parcel: output) {
-                        shared_ptr<LogEvent> event = make_shared<LogEvent>(/*uid=*/-1, /*pid=*/-1);
-                        bool valid = event->parseBuffer((uint8_t*)parcel.buffer.data(),
-                                                        parcel.buffer.size());
-                        if (valid) {
-                            sharedData->push_back(event);
-                        } else {
-                            StatsdStats::getInstance().noteAtomError(event->GetTagId(),
-                                                                     /*pull=*/true);
-                        }
-                    }
-                    *pullSuccess = success;
-                    *pullFinish = true;
-                }
-                cv->notify_one();
-            });
-
-    // Initiate the pull. This is a oneway call to a different process, except
-    // in unit tests. In process calls are not oneway.
-    Status status = mCallback->onPullAtom(mTagId, resultReceiver);
-    if (!status.isOk()) {
-        StatsdStats::getInstance().notePullBinderCallFailed(mTagId);
-        return false;
-    }
-
-    {
-        unique_lock<mutex> unique_lk(*cv_mutex);
-        // Wait until the pull finishes, or until the pull timeout.
-        cv->wait_for(unique_lk, chrono::nanoseconds(mPullTimeoutNs),
-                     [pullFinish] { return *pullFinish; });
-        if (!*pullFinish) {
-            // Note: The parent stats puller will also note that there was a timeout and that the
-            // cache should be cleared. Once we migrate all pullers to this callback, we could
-            // consolidate the logic.
-            return true;
-        } else {
-            // Only copy the data if we did not timeout and the pull was successful.
-            if (*pullSuccess) {
-                *data = std::move(*sharedData);
-            }
-            VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
-            return *pullSuccess;
-        }
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.h b/cmds/statsd/src/external/StatsCallbackPuller.h
deleted file mode 100644
index e82e8bb..0000000
--- a/cmds/statsd/src/external/StatsCallbackPuller.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#pragma once
-
-#include <aidl/android/os/IPullAtomCallback.h>
-#include "StatsPuller.h"
-
-using aidl::android::os::IPullAtomCallback;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsCallbackPuller : public StatsPuller {
-public:
-    explicit StatsCallbackPuller(int tagId, const shared_ptr<IPullAtomCallback>& callback,
-                                 const int64_t coolDownNs, const int64_t timeoutNs,
-                                 const std::vector<int> additiveFields);
-
-private:
-    bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
-    const shared_ptr<IPullAtomCallback> mCallback;
-
-    FRIEND_TEST(StatsCallbackPullerTest, PullFail);
-    FRIEND_TEST(StatsCallbackPullerTest, PullSuccess);
-    FRIEND_TEST(StatsCallbackPullerTest, PullTimeout);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp
deleted file mode 100644
index bb5d0a6..0000000
--- a/cmds/statsd/src/external/StatsPuller.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsPuller.h"
-#include "StatsPullerManager.h"
-#include "guardrail/StatsdStats.h"
-#include "puller_util.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::lock_guard;
-
-sp<UidMap> StatsPuller::mUidMap = nullptr;
-void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; }
-
-StatsPuller::StatsPuller(const int tagId, const int64_t coolDownNs, const int64_t pullTimeoutNs,
-                         const std::vector<int> additiveFields)
-    : mTagId(tagId),
-      mPullTimeoutNs(pullTimeoutNs),
-      mCoolDownNs(coolDownNs),
-      mAdditiveFields(additiveFields),
-      mLastPullTimeNs(0),
-      mLastEventTimeNs(0) {
-}
-
-bool StatsPuller::Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data) {
-    lock_guard<std::mutex> lock(mLock);
-    const int64_t elapsedTimeNs = getElapsedRealtimeNs();
-    const int64_t systemUptimeMillis = getSystemUptimeMillis();
-    StatsdStats::getInstance().notePull(mTagId);
-    const bool shouldUseCache =
-            (mLastEventTimeNs == eventTimeNs) || (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs);
-    if (shouldUseCache) {
-        if (mHasGoodData) {
-            (*data) = mCachedData;
-            StatsdStats::getInstance().notePullFromCache(mTagId);
-
-        }
-        return mHasGoodData;
-    }
-    if (mLastPullTimeNs > 0) {
-        StatsdStats::getInstance().updateMinPullIntervalSec(
-                mTagId, (elapsedTimeNs - mLastPullTimeNs) / NS_PER_SEC);
-    }
-    mCachedData.clear();
-    mLastPullTimeNs = elapsedTimeNs;
-    mLastEventTimeNs = eventTimeNs;
-    mHasGoodData = PullInternal(&mCachedData);
-    if (!mHasGoodData) {
-        return mHasGoodData;
-    }
-    const int64_t pullElapsedDurationNs = getElapsedRealtimeNs() - elapsedTimeNs;
-    const int64_t pullSystemUptimeDurationMillis = getSystemUptimeMillis() - systemUptimeMillis;
-    StatsdStats::getInstance().notePullTime(mTagId, pullElapsedDurationNs);
-    const bool pullTimeOut = pullElapsedDurationNs > mPullTimeoutNs;
-    if (pullTimeOut) {
-        // Something went wrong. Discard the data.
-        mCachedData.clear();
-        mHasGoodData = false;
-        StatsdStats::getInstance().notePullTimeout(
-                mTagId, pullSystemUptimeDurationMillis, NanoToMillis(pullElapsedDurationNs));
-        ALOGW("Pull for atom %d exceeds timeout %lld nano seconds.", mTagId,
-              (long long)pullElapsedDurationNs);
-        return mHasGoodData;
-    }
-
-    if (mCachedData.size() > 0) {
-        mapAndMergeIsolatedUidsToHostUid(mCachedData, mUidMap, mTagId, mAdditiveFields);
-    }
-
-    if (mCachedData.empty()) {
-        VLOG("Data pulled is empty");
-        StatsdStats::getInstance().noteEmptyData(mTagId);
-    }
-
-    (*data) = mCachedData;
-    return mHasGoodData;
-}
-
-int StatsPuller::ForceClearCache() {
-    return clearCache();
-}
-
-int StatsPuller::clearCache() {
-    lock_guard<std::mutex> lock(mLock);
-    return clearCacheLocked();
-}
-
-int StatsPuller::clearCacheLocked() {
-    int ret = mCachedData.size();
-    mCachedData.clear();
-    mLastPullTimeNs = 0;
-    mLastEventTimeNs = 0;
-    return ret;
-}
-
-int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) {
-    if (timestampNs - mLastPullTimeNs > mCoolDownNs) {
-        return clearCache();
-    } else {
-        return 0;
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h
deleted file mode 100644
index 470d15e..0000000
--- a/cmds/statsd/src/external/StatsPuller.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <utils/RefBase.h>
-#include <mutex>
-#include <vector>
-#include "packages/UidMap.h"
-
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "puller_util.h"
-
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsPuller : public virtual RefBase {
-public:
-    explicit StatsPuller(const int tagId,
-                         const int64_t coolDownNs = NS_PER_SEC,
-                         const int64_t pullTimeoutNs = StatsdStats::kPullMaxDelayNs,
-                         const std::vector<int> additiveFields = std::vector<int>());
-
-    virtual ~StatsPuller() {}
-
-    // Pulls the most recent data.
-    // The data may be served from cache if consecutive pulls come within
-    // predefined cooldown time.
-    // Returns true if the pull was successful.
-    // Returns false when
-    //   1) the pull fails
-    //   2) pull takes longer than mPullTimeoutNs (intrinsic to puller)
-    // If a metric wants to make any change to the data, like timestamps, it
-    // should make a copy as this data may be shared with multiple metrics.
-    bool Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data);
-
-    // Clear cache immediately
-    int ForceClearCache();
-
-    // Clear cache if elapsed time is more than cooldown time
-    int ClearCacheIfNecessary(int64_t timestampNs);
-
-    static void SetUidMap(const sp<UidMap>& uidMap);
-
-    virtual void SetStatsCompanionService(
-            shared_ptr<IStatsCompanionService> statsCompanionService) {};
-
-protected:
-    const int mTagId;
-
-    // Max time allowed to pull this atom.
-    // We cannot reliably kill a pull thread. So we don't terminate the puller.
-    // The data is discarded if the pull takes longer than this and mHasGoodData
-    // marked as false.
-    const int64_t mPullTimeoutNs = StatsdStats::kPullMaxDelayNs;
-
-private:
-    mutable std::mutex mLock;
-
-    // Real puller impl.
-    virtual bool PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) = 0;
-
-    bool mHasGoodData = false;
-
-    // Minimum time before this puller does actual pull again.
-    // Pullers can cause significant impact to system health and battery.
-    // So that we don't pull too frequently.
-    // If a pull request comes before cooldown, a cached version from previous pull
-    // will be returned.
-    const int64_t mCoolDownNs = 1 * NS_PER_SEC;
-
-    // The field numbers of the fields that need to be summed when merging
-    // isolated uid with host uid.
-    const std::vector<int> mAdditiveFields;
-
-    int64_t mLastPullTimeNs;
-
-    // All pulls happen due to an event (app upgrade, bucket boundary, condition change, etc).
-    // If multiple pulls need to be done at the same event time, we will always use the cache after
-    // the first pull.
-    int64_t mLastEventTimeNs;
-
-    // Cache of data from last pull. If next request comes before cool down finishes,
-    // cached data will be returned.
-    // Cached data is cleared when
-    //   1) A pull fails
-    //   2) A new pull request comes after cooldown time.
-    //   3) clearCache is called.
-    std::vector<std::shared_ptr<LogEvent>> mCachedData;
-
-    int clearCache();
-
-    int clearCacheLocked();
-
-    static sp<UidMap> mUidMap;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
deleted file mode 100644
index 8334b6b..0000000
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false
-#include "Log.h"
-
-#include "StatsPullerManager.h"
-
-#include <cutils/log.h>
-#include <math.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <iostream>
-
-#include "../StatsService.h"
-#include "../logd/LogEvent.h"
-#include "../stats_log_util.h"
-#include "../statscompanion_util.h"
-#include "StatsCallbackPuller.h"
-#include "TrainInfoPuller.h"
-#include "statslog_statsd.h"
-
-using std::shared_ptr;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Stores the puller as a wp to avoid holding a reference in case it is unregistered and
-// pullAtomCallbackDied is never called.
-struct PullAtomCallbackDeathCookie {
-    PullAtomCallbackDeathCookie(const wp<StatsPullerManager>& pullerManager,
-                                const PullerKey& pullerKey, const wp<StatsPuller>& puller) :
-            mPullerManager(pullerManager), mPullerKey(pullerKey), mPuller(puller) {
-    }
-
-    wp<StatsPullerManager> mPullerManager;
-    PullerKey mPullerKey;
-    wp<StatsPuller> mPuller;
-};
-
-void StatsPullerManager::pullAtomCallbackDied(void* cookie) {
-    PullAtomCallbackDeathCookie* cookie_ = static_cast<PullAtomCallbackDeathCookie*>(cookie);
-    sp<StatsPullerManager> thiz = cookie_->mPullerManager.promote();
-    if (!thiz) {
-        return;
-    }
-
-    const PullerKey& pullerKey = cookie_->mPullerKey;
-    wp<StatsPuller> puller = cookie_->mPuller;
-
-    // Erase the mapping from the puller key to the puller if the mapping still exists.
-    // Note that we are removing the StatsPuller object, which internally holds the binder
-    // IPullAtomCallback. However, each new registration creates a new StatsPuller, so this works.
-    lock_guard<mutex> lock(thiz->mLock);
-    const auto& it = thiz->kAllPullAtomInfo.find(pullerKey);
-    if (it != thiz->kAllPullAtomInfo.end() && puller != nullptr && puller == it->second) {
-        StatsdStats::getInstance().notePullerCallbackRegistrationChanged(pullerKey.atomTag,
-                                                                         /*registered=*/false);
-        thiz->kAllPullAtomInfo.erase(pullerKey);
-    }
-    // The death recipient corresponding to this specific IPullAtomCallback can never
-    // be triggered again, so free up resources.
-    delete cookie_;
-}
-
-// Values smaller than this may require to update the alarm.
-const int64_t NO_ALARM_UPDATE = INT64_MAX;
-
-StatsPullerManager::StatsPullerManager()
-    : kAllPullAtomInfo({
-              // TrainInfo.
-              {{.atomTag = util::TRAIN_INFO, .uid = AID_STATSD}, new TrainInfoPuller()},
-      }),
-      mNextPullTimeNs(NO_ALARM_UPDATE),
-      mPullAtomCallbackDeathRecipient(AIBinder_DeathRecipient_new(pullAtomCallbackDied)) {
-}
-
-bool StatsPullerManager::Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
-                              vector<shared_ptr<LogEvent>>* data) {
-    std::lock_guard<std::mutex> _l(mLock);
-    return PullLocked(tagId, configKey, eventTimeNs, data);
-}
-
-bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
-                              vector<std::shared_ptr<LogEvent>>* data) {
-    std::lock_guard<std::mutex> _l(mLock);
-    return PullLocked(tagId, uids, eventTimeNs, data);
-}
-
-bool StatsPullerManager::PullLocked(int tagId, const ConfigKey& configKey,
-                                    const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data) {
-    vector<int32_t> uids;
-    const auto& uidProviderIt = mPullUidProviders.find(configKey);
-    if (uidProviderIt == mPullUidProviders.end()) {
-        ALOGE("Error pulling tag %d. No pull uid provider for config key %s", tagId,
-              configKey.ToString().c_str());
-        StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
-        return false;
-    }
-    sp<PullUidProvider> pullUidProvider = uidProviderIt->second.promote();
-    if (pullUidProvider == nullptr) {
-        ALOGE("Error pulling tag %d, pull uid provider for config %s is gone.", tagId,
-              configKey.ToString().c_str());
-        StatsdStats::getInstance().notePullUidProviderNotFound(tagId);
-        return false;
-    }
-    uids = pullUidProvider->getPullAtomUids(tagId);
-    return PullLocked(tagId, uids, eventTimeNs, data);
-}
-
-bool StatsPullerManager::PullLocked(int tagId, const vector<int32_t>& uids,
-                                    const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data) {
-    VLOG("Initiating pulling %d", tagId);
-    for (int32_t uid : uids) {
-        PullerKey key = {.atomTag = tagId, .uid = uid};
-        auto pullerIt = kAllPullAtomInfo.find(key);
-        if (pullerIt != kAllPullAtomInfo.end()) {
-            bool ret = pullerIt->second->Pull(eventTimeNs, data);
-            VLOG("pulled %zu items", data->size());
-            if (!ret) {
-                StatsdStats::getInstance().notePullFailed(tagId);
-            }
-            return ret;
-        }
-    }
-    StatsdStats::getInstance().notePullerNotFound(tagId);
-    ALOGW("StatsPullerManager: Unknown tagId %d", tagId);
-    return false;  // Return early since we don't know what to pull.
-}
-
-bool StatsPullerManager::PullerForMatcherExists(int tagId) const {
-    // Pulled atoms might be registered after we parse the config, so just make sure the id is in
-    // an appropriate range.
-    return isVendorPulledAtom(tagId) || isPulledAtom(tagId);
-}
-
-void StatsPullerManager::updateAlarmLocked() {
-    if (mNextPullTimeNs == NO_ALARM_UPDATE) {
-        VLOG("No need to set alarms. Skipping");
-        return;
-    }
-
-    // TODO(b/151045771): do not hold a lock while making a binder call
-    if (mStatsCompanionService != nullptr) {
-        mStatsCompanionService->setPullingAlarm(mNextPullTimeNs / 1000000);
-    } else {
-        VLOG("StatsCompanionService not available. Alarm not set.");
-    }
-    return;
-}
-
-void StatsPullerManager::SetStatsCompanionService(
-        shared_ptr<IStatsCompanionService> statsCompanionService) {
-    std::lock_guard<std::mutex> _l(mLock);
-    shared_ptr<IStatsCompanionService> tmpForLock = mStatsCompanionService;
-    mStatsCompanionService = statsCompanionService;
-    for (const auto& pulledAtom : kAllPullAtomInfo) {
-        pulledAtom.second->SetStatsCompanionService(statsCompanionService);
-    }
-    if (mStatsCompanionService != nullptr) {
-        updateAlarmLocked();
-    }
-}
-
-void StatsPullerManager::RegisterReceiver(int tagId, const ConfigKey& configKey,
-                                          wp<PullDataReceiver> receiver, int64_t nextPullTimeNs,
-                                          int64_t intervalNs) {
-    std::lock_guard<std::mutex> _l(mLock);
-    auto& receivers = mReceivers[{.atomTag = tagId, .configKey = configKey}];
-    for (auto it = receivers.begin(); it != receivers.end(); it++) {
-        if (it->receiver == receiver) {
-            VLOG("Receiver already registered of %d", (int)receivers.size());
-            return;
-        }
-    }
-    ReceiverInfo receiverInfo;
-    receiverInfo.receiver = receiver;
-
-    // Round it to the nearest minutes. This is the limit of alarm manager.
-    // In practice, we should always have larger buckets.
-    int64_t roundedIntervalNs = intervalNs / NS_PER_SEC / 60 * NS_PER_SEC * 60;
-    // Scheduled pulling should be at least 1 min apart.
-    // This can be lower in cts tests, in which case we round it to 1 min.
-    if (roundedIntervalNs < 60 * (int64_t)NS_PER_SEC) {
-        roundedIntervalNs = 60 * (int64_t)NS_PER_SEC;
-    }
-
-    receiverInfo.intervalNs = roundedIntervalNs;
-    receiverInfo.nextPullTimeNs = nextPullTimeNs;
-    receivers.push_back(receiverInfo);
-
-    // There is only one alarm for all pulled events. So only set it to the smallest denom.
-    if (nextPullTimeNs < mNextPullTimeNs) {
-        VLOG("Updating next pull time %lld", (long long)mNextPullTimeNs);
-        mNextPullTimeNs = nextPullTimeNs;
-        updateAlarmLocked();
-    }
-    VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size());
-}
-
-void StatsPullerManager::UnRegisterReceiver(int tagId, const ConfigKey& configKey,
-                                            wp<PullDataReceiver> receiver) {
-    std::lock_guard<std::mutex> _l(mLock);
-    auto receiversIt = mReceivers.find({.atomTag = tagId, .configKey = configKey});
-    if (receiversIt == mReceivers.end()) {
-        VLOG("Unknown pull code or no receivers: %d", tagId);
-        return;
-    }
-    std::list<ReceiverInfo>& receivers = receiversIt->second;
-    for (auto it = receivers.begin(); it != receivers.end(); it++) {
-        if (receiver == it->receiver) {
-            receivers.erase(it);
-            VLOG("Puller for tagId %d unregistered of %d", tagId, (int)receivers.size());
-            return;
-        }
-    }
-}
-
-void StatsPullerManager::RegisterPullUidProvider(const ConfigKey& configKey,
-                                                 wp<PullUidProvider> provider) {
-    std::lock_guard<std::mutex> _l(mLock);
-    mPullUidProviders[configKey] = provider;
-}
-
-void StatsPullerManager::UnregisterPullUidProvider(const ConfigKey& configKey,
-                                                   wp<PullUidProvider> provider) {
-    std::lock_guard<std::mutex> _l(mLock);
-    const auto& it = mPullUidProviders.find(configKey);
-    if (it != mPullUidProviders.end() && it->second == provider) {
-        mPullUidProviders.erase(it);
-    }
-}
-
-void StatsPullerManager::OnAlarmFired(int64_t elapsedTimeNs) {
-    std::lock_guard<std::mutex> _l(mLock);
-    int64_t wallClockNs = getWallClockNs();
-
-    int64_t minNextPullTimeNs = NO_ALARM_UPDATE;
-
-    vector<pair<const ReceiverKey*, vector<ReceiverInfo*>>> needToPull;
-    for (auto& pair : mReceivers) {
-        vector<ReceiverInfo*> receivers;
-        if (pair.second.size() != 0) {
-            for (ReceiverInfo& receiverInfo : pair.second) {
-                if (receiverInfo.nextPullTimeNs <= elapsedTimeNs) {
-                    receivers.push_back(&receiverInfo);
-                } else {
-                    if (receiverInfo.nextPullTimeNs < minNextPullTimeNs) {
-                        minNextPullTimeNs = receiverInfo.nextPullTimeNs;
-                    }
-                }
-            }
-            if (receivers.size() > 0) {
-                needToPull.push_back(make_pair(&pair.first, receivers));
-            }
-        }
-    }
-    for (const auto& pullInfo : needToPull) {
-        vector<shared_ptr<LogEvent>> data;
-        bool pullSuccess = PullLocked(pullInfo.first->atomTag, pullInfo.first->configKey,
-                                      elapsedTimeNs, &data);
-        if (!pullSuccess) {
-            VLOG("pull failed at %lld, will try again later", (long long)elapsedTimeNs);
-        }
-
-        // Convention is to mark pull atom timestamp at request time.
-        // If we pull at t0, puller starts at t1, finishes at t2, and send back
-        // at t3, we mark t0 as its timestamp, which should correspond to its
-        // triggering event, such as condition change at t0.
-        // Here the triggering event is alarm fired from AlarmManager.
-        // In ValueMetricProducer and GaugeMetricProducer we do same thing
-        // when pull on condition change, etc.
-        for (auto& event : data) {
-            event->setElapsedTimestampNs(elapsedTimeNs);
-            event->setLogdWallClockTimestampNs(wallClockNs);
-        }
-
-        for (const auto& receiverInfo : pullInfo.second) {
-            sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote();
-            if (receiverPtr != nullptr) {
-                receiverPtr->onDataPulled(data, pullSuccess, elapsedTimeNs);
-                // We may have just come out of a coma, compute next pull time.
-                int numBucketsAhead =
-                        (elapsedTimeNs - receiverInfo->nextPullTimeNs) / receiverInfo->intervalNs;
-                receiverInfo->nextPullTimeNs += (numBucketsAhead + 1) * receiverInfo->intervalNs;
-                if (receiverInfo->nextPullTimeNs < minNextPullTimeNs) {
-                    minNextPullTimeNs = receiverInfo->nextPullTimeNs;
-                }
-            } else {
-                VLOG("receiver already gone.");
-            }
-        }
-    }
-
-    VLOG("mNextPullTimeNs: %lld updated to %lld", (long long)mNextPullTimeNs,
-         (long long)minNextPullTimeNs);
-    mNextPullTimeNs = minNextPullTimeNs;
-    updateAlarmLocked();
-}
-
-int StatsPullerManager::ForceClearPullerCache() {
-    std::lock_guard<std::mutex> _l(mLock);
-    int totalCleared = 0;
-    for (const auto& pulledAtom : kAllPullAtomInfo) {
-        totalCleared += pulledAtom.second->ForceClearCache();
-    }
-    return totalCleared;
-}
-
-int StatsPullerManager::ClearPullerCacheIfNecessary(int64_t timestampNs) {
-    std::lock_guard<std::mutex> _l(mLock);
-    int totalCleared = 0;
-    for (const auto& pulledAtom : kAllPullAtomInfo) {
-        totalCleared += pulledAtom.second->ClearCacheIfNecessary(timestampNs);
-    }
-    return totalCleared;
-}
-
-void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag,
-                                                  const int64_t coolDownNs, const int64_t timeoutNs,
-                                                  const vector<int32_t>& additiveFields,
-                                                  const shared_ptr<IPullAtomCallback>& callback) {
-    std::lock_guard<std::mutex> _l(mLock);
-    VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
-
-    if (callback == nullptr) {
-        ALOGW("SetPullAtomCallback called with null callback for atom %d.", atomTag);
-        return;
-    }
-
-    StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
-    int64_t actualCoolDownNs = coolDownNs < kMinCoolDownNs ? kMinCoolDownNs : coolDownNs;
-    int64_t actualTimeoutNs = timeoutNs > kMaxTimeoutNs ? kMaxTimeoutNs : timeoutNs;
-
-    sp<StatsCallbackPuller> puller = new StatsCallbackPuller(atomTag, callback, actualCoolDownNs,
-                                                             actualTimeoutNs, additiveFields);
-    PullerKey key = {.atomTag = atomTag, .uid = uid};
-    AIBinder_linkToDeath(callback->asBinder().get(), mPullAtomCallbackDeathRecipient.get(),
-                         new PullAtomCallbackDeathCookie(this, key, puller));
-    kAllPullAtomInfo[key] = puller;
-}
-
-void StatsPullerManager::UnregisterPullAtomCallback(const int uid, const int32_t atomTag) {
-    std::lock_guard<std::mutex> _l(mLock);
-    PullerKey key = {.atomTag = atomTag, .uid = uid};
-    if (kAllPullAtomInfo.find(key) != kAllPullAtomInfo.end()) {
-        StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag,
-                                                                         /*registered=*/false);
-        kAllPullAtomInfo.erase(key);
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
deleted file mode 100644
index 489cbdb..0000000
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <aidl/android/os/IPullAtomCallback.h>
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <utils/RefBase.h>
-
-#include <list>
-#include <vector>
-
-#include "PullDataReceiver.h"
-#include "PullUidProvider.h"
-#include "StatsPuller.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-
-using aidl::android::os::IPullAtomCallback;
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-typedef struct PullerKey {
-    // The uid of the process that registers this puller.
-    const int uid = -1;
-    // The atom that this puller is for.
-    const int atomTag;
-
-    bool operator<(const PullerKey& that) const {
-        if (uid < that.uid) {
-            return true;
-        }
-        if (uid > that.uid) {
-            return false;
-        }
-        return atomTag < that.atomTag;
-    };
-
-    bool operator==(const PullerKey& that) const {
-        return uid == that.uid && atomTag == that.atomTag;
-    };
-} PullerKey;
-
-class StatsPullerManager : public virtual RefBase {
-public:
-    StatsPullerManager();
-
-    virtual ~StatsPullerManager() {
-    }
-
-
-    // Registers a receiver for tagId. It will be pulled on the nextPullTimeNs
-    // and then every intervalNs thereafter.
-    virtual void RegisterReceiver(int tagId, const ConfigKey& configKey,
-                                  wp<PullDataReceiver> receiver, int64_t nextPullTimeNs,
-                                  int64_t intervalNs);
-
-    // Stop listening on a tagId.
-    virtual void UnRegisterReceiver(int tagId, const ConfigKey& configKey,
-                                    wp<PullDataReceiver> receiver);
-
-    // Registers a pull uid provider for the config key. When pulling atoms, it will be used to
-    // determine which uids to pull from.
-    virtual void RegisterPullUidProvider(const ConfigKey& configKey, wp<PullUidProvider> provider);
-
-    // Unregister a pull uid provider.
-    virtual void UnregisterPullUidProvider(const ConfigKey& configKey,
-                                           wp<PullUidProvider> provider);
-
-    // Verify if we know how to pull for this matcher
-    bool PullerForMatcherExists(int tagId) const;
-
-    void OnAlarmFired(int64_t elapsedTimeNs);
-
-    // Pulls the most recent data.
-    // The data may be served from cache if consecutive pulls come within
-    // mCoolDownNs.
-    // Returns true if the pull was successful.
-    // Returns false when
-    //   1) the pull fails
-    //   2) pull takes longer than mPullTimeoutNs (intrinsic to puller)
-    //   3) Either a PullUidProvider was not registered for the config, or the there was no puller
-    //      registered for any of the uids for this atom.
-    // If the metric wants to make any change to the data, like timestamps, they
-    // should make a copy as this data may be shared with multiple metrics.
-    virtual bool Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
-                      vector<std::shared_ptr<LogEvent>>* data);
-
-    // Same as above, but directly specify the allowed uids to pull from.
-    virtual bool Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
-                      vector<std::shared_ptr<LogEvent>>* data);
-
-    // Clear pull data cache immediately.
-    int ForceClearPullerCache();
-
-    // Clear pull data cache if it is beyond respective cool down time.
-    int ClearPullerCacheIfNecessary(int64_t timestampNs);
-
-    void SetStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService);
-
-    void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs,
-                                  const int64_t timeoutNs, const vector<int32_t>& additiveFields,
-                                  const shared_ptr<IPullAtomCallback>& callback);
-
-    void UnregisterPullAtomCallback(const int uid, const int32_t atomTag);
-
-    std::map<const PullerKey, sp<StatsPuller>> kAllPullAtomInfo;
-
-private:
-    const static int64_t kMinCoolDownNs = NS_PER_SEC;
-    const static int64_t kMaxTimeoutNs = 10 * NS_PER_SEC;
-    shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr;
-
-    // A struct containing an atom id and a Config Key
-    typedef struct ReceiverKey {
-        const int atomTag;
-        const ConfigKey configKey;
-
-        inline bool operator<(const ReceiverKey& that) const {
-            return atomTag == that.atomTag ? configKey < that.configKey : atomTag < that.atomTag;
-        }
-    } ReceiverKey;
-
-    typedef struct {
-        int64_t nextPullTimeNs;
-        int64_t intervalNs;
-        wp<PullDataReceiver> receiver;
-    } ReceiverInfo;
-
-    // mapping from Receiver Key to receivers
-    std::map<ReceiverKey, std::list<ReceiverInfo>> mReceivers;
-
-    // mapping from Config Key to the PullUidProvider for that config
-    std::map<ConfigKey, wp<PullUidProvider>> mPullUidProviders;
-
-    bool PullLocked(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
-                    vector<std::shared_ptr<LogEvent>>* data);
-
-    bool PullLocked(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
-                    vector<std::shared_ptr<LogEvent>>* data);
-
-    // locks for data receiver and StatsCompanionService changes
-    std::mutex mLock;
-
-    void updateAlarmLocked();
-
-    int64_t mNextPullTimeNs;
-
-    // Death recipient that is triggered when the process holding the IPullAtomCallback has died.
-    ::ndk::ScopedAIBinder_DeathRecipient mPullAtomCallbackDeathRecipient;
-
-    /**
-     * Death recipient callback that is called when a pull atom callback dies.
-     * The cookie is a pointer to a PullAtomCallbackDeathCookie.
-     */
-    static void pullAtomCallbackDied(void* cookie);
-
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
-    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
-    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
-    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
-
-    FRIEND_TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/TrainInfoPuller.cpp b/cmds/statsd/src/external/TrainInfoPuller.cpp
deleted file mode 100644
index 3837f4a..0000000
--- a/cmds/statsd/src/external/TrainInfoPuller.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "external/StatsPuller.h"
-
-#include "TrainInfoPuller.h"
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-#include "statslog_statsd.h"
-#include "storage/StorageManager.h"
-
-using std::make_shared;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-TrainInfoPuller::TrainInfoPuller() :
-    StatsPuller(util::TRAIN_INFO) {
-}
-
-bool TrainInfoPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
-    vector<InstallTrainInfo> trainInfoList =
-        StorageManager::readAllTrainInfo();
-    if (trainInfoList.empty()) {
-        ALOGW("Train info was empty.");
-        return true;
-    }
-    for (InstallTrainInfo& trainInfo : trainInfoList) {
-        auto event = make_shared<LogEvent>(getWallClockNs(), getElapsedRealtimeNs(), trainInfo);
-        data->push_back(event);
-    }
-    return true;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/TrainInfoPuller.h b/cmds/statsd/src/external/TrainInfoPuller.h
deleted file mode 100644
index 615d023..0000000
--- a/cmds/statsd/src/external/TrainInfoPuller.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#pragma once
-
-#include "StatsPuller.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Reads train info from disk.
- */
-class TrainInfoPuller : public StatsPuller {
- public:
-  TrainInfoPuller();
-
- private:
-  bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp
deleted file mode 100644
index aa99d00..0000000
--- a/cmds/statsd/src/external/puller_util.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "puller_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace std;
-
-/**
- * Process all data and merge isolated with host if necessary.
- * For example:
- *   NetworkBytesAtom {
- *       int uid = 1;
- *       State process_state = 2;
- *       int byte_send = 3;
- *       int byte_recv = 4;
- *   }
- *   additive fields are {3, 4}
- * If we pulled the following events (uid1_child is an isolated uid which maps to uid1):
- * [uid1, fg, 100, 200]
- * [uid1_child, fg, 100, 200]
- * [uid1, bg, 100, 200]
- *
- * We want to merge them and results should be:
- * [uid1, fg, 200, 400]
- * [uid1, bg, 100, 200]
- *
- * All atoms should be of the same tagId. All fields should be present.
- */
-void mapAndMergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const sp<UidMap>& uidMap,
-                                      int tagId, const vector<int>& additiveFieldsVec) {
-    // Check the first LogEvent for attribution chain or a uid field as either all atoms with this
-    // tagId have them or none of them do.
-    std::pair<int, int> attrIndexRange;
-    const bool hasAttributionChain = data[0]->hasAttributionChain(&attrIndexRange);
-    bool hasUidField = (data[0]->getUidFieldIndex() != -1);
-
-    if (!hasAttributionChain && !hasUidField) {
-        VLOG("No uid or attribution chain to merge, atom %d", tagId);
-        return;
-    }
-
-    // 1. Map all isolated uid in-place to host uid
-    for (shared_ptr<LogEvent>& event : data) {
-        if (event->GetTagId() != tagId) {
-            ALOGE("Wrong atom. Expecting %d, got %d", tagId, event->GetTagId());
-            return;
-        }
-        if (hasAttributionChain) {
-            vector<FieldValue>* const fieldValues = event->getMutableValues();
-            for (int i = attrIndexRange.first; i <= attrIndexRange.second; i++) {
-                FieldValue& fieldValue = fieldValues->at(i);
-                if (isAttributionUidField(fieldValue)) {
-                    const int hostUid = uidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
-                    fieldValue.mValue.setInt(hostUid);
-                }
-            }
-        } else {
-            int uidFieldIndex = event->getUidFieldIndex();
-            if (uidFieldIndex != -1) {
-                Value& value = (*event->getMutableValues())[uidFieldIndex].mValue;
-                const int hostUid = uidMap->getHostUidOrSelf(value.int_value);
-                value.setInt(hostUid);
-            } else {
-                ALOGE("Malformed log, uid not found. %s", event->ToString().c_str());
-            }
-        }
-    }
-
-    // 2. sort the data, bit-wise
-    sort(data.begin(), data.end(),
-         [](const shared_ptr<LogEvent>& lhs, const shared_ptr<LogEvent>& rhs) {
-             if (lhs->size() != rhs->size()) {
-                 return lhs->size() < rhs->size();
-             }
-             const std::vector<FieldValue>& lhsValues = lhs->getValues();
-             const std::vector<FieldValue>& rhsValues = rhs->getValues();
-             for (int i = 0; i < (int)lhs->size(); i++) {
-                 if (lhsValues[i] != rhsValues[i]) {
-                     return lhsValues[i] < rhsValues[i];
-                 }
-             }
-             return false;
-         });
-
-    vector<shared_ptr<LogEvent>> mergedData;
-    const set<int> additiveFields(additiveFieldsVec.begin(), additiveFieldsVec.end());
-    bool needMerge = true;
-
-    // 3. do the merge.
-    // The loop invariant is this: for every event, check if it differs on
-    // non-additive fields, or have different attribution chain length.
-    // If so, no need to merge, add itself to the result.
-    // Otherwise, merge the value onto the one immediately next to it.
-    for (int i = 0; i < (int)data.size() - 1; i++) {
-        // Size different, must be different chains.
-        if (data[i]->size() != data[i + 1]->size()) {
-            mergedData.push_back(data[i]);
-            continue;
-        }
-        vector<FieldValue>* lhsValues = data[i]->getMutableValues();
-        vector<FieldValue>* rhsValues = data[i + 1]->getMutableValues();
-        needMerge = true;
-        for (int p = 0; p < (int)lhsValues->size(); p++) {
-            if ((*lhsValues)[p] != (*rhsValues)[p]) {
-                int pos = (*lhsValues)[p].mField.getPosAtDepth(0);
-                // Differ on non-additive field, abort.
-                if (additiveFields.find(pos) == additiveFields.end()) {
-                    needMerge = false;
-                    break;
-                }
-            }
-        }
-        if (!needMerge) {
-            mergedData.push_back(data[i]);
-            continue;
-        }
-        // This should be infrequent operation.
-        for (int p = 0; p < (int)lhsValues->size(); p++) {
-            int pos = (*lhsValues)[p].mField.getPosAtDepth(0);
-            if (additiveFields.find(pos) != additiveFields.end()) {
-                (*rhsValues)[p].mValue += (*lhsValues)[p].mValue;
-            }
-        }
-    }
-    mergedData.push_back(data.back());
-
-    data.clear();
-    data = mergedData;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/puller_util.h b/cmds/statsd/src/external/puller_util.h
deleted file mode 100644
index afcf68c..0000000
--- a/cmds/statsd/src/external/puller_util.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include <vector>
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void mapAndMergeIsolatedUidsToHostUid(std::vector<std::shared_ptr<LogEvent>>& data,
-                                      const sp<UidMap>& uidMap, int tagId,
-                                      const vector<int>& additiveFieldsVec);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/flags/flags.cpp b/cmds/statsd/src/flags/flags.cpp
deleted file mode 100644
index e9fceda..0000000
--- a/cmds/statsd/src/flags/flags.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "flags.h"
-
-#include <server_configurable_flags/get_flags.h>
-
-using server_configurable_flags::GetServerConfigurableFlag;
-using std::string;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-string getFlagString(const string& flagName, const string& defaultValue) {
-    return GetServerConfigurableFlag(STATSD_NATIVE_NAMESPACE, flagName, defaultValue);
-}
-
-bool getFlagBool(const string& flagName, const string& defaultValue) {
-    return getFlagString(flagName, defaultValue) == "true";
-}
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/flags/flags.h b/cmds/statsd/src/flags/flags.h
deleted file mode 100644
index 213e1a4..0000000
--- a/cmds/statsd/src/flags/flags.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const std::string STATSD_NATIVE_NAMESPACE = "statsd_native";
-
-const std::string PARTIAL_CONFIG_UPDATE_FLAG = "partial_config_update";
-
-std::string getFlagString(const std::string& flagName, const std::string& defaultValue);
-
-// Returns true IFF flagName has a value of "true".
-bool getFlagBool(const std::string& flagName, const std::string& defaultValue);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
deleted file mode 100644
index 6e89038..0000000
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ /dev/null
@@ -1,1101 +0,0 @@
-/*
- * 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.
- */
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsdStats.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include "../stats_log_util.h"
-#include "statslog_statsd.h"
-#include "storage/StorageManager.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::lock_guard;
-using std::shared_ptr;
-using std::string;
-using std::to_string;
-using std::vector;
-
-const int FIELD_ID_BEGIN_TIME = 1;
-const int FIELD_ID_END_TIME = 2;
-const int FIELD_ID_CONFIG_STATS = 3;
-const int FIELD_ID_ATOM_STATS = 7;
-const int FIELD_ID_UIDMAP_STATS = 8;
-const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
-const int FIELD_ID_PERIODIC_ALARM_STATS = 12;
-const int FIELD_ID_SYSTEM_SERVER_RESTART = 15;
-const int FIELD_ID_LOGGER_ERROR_STATS = 16;
-const int FIELD_ID_OVERFLOW = 18;
-const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL = 19;
-
-const int FIELD_ID_ATOM_STATS_TAG = 1;
-const int FIELD_ID_ATOM_STATS_COUNT = 2;
-const int FIELD_ID_ATOM_STATS_ERROR_COUNT = 3;
-
-const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
-const int FIELD_ID_PERIODIC_ALARMS_REGISTERED = 1;
-
-const int FIELD_ID_LOG_LOSS_STATS_TIME = 1;
-const int FIELD_ID_LOG_LOSS_STATS_COUNT = 2;
-const int FIELD_ID_LOG_LOSS_STATS_ERROR = 3;
-const int FIELD_ID_LOG_LOSS_STATS_TAG = 4;
-const int FIELD_ID_LOG_LOSS_STATS_UID = 5;
-const int FIELD_ID_LOG_LOSS_STATS_PID = 6;
-
-const int FIELD_ID_OVERFLOW_COUNT = 1;
-const int FIELD_ID_OVERFLOW_MAX_HISTORY = 2;
-const int FIELD_ID_OVERFLOW_MIN_HISTORY = 3;
-
-const int FIELD_ID_CONFIG_STATS_UID = 1;
-const int FIELD_ID_CONFIG_STATS_ID = 2;
-const int FIELD_ID_CONFIG_STATS_CREATION = 3;
-const int FIELD_ID_CONFIG_STATS_RESET = 19;
-const int FIELD_ID_CONFIG_STATS_DELETION = 4;
-const int FIELD_ID_CONFIG_STATS_METRIC_COUNT = 5;
-const int FIELD_ID_CONFIG_STATS_CONDITION_COUNT = 6;
-const int FIELD_ID_CONFIG_STATS_MATCHER_COUNT = 7;
-const int FIELD_ID_CONFIG_STATS_ALERT_COUNT = 8;
-const int FIELD_ID_CONFIG_STATS_VALID = 9;
-const int FIELD_ID_CONFIG_STATS_BROADCAST = 10;
-const int FIELD_ID_CONFIG_STATS_DATA_DROP_TIME = 11;
-const int FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES = 21;
-const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME = 12;
-const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES = 20;
-const int FIELD_ID_CONFIG_STATS_MATCHER_STATS = 13;
-const int FIELD_ID_CONFIG_STATS_CONDITION_STATS = 14;
-const int FIELD_ID_CONFIG_STATS_METRIC_STATS = 15;
-const int FIELD_ID_CONFIG_STATS_ALERT_STATS = 16;
-const int FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS = 17;
-const int FIELD_ID_CONFIG_STATS_ANNOTATION = 18;
-const int FIELD_ID_CONFIG_STATS_ACTIVATION = 22;
-const int FIELD_ID_CONFIG_STATS_DEACTIVATION = 23;
-const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT64 = 1;
-const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT32 = 2;
-
-const int FIELD_ID_MATCHER_STATS_ID = 1;
-const int FIELD_ID_MATCHER_STATS_COUNT = 2;
-const int FIELD_ID_CONDITION_STATS_ID = 1;
-const int FIELD_ID_CONDITION_STATS_COUNT = 2;
-const int FIELD_ID_METRIC_STATS_ID = 1;
-const int FIELD_ID_METRIC_STATS_COUNT = 2;
-const int FIELD_ID_ALERT_STATS_ID = 1;
-const int FIELD_ID_ALERT_STATS_COUNT = 2;
-
-const int FIELD_ID_UID_MAP_CHANGES = 1;
-const int FIELD_ID_UID_MAP_BYTES_USED = 2;
-const int FIELD_ID_UID_MAP_DROPPED_CHANGES = 3;
-const int FIELD_ID_UID_MAP_DELETED_APPS = 4;
-
-const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID = 1;
-const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME = 2;
-
-const std::map<int, std::pair<size_t, size_t>> StatsdStats::kAtomDimensionKeySizeLimitMap = {
-        {util::BINDER_CALLS, {6000, 10000}},
-        {util::LOOPER_STATS, {1500, 2500}},
-        {util::CPU_TIME_PER_UID_FREQ, {6000, 10000}},
-};
-
-StatsdStats::StatsdStats() {
-    mPushedAtomStats.resize(kMaxPushedAtomId + 1);
-    mStartTimeSec = getWallClockSec();
-}
-
-StatsdStats& StatsdStats::getInstance() {
-    static StatsdStats statsInstance;
-    return statsInstance;
-}
-
-void StatsdStats::addToIceBoxLocked(shared_ptr<ConfigStats>& stats) {
-    // The size of mIceBox grows strictly by one at a time. It won't be > kMaxIceBoxSize.
-    if (mIceBox.size() == kMaxIceBoxSize) {
-        mIceBox.pop_front();
-    }
-    mIceBox.push_back(stats);
-}
-
-void StatsdStats::noteConfigReceived(
-        const ConfigKey& key, int metricsCount, int conditionsCount, int matchersCount,
-        int alertsCount, const std::list<std::pair<const int64_t, const int32_t>>& annotations,
-        bool isValid) {
-    lock_guard<std::mutex> lock(mLock);
-    int32_t nowTimeSec = getWallClockSec();
-
-    // If there is an existing config for the same key, icebox the old config.
-    noteConfigRemovedInternalLocked(key);
-
-    shared_ptr<ConfigStats> configStats = std::make_shared<ConfigStats>();
-    configStats->uid = key.GetUid();
-    configStats->id = key.GetId();
-    configStats->creation_time_sec = nowTimeSec;
-    configStats->metric_count = metricsCount;
-    configStats->condition_count = conditionsCount;
-    configStats->matcher_count = matchersCount;
-    configStats->alert_count = alertsCount;
-    configStats->is_valid = isValid;
-    for (auto& v : annotations) {
-        configStats->annotations.emplace_back(v);
-    }
-
-    if (isValid) {
-        mConfigStats[key] = configStats;
-    } else {
-        configStats->deletion_time_sec = nowTimeSec;
-        addToIceBoxLocked(configStats);
-    }
-}
-
-void StatsdStats::noteConfigRemovedInternalLocked(const ConfigKey& key) {
-    auto it = mConfigStats.find(key);
-    if (it != mConfigStats.end()) {
-        int32_t nowTimeSec = getWallClockSec();
-        it->second->deletion_time_sec = nowTimeSec;
-        addToIceBoxLocked(it->second);
-        mConfigStats.erase(it);
-    }
-}
-
-void StatsdStats::noteConfigRemoved(const ConfigKey& key) {
-    lock_guard<std::mutex> lock(mLock);
-    noteConfigRemovedInternalLocked(key);
-}
-
-void StatsdStats::noteConfigResetInternalLocked(const ConfigKey& key) {
-    auto it = mConfigStats.find(key);
-    if (it != mConfigStats.end()) {
-        it->second->reset_time_sec = getWallClockSec();
-    }
-}
-
-void StatsdStats::noteConfigReset(const ConfigKey& key) {
-    lock_guard<std::mutex> lock(mLock);
-    noteConfigResetInternalLocked(key);
-}
-
-void StatsdStats::noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
-                              int32_t lastTag, int32_t uid, int32_t pid) {
-    lock_guard<std::mutex> lock(mLock);
-    if (mLogLossStats.size() == kMaxLoggerErrors) {
-        mLogLossStats.pop_front();
-    }
-    mLogLossStats.emplace_back(wallClockTimeSec, count, lastError, lastTag, uid, pid);
-}
-
-void StatsdStats::noteBroadcastSent(const ConfigKey& key) {
-    noteBroadcastSent(key, getWallClockSec());
-}
-
-void StatsdStats::noteBroadcastSent(const ConfigKey& key, int32_t timeSec) {
-    lock_guard<std::mutex> lock(mLock);
-    auto it = mConfigStats.find(key);
-    if (it == mConfigStats.end()) {
-        ALOGE("Config key %s not found!", key.ToString().c_str());
-        return;
-    }
-    if (it->second->broadcast_sent_time_sec.size() == kMaxTimestampCount) {
-        it->second->broadcast_sent_time_sec.pop_front();
-    }
-    it->second->broadcast_sent_time_sec.push_back(timeSec);
-}
-
-void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated) {
-    noteActiveStatusChanged(key, activated, getWallClockSec());
-}
-
-void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated, int32_t timeSec) {
-    lock_guard<std::mutex> lock(mLock);
-    auto it = mConfigStats.find(key);
-    if (it == mConfigStats.end()) {
-        ALOGE("Config key %s not found!", key.ToString().c_str());
-        return;
-    }
-    auto& vec = activated ? it->second->activation_time_sec
-                          : it->second->deactivation_time_sec;
-    if (vec.size() == kMaxTimestampCount) {
-        vec.pop_front();
-    }
-    vec.push_back(timeSec);
-}
-
-void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid) {
-    noteActivationBroadcastGuardrailHit(uid, getWallClockSec());
-}
-
-void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid, const int32_t timeSec) {
-    lock_guard<std::mutex> lock(mLock);
-    auto& guardrailTimes = mActivationBroadcastGuardrailStats[uid];
-    if (guardrailTimes.size() == kMaxTimestampCount) {
-        guardrailTimes.pop_front();
-    }
-    guardrailTimes.push_back(timeSec);
-}
-
-void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes) {
-    noteDataDropped(key, totalBytes, getWallClockSec());
-}
-
-void StatsdStats::noteEventQueueOverflow(int64_t oldestEventTimestampNs) {
-    lock_guard<std::mutex> lock(mLock);
-
-    mOverflowCount++;
-
-    int64_t history = getElapsedRealtimeNs() - oldestEventTimestampNs;
-
-    if (history > mMaxQueueHistoryNs) {
-        mMaxQueueHistoryNs = history;
-    }
-
-    if (history < mMinQueueHistoryNs) {
-        mMinQueueHistoryNs = history;
-    }
-}
-
-void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec) {
-    lock_guard<std::mutex> lock(mLock);
-    auto it = mConfigStats.find(key);
-    if (it == mConfigStats.end()) {
-        ALOGE("Config key %s not found!", key.ToString().c_str());
-        return;
-    }
-    if (it->second->data_drop_time_sec.size() == kMaxTimestampCount) {
-        it->second->data_drop_time_sec.pop_front();
-        it->second->data_drop_bytes.pop_front();
-    }
-    it->second->data_drop_time_sec.push_back(timeSec);
-    it->second->data_drop_bytes.push_back(totalBytes);
-}
-
-void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes) {
-    noteMetricsReportSent(key, num_bytes, getWallClockSec());
-}
-
-void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes,
-                                        int32_t timeSec) {
-    lock_guard<std::mutex> lock(mLock);
-    auto it = mConfigStats.find(key);
-    if (it == mConfigStats.end()) {
-        ALOGE("Config key %s not found!", key.ToString().c_str());
-        return;
-    }
-    if (it->second->dump_report_stats.size() == kMaxTimestampCount) {
-        it->second->dump_report_stats.pop_front();
-    }
-    it->second->dump_report_stats.push_back(std::make_pair(timeSec, num_bytes));
-}
-
-void StatsdStats::noteUidMapDropped(int deltas) {
-    lock_guard<std::mutex> lock(mLock);
-    mUidMapStats.dropped_changes += mUidMapStats.dropped_changes + deltas;
-}
-
-void StatsdStats::noteUidMapAppDeletionDropped() {
-    lock_guard<std::mutex> lock(mLock);
-    mUidMapStats.deleted_apps++;
-}
-
-void StatsdStats::setUidMapChanges(int changes) {
-    lock_guard<std::mutex> lock(mLock);
-    mUidMapStats.changes = changes;
-}
-
-void StatsdStats::setCurrentUidMapMemory(int bytes) {
-    lock_guard<std::mutex> lock(mLock);
-    mUidMapStats.bytes_used = bytes;
-}
-
-void StatsdStats::noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size) {
-    lock_guard<std::mutex> lock(mLock);
-    // if name doesn't exist before, it will create the key with count 0.
-    auto statsIt = mConfigStats.find(key);
-    if (statsIt == mConfigStats.end()) {
-        return;
-    }
-
-    auto& conditionSizeMap = statsIt->second->condition_stats;
-    if (size > conditionSizeMap[id]) {
-        conditionSizeMap[id] = size;
-    }
-}
-
-void StatsdStats::noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size) {
-    lock_guard<std::mutex> lock(mLock);
-    // if name doesn't exist before, it will create the key with count 0.
-    auto statsIt = mConfigStats.find(key);
-    if (statsIt == mConfigStats.end()) {
-        return;
-    }
-    auto& metricsDimensionMap = statsIt->second->metric_stats;
-    if (size > metricsDimensionMap[id]) {
-        metricsDimensionMap[id] = size;
-    }
-}
-
-void StatsdStats::noteMetricDimensionInConditionSize(
-        const ConfigKey& key, const int64_t& id, int size) {
-    lock_guard<std::mutex> lock(mLock);
-    // if name doesn't exist before, it will create the key with count 0.
-    auto statsIt = mConfigStats.find(key);
-    if (statsIt == mConfigStats.end()) {
-        return;
-    }
-    auto& metricsDimensionMap = statsIt->second->metric_dimension_in_condition_stats;
-    if (size > metricsDimensionMap[id]) {
-        metricsDimensionMap[id] = size;
-    }
-}
-
-void StatsdStats::noteMatcherMatched(const ConfigKey& key, const int64_t& id) {
-    lock_guard<std::mutex> lock(mLock);
-
-    auto statsIt = mConfigStats.find(key);
-    if (statsIt == mConfigStats.end()) {
-        return;
-    }
-    statsIt->second->matcher_stats[id]++;
-}
-
-void StatsdStats::noteAnomalyDeclared(const ConfigKey& key, const int64_t& id) {
-    lock_guard<std::mutex> lock(mLock);
-    auto statsIt = mConfigStats.find(key);
-    if (statsIt == mConfigStats.end()) {
-        return;
-    }
-    statsIt->second->alert_stats[id]++;
-}
-
-void StatsdStats::noteRegisteredAnomalyAlarmChanged() {
-    lock_guard<std::mutex> lock(mLock);
-    mAnomalyAlarmRegisteredStats++;
-}
-
-void StatsdStats::noteRegisteredPeriodicAlarmChanged() {
-    lock_guard<std::mutex> lock(mLock);
-    mPeriodicAlarmRegisteredStats++;
-}
-
-void StatsdStats::updateMinPullIntervalSec(int pullAtomId, long intervalSec) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[pullAtomId].minPullIntervalSec =
-            std::min(mPulledAtomStats[pullAtomId].minPullIntervalSec, intervalSec);
-}
-
-void StatsdStats::notePull(int pullAtomId) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[pullAtomId].totalPull++;
-}
-
-void StatsdStats::notePullFromCache(int pullAtomId) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[pullAtomId].totalPullFromCache++;
-}
-
-void StatsdStats::notePullTime(int pullAtomId, int64_t pullTimeNs) {
-    lock_guard<std::mutex> lock(mLock);
-    auto& pullStats = mPulledAtomStats[pullAtomId];
-    pullStats.maxPullTimeNs = std::max(pullStats.maxPullTimeNs, pullTimeNs);
-    pullStats.avgPullTimeNs = (pullStats.avgPullTimeNs * pullStats.numPullTime + pullTimeNs) /
-                              (pullStats.numPullTime + 1);
-    pullStats.numPullTime += 1;
-}
-
-void StatsdStats::notePullDelay(int pullAtomId, int64_t pullDelayNs) {
-    lock_guard<std::mutex> lock(mLock);
-    auto& pullStats = mPulledAtomStats[pullAtomId];
-    pullStats.maxPullDelayNs = std::max(pullStats.maxPullDelayNs, pullDelayNs);
-    pullStats.avgPullDelayNs =
-        (pullStats.avgPullDelayNs * pullStats.numPullDelay + pullDelayNs) /
-            (pullStats.numPullDelay + 1);
-    pullStats.numPullDelay += 1;
-}
-
-void StatsdStats::notePullDataError(int pullAtomId) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[pullAtomId].dataError++;
-}
-
-void StatsdStats::notePullTimeout(int pullAtomId,
-                                  int64_t pullUptimeMillis,
-                                  int64_t pullElapsedMillis) {
-    lock_guard<std::mutex> lock(mLock);
-    PulledAtomStats& pulledAtomStats = mPulledAtomStats[pullAtomId];
-    pulledAtomStats.pullTimeout++;
-
-    if (pulledAtomStats.pullTimeoutMetadata.size() == kMaxTimestampCount) {
-        pulledAtomStats.pullTimeoutMetadata.pop_front();
-    }
-
-    pulledAtomStats.pullTimeoutMetadata.emplace_back(pullUptimeMillis, pullElapsedMillis);
-}
-
-void StatsdStats::notePullExceedMaxDelay(int pullAtomId) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[pullAtomId].pullExceedMaxDelay++;
-}
-
-void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) {
-    lock_guard<std::mutex> lock(mLock);
-
-    if (atomId <= kMaxPushedAtomId) {
-        mPushedAtomStats[atomId]++;
-    } else {
-        if (mNonPlatformPushedAtomStats.size() < kMaxNonPlatformPushedAtoms) {
-            mNonPlatformPushedAtomStats[atomId]++;
-        }
-    }
-}
-
-void StatsdStats::noteSystemServerRestart(int32_t timeSec) {
-    lock_guard<std::mutex> lock(mLock);
-
-    if (mSystemServerRestartSec.size() == kMaxSystemServerRestarts) {
-        mSystemServerRestartSec.pop_front();
-    }
-    mSystemServerRestartSec.push_back(timeSec);
-}
-
-void StatsdStats::notePullFailed(int atomId) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[atomId].pullFailed++;
-}
-
-void StatsdStats::notePullUidProviderNotFound(int atomId) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[atomId].pullUidProviderNotFound++;
-}
-
-void StatsdStats::notePullerNotFound(int atomId) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[atomId].pullerNotFound++;
-}
-
-void StatsdStats::notePullBinderCallFailed(int atomId) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[atomId].binderCallFailCount++;
-}
-
-void StatsdStats::noteEmptyData(int atomId) {
-    lock_guard<std::mutex> lock(mLock);
-    mPulledAtomStats[atomId].emptyData++;
-}
-
-void StatsdStats::notePullerCallbackRegistrationChanged(int atomId, bool registered) {
-    lock_guard<std::mutex> lock(mLock);
-    if (registered) {
-        mPulledAtomStats[atomId].registeredCount++;
-    } else {
-        mPulledAtomStats[atomId].unregisteredCount++;
-    }
-}
-
-void StatsdStats::noteHardDimensionLimitReached(int64_t metricId) {
-    lock_guard<std::mutex> lock(mLock);
-    getAtomMetricStats(metricId).hardDimensionLimitReached++;
-}
-
-void StatsdStats::noteLateLogEventSkipped(int64_t metricId) {
-    lock_guard<std::mutex> lock(mLock);
-    getAtomMetricStats(metricId).lateLogEventSkipped++;
-}
-
-void StatsdStats::noteSkippedForwardBuckets(int64_t metricId) {
-    lock_guard<std::mutex> lock(mLock);
-    getAtomMetricStats(metricId).skippedForwardBuckets++;
-}
-
-void StatsdStats::noteBadValueType(int64_t metricId) {
-    lock_guard<std::mutex> lock(mLock);
-    getAtomMetricStats(metricId).badValueType++;
-}
-
-void StatsdStats::noteBucketDropped(int64_t metricId) {
-    lock_guard<std::mutex> lock(mLock);
-    getAtomMetricStats(metricId).bucketDropped++;
-}
-
-void StatsdStats::noteBucketUnknownCondition(int64_t metricId) {
-    lock_guard<std::mutex> lock(mLock);
-    getAtomMetricStats(metricId).bucketUnknownCondition++;
-}
-
-void StatsdStats::noteConditionChangeInNextBucket(int64_t metricId) {
-    lock_guard<std::mutex> lock(mLock);
-    getAtomMetricStats(metricId).conditionChangeInNextBucket++;
-}
-
-void StatsdStats::noteInvalidatedBucket(int64_t metricId) {
-    lock_guard<std::mutex> lock(mLock);
-    getAtomMetricStats(metricId).invalidatedBucket++;
-}
-
-void StatsdStats::noteBucketCount(int64_t metricId) {
-    lock_guard<std::mutex> lock(mLock);
-    getAtomMetricStats(metricId).bucketCount++;
-}
-
-void StatsdStats::noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs) {
-    lock_guard<std::mutex> lock(mLock);
-    AtomMetricStats& pullStats = getAtomMetricStats(metricId);
-    pullStats.maxBucketBoundaryDelayNs =
-            std::max(pullStats.maxBucketBoundaryDelayNs, timeDelayNs);
-    pullStats.minBucketBoundaryDelayNs =
-            std::min(pullStats.minBucketBoundaryDelayNs, timeDelayNs);
-}
-
-void StatsdStats::noteAtomError(int atomTag, bool pull) {
-    lock_guard<std::mutex> lock(mLock);
-    if (pull) {
-        mPulledAtomStats[atomTag].atomErrorCount++;
-        return;
-    }
-
-    bool present = (mPushedAtomErrorStats.find(atomTag) != mPushedAtomErrorStats.end());
-    bool full = (mPushedAtomErrorStats.size() >= (size_t)kMaxPushedAtomErrorStatsSize);
-    if (!full || present) {
-        mPushedAtomErrorStats[atomTag]++;
-    }
-}
-
-StatsdStats::AtomMetricStats& StatsdStats::getAtomMetricStats(int64_t metricId) {
-    auto atomMetricStatsIter = mAtomMetricStats.find(metricId);
-    if (atomMetricStatsIter != mAtomMetricStats.end()) {
-        return atomMetricStatsIter->second;
-    }
-    auto emplaceResult = mAtomMetricStats.emplace(metricId, AtomMetricStats());
-    return emplaceResult.first->second;
-}
-
-void StatsdStats::reset() {
-    lock_guard<std::mutex> lock(mLock);
-    resetInternalLocked();
-}
-
-void StatsdStats::resetInternalLocked() {
-    // Reset the historical data, but keep the active ConfigStats
-    mStartTimeSec = getWallClockSec();
-    mIceBox.clear();
-    std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), 0);
-    mNonPlatformPushedAtomStats.clear();
-    mAnomalyAlarmRegisteredStats = 0;
-    mPeriodicAlarmRegisteredStats = 0;
-    mSystemServerRestartSec.clear();
-    mLogLossStats.clear();
-    mOverflowCount = 0;
-    mMinQueueHistoryNs = kInt64Max;
-    mMaxQueueHistoryNs = 0;
-    for (auto& config : mConfigStats) {
-        config.second->broadcast_sent_time_sec.clear();
-        config.second->activation_time_sec.clear();
-        config.second->deactivation_time_sec.clear();
-        config.second->data_drop_time_sec.clear();
-        config.second->data_drop_bytes.clear();
-        config.second->dump_report_stats.clear();
-        config.second->annotations.clear();
-        config.second->matcher_stats.clear();
-        config.second->condition_stats.clear();
-        config.second->metric_stats.clear();
-        config.second->metric_dimension_in_condition_stats.clear();
-        config.second->alert_stats.clear();
-    }
-    for (auto& pullStats : mPulledAtomStats) {
-        pullStats.second.totalPull = 0;
-        pullStats.second.totalPullFromCache = 0;
-        pullStats.second.minPullIntervalSec = LONG_MAX;
-        pullStats.second.avgPullTimeNs = 0;
-        pullStats.second.maxPullTimeNs = 0;
-        pullStats.second.numPullTime = 0;
-        pullStats.second.avgPullDelayNs = 0;
-        pullStats.second.maxPullDelayNs = 0;
-        pullStats.second.numPullDelay = 0;
-        pullStats.second.dataError = 0;
-        pullStats.second.pullTimeout = 0;
-        pullStats.second.pullExceedMaxDelay = 0;
-        pullStats.second.pullFailed = 0;
-        pullStats.second.pullUidProviderNotFound = 0;
-        pullStats.second.pullerNotFound = 0;
-        pullStats.second.registeredCount = 0;
-        pullStats.second.unregisteredCount = 0;
-        pullStats.second.atomErrorCount = 0;
-        pullStats.second.binderCallFailCount = 0;
-        pullStats.second.pullTimeoutMetadata.clear();
-    }
-    mAtomMetricStats.clear();
-    mActivationBroadcastGuardrailStats.clear();
-    mPushedAtomErrorStats.clear();
-}
-
-string buildTimeString(int64_t timeSec) {
-    time_t t = timeSec;
-    struct tm* tm = localtime(&t);
-    char timeBuffer[80];
-    strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p", tm);
-    return string(timeBuffer);
-}
-
-int StatsdStats::getPushedAtomErrors(int atomId) const {
-    const auto& it = mPushedAtomErrorStats.find(atomId);
-    if (it != mPushedAtomErrorStats.end()) {
-        return it->second;
-    } else {
-        return 0;
-    }
-}
-
-void StatsdStats::dumpStats(int out) const {
-    lock_guard<std::mutex> lock(mLock);
-    time_t t = mStartTimeSec;
-    struct tm* tm = localtime(&t);
-    char timeBuffer[80];
-    strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm);
-    dprintf(out, "Stats collection start second: %s\n", timeBuffer);
-    dprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
-    for (const auto& configStats : mIceBox) {
-        dprintf(out,
-                "Config {%d_%lld}: creation=%d, deletion=%d, reset=%d, #metric=%d, #condition=%d, "
-                "#matcher=%d, #alert=%d,  valid=%d\n",
-                configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
-                configStats->deletion_time_sec, configStats->reset_time_sec,
-                configStats->metric_count, configStats->condition_count, configStats->matcher_count,
-                configStats->alert_count, configStats->is_valid);
-
-        for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
-            dprintf(out, "\tbroadcast time: %d\n", broadcastTime);
-        }
-
-        for (const int& activationTime : configStats->activation_time_sec) {
-            dprintf(out, "\tactivation time: %d\n", activationTime);
-        }
-
-        for (const int& deactivationTime : configStats->deactivation_time_sec) {
-            dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
-        }
-
-        auto dropTimePtr = configStats->data_drop_time_sec.begin();
-        auto dropBytesPtr = configStats->data_drop_bytes.begin();
-        for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
-             i++, dropTimePtr++, dropBytesPtr++) {
-            dprintf(out, "\tdata drop time: %d with size %lld", *dropTimePtr,
-                    (long long)*dropBytesPtr);
-        }
-    }
-    dprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size());
-    for (auto& pair : mConfigStats) {
-        auto& configStats = pair.second;
-        dprintf(out,
-                "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
-                "#matcher=%d, #alert=%d,  valid=%d\n",
-                configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
-                configStats->deletion_time_sec, configStats->metric_count,
-                configStats->condition_count, configStats->matcher_count, configStats->alert_count,
-                configStats->is_valid);
-        for (const auto& annotation : configStats->annotations) {
-            dprintf(out, "\tannotation: %lld, %d\n", (long long)annotation.first,
-                    annotation.second);
-        }
-
-        for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
-            dprintf(out, "\tbroadcast time: %s(%lld)\n", buildTimeString(broadcastTime).c_str(),
-                    (long long)broadcastTime);
-        }
-
-        for (const int& activationTime : configStats->activation_time_sec) {
-            dprintf(out, "\tactivation time: %d\n", activationTime);
-        }
-
-        for (const int& deactivationTime : configStats->deactivation_time_sec) {
-            dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
-        }
-
-        auto dropTimePtr = configStats->data_drop_time_sec.begin();
-        auto dropBytesPtr = configStats->data_drop_bytes.begin();
-        for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
-             i++, dropTimePtr++, dropBytesPtr++) {
-            dprintf(out, "\tdata drop time: %s(%lld) with %lld bytes\n",
-                    buildTimeString(*dropTimePtr).c_str(), (long long)*dropTimePtr,
-                    (long long)*dropBytesPtr);
-        }
-
-        for (const auto& dump : configStats->dump_report_stats) {
-            dprintf(out, "\tdump report time: %s(%lld) bytes: %lld\n",
-                    buildTimeString(dump.first).c_str(), (long long)dump.first,
-                    (long long)dump.second);
-        }
-
-        for (const auto& stats : pair.second->matcher_stats) {
-            dprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second);
-        }
-
-        for (const auto& stats : pair.second->condition_stats) {
-            dprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first,
-                    stats.second);
-        }
-
-        for (const auto& stats : pair.second->condition_stats) {
-            dprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first,
-                    stats.second);
-        }
-
-        for (const auto& stats : pair.second->alert_stats) {
-            dprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second);
-        }
-    }
-    dprintf(out, "********Disk Usage stats***********\n");
-    StorageManager::printStats(out);
-    dprintf(out, "********Pushed Atom stats***********\n");
-    const size_t atomCounts = mPushedAtomStats.size();
-    for (size_t i = 2; i < atomCounts; i++) {
-        if (mPushedAtomStats[i] > 0) {
-            dprintf(out, "Atom %zu->(total count)%d, (error count)%d\n", i, mPushedAtomStats[i],
-                    getPushedAtomErrors((int)i));
-        }
-    }
-    for (const auto& pair : mNonPlatformPushedAtomStats) {
-        dprintf(out, "Atom %d->(total count)%d, (error count)%d\n", pair.first, pair.second,
-                getPushedAtomErrors(pair.first));
-    }
-
-    dprintf(out, "********Pulled Atom stats***********\n");
-    for (const auto& pair : mPulledAtomStats) {
-        dprintf(out,
-                "Atom %d->(total pull)%ld, (pull from cache)%ld, "
-                "(pull failed)%ld, (min pull interval)%ld \n"
-                "  (average pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay "
-                "nanos)%lld, "
-                "  (max pull delay nanos)%lld, (data error)%ld\n"
-                "  (pull timeout)%ld, (pull exceed max delay)%ld"
-                "  (no uid provider count)%ld, (no puller found count)%ld\n"
-                "  (registered count) %ld, (unregistered count) %ld"
-                "  (atom error count) %d\n",
-                (int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache,
-                (long)pair.second.pullFailed, (long)pair.second.minPullIntervalSec,
-                (long long)pair.second.avgPullTimeNs, (long long)pair.second.maxPullTimeNs,
-                (long long)pair.second.avgPullDelayNs, (long long)pair.second.maxPullDelayNs,
-                pair.second.dataError, pair.second.pullTimeout, pair.second.pullExceedMaxDelay,
-                pair.second.pullUidProviderNotFound, pair.second.pullerNotFound,
-                pair.second.registeredCount, pair.second.unregisteredCount,
-                pair.second.atomErrorCount);
-        if (pair.second.pullTimeoutMetadata.size() > 0) {
-            string uptimeMillis = "(pull timeout system uptime millis) ";
-            string pullTimeoutMillis = "(pull timeout elapsed time millis) ";
-            for (const auto& stats : pair.second.pullTimeoutMetadata) {
-                uptimeMillis.append(to_string(stats.pullTimeoutUptimeMillis)).append(",");;
-                pullTimeoutMillis.append(to_string(stats.pullTimeoutElapsedMillis)).append(",");
-            }
-            uptimeMillis.pop_back();
-            uptimeMillis.push_back('\n');
-            pullTimeoutMillis.pop_back();
-            pullTimeoutMillis.push_back('\n');
-            dprintf(out, "%s", uptimeMillis.c_str());
-            dprintf(out, "%s", pullTimeoutMillis.c_str());
-        }
-    }
-
-    if (mAnomalyAlarmRegisteredStats > 0) {
-        dprintf(out, "********AnomalyAlarmStats stats***********\n");
-        dprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats);
-    }
-
-    if (mPeriodicAlarmRegisteredStats > 0) {
-        dprintf(out, "********SubscriberAlarmStats stats***********\n");
-        dprintf(out, "Subscriber alarm registrations: %d\n", mPeriodicAlarmRegisteredStats);
-    }
-
-    dprintf(out, "UID map stats: bytes=%d, changes=%d, deleted=%d, changes lost=%d\n",
-            mUidMapStats.bytes_used, mUidMapStats.changes, mUidMapStats.deleted_apps,
-            mUidMapStats.dropped_changes);
-
-    for (const auto& restart : mSystemServerRestartSec) {
-        dprintf(out, "System server restarts at %s(%lld)\n", buildTimeString(restart).c_str(),
-                (long long)restart);
-    }
-
-    for (const auto& loss : mLogLossStats) {
-        dprintf(out,
-                "Log loss: %lld (wall clock sec) - %d (count), %d (last error), %d (last tag), %d "
-                "(uid), %d (pid)\n",
-                (long long)loss.mWallClockSec, loss.mCount, loss.mLastError, loss.mLastTag,
-                loss.mUid, loss.mPid);
-    }
-
-    dprintf(out, "Event queue overflow: %d; MaxHistoryNs: %lld; MinHistoryNs: %lld\n",
-            mOverflowCount, (long long)mMaxQueueHistoryNs, (long long)mMinQueueHistoryNs);
-
-    if (mActivationBroadcastGuardrailStats.size() > 0) {
-        dprintf(out, "********mActivationBroadcastGuardrail stats***********\n");
-        for (const auto& pair: mActivationBroadcastGuardrailStats) {
-            dprintf(out, "Uid %d: Times: ", pair.first);
-            for (const auto& guardrailHitTime : pair.second) {
-                dprintf(out, "%d ", guardrailHitTime);
-            }
-        }
-        dprintf(out, "\n");
-    }
-}
-
-void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* proto) {
-    uint64_t token =
-            proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS);
-    proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_UID, configStats.uid);
-    proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ID, (long long)configStats.id);
-    proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CREATION, configStats.creation_time_sec);
-    if (configStats.reset_time_sec != 0) {
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_RESET, configStats.reset_time_sec);
-    }
-    if (configStats.deletion_time_sec != 0) {
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DELETION,
-                     configStats.deletion_time_sec);
-    }
-    proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_METRIC_COUNT, configStats.metric_count);
-    proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CONDITION_COUNT,
-                 configStats.condition_count);
-    proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_MATCHER_COUNT, configStats.matcher_count);
-    proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ALERT_COUNT, configStats.alert_count);
-    proto->write(FIELD_TYPE_BOOL | FIELD_ID_CONFIG_STATS_VALID, configStats.is_valid);
-
-    for (const auto& broadcast : configStats.broadcast_sent_time_sec) {
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_BROADCAST | FIELD_COUNT_REPEATED,
-                     broadcast);
-    }
-
-    for (const auto& activation : configStats.activation_time_sec) {
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ACTIVATION | FIELD_COUNT_REPEATED,
-                     activation);
-    }
-
-    for (const auto& deactivation : configStats.deactivation_time_sec) {
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DEACTIVATION | FIELD_COUNT_REPEATED,
-                     deactivation);
-    }
-
-    for (const auto& drop_time : configStats.data_drop_time_sec) {
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DATA_DROP_TIME | FIELD_COUNT_REPEATED,
-                     drop_time);
-    }
-
-    for (const auto& drop_bytes : configStats.data_drop_bytes) {
-        proto->write(
-                FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES | FIELD_COUNT_REPEATED,
-                (long long)drop_bytes);
-    }
-
-    for (const auto& dump : configStats.dump_report_stats) {
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME |
-                     FIELD_COUNT_REPEATED,
-                     dump.first);
-    }
-
-    for (const auto& dump : configStats.dump_report_stats) {
-        proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES |
-                     FIELD_COUNT_REPEATED,
-                     (long long)dump.second);
-    }
-
-    for (const auto& annotation : configStats.annotations) {
-        uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                      FIELD_ID_CONFIG_STATS_ANNOTATION);
-        proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT64,
-                     (long long)annotation.first);
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT32, annotation.second);
-        proto->end(token);
-    }
-
-    for (const auto& pair : configStats.matcher_stats) {
-        uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                          FIELD_ID_CONFIG_STATS_MATCHER_STATS);
-        proto->write(FIELD_TYPE_INT64 | FIELD_ID_MATCHER_STATS_ID, (long long)pair.first);
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_MATCHER_STATS_COUNT, pair.second);
-        proto->end(tmpToken);
-    }
-
-    for (const auto& pair : configStats.condition_stats) {
-        uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                          FIELD_ID_CONFIG_STATS_CONDITION_STATS);
-        proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_STATS_ID, (long long)pair.first);
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONDITION_STATS_COUNT, pair.second);
-        proto->end(tmpToken);
-    }
-
-    for (const auto& pair : configStats.metric_stats) {
-        uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                          FIELD_ID_CONFIG_STATS_METRIC_STATS);
-        proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
-        proto->end(tmpToken);
-    }
-    for (const auto& pair : configStats.metric_dimension_in_condition_stats) {
-        uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                         FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS);
-        proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
-        proto->end(tmpToken);
-    }
-
-    for (const auto& pair : configStats.alert_stats) {
-        uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                          FIELD_ID_CONFIG_STATS_ALERT_STATS);
-        proto->write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_STATS_ID, (long long)pair.first);
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_ALERT_STATS_COUNT, pair.second);
-        proto->end(tmpToken);
-    }
-
-    proto->end(token);
-}
-
-void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
-    lock_guard<std::mutex> lock(mLock);
-
-    ProtoOutputStream proto;
-    proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec);
-    proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)getWallClockSec());
-
-    for (const auto& configStats : mIceBox) {
-        addConfigStatsToProto(*configStats, &proto);
-    }
-
-    for (auto& pair : mConfigStats) {
-        addConfigStatsToProto(*(pair.second), &proto);
-    }
-
-    const size_t atomCounts = mPushedAtomStats.size();
-    for (size_t i = 2; i < atomCounts; i++) {
-        if (mPushedAtomStats[i] > 0) {
-            uint64_t token =
-                    proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
-            proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, (int32_t)i);
-            proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, mPushedAtomStats[i]);
-            int errors = getPushedAtomErrors(i);
-            if (errors > 0) {
-                proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors);
-            }
-            proto.end(token);
-        }
-    }
-
-    for (const auto& pair : mNonPlatformPushedAtomStats) {
-        uint64_t token =
-                proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, pair.first);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, pair.second);
-        int errors = getPushedAtomErrors(pair.first);
-        if (errors > 0) {
-            proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors);
-        }
-        proto.end(token);
-    }
-
-    for (const auto& pair : mPulledAtomStats) {
-        android::os::statsd::writePullerStatsToStream(pair, &proto);
-    }
-
-    for (const auto& pair : mAtomMetricStats) {
-        android::os::statsd::writeAtomMetricStatsToStream(pair, &proto);
-    }
-
-    if (mAnomalyAlarmRegisteredStats > 0) {
-        uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED,
-                    mAnomalyAlarmRegisteredStats);
-        proto.end(token);
-    }
-
-    if (mPeriodicAlarmRegisteredStats > 0) {
-        uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_PERIODIC_ALARM_STATS);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_PERIODIC_ALARMS_REGISTERED,
-                    mPeriodicAlarmRegisteredStats);
-        proto.end(token);
-    }
-
-    uint64_t uidMapToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS);
-    proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_CHANGES, mUidMapStats.changes);
-    proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_BYTES_USED, mUidMapStats.bytes_used);
-    proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DROPPED_CHANGES, mUidMapStats.dropped_changes);
-    proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DELETED_APPS, mUidMapStats.deleted_apps);
-    proto.end(uidMapToken);
-
-    for (const auto& error : mLogLossStats) {
-        uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS |
-                                      FIELD_COUNT_REPEATED);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TIME, error.mWallClockSec);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_COUNT, error.mCount);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_ERROR, error.mLastError);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TAG, error.mLastTag);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_UID, error.mUid);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_PID, error.mPid);
-        proto.end(token);
-    }
-
-    if (mOverflowCount > 0) {
-        uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_OVERFLOW);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_OVERFLOW_COUNT, (int32_t)mOverflowCount);
-        proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MAX_HISTORY,
-                    (long long)mMaxQueueHistoryNs);
-        proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MIN_HISTORY,
-                    (long long)mMinQueueHistoryNs);
-        proto.end(token);
-    }
-
-    for (const auto& restart : mSystemServerRestartSec) {
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_SYSTEM_SERVER_RESTART | FIELD_COUNT_REPEATED,
-                    restart);
-    }
-
-    for (const auto& pair: mActivationBroadcastGuardrailStats) {
-        uint64_t token = proto.start(FIELD_TYPE_MESSAGE |
-                                     FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL |
-                                     FIELD_COUNT_REPEATED);
-        proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID,
-                    (int32_t) pair.first);
-        for (const auto& guardrailHitTime : pair.second) {
-            proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME |
-                            FIELD_COUNT_REPEATED,
-                        guardrailHitTime);
-        }
-        proto.end(token);
-    }
-
-    output->clear();
-    size_t bufferSize = proto.size();
-    output->resize(bufferSize);
-
-    size_t pos = 0;
-    sp<android::util::ProtoReader> reader = proto.data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(&((*output)[pos]), reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-
-    if (reset) {
-        resetInternalLocked();
-    }
-
-    VLOG("reset=%d, returned proto size %lu", reset, (unsigned long)bufferSize);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
deleted file mode 100644
index 0050484..0000000
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * 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.
- */
-#pragma once
-
-#include "config/ConfigKey.h"
-
-#include <gtest/gtest_prod.h>
-#include <log/log_time.h>
-#include <list>
-#include <mutex>
-#include <string>
-#include <vector>
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct ConfigStats {
-    int32_t uid;
-    int64_t id;
-    int32_t creation_time_sec;
-    int32_t deletion_time_sec = 0;
-    int32_t reset_time_sec = 0;
-    int32_t metric_count;
-    int32_t condition_count;
-    int32_t matcher_count;
-    int32_t alert_count;
-    bool is_valid;
-
-    std::list<int32_t> broadcast_sent_time_sec;
-
-    // Times at which this config is activated.
-    std::list<int32_t> activation_time_sec;
-
-    // Times at which this config is deactivated.
-    std::list<int32_t> deactivation_time_sec;
-
-    std::list<int32_t> data_drop_time_sec;
-    // Number of bytes dropped at corresponding time.
-    std::list<int64_t> data_drop_bytes;
-    std::list<std::pair<int32_t, int64_t>> dump_report_stats;
-
-    // Stores how many times a matcher have been matched. The map size is capped by kMaxConfigCount.
-    std::map<const int64_t, int> matcher_stats;
-
-    // Stores the number of output tuple of condition trackers when it's bigger than
-    // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
-    // it means some data has been dropped. The map size is capped by kMaxConfigCount.
-    std::map<const int64_t, int> condition_stats;
-
-    // Stores the number of output tuple of metric producers when it's bigger than
-    // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
-    // it means some data has been dropped. The map size is capped by kMaxConfigCount.
-    std::map<const int64_t, int> metric_stats;
-
-    // Stores the max number of output tuple of dimensions in condition across dimensions in what
-    // when it's bigger than kDimensionKeySizeSoftLimit. When you see the number is
-    // kDimensionKeySizeHardLimit +1, it means some data has been dropped. The map size is capped by
-    // kMaxConfigCount.
-    std::map<const int64_t, int> metric_dimension_in_condition_stats;
-
-    // Stores the number of times an anomaly detection alert has been declared.
-    // The map size is capped by kMaxConfigCount.
-    std::map<const int64_t, int> alert_stats;
-
-    // Stores the config ID for each sub-config used.
-    std::list<std::pair<const int64_t, const int32_t>> annotations;
-};
-
-struct UidMapStats {
-    int32_t changes;
-    int32_t bytes_used;
-    int32_t dropped_changes;
-    int32_t deleted_apps = 0;
-};
-
-// Keeps track of stats of statsd.
-// Single instance shared across the process. All public methods are thread safe.
-class StatsdStats {
-public:
-    static StatsdStats& getInstance();
-    ~StatsdStats(){};
-
-    const static int kDimensionKeySizeSoftLimit = 500;
-    const static int kDimensionKeySizeHardLimit = 800;
-
-    // Per atom dimension key size limit
-    static const std::map<int, std::pair<size_t, size_t>> kAtomDimensionKeySizeLimitMap;
-
-    const static int kMaxConfigCountPerUid = 20;
-    const static int kMaxAlertCountPerConfig = 100;
-    const static int kMaxConditionCountPerConfig = 300;
-    const static int kMaxMetricCountPerConfig = 1000;
-    const static int kMaxMatcherCountPerConfig = 800;
-
-    // The max number of old config stats we keep.
-    const static int kMaxIceBoxSize = 20;
-
-    const static int kMaxLoggerErrors = 20;
-
-    const static int kMaxSystemServerRestarts = 20;
-
-    const static int kMaxTimestampCount = 20;
-
-    const static int kMaxLogSourceCount = 50;
-
-    const static int kMaxPullAtomPackages = 100;
-
-    // Max memory allowed for storing metrics per configuration. If this limit is exceeded, statsd
-    // drops the metrics data in memory.
-    static const size_t kMaxMetricsBytesPerConfig = 2 * 1024 * 1024;
-
-    // Soft memory limit per configuration. Once this limit is exceeded, we begin notifying the
-    // data subscriber that it's time to call getData.
-    static const size_t kBytesPerConfigTriggerGetData = 192 * 1024;
-
-    // Cap the UID map's memory usage to this. This should be fairly high since the UID information
-    // is critical for understanding the metrics.
-    const static size_t kMaxBytesUsedUidMap = 50 * 1024;
-
-    // The number of deleted apps that are stored in the uid map.
-    const static int kMaxDeletedAppsInUidMap = 100;
-
-    /* Minimum period between two broadcasts in nanoseconds. */
-    static const int64_t kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
-
-    /* Min period between two checks of byte size per config key in nanoseconds. */
-    static const int64_t kMinByteSizeCheckPeriodNs = 60 * NS_PER_SEC;
-
-    /* Minimum period between two activation broadcasts in nanoseconds. */
-    static const int64_t kMinActivationBroadcastPeriodNs = 10 * NS_PER_SEC;
-
-    // Maximum age (30 days) that files on disk can exist in seconds.
-    static const int kMaxAgeSecond = 60 * 60 * 24 * 30;
-
-    // Maximum age (2 days) that local history files on disk can exist in seconds.
-    static const int kMaxLocalHistoryAgeSecond = 60 * 60 * 24 * 2;
-
-    // Maximum number of files (1000) that can be in stats directory on disk.
-    static const int kMaxFileNumber = 1000;
-
-    // Maximum size of all files that can be written to stats directory on disk.
-    static const int kMaxFileSize = 50 * 1024 * 1024;
-
-    // How long to try to clear puller cache from last time
-    static const long kPullerCacheClearIntervalSec = 1;
-
-    // Max time to do a pull.
-    static const int64_t kPullMaxDelayNs = 30 * NS_PER_SEC;
-
-    // Maximum number of pushed atoms statsd stats will track above kMaxPushedAtomId.
-    static const int kMaxNonPlatformPushedAtoms = 100;
-
-    // Maximum atom id value that we consider a platform pushed atom.
-    // This should be updated once highest pushed atom id in atoms.proto approaches this value.
-    static const int kMaxPushedAtomId = 500;
-
-    // Atom id that is the start of the pulled atoms.
-    static const int kPullAtomStartTag = 10000;
-
-    // Atom id that is the start of vendor atoms.
-    static const int kVendorAtomStartTag = 100000;
-
-    // Vendor pulled atom start id.
-    static const int32_t kVendorPulledAtomStartTag = 150000;
-
-    // Beginning of range for timestamp truncation.
-    static const int32_t kTimestampTruncationStartTag = 300000;
-
-    // End of range for timestamp truncation.
-    static const int32_t kTimestampTruncationEndTag = 304999;
-
-    // Max accepted atom id.
-    static const int32_t kMaxAtomTag = 200000;
-
-    static const int64_t kInt64Max = 0x7fffffffffffffffLL;
-
-    static const int32_t kMaxLoggedBucketDropEvents = 10;
-
-    /**
-     * Report a new config has been received and report the static stats about the config.
-     *
-     * The static stats include: the count of metrics, conditions, matchers, and alerts.
-     * If the config is not valid, this config stats will be put into icebox immediately.
-     */
-    void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
-                            int matchersCount, int alertCount,
-                            const std::list<std::pair<const int64_t, const int32_t>>& annotations,
-                            bool isValid);
-    /**
-     * Report a config has been removed.
-     */
-    void noteConfigRemoved(const ConfigKey& key);
-    /**
-     * Report a config has been reset when ttl expires.
-     */
-    void noteConfigReset(const ConfigKey& key);
-
-    /**
-     * Report a broadcast has been sent to a config owner to collect the data.
-     */
-    void noteBroadcastSent(const ConfigKey& key);
-
-    /**
-     * Report that a config has become activated or deactivated.
-     * This can be different from whether or not a broadcast is sent if the
-     * guardrail prevented the broadcast from being sent.
-     */
-    void noteActiveStatusChanged(const ConfigKey& key, bool activate);
-
-    /**
-     * Report a config's metrics data has been dropped.
-     */
-    void noteDataDropped(const ConfigKey& key, const size_t totalBytes);
-
-    /**
-     * Report metrics data report has been sent.
-     *
-     * The report may be requested via StatsManager API, or through adb cmd.
-     */
-    void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes);
-
-    /**
-     * Report the size of output tuple of a condition.
-     *
-     * Note: only report when the condition has an output dimension, and the tuple
-     * count > kDimensionKeySizeSoftLimit.
-     *
-     * [key]: The config key that this condition belongs to.
-     * [id]: The id of the condition.
-     * [size]: The output tuple size.
-     */
-    void noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size);
-
-    /**
-     * Report the size of output tuple of a metric.
-     *
-     * Note: only report when the metric has an output dimension, and the tuple
-     * count > kDimensionKeySizeSoftLimit.
-     *
-     * [key]: The config key that this metric belongs to.
-     * [id]: The id of the metric.
-     * [size]: The output tuple size.
-     */
-    void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
-
-    /**
-     * Report the max size of output tuple of dimension in condition across dimensions in what.
-     *
-     * Note: only report when the metric has an output dimension in condition, and the max tuple
-     * count > kDimensionKeySizeSoftLimit.
-     *
-     * [key]: The config key that this metric belongs to.
-     * [id]: The id of the metric.
-     * [size]: The output tuple size.
-     */
-    void noteMetricDimensionInConditionSize(const ConfigKey& key, const int64_t& id, int size);
-
-    /**
-     * Report a matcher has been matched.
-     *
-     * [key]: The config key that this matcher belongs to.
-     * [id]: The id of the matcher.
-     */
-    void noteMatcherMatched(const ConfigKey& key, const int64_t& id);
-
-    /**
-     * Report that an anomaly detection alert has been declared.
-     *
-     * [key]: The config key that this alert belongs to.
-     * [id]: The id of the alert.
-     */
-    void noteAnomalyDeclared(const ConfigKey& key, const int64_t& id);
-
-    /**
-     * Report an atom event has been logged.
-     */
-    void noteAtomLogged(int atomId, int32_t timeSec);
-
-    /**
-     * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
-     */
-    void noteRegisteredAnomalyAlarmChanged();
-
-    /**
-     * Report that statsd modified the periodic alarm registered with StatsCompanionService.
-     */
-    void noteRegisteredPeriodicAlarmChanged();
-
-    /**
-     * Records the number of delta entries that are being dropped from the uid map.
-     */
-    void noteUidMapDropped(int deltas);
-
-    /**
-     * Records that an app was deleted (from statsd's map).
-     */
-    void noteUidMapAppDeletionDropped();
-
-    /**
-     * Updates the number of changes currently stored in the uid map.
-     */
-    void setUidMapChanges(int changes);
-    void setCurrentUidMapMemory(int bytes);
-
-    /*
-     * Updates minimum interval between pulls for an pulled atom.
-     */
-    void updateMinPullIntervalSec(int pullAtomId, long intervalSec);
-
-    /*
-     * Notes an atom is pulled.
-     */
-    void notePull(int pullAtomId);
-
-    /*
-     * Notes an atom is served from puller cache.
-     */
-    void notePullFromCache(int pullAtomId);
-
-    /*
-     * Notify data error for pulled atom.
-     */
-    void notePullDataError(int pullAtomId);
-
-    /*
-     * Records time for actual pulling, not including those served from cache and not including
-     * statsd processing delays.
-     */
-    void notePullTime(int pullAtomId, int64_t pullTimeNs);
-
-    /*
-     * Records pull delay for a pulled atom, including those served from cache and including statsd
-     * processing delays.
-     */
-    void notePullDelay(int pullAtomId, int64_t pullDelayNs);
-
-    /*
-     * Records pull exceeds timeout for the puller.
-     */
-    void notePullTimeout(int pullAtomId, int64_t pullUptimeMillis, int64_t pullElapsedMillis);
-
-    /*
-     * Records pull exceeds max delay for a metric.
-     */
-    void notePullExceedMaxDelay(int pullAtomId);
-
-    /*
-     * Records when system server restarts.
-     */
-    void noteSystemServerRestart(int32_t timeSec);
-
-    /**
-     * Records statsd skipped an event.
-     */
-    void noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
-                     int32_t lastAtomTag, int32_t uid, int32_t pid);
-
-    /**
-     * Records that the pull of an atom has failed. Eg, if the client indicated the pull failed, if
-     * the pull timed out, or if the outgoing binder call failed.
-     * This count will only increment if the puller was actually invoked.
-     *
-     * It does not include a pull not occurring due to not finding the appropriate
-     * puller. These cases are covered in other counts.
-     */
-    void notePullFailed(int atomId);
-
-    /**
-     * Records that the pull of an atom has failed due to not having a uid provider.
-     */
-    void notePullUidProviderNotFound(int atomId);
-
-    /**
-     * Records that the pull of an atom has failed due not finding a puller registered by a
-     * trusted uid.
-     */
-    void notePullerNotFound(int atomId);
-
-    /**
-     * Records that the pull has failed due to the outgoing binder call failing.
-     */
-    void notePullBinderCallFailed(int atomId);
-
-    /**
-     * A pull with no data occurred
-     */
-    void noteEmptyData(int atomId);
-
-    /**
-     * Records that a puller callback for the given atomId was registered or unregistered.
-     *
-     * @param registered True if the callback was registered, false if was unregistered.
-     */
-    void notePullerCallbackRegistrationChanged(int atomId, bool registered);
-
-    /**
-     * Hard limit was reached in the cardinality of an atom
-     */
-    void noteHardDimensionLimitReached(int64_t metricId);
-
-    /**
-     * A log event was too late, arrived in the wrong bucket and was skipped
-     */
-    void noteLateLogEventSkipped(int64_t metricId);
-
-    /**
-     * Buckets were skipped as time elapsed without any data for them
-     */
-    void noteSkippedForwardBuckets(int64_t metricId);
-
-    /**
-     * An unsupported value type was received
-     */
-    void noteBadValueType(int64_t metricId);
-
-    /**
-     * Buckets were dropped due to reclaim memory.
-     */
-    void noteBucketDropped(int64_t metricId);
-
-    /**
-     * A condition change was too late, arrived in the wrong bucket and was skipped
-     */
-    void noteConditionChangeInNextBucket(int64_t metricId);
-
-    /**
-     * A bucket has been tagged as invalid.
-     */
-    void noteInvalidatedBucket(int64_t metricId);
-
-    /**
-     * Tracks the total number of buckets (include skipped/invalid buckets).
-     */
-    void noteBucketCount(int64_t metricId);
-
-    /**
-     * For pulls at bucket boundaries, it represents the misalignment between the real timestamp and
-     * the end of the bucket.
-     */
-    void noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs);
-
-    /**
-     * Number of buckets with unknown condition.
-     */
-    void noteBucketUnknownCondition(int64_t metricId);
-
-    /* Reports one event has been dropped due to queue overflow, and the oldest event timestamp in
-     * the queue */
-    void noteEventQueueOverflow(int64_t oldestEventTimestampNs);
-
-    /**
-     * Reports that the activation broadcast guardrail was hit for this uid. Namely, the broadcast
-     * should have been sent, but instead was skipped due to hitting the guardrail.
-     */
-     void noteActivationBroadcastGuardrailHit(const int uid);
-
-     /**
-      * Reports that an atom is erroneous or cannot be parsed successfully by
-      * statsd. An atom tag of 0 indicates that the client did not supply the
-      * atom id within the encoding.
-      *
-      * For pushed atoms only, this call should be preceded by a call to
-      * noteAtomLogged.
-      */
-     void noteAtomError(int atomTag, bool pull=false);
-
-    /**
-     * Reset the historical stats. Including all stats in icebox, and the tracked stats about
-     * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
-     * to collect stats after reset() has been called.
-     */
-    void reset();
-
-    /**
-     * Output the stats in protobuf binary format to [buffer].
-     *
-     * [reset]: whether to clear the historical stats after the call.
-     */
-    void dumpStats(std::vector<uint8_t>* buffer, bool reset);
-
-    /**
-     * Output statsd stats in human readable format to [out] file descriptor.
-     */
-    void dumpStats(int outFd) const;
-
-    typedef struct PullTimeoutMetadata {
-        int64_t pullTimeoutUptimeMillis;
-        int64_t pullTimeoutElapsedMillis;
-        PullTimeoutMetadata(int64_t uptimeMillis, int64_t elapsedMillis) :
-            pullTimeoutUptimeMillis(uptimeMillis),
-            pullTimeoutElapsedMillis(elapsedMillis) {/* do nothing */}
-    } PullTimeoutMetadata;
-
-    typedef struct {
-        long totalPull = 0;
-        long totalPullFromCache = 0;
-        long minPullIntervalSec = LONG_MAX;
-        int64_t avgPullTimeNs = 0;
-        int64_t maxPullTimeNs = 0;
-        long numPullTime = 0;
-        int64_t avgPullDelayNs = 0;
-        int64_t maxPullDelayNs = 0;
-        long numPullDelay = 0;
-        long dataError = 0;
-        long pullTimeout = 0;
-        long pullExceedMaxDelay = 0;
-        long pullFailed = 0;
-        long pullUidProviderNotFound = 0;
-        long pullerNotFound = 0;
-        long emptyData = 0;
-        long registeredCount = 0;
-        long unregisteredCount = 0;
-        int32_t atomErrorCount = 0;
-        long binderCallFailCount = 0;
-        std::list<PullTimeoutMetadata> pullTimeoutMetadata;
-    } PulledAtomStats;
-
-    typedef struct {
-        long hardDimensionLimitReached = 0;
-        long lateLogEventSkipped = 0;
-        long skippedForwardBuckets = 0;
-        long badValueType = 0;
-        long conditionChangeInNextBucket = 0;
-        long invalidatedBucket = 0;
-        long bucketDropped = 0;
-        int64_t minBucketBoundaryDelayNs = 0;
-        int64_t maxBucketBoundaryDelayNs = 0;
-        long bucketUnknownCondition = 0;
-        long bucketCount = 0;
-    } AtomMetricStats;
-
-private:
-    StatsdStats();
-
-    mutable std::mutex mLock;
-
-    int32_t mStartTimeSec;
-
-    // Track the number of dropped entries used by the uid map.
-    UidMapStats mUidMapStats;
-
-    // The stats about the configs that are still in use.
-    // The map size is capped by kMaxConfigCount.
-    std::map<const ConfigKey, std::shared_ptr<ConfigStats>> mConfigStats;
-
-    // Stores the stats for the configs that are no longer in use.
-    // The size of the vector is capped by kMaxIceBoxSize.
-    std::list<const std::shared_ptr<ConfigStats>> mIceBox;
-
-    // Stores the number of times a pushed atom is logged.
-    // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
-    // out of that range will be put in mNonPlatformPushedAtomStats.
-    // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
-    std::vector<int> mPushedAtomStats;
-
-    // Stores the number of times a pushed atom is logged for atom ids above kMaxPushedAtomId.
-    // The max size of the map is kMaxNonPlatformPushedAtoms.
-    std::unordered_map<int, int> mNonPlatformPushedAtomStats;
-
-    // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
-    std::map<int, PulledAtomStats> mPulledAtomStats;
-
-    // Stores the number of times a pushed atom was logged erroneously. The
-    // corresponding counts for pulled atoms are stored in PulledAtomStats.
-    // The max size of this map is kMaxAtomErrorsStatsSize.
-    std::map<int, int> mPushedAtomErrorStats;
-    int kMaxPushedAtomErrorStatsSize = 100;
-
-    // Maps metric ID to its stats. The size is capped by the number of metrics.
-    std::map<int64_t, AtomMetricStats> mAtomMetricStats;
-
-    // Maps uids to times when the activation changed broadcast not sent due to hitting the
-    // guardrail. The size is capped by the number of configs, and up to 20 times per uid.
-    std::map<int, std::list<int32_t>> mActivationBroadcastGuardrailStats;
-
-    struct LogLossStats {
-        LogLossStats(int32_t sec, int32_t count, int32_t error, int32_t tag, int32_t uid,
-                     int32_t pid)
-            : mWallClockSec(sec),
-              mCount(count),
-              mLastError(error),
-              mLastTag(tag),
-              mUid(uid),
-              mPid(pid) {
-        }
-        int32_t mWallClockSec;
-        int32_t mCount;
-        // error code defined in linux/errno.h
-        int32_t mLastError;
-        int32_t mLastTag;
-        int32_t mUid;
-        int32_t mPid;
-    };
-
-    // Max of {(now - oldestEventTimestamp) when overflow happens}.
-    // This number is helpful to understand how SLOW statsd can be.
-    int64_t mMaxQueueHistoryNs = 0;
-
-    // Min of {(now - oldestEventTimestamp) when overflow happens}.
-    // This number is helpful to understand how FAST the events floods to statsd.
-    int64_t mMinQueueHistoryNs = kInt64Max;
-
-    // Total number of events that are lost due to queue overflow.
-    int32_t mOverflowCount = 0;
-
-    // Timestamps when we detect log loss, and the number of logs lost.
-    std::list<LogLossStats> mLogLossStats;
-
-    std::list<int32_t> mSystemServerRestartSec;
-
-    // Stores the number of times statsd modified the anomaly alarm registered with
-    // StatsCompanionService.
-    int mAnomalyAlarmRegisteredStats = 0;
-
-    // Stores the number of times statsd registers the periodic alarm changes
-    int mPeriodicAlarmRegisteredStats = 0;
-
-    void noteConfigResetInternalLocked(const ConfigKey& key);
-
-    void noteConfigRemovedInternalLocked(const ConfigKey& key);
-
-    void resetInternalLocked();
-
-    void noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec);
-
-    void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes, int32_t timeSec);
-
-    void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
-
-    void noteActiveStatusChanged(const ConfigKey& key, bool activate, int32_t timeSec);
-
-    void noteActivationBroadcastGuardrailHit(const int uid, int32_t timeSec);
-
-    void addToIceBoxLocked(std::shared_ptr<ConfigStats>& stats);
-
-    int getPushedAtomErrors(int atomId) const;
-
-    /**
-     * Get a reference to AtomMetricStats for a metric. If none exists, create it. The reference
-     * will live as long as `this`.
-     */
-    StatsdStats::AtomMetricStats& getAtomMetricStats(int64_t metricId);
-
-    FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
-    FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
-    FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
-    FRIEND_TEST(StatsdStatsTest, TestSubStats);
-    FRIEND_TEST(StatsdStatsTest, TestAtomLog);
-    FRIEND_TEST(StatsdStatsTest, TestNonPlatformAtomLog);
-    FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
-    FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
-    FRIEND_TEST(StatsdStatsTest, TestSystemServerCrash);
-    FRIEND_TEST(StatsdStatsTest, TestPullAtomStats);
-    FRIEND_TEST(StatsdStatsTest, TestAtomMetricsStats);
-    FRIEND_TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit);
-    FRIEND_TEST(StatsdStatsTest, TestAtomErrorStats);
-
-    FRIEND_TEST(StatsLogProcessorTest, InvalidConfigRemoved);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/hash.cpp b/cmds/statsd/src/hash.cpp
deleted file mode 100644
index 543a748..0000000
--- a/cmds/statsd/src/hash.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "hash.h"
-
-#ifndef FALLTHROUGH_INTENDED
-#define FALLTHROUGH_INTENDED [[fallthrough]]
-#endif
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-// Lower-level versions of Get... that read directly from a character buffer
-// without any bounds checking.
-inline uint32_t DecodeFixed32(const char *ptr) {
-  return ((static_cast<uint32_t>(static_cast<unsigned char>(ptr[0]))) |
-          (static_cast<uint32_t>(static_cast<unsigned char>(ptr[1])) << 8) |
-          (static_cast<uint32_t>(static_cast<unsigned char>(ptr[2])) << 16) |
-          (static_cast<uint32_t>(static_cast<unsigned char>(ptr[3])) << 24));
-}
-
-inline uint64_t DecodeFixed64(const char* ptr) {
-    uint64_t lo = DecodeFixed32(ptr);
-    uint64_t hi = DecodeFixed32(ptr + 4);
-    return (hi << 32) | lo;
-}
-
-// 0xff is in case char is signed.
-static inline uint32_t ByteAs32(char c) { return static_cast<uint32_t>(c) & 0xff; }
-static inline uint64_t ByteAs64(char c) { return static_cast<uint64_t>(c) & 0xff; }
-
-}  // namespace
-
-uint32_t Hash32(const char *data, size_t n, uint32_t seed) {
-  // 'm' and 'r' are mixing constants generated offline.
-  // They're not really 'magic', they just happen to work well.
-  const uint32_t m = 0x5bd1e995;
-  const int r = 24;
-
-  // Initialize the hash to a 'random' value
-  uint32_t h = static_cast<uint32_t>(seed ^ n);
-
-  // Mix 4 bytes at a time into the hash
-  while (n >= 4) {
-    uint32_t k = DecodeFixed32(data);
-    k *= m;
-    k ^= k >> r;
-    k *= m;
-    h *= m;
-    h ^= k;
-    data += 4;
-    n -= 4;
-  }
-
-  // Handle the last few bytes of the input array
-  switch (n) {
-    case 3:
-      h ^= ByteAs32(data[2]) << 16;
-      FALLTHROUGH_INTENDED;
-    case 2:
-      h ^= ByteAs32(data[1]) << 8;
-      FALLTHROUGH_INTENDED;
-    case 1:
-      h ^= ByteAs32(data[0]);
-      h *= m;
-  }
-
-  // Do a few final mixes of the hash to ensure the last few
-  // bytes are well-incorporated.
-  h ^= h >> 13;
-  h *= m;
-  h ^= h >> 15;
-  return h;
-}
-
-uint64_t Hash64(const char* data, size_t n, uint64_t seed) {
-  const uint64_t m = 0xc6a4a7935bd1e995;
-  const int r = 47;
-
-  uint64_t h = seed ^ (n * m);
-
-  while (n >= 8) {
-    uint64_t k = DecodeFixed64(data);
-    data += 8;
-    n -= 8;
-
-    k *= m;
-    k ^= k >> r;
-    k *= m;
-
-    h ^= k;
-    h *= m;
-  }
-
-  switch (n) {
-    case 7:
-      h ^= ByteAs64(data[6]) << 48;
-      FALLTHROUGH_INTENDED;
-    case 6:
-      h ^= ByteAs64(data[5]) << 40;
-      FALLTHROUGH_INTENDED;
-    case 5:
-      h ^= ByteAs64(data[4]) << 32;
-      FALLTHROUGH_INTENDED;
-    case 4:
-      h ^= ByteAs64(data[3]) << 24;
-      FALLTHROUGH_INTENDED;
-    case 3:
-      h ^= ByteAs64(data[2]) << 16;
-      FALLTHROUGH_INTENDED;
-    case 2:
-      h ^= ByteAs64(data[1]) << 8;
-      FALLTHROUGH_INTENDED;
-    case 1:
-      h ^= ByteAs64(data[0]);
-      h *= m;
-  }
-
-  h ^= h >> r;
-  h *= m;
-  h ^= h >> r;
-
-  return h;
-}
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/hash.h b/cmds/statsd/src/hash.h
deleted file mode 100644
index bd6b0cd..0000000
--- a/cmds/statsd/src/hash.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Uses murmur2 hashing algorithm.
-extern uint32_t Hash32(const char *data, size_t n, uint32_t seed);
-extern uint64_t Hash64(const char* data, size_t n, uint64_t seed);
-
-inline uint32_t Hash32(const char *data, size_t n) {
-  return Hash32(data, n, 0xBEEF);
-}
-
-inline uint32_t Hash32(const std::string &input) {
-  return Hash32(input.data(), input.size());
-}
-
-inline uint64_t Hash64(const char* data, size_t n) {
-  return Hash64(data, n, 0xDECAFCAFFE);
-}
-
-inline uint64_t Hash64(const std::string& str) {
-  return Hash64(str.data(), str.size());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
deleted file mode 100644
index f56fa62..0000000
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "logd/LogEvent.h"
-
-#include <android-base/stringprintf.h>
-#include <android/binder_ibinder.h>
-#include <private/android_filesystem_config.h>
-
-#include "annotations.h"
-#include "stats_log_util.h"
-#include "statslog_statsd.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for TrainInfo experiment id serialization
-const int FIELD_ID_EXPERIMENT_ID = 1;
-
-using namespace android::util;
-using android::base::StringPrintf;
-using android::util::ProtoOutputStream;
-using std::string;
-using std::vector;
-
-// stats_event.h socket types. Keep in sync.
-/* ERRORS */
-#define ERROR_NO_TIMESTAMP 0x1
-#define ERROR_NO_ATOM_ID 0x2
-#define ERROR_OVERFLOW 0x4
-#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
-#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
-#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
-#define ERROR_INVALID_ANNOTATION_ID 0x40
-#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
-#define ERROR_TOO_MANY_ANNOTATIONS 0x100
-#define ERROR_TOO_MANY_FIELDS 0x200
-#define ERROR_INVALID_VALUE_TYPE 0x400
-#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
-
-/* TYPE IDS */
-#define INT32_TYPE 0x00
-#define INT64_TYPE 0x01
-#define STRING_TYPE 0x02
-#define LIST_TYPE 0x03
-#define FLOAT_TYPE 0x04
-#define BOOL_TYPE 0x05
-#define BYTE_ARRAY_TYPE 0x06
-#define OBJECT_TYPE 0x07
-#define KEY_VALUE_PAIRS_TYPE 0x08
-#define ATTRIBUTION_CHAIN_TYPE 0x09
-#define ERROR_TYPE 0x0F
-
-LogEvent::LogEvent(int32_t uid, int32_t pid)
-    : mLogdTimestampNs(time(nullptr)), mLogUid(uid), mLogPid(pid) {
-}
-
-LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requiresStaging,
-                   bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state,
-                   const std::vector<uint8_t>& experimentIds, int32_t userId) {
-    mLogdTimestampNs = getWallClockNs();
-    mElapsedTimestampNs = getElapsedRealtimeNs();
-    mTagId = util::BINARY_PUSH_STATE_CHANGED;
-    mLogUid = AIBinder_getCallingUid();
-    mLogPid = AIBinder_getCallingPid();
-
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(1)), Value(trainName)));
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainVersionCode)));
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value((int)requiresStaging)));
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value((int)rollbackEnabled)));
-    mValues.push_back(
-            FieldValue(Field(mTagId, getSimpleField(5)), Value((int)requiresLowLatencyMonitor)));
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(6)), Value(state)));
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(7)), Value(experimentIds)));
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(8)), Value(userId)));
-}
-
-LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
-                   const InstallTrainInfo& trainInfo) {
-    mLogdTimestampNs = wallClockTimestampNs;
-    mElapsedTimestampNs = elapsedTimestampNs;
-    mTagId = util::TRAIN_INFO;
-
-    mValues.push_back(
-            FieldValue(Field(mTagId, getSimpleField(1)), Value(trainInfo.trainVersionCode)));
-    std::vector<uint8_t> experimentIdsProto;
-    writeExperimentIdsToProto(trainInfo.experimentIds, &experimentIdsProto);
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(experimentIdsProto)));
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value(trainInfo.trainName)));
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value(trainInfo.status)));
-}
-
-void LogEvent::parseInt32(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
-    int32_t value = readNextValue<int32_t>();
-    addToValues(pos, depth, value, last);
-    parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseInt64(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
-    int64_t value = readNextValue<int64_t>();
-    addToValues(pos, depth, value, last);
-    parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseString(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
-    int32_t numBytes = readNextValue<int32_t>();
-    if ((uint32_t)numBytes > mRemainingLen) {
-        mValid = false;
-        return;
-    }
-
-    string value = string((char*)mBuf, numBytes);
-    mBuf += numBytes;
-    mRemainingLen -= numBytes;
-    addToValues(pos, depth, value, last);
-    parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseFloat(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
-    float value = readNextValue<float>();
-    addToValues(pos, depth, value, last);
-    parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseBool(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
-    // cast to int32_t because FieldValue does not support bools
-    int32_t value = (int32_t)readNextValue<uint8_t>();
-    addToValues(pos, depth, value, last);
-    parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseByteArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
-    int32_t numBytes = readNextValue<int32_t>();
-    if ((uint32_t)numBytes > mRemainingLen) {
-        mValid = false;
-        return;
-    }
-
-    vector<uint8_t> value(mBuf, mBuf + numBytes);
-    mBuf += numBytes;
-    mRemainingLen -= numBytes;
-    addToValues(pos, depth, value, last);
-    parseAnnotations(numAnnotations);
-}
-
-void LogEvent::parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
-    int32_t numPairs = readNextValue<uint8_t>();
-
-    for (pos[1] = 1; pos[1] <= numPairs; pos[1]++) {
-        last[1] = (pos[1] == numPairs);
-
-        // parse key
-        pos[2] = 1;
-        parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-
-        // parse value
-        last[2] = true;
-
-        uint8_t typeInfo = readNextValue<uint8_t>();
-        switch (getTypeId(typeInfo)) {
-            case INT32_TYPE:
-                pos[2] = 2;  // pos[2] determined by index of type in KeyValuePair in atoms.proto
-                parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-                break;
-            case INT64_TYPE:
-                pos[2] = 3;
-                parseInt64(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-                break;
-            case STRING_TYPE:
-                pos[2] = 4;
-                parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-                break;
-            case FLOAT_TYPE:
-                pos[2] = 5;
-                parseFloat(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-                break;
-            default:
-                mValid = false;
-        }
-    }
-
-    parseAnnotations(numAnnotations);
-
-    pos[1] = pos[2] = 1;
-    last[1] = last[2] = false;
-}
-
-void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last,
-                                     uint8_t numAnnotations) {
-    const unsigned int firstUidInChainIndex = mValues.size();
-    const int32_t numNodes = readNextValue<uint8_t>();
-    for (pos[1] = 1; pos[1] <= numNodes; pos[1]++) {
-        last[1] = (pos[1] == numNodes);
-
-        // parse uid
-        pos[2] = 1;
-        parseInt32(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-
-        // parse tag
-        pos[2] = 2;
-        last[2] = true;
-        parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
-    }
-    // Check if at least one node was successfully parsed.
-    if (mValues.size() - 1 > firstUidInChainIndex) {
-        mAttributionChainStartIndex = static_cast<int8_t>(firstUidInChainIndex);
-        mAttributionChainEndIndex = static_cast<int8_t>(mValues.size() - 1);
-    }
-
-    parseAnnotations(numAnnotations, firstUidInChainIndex);
-
-    pos[1] = pos[2] = 1;
-    last[1] = last[2] = false;
-}
-
-// Assumes that mValues is not empty
-bool LogEvent::checkPreviousValueType(Type expected) {
-    return mValues[mValues.size() - 1].mValue.getType() == expected;
-}
-
-void LogEvent::parseIsUidAnnotation(uint8_t annotationType) {
-    if (mValues.empty() || !checkPreviousValueType(INT) || annotationType != BOOL_TYPE) {
-        mValid = false;
-        return;
-    }
-
-    bool isUid = readNextValue<uint8_t>();
-    if (isUid) mUidFieldIndex = static_cast<int8_t>(mValues.size() - 1);
-    mValues[mValues.size() - 1].mAnnotations.setUidField(isUid);
-}
-
-void LogEvent::parseTruncateTimestampAnnotation(uint8_t annotationType) {
-    if (!mValues.empty() || annotationType != BOOL_TYPE) {
-        mValid = false;
-        return;
-    }
-
-    mTruncateTimestamp = readNextValue<uint8_t>();
-}
-
-void LogEvent::parsePrimaryFieldAnnotation(uint8_t annotationType) {
-    if (mValues.empty() || annotationType != BOOL_TYPE) {
-        mValid = false;
-        return;
-    }
-
-    const bool primaryField = readNextValue<uint8_t>();
-    mValues[mValues.size() - 1].mAnnotations.setPrimaryField(primaryField);
-}
-
-void LogEvent::parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType,
-                                                   int firstUidInChainIndex) {
-    if (mValues.empty() || annotationType != BOOL_TYPE || -1 == firstUidInChainIndex) {
-        mValid = false;
-        return;
-    }
-
-    const bool primaryField = readNextValue<uint8_t>();
-    mValues[firstUidInChainIndex].mAnnotations.setPrimaryField(primaryField);
-}
-
-void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType) {
-    if (mValues.empty() || annotationType != BOOL_TYPE) {
-        mValid = false;
-        return;
-    }
-
-    const bool exclusiveState = readNextValue<uint8_t>();
-    mExclusiveStateFieldIndex = static_cast<int8_t>(mValues.size() - 1);
-    mValues[getExclusiveStateFieldIndex()].mAnnotations.setExclusiveState(exclusiveState);
-}
-
-void LogEvent::parseTriggerStateResetAnnotation(uint8_t annotationType) {
-    if (mValues.empty() || annotationType != INT32_TYPE) {
-        mValid = false;
-        return;
-    }
-
-    mResetState = readNextValue<int32_t>();
-}
-
-void LogEvent::parseStateNestedAnnotation(uint8_t annotationType) {
-    if (mValues.empty() || annotationType != BOOL_TYPE) {
-        mValid = false;
-        return;
-    }
-
-    bool nested = readNextValue<uint8_t>();
-    mValues[mValues.size() - 1].mAnnotations.setNested(nested);
-}
-
-// firstUidInChainIndex is a default parameter that is only needed when parsing
-// annotations for attribution chains.
-void LogEvent::parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex) {
-    for (uint8_t i = 0; i < numAnnotations; i++) {
-        uint8_t annotationId = readNextValue<uint8_t>();
-        uint8_t annotationType = readNextValue<uint8_t>();
-
-        switch (annotationId) {
-            case ANNOTATION_ID_IS_UID:
-                parseIsUidAnnotation(annotationType);
-                break;
-            case ANNOTATION_ID_TRUNCATE_TIMESTAMP:
-                parseTruncateTimestampAnnotation(annotationType);
-                break;
-            case ANNOTATION_ID_PRIMARY_FIELD:
-                parsePrimaryFieldAnnotation(annotationType);
-                break;
-            case ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID:
-                parsePrimaryFieldFirstUidAnnotation(annotationType, firstUidInChainIndex);
-                break;
-            case ANNOTATION_ID_EXCLUSIVE_STATE:
-                parseExclusiveStateAnnotation(annotationType);
-                break;
-            case ANNOTATION_ID_TRIGGER_STATE_RESET:
-                parseTriggerStateResetAnnotation(annotationType);
-                break;
-            case ANNOTATION_ID_STATE_NESTED:
-                parseStateNestedAnnotation(annotationType);
-                break;
-            default:
-                mValid = false;
-                return;
-        }
-    }
-}
-
-// This parsing logic is tied to the encoding scheme used in StatsEvent.java and
-// stats_event.c
-bool LogEvent::parseBuffer(uint8_t* buf, size_t len) {
-    mBuf = buf;
-    mRemainingLen = (uint32_t)len;
-
-    int32_t pos[] = {1, 1, 1};
-    bool last[] = {false, false, false};
-
-    // Beginning of buffer is OBJECT_TYPE | NUM_FIELDS | TIMESTAMP | ATOM_ID
-    uint8_t typeInfo = readNextValue<uint8_t>();
-    if (getTypeId(typeInfo) != OBJECT_TYPE) mValid = false;
-
-    uint8_t numElements = readNextValue<uint8_t>();
-    if (numElements < 2 || numElements > 127) mValid = false;
-
-    typeInfo = readNextValue<uint8_t>();
-    if (getTypeId(typeInfo) != INT64_TYPE) mValid = false;
-    mElapsedTimestampNs = readNextValue<int64_t>();
-    numElements--;
-
-    typeInfo = readNextValue<uint8_t>();
-    if (getTypeId(typeInfo) != INT32_TYPE) mValid = false;
-    mTagId = readNextValue<int32_t>();
-    numElements--;
-    parseAnnotations(getNumAnnotations(typeInfo));  // atom-level annotations
-
-    for (pos[0] = 1; pos[0] <= numElements && mValid; pos[0]++) {
-        last[0] = (pos[0] == numElements);
-
-        typeInfo = readNextValue<uint8_t>();
-        uint8_t typeId = getTypeId(typeInfo);
-
-        switch (typeId) {
-            case BOOL_TYPE:
-                parseBool(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
-                break;
-            case INT32_TYPE:
-                parseInt32(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
-                break;
-            case INT64_TYPE:
-                parseInt64(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
-                break;
-            case FLOAT_TYPE:
-                parseFloat(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
-                break;
-            case BYTE_ARRAY_TYPE:
-                parseByteArray(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
-                break;
-            case STRING_TYPE:
-                parseString(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
-                break;
-            case KEY_VALUE_PAIRS_TYPE:
-                parseKeyValuePairs(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
-                break;
-            case ATTRIBUTION_CHAIN_TYPE:
-                parseAttributionChain(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
-                break;
-            case ERROR_TYPE:
-                /* mErrorBitmask =*/ readNextValue<int32_t>();
-                mValid = false;
-                break;
-            default:
-                mValid = false;
-                break;
-        }
-    }
-
-    if (mRemainingLen != 0) mValid = false;
-    mBuf = nullptr;
-    return mValid;
-}
-
-uint8_t LogEvent::getTypeId(uint8_t typeInfo) {
-    return typeInfo & 0x0F;  // type id in lower 4 bytes
-}
-
-uint8_t LogEvent::getNumAnnotations(uint8_t typeInfo) {
-    return (typeInfo >> 4) & 0x0F;  // num annotations in upper 4 bytes
-}
-
-int64_t LogEvent::GetLong(size_t key, status_t* err) const {
-    // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
-    int field = getSimpleField(key);
-    for (const auto& value : mValues) {
-        if (value.mField.getField() == field) {
-            if (value.mValue.getType() == LONG) {
-                return value.mValue.long_value;
-            } else if (value.mValue.getType() == INT) {
-                return value.mValue.int_value;
-            } else {
-                *err = BAD_TYPE;
-                return 0;
-            }
-        }
-        if ((size_t)value.mField.getPosAtDepth(0) > key) {
-            break;
-        }
-    }
-
-    *err = BAD_INDEX;
-    return 0;
-}
-
-int LogEvent::GetInt(size_t key, status_t* err) const {
-    int field = getSimpleField(key);
-    for (const auto& value : mValues) {
-        if (value.mField.getField() == field) {
-            if (value.mValue.getType() == INT) {
-                return value.mValue.int_value;
-            } else {
-                *err = BAD_TYPE;
-                return 0;
-            }
-        }
-        if ((size_t)value.mField.getPosAtDepth(0) > key) {
-            break;
-        }
-    }
-
-    *err = BAD_INDEX;
-    return 0;
-}
-
-const char* LogEvent::GetString(size_t key, status_t* err) const {
-    int field = getSimpleField(key);
-    for (const auto& value : mValues) {
-        if (value.mField.getField() == field) {
-            if (value.mValue.getType() == STRING) {
-                return value.mValue.str_value.c_str();
-            } else {
-                *err = BAD_TYPE;
-                return 0;
-            }
-        }
-        if ((size_t)value.mField.getPosAtDepth(0) > key) {
-            break;
-        }
-    }
-
-    *err = BAD_INDEX;
-    return NULL;
-}
-
-bool LogEvent::GetBool(size_t key, status_t* err) const {
-    int field = getSimpleField(key);
-    for (const auto& value : mValues) {
-        if (value.mField.getField() == field) {
-            if (value.mValue.getType() == INT) {
-                return value.mValue.int_value != 0;
-            } else if (value.mValue.getType() == LONG) {
-                return value.mValue.long_value != 0;
-            } else {
-                *err = BAD_TYPE;
-                return false;
-            }
-        }
-        if ((size_t)value.mField.getPosAtDepth(0) > key) {
-            break;
-        }
-    }
-
-    *err = BAD_INDEX;
-    return false;
-}
-
-float LogEvent::GetFloat(size_t key, status_t* err) const {
-    int field = getSimpleField(key);
-    for (const auto& value : mValues) {
-        if (value.mField.getField() == field) {
-            if (value.mValue.getType() == FLOAT) {
-                return value.mValue.float_value;
-            } else {
-                *err = BAD_TYPE;
-                return 0.0;
-            }
-        }
-        if ((size_t)value.mField.getPosAtDepth(0) > key) {
-            break;
-        }
-    }
-
-    *err = BAD_INDEX;
-    return 0.0;
-}
-
-std::vector<uint8_t> LogEvent::GetStorage(size_t key, status_t* err) const {
-    int field = getSimpleField(key);
-    for (const auto& value : mValues) {
-        if (value.mField.getField() == field) {
-            if (value.mValue.getType() == STORAGE) {
-                return value.mValue.storage_value;
-            } else {
-                *err = BAD_TYPE;
-                return vector<uint8_t>();
-            }
-        }
-        if ((size_t)value.mField.getPosAtDepth(0) > key) {
-            break;
-        }
-    }
-
-    *err = BAD_INDEX;
-    return vector<uint8_t>();
-}
-
-string LogEvent::ToString() const {
-    string result;
-    result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs,
-                           (long long)mElapsedTimestampNs, mTagId);
-    for (const auto& value : mValues) {
-        result +=
-                StringPrintf("%#x", value.mField.getField()) + "->" + value.mValue.toString() + " ";
-    }
-    result += " }";
-    return result;
-}
-
-void LogEvent::ToProto(ProtoOutputStream& protoOutput) const {
-    writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
-}
-
-bool LogEvent::hasAttributionChain(std::pair<int, int>* indexRange) const {
-    if (mAttributionChainStartIndex == -1 || mAttributionChainEndIndex == -1) {
-        return false;
-    }
-
-    if (nullptr != indexRange) {
-        indexRange->first = static_cast<int>(mAttributionChainStartIndex);
-        indexRange->second = static_cast<int>(mAttributionChainEndIndex);
-    }
-
-    return true;
-}
-
-void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds,
-                               std::vector<uint8_t>* protoOut) {
-    ProtoOutputStream proto;
-    for (const auto& expId : experimentIds) {
-        proto.write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_EXPERIMENT_ID,
-                    (long long)expId);
-    }
-
-    protoOut->resize(proto.size());
-    size_t pos = 0;
-    sp<ProtoReader> reader = proto.data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(protoOut->data() + pos, reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
deleted file mode 100644
index a5f2460..0000000
--- a/cmds/statsd/src/logd/LogEvent.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "FieldValue.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include <private/android_logger.h>
-
-#include <string>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct InstallTrainInfo {
-    int64_t trainVersionCode;
-    std::string trainName;
-    int32_t status;
-    std::vector<int64_t> experimentIds;
-    bool requiresStaging;
-    bool rollbackEnabled;
-    bool requiresLowLatencyMonitor;
-};
-
-/**
- * This class decodes the structured, serialized encoding of an atom into a
- * vector of FieldValues.
- */
-class LogEvent {
-public:
-    /**
-     * \param uid user id of the logging caller
-     * \param pid process id of the logging caller
-     */
-    explicit LogEvent(int32_t uid, int32_t pid);
-
-    /**
-     * Parses the atomId, timestamp, and vector of values from a buffer
-     * containing the StatsEvent/AStatsEvent encoding of an atom.
-     *
-     * \param buf a buffer that begins at the start of the serialized atom (it
-     * should not include the android_log_header_t or the StatsEventTag)
-     * \param len size of the buffer
-     *
-     * \return success of the initialization
-     */
-    bool parseBuffer(uint8_t* buf, size_t len);
-
-    // Constructs a BinaryPushStateChanged LogEvent from API call.
-    explicit LogEvent(const std::string& trainName, int64_t trainVersionCode, bool requiresStaging,
-                      bool rollbackEnabled, bool requiresLowLatencyMonitor, int32_t state,
-                      const std::vector<uint8_t>& experimentIds, int32_t userId);
-
-    explicit LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
-                      const InstallTrainInfo& installTrainInfo);
-
-    ~LogEvent() {}
-
-    /**
-     * Get the timestamp associated with this event.
-     */
-    inline int64_t GetLogdTimestampNs() const { return mLogdTimestampNs; }
-    inline int64_t GetElapsedTimestampNs() const { return mElapsedTimestampNs; }
-
-    /**
-     * Get the tag for this event.
-     */
-    inline int GetTagId() const { return mTagId; }
-
-    /**
-     * Get the uid of the logging client.
-     * Returns -1 if the uid is unknown/has not been set.
-     */
-    inline int32_t GetUid() const { return mLogUid; }
-
-    /**
-     * Get the pid of the logging client.
-     * Returns -1 if the pid is unknown/has not been set.
-     */
-    inline int32_t GetPid() const { return mLogPid; }
-
-    /**
-     * Get the nth value, starting at 1.
-     *
-     * Returns BAD_INDEX if the index is larger than the number of elements.
-     * Returns BAD_TYPE if the index is available but the data is the wrong type.
-     */
-    int64_t GetLong(size_t key, status_t* err) const;
-    int GetInt(size_t key, status_t* err) const;
-    const char* GetString(size_t key, status_t* err) const;
-    bool GetBool(size_t key, status_t* err) const;
-    float GetFloat(size_t key, status_t* err) const;
-    std::vector<uint8_t> GetStorage(size_t key, status_t* err) const;
-
-    /**
-     * Return a string representation of this event.
-     */
-    std::string ToString() const;
-
-    /**
-     * Write this object to a ProtoOutputStream.
-     */
-    void ToProto(android::util::ProtoOutputStream& out) const;
-
-    /**
-     * Set elapsed timestamp if the original timestamp is missing.
-     */
-    void setElapsedTimestampNs(int64_t timestampNs) {
-        mElapsedTimestampNs = timestampNs;
-    }
-
-    /**
-     * Set the timestamp if the original logd timestamp is missing.
-     */
-    void setLogdWallClockTimestampNs(int64_t timestampNs) {
-        mLogdTimestampNs = timestampNs;
-    }
-
-    inline int size() const {
-        return mValues.size();
-    }
-
-    const std::vector<FieldValue>& getValues() const {
-        return mValues;
-    }
-
-    std::vector<FieldValue>* getMutableValues() {
-        return &mValues;
-    }
-
-    // Default value = false
-    inline bool shouldTruncateTimestamp() const {
-        return mTruncateTimestamp;
-    }
-
-    // Returns the index of the uid field within the FieldValues vector if the
-    // uid exists. If there is no uid field, returns -1.
-    //
-    // If the index within the atom definition is desired, do the following:
-    //    int vectorIndex = LogEvent.getUidFieldIndex();
-    //    if (vectorIndex != -1) {
-    //        FieldValue& v = LogEvent.getValues()[vectorIndex];
-    //        int atomIndex = v.mField.getPosAtDepth(0);
-    //    }
-    // Note that atomIndex is 1-indexed.
-    inline int getUidFieldIndex() {
-        return static_cast<int>(mUidFieldIndex);
-    }
-
-    // Returns whether this LogEvent has an AttributionChain.
-    // If it does and indexRange is not a nullptr, populate indexRange with the start and end index
-    // of the AttributionChain within mValues.
-    bool hasAttributionChain(std::pair<int, int>* indexRange = nullptr) const;
-
-    // Returns the index of the exclusive state field within the FieldValues vector if
-    // an exclusive state exists. If there is no exclusive state field, returns -1.
-    //
-    // If the index within the atom definition is desired, do the following:
-    //    int vectorIndex = LogEvent.getExclusiveStateFieldIndex();
-    //    if (vectorIndex != -1) {
-    //        FieldValue& v = LogEvent.getValues()[vectorIndex];
-    //        int atomIndex = v.mField.getPosAtDepth(0);
-    //    }
-    // Note that atomIndex is 1-indexed.
-    inline int getExclusiveStateFieldIndex() const {
-        return static_cast<int>(mExclusiveStateFieldIndex);
-    }
-
-    // If a reset state is not sent in the StatsEvent, returns -1. Note that a
-    // reset state is sent if and only if a reset should be triggered.
-    inline int getResetState() const {
-        return mResetState;
-    }
-
-    inline LogEvent makeCopy() {
-        return LogEvent(*this);
-    }
-
-    template <class T>
-    status_t updateValue(size_t key, T& value, Type type) {
-        int field = getSimpleField(key);
-        for (auto& fieldValue : mValues) {
-            if (fieldValue.mField.getField() == field) {
-                if (fieldValue.mValue.getType() == type) {
-                    fieldValue.mValue = Value(value);
-                   return OK;
-               } else {
-                   return BAD_TYPE;
-                }
-            }
-        }
-        return BAD_INDEX;
-    }
-
-    bool isValid() const {
-        return mValid;
-    }
-
-private:
-    /**
-     * Only use this if copy is absolutely needed.
-     */
-    LogEvent(const LogEvent&) = default;
-
-    void parseInt32(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-    void parseInt64(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-    void parseString(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-    void parseFloat(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-    void parseBool(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-    void parseByteArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-    void parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-    void parseAttributionChain(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-
-    void parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex = -1);
-    void parseIsUidAnnotation(uint8_t annotationType);
-    void parseTruncateTimestampAnnotation(uint8_t annotationType);
-    void parsePrimaryFieldAnnotation(uint8_t annotationType);
-    void parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType, int firstUidInChainIndex);
-    void parseExclusiveStateAnnotation(uint8_t annotationType);
-    void parseTriggerStateResetAnnotation(uint8_t annotationType);
-    void parseStateNestedAnnotation(uint8_t annotationType);
-    bool checkPreviousValueType(Type expected);
-
-    /**
-     * The below two variables are only valid during the execution of
-     * parseBuffer. There are no guarantees about the state of these variables
-     * before/after.
-     */
-    uint8_t* mBuf;
-    uint32_t mRemainingLen; // number of valid bytes left in the buffer being parsed
-
-    bool mValid = true; // stores whether the event we received from the socket is valid
-
-    /**
-     * Side-effects:
-     *    If there is enough space in buffer to read value of type T
-     *        - move mBuf past the value that was just read
-     *        - decrement mRemainingLen by size of T
-     *    Else
-     *        - set mValid to false
-     */
-    template <class T>
-    T readNextValue() {
-        T value;
-        if (mRemainingLen < sizeof(T)) {
-            mValid = false;
-            value = 0; // all primitive types can successfully cast 0
-        } else {
-            // When alignof(T) == 1, hopefully the compiler can optimize away
-            // this conditional as always true.
-            if ((reinterpret_cast<uintptr_t>(mBuf) % alignof(T)) == 0) {
-                // We're properly aligned, and can safely make this assignment.
-                value = *((T*)mBuf);
-            } else {
-                // We need to use memcpy.  It's slower, but safe.
-                memcpy(&value, mBuf, sizeof(T));
-            }
-            mBuf += sizeof(T);
-            mRemainingLen -= sizeof(T);
-        }
-        return value;
-    }
-
-    template <class T>
-    void addToValues(int32_t* pos, int32_t depth, T& value, bool* last) {
-        Field f = Field(mTagId, pos, depth);
-        // do not decorate last position at depth 0
-        for (int i = 1; i < depth; i++) {
-            if (last[i]) f.decorateLastPos(i);
-        }
-
-        Value v = Value(value);
-        mValues.push_back(FieldValue(f, v));
-    }
-
-    uint8_t getTypeId(uint8_t typeInfo);
-    uint8_t getNumAnnotations(uint8_t typeInfo);
-
-    // The items are naturally sorted in DFS order as we read them. this allows us to do fast
-    // matching.
-    std::vector<FieldValue> mValues;
-
-    // The timestamp set by the logd.
-    int64_t mLogdTimestampNs;
-
-    // The elapsed timestamp set by statsd log writer.
-    int64_t mElapsedTimestampNs;
-
-    // The atom tag of the event (defaults to 0 if client does not
-    // appropriately set the atom id).
-    int mTagId = 0;
-
-    // The uid of the logging client (defaults to -1).
-    int32_t mLogUid = -1;
-
-    // The pid of the logging client (defaults to -1).
-    int32_t mLogPid = -1;
-
-    // Annotations
-    bool mTruncateTimestamp = false;
-    int mResetState = -1;
-
-    // Indexes within the FieldValue vector can be stored in 7 bits because
-    // that's the assumption enforced by the encoding used in FieldValue.
-    int8_t mUidFieldIndex = -1;
-    int8_t mAttributionChainStartIndex = -1;
-    int8_t mAttributionChainEndIndex = -1;
-    int8_t mExclusiveStateFieldIndex = -1;
-};
-
-void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/logd/LogEventQueue.cpp b/cmds/statsd/src/logd/LogEventQueue.cpp
deleted file mode 100644
index 146464b..0000000
--- a/cmds/statsd/src/logd/LogEventQueue.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "LogEventQueue.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unique_lock;
-using std::unique_ptr;
-
-unique_ptr<LogEvent> LogEventQueue::waitPop() {
-    std::unique_lock<std::mutex> lock(mMutex);
-
-    if (mQueue.empty()) {
-        mCondition.wait(lock, [this] { return !this->mQueue.empty(); });
-    }
-
-    unique_ptr<LogEvent> item = std::move(mQueue.front());
-    mQueue.pop();
-
-    return item;
-}
-
-bool LogEventQueue::push(unique_ptr<LogEvent> item, int64_t* oldestTimestampNs) {
-    bool success;
-    {
-        std::unique_lock<std::mutex> lock(mMutex);
-        if (mQueue.size() < mQueueLimit) {
-            mQueue.push(std::move(item));
-            success = true;
-        } else {
-            // safe operation as queue must not be empty.
-            *oldestTimestampNs = mQueue.front()->GetElapsedTimestampNs();
-            success = false;
-        }
-    }
-
-    mCondition.notify_one();
-    return success;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/logd/LogEventQueue.h b/cmds/statsd/src/logd/LogEventQueue.h
deleted file mode 100644
index 9dda3d2..0000000
--- a/cmds/statsd/src/logd/LogEventQueue.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#pragma once
-
-#include "LogEvent.h"
-
-#include <condition_variable>
-#include <mutex>
-#include <queue>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * A zero copy thread safe queue buffer for producing and consuming LogEvent.
- */
-class LogEventQueue {
-public:
-    explicit LogEventQueue(size_t maxSize) : mQueueLimit(maxSize){};
-
-    /**
-     * Blocking read one event from the queue.
-     */
-    std::unique_ptr<LogEvent> waitPop();
-
-    /**
-     * Puts a LogEvent ptr to the end of the queue.
-     * Returns false on failure when the queue is full, and output the oldest event timestamp
-     * in the queue.
-     */
-    bool push(std::unique_ptr<LogEvent> event, int64_t* oldestTimestampNs);
-
-private:
-    const size_t mQueueLimit;
-    std::condition_variable mCondition;
-    std::mutex mMutex;
-    std::queue<std::unique_ptr<LogEvent>> mQueue;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
deleted file mode 100644
index 03b178a..0000000
--- a/cmds/statsd/src/main.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsService.h"
-#include "socket/StatsSocketListener.h"
-
-#include <android/binder_interface_utils.h>
-#include <android/binder_process.h>
-#include <android/binder_manager.h>
-#include <utils/Looper.h>
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-using namespace android;
-using namespace android::os::statsd;
-using ::ndk::SharedRefBase;
-using std::shared_ptr;
-using std::make_shared;
-
-shared_ptr<StatsService> gStatsService = nullptr;
-sp<StatsSocketListener> gSocketListener = nullptr;
-
-void signalHandler(int sig) {
-    if (sig == SIGPIPE) {
-        // ShellSubscriber uses SIGPIPE as a signal to detect the end of the
-        // client process. Don't prematurely exit(1) here. Instead, ignore the
-        // signal and allow the write call to return EPIPE.
-        ALOGI("statsd received SIGPIPE. Ignoring signal.");
-        return;
-    }
-
-    if (gSocketListener != nullptr) gSocketListener->stopListener();
-    if (gStatsService != nullptr) gStatsService->Terminate();
-    ALOGW("statsd terminated on receiving signal %d.", sig);
-    exit(1);
-}
-
-void registerSignalHandlers()
-{
-    struct sigaction sa;
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = 0;
-    sa.sa_handler = signalHandler;
-    sigaction(SIGPIPE, &sa, nullptr);
-    sigaction(SIGHUP, &sa, nullptr);
-    sigaction(SIGINT, &sa, nullptr);
-    sigaction(SIGQUIT, &sa, nullptr);
-    sigaction(SIGTERM, &sa, nullptr);
-}
-
-int main(int /*argc*/, char** /*argv*/) {
-    // Set up the looper
-    sp<Looper> looper(Looper::prepare(0 /* opts */));
-
-    // Set up the binder
-    ABinderProcess_setThreadPoolMaxThreadCount(9);
-    ABinderProcess_startThreadPool();
-
-    std::shared_ptr<LogEventQueue> eventQueue =
-            std::make_shared<LogEventQueue>(4000 /*buffer limit. Buffer is NOT pre-allocated*/);
-
-    // Create the service
-    gStatsService = SharedRefBase::make<StatsService>(looper, eventQueue);
-    // TODO(b/149582373): Set DUMP_FLAG_PROTO once libbinder_ndk supports
-    // setting dumpsys priorities.
-    binder_status_t status = AServiceManager_addService(gStatsService->asBinder().get(), "stats");
-    if (status != STATUS_OK) {
-        ALOGE("Failed to add service as AIDL service");
-        return -1;
-    }
-
-    registerSignalHandlers();
-
-    gStatsService->sayHiToStatsCompanion();
-
-    gStatsService->Startup();
-
-    gSocketListener = new StatsSocketListener(eventQueue);
-
-    ALOGI("Statsd starts to listen to socket.");
-    // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
-    if (gSocketListener->startListener(600)) {
-        exit(1);
-    }
-
-    // Loop forever -- the reports run on this thread in a handler, and the
-    // binder calls remain responsive in their pool of one thread.
-    while (true) {
-        looper->pollAll(-1 /* timeoutMillis */);
-    }
-    ALOGW("statsd escaped from its loop.");
-
-    return 1;
-}
diff --git a/cmds/statsd/src/matchers/AtomMatchingTracker.h b/cmds/statsd/src/matchers/AtomMatchingTracker.h
deleted file mode 100644
index c138497..0000000
--- a/cmds/statsd/src/matchers/AtomMatchingTracker.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ATOM_MATCHING_TRACKER_H
-#define ATOM_MATCHING_TRACKER_H
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "logd/LogEvent.h"
-#include "matchers/matcher_util.h"
-
-#include <utils/RefBase.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class AtomMatchingTracker : public virtual RefBase {
-public:
-    AtomMatchingTracker(const int64_t& id, const int index, const uint64_t protoHash)
-        : mId(id), mIndex(index), mInitialized(false), mProtoHash(protoHash){};
-
-    virtual ~AtomMatchingTracker(){};
-
-    // Initialize this AtomMatchingTracker.
-    // allAtomMatchers: the list of the AtomMatcher proto config. This is needed because we don't
-    //                  store the proto object in memory. We only need it during initilization.
-    // allAtomMatchingTrackers: the list of the AtomMatchingTracker objects. It's a one-to-one
-    //                          mapping with allAtomMatchers. This is needed because the
-    //                          initialization is done recursively for
-    //                          CombinationAtomMatchingTrackers using DFS.
-    // stack: a bit map to record which matcher has been visited on the stack. This is for detecting
-    //        circle dependency.
-    virtual bool init(const std::vector<AtomMatcher>& allAtomMatchers,
-                      const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                      const std::unordered_map<int64_t, int>& matcherMap,
-                      std::vector<bool>& stack) = 0;
-
-    // Update appropriate state on config updates. Primarily, all indices need to be updated.
-    // This matcher and all of its children are guaranteed to be preserved across the update.
-    // matcher: the AtomMatcher proto from the config.
-    // index: the index of this matcher in mAllAtomMatchingTrackers.
-    // atomMatchingTrackerMap: map from matcher id to index in mAllAtomMatchingTrackers
-    virtual bool onConfigUpdated(
-            const AtomMatcher& matcher, const int index,
-            const std::unordered_map<int64_t, int>& atomMatchingTrackerMap) = 0;
-
-    // Called when a log event comes.
-    // event: the log event.
-    // allAtomMatchingTrackers: the list of all AtomMatchingTrackers. This is needed because the log
-    //                          processing is done recursively.
-    // matcherResults: The cached results for all matchers for this event. Parent matchers can
-    //                 directly access the children's matching results if they have been evaluated.
-    //                 Otherwise, call children matchers' onLogEvent.
-    virtual void onLogEvent(const LogEvent& event,
-                            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                            std::vector<MatchingState>& matcherResults) = 0;
-
-    // Get the tagIds that this matcher cares about. The combined collection is stored
-    // in MetricMananger, so that we can pass any LogEvents that are not interest of us. It uses
-    // some memory but hopefully it can save us much CPU time when there is flood of events.
-    virtual const std::set<int>& getAtomIds() const {
-        return mAtomIds;
-    }
-
-    int64_t getId() const {
-        return mId;
-    }
-
-    uint64_t getProtoHash() const {
-        return mProtoHash;
-    }
-
-protected:
-    // Name of this matching. We don't really need the name, but it makes log message easy to debug.
-    const int64_t mId;
-
-    // Index of this AtomMatchingTracker in MetricsManager's container.
-    int mIndex;
-
-    // Whether this AtomMatchingTracker has been properly initialized.
-    bool mInitialized;
-
-    // The collection of the event tag ids that this AtomMatchingTracker cares. So we can quickly
-    // return kNotMatched when we receive an event with an id not in the list. This is especially
-    // useful when we have a complex CombinationAtomMatchingTracker.
-    std::set<int> mAtomIds;
-
-    // Hash of the AtomMatcher's proto bytes from StatsdConfig.
-    // Used to determine if the definition of this matcher has changed across a config update.
-    const uint64_t mProtoHash;
-
-    FRIEND_TEST(MetricsManagerTest, TestCreateAtomMatchingTrackerSimple);
-    FRIEND_TEST(MetricsManagerTest, TestCreateAtomMatchingTrackerCombination);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateMatchers);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // ATOM_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/CombinationAtomMatchingTracker.cpp b/cmds/statsd/src/matchers/CombinationAtomMatchingTracker.cpp
deleted file mode 100644
index 45685ce..0000000
--- a/cmds/statsd/src/matchers/CombinationAtomMatchingTracker.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "Log.h"
-
-#include "CombinationAtomMatchingTracker.h"
-
-#include "matchers/matcher_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-CombinationAtomMatchingTracker::CombinationAtomMatchingTracker(const int64_t& id, const int index,
-                                                               const uint64_t protoHash)
-    : AtomMatchingTracker(id, index, protoHash) {
-}
-
-CombinationAtomMatchingTracker::~CombinationAtomMatchingTracker() {
-}
-
-bool CombinationAtomMatchingTracker::init(
-        const vector<AtomMatcher>& allAtomMatchers,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& matcherMap, vector<bool>& stack) {
-    if (mInitialized) {
-        return true;
-    }
-
-    // mark this node as visited in the recursion stack.
-    stack[mIndex] = true;
-
-    AtomMatcher_Combination matcher = allAtomMatchers[mIndex].combination();
-
-    // LogicalOperation is missing in the config
-    if (!matcher.has_operation()) {
-        return false;
-    }
-
-    mLogicalOperation = matcher.operation();
-
-    if (mLogicalOperation == LogicalOperation::NOT && matcher.matcher_size() != 1) {
-        return false;
-    }
-
-    for (const auto& child : matcher.matcher()) {
-        auto pair = matcherMap.find(child);
-        if (pair == matcherMap.end()) {
-            ALOGW("Matcher %lld not found in the config", (long long)child);
-            return false;
-        }
-
-        int childIndex = pair->second;
-
-        // if the child is a visited node in the recursion -> circle detected.
-        if (stack[childIndex]) {
-            ALOGE("Circle detected in matcher config");
-            return false;
-        }
-
-        if (!allAtomMatchingTrackers[childIndex]->init(allAtomMatchers, allAtomMatchingTrackers,
-                                                       matcherMap, stack)) {
-            ALOGW("child matcher init failed %lld", (long long)child);
-            return false;
-        }
-
-        mChildren.push_back(childIndex);
-
-        const set<int>& childTagIds = allAtomMatchingTrackers[childIndex]->getAtomIds();
-        mAtomIds.insert(childTagIds.begin(), childTagIds.end());
-    }
-
-    mInitialized = true;
-    // unmark this node in the recursion stack.
-    stack[mIndex] = false;
-    return true;
-}
-
-bool CombinationAtomMatchingTracker::onConfigUpdated(
-        const AtomMatcher& matcher, const int index,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap) {
-    mIndex = index;
-    mChildren.clear();
-    AtomMatcher_Combination combinationMatcher = matcher.combination();
-    for (const int64_t child : combinationMatcher.matcher()) {
-        const auto& pair = atomMatchingTrackerMap.find(child);
-        if (pair == atomMatchingTrackerMap.end()) {
-            ALOGW("Matcher %lld not found in the config", (long long)child);
-            return false;
-        }
-        mChildren.push_back(pair->second);
-    }
-    return true;
-}
-
-void CombinationAtomMatchingTracker::onLogEvent(
-        const LogEvent& event, const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        vector<MatchingState>& matcherResults) {
-    // this event has been processed.
-    if (matcherResults[mIndex] != MatchingState::kNotComputed) {
-        return;
-    }
-
-    if (mAtomIds.find(event.GetTagId()) == mAtomIds.end()) {
-        matcherResults[mIndex] = MatchingState::kNotMatched;
-        return;
-    }
-
-    // evaluate children matchers if they haven't been evaluated.
-    for (const int childIndex : mChildren) {
-        if (matcherResults[childIndex] == MatchingState::kNotComputed) {
-            const sp<AtomMatchingTracker>& child = allAtomMatchingTrackers[childIndex];
-            child->onLogEvent(event, allAtomMatchingTrackers, matcherResults);
-        }
-    }
-
-    bool matched = combinationMatch(mChildren, mLogicalOperation, matcherResults);
-    matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/matchers/CombinationAtomMatchingTracker.h b/cmds/statsd/src/matchers/CombinationAtomMatchingTracker.h
deleted file mode 100644
index 3160448..0000000
--- a/cmds/statsd/src/matchers/CombinationAtomMatchingTracker.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-#ifndef COMBINATION_ATOM_MATCHING_TRACKER_H
-#define COMBINATION_ATOM_MATCHING_TRACKER_H
-
-#include <unordered_map>
-#include <vector>
-
-#include "AtomMatchingTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Represents a AtomMatcher_Combination in the StatsdConfig.
-class CombinationAtomMatchingTracker : public AtomMatchingTracker {
-public:
-    CombinationAtomMatchingTracker(const int64_t& id, const int index, const uint64_t protoHash);
-
-    bool init(const std::vector<AtomMatcher>& allAtomMatchers,
-              const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-              const std::unordered_map<int64_t, int>& matcherMap, std::vector<bool>& stack);
-
-    bool onConfigUpdated(const AtomMatcher& matcher, const int index,
-                         const std::unordered_map<int64_t, int>& atomMatchingTrackerMap) override;
-
-    ~CombinationAtomMatchingTracker();
-
-    void onLogEvent(const LogEvent& event,
-                    const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                    std::vector<MatchingState>& matcherResults) override;
-
-private:
-    LogicalOperation mLogicalOperation;
-
-    std::vector<int> mChildren;
-
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateMatchers);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#endif  // COMBINATION_ATOM_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/EventMatcherWizard.cpp b/cmds/statsd/src/matchers/EventMatcherWizard.cpp
deleted file mode 100644
index 025c9a8..0000000
--- a/cmds/statsd/src/matchers/EventMatcherWizard.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#include "EventMatcherWizard.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-MatchingState EventMatcherWizard::matchLogEvent(const LogEvent& event, int matcher_index) {
-    if (matcher_index < 0 || matcher_index >= (int)mAllEventMatchers.size()) {
-        return MatchingState::kNotComputed;
-    }
-    vector<MatchingState> matcherCache(mAllEventMatchers.size(), MatchingState::kNotComputed);
-    mAllEventMatchers[matcher_index]->onLogEvent(event, mAllEventMatchers, matcherCache);
-    return matcherCache[matcher_index];
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/matchers/EventMatcherWizard.h b/cmds/statsd/src/matchers/EventMatcherWizard.h
deleted file mode 100644
index 5d780f2..0000000
--- a/cmds/statsd/src/matchers/EventMatcherWizard.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include "AtomMatchingTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class EventMatcherWizard : public virtual android::RefBase {
-public:
-    EventMatcherWizard(){};  // for testing
-    EventMatcherWizard(const std::vector<sp<AtomMatchingTracker>>& eventTrackers)
-        : mAllEventMatchers(eventTrackers){};
-
-    virtual ~EventMatcherWizard(){};
-
-    MatchingState matchLogEvent(const LogEvent& event, int matcher_index);
-
-private:
-    std::vector<sp<AtomMatchingTracker>> mAllEventMatchers;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.cpp
deleted file mode 100644
index 423da5b..0000000
--- a/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "SimpleAtomMatchingTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::unordered_map;
-using std::vector;
-
-SimpleAtomMatchingTracker::SimpleAtomMatchingTracker(const int64_t& id, const int index,
-                                                     const uint64_t protoHash,
-                                                     const SimpleAtomMatcher& matcher,
-                                                     const sp<UidMap>& uidMap)
-    : AtomMatchingTracker(id, index, protoHash), mMatcher(matcher), mUidMap(uidMap) {
-    if (!matcher.has_atom_id()) {
-        mInitialized = false;
-    } else {
-        mAtomIds.insert(matcher.atom_id());
-        mInitialized = true;
-    }
-}
-
-SimpleAtomMatchingTracker::~SimpleAtomMatchingTracker() {
-}
-
-bool SimpleAtomMatchingTracker::init(const vector<AtomMatcher>& allAtomMatchers,
-                                     const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                                     const unordered_map<int64_t, int>& matcherMap,
-                                     vector<bool>& stack) {
-    // no need to do anything.
-    return mInitialized;
-}
-
-bool SimpleAtomMatchingTracker::onConfigUpdated(
-        const AtomMatcher& matcher, const int index,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap) {
-    mIndex = index;
-    // Do not need to update mMatcher since the matcher must be identical across the update.
-    return mInitialized;
-}
-
-void SimpleAtomMatchingTracker::onLogEvent(
-        const LogEvent& event, const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        vector<MatchingState>& matcherResults) {
-    if (matcherResults[mIndex] != MatchingState::kNotComputed) {
-        VLOG("Matcher %lld already evaluated ", (long long)mId);
-        return;
-    }
-
-    if (mAtomIds.find(event.GetTagId()) == mAtomIds.end()) {
-        matcherResults[mIndex] = MatchingState::kNotMatched;
-        return;
-    }
-
-    bool matched = matchesSimple(mUidMap, mMatcher, event);
-    matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched;
-    VLOG("Stats SimpleAtomMatcher %lld matched? %d", (long long)mId, matched);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.h b/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.h
deleted file mode 100644
index b67e6c2..0000000
--- a/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef SIMPLE_ATOM_MATCHING_TRACKER_H
-#define SIMPLE_ATOM_MATCHING_TRACKER_H
-
-#include <unordered_map>
-#include <vector>
-
-#include "AtomMatchingTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class SimpleAtomMatchingTracker : public AtomMatchingTracker {
-public:
-    SimpleAtomMatchingTracker(const int64_t& id, const int index, const uint64_t protoHash,
-                              const SimpleAtomMatcher& matcher, const sp<UidMap>& uidMap);
-
-    ~SimpleAtomMatchingTracker();
-
-    bool init(const std::vector<AtomMatcher>& allAtomMatchers,
-              const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-              const std::unordered_map<int64_t, int>& matcherMap,
-              std::vector<bool>& stack) override;
-
-    bool onConfigUpdated(const AtomMatcher& matcher, const int index,
-                         const std::unordered_map<int64_t, int>& atomMatchingTrackerMap) override;
-
-    void onLogEvent(const LogEvent& event,
-                    const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                    std::vector<MatchingState>& matcherResults) override;
-
-private:
-    const SimpleAtomMatcher mMatcher;
-    const sp<UidMap> mUidMap;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#endif  // SIMPLE_ATOM_MATCHING_TRACKER_H
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
deleted file mode 100644
index a7454c5..0000000
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/AtomMatchingTracker.h"
-#include "matchers/matcher_util.h"
-#include "stats_util.h"
-
-using std::set;
-using std::string;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-bool combinationMatch(const vector<int>& children, const LogicalOperation& operation,
-                      const vector<MatchingState>& matcherResults) {
-    bool matched;
-    switch (operation) {
-        case LogicalOperation::AND: {
-            matched = true;
-            for (const int childIndex : children) {
-                if (matcherResults[childIndex] != MatchingState::kMatched) {
-                    matched = false;
-                    break;
-                }
-            }
-            break;
-        }
-        case LogicalOperation::OR: {
-            matched = false;
-            for (const int childIndex : children) {
-                if (matcherResults[childIndex] == MatchingState::kMatched) {
-                    matched = true;
-                    break;
-                }
-            }
-            break;
-        }
-        case LogicalOperation::NOT:
-            matched = matcherResults[children[0]] == MatchingState::kNotMatched;
-            break;
-        case LogicalOperation::NAND:
-            matched = false;
-            for (const int childIndex : children) {
-                if (matcherResults[childIndex] != MatchingState::kMatched) {
-                    matched = true;
-                    break;
-                }
-            }
-            break;
-        case LogicalOperation::NOR:
-            matched = true;
-            for (const int childIndex : children) {
-                if (matcherResults[childIndex] == MatchingState::kMatched) {
-                    matched = false;
-                    break;
-                }
-            }
-            break;
-        case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
-            matched = false;
-            break;
-    }
-    return matched;
-}
-
-bool tryMatchString(const sp<UidMap>& uidMap, const FieldValue& fieldValue,
-                    const string& str_match) {
-    if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) {
-        int uid = fieldValue.mValue.int_value;
-        auto aidIt = UidMap::sAidToUidMapping.find(str_match);
-        if (aidIt != UidMap::sAidToUidMapping.end()) {
-            return ((int)aidIt->second) == uid;
-        }
-        std::set<string> packageNames = uidMap->getAppNamesFromUid(uid, true /* normalize*/);
-        return packageNames.find(str_match) != packageNames.end();
-    } else if (fieldValue.mValue.getType() == STRING) {
-        return fieldValue.mValue.str_value == str_match;
-    }
-    return false;
-}
-
-bool matchesSimple(const sp<UidMap>& uidMap, const FieldValueMatcher& matcher,
-                   const vector<FieldValue>& values, int start, int end, int depth) {
-    if (depth > 2) {
-        ALOGE("Depth > 3 not supported");
-        return false;
-    }
-
-    if (start >= end) {
-        return false;
-    }
-
-    // Filter by entry field first
-    int newStart = -1;
-    int newEnd = end;
-    // because the fields are naturally sorted in the DFS order. we can safely
-    // break when pos is larger than the one we are searching for.
-    for (int i = start; i < end; i++) {
-        int pos = values[i].mField.getPosAtDepth(depth);
-        if (pos == matcher.field()) {
-            if (newStart == -1) {
-                newStart = i;
-            }
-            newEnd = i + 1;
-        } else if (pos > matcher.field()) {
-            break;
-        }
-    }
-
-    // Now we have zoomed in to a new range
-    start = newStart;
-    end = newEnd;
-
-    if (start == -1) {
-        // No such field found.
-        return false;
-    }
-
-    vector<pair<int, int>> ranges; // the ranges are for matching ANY position
-    if (matcher.has_position()) {
-        // Repeated fields position is stored as a node in the path.
-        depth++;
-        if (depth > 2) {
-            return false;
-        }
-        switch (matcher.position()) {
-            case Position::FIRST: {
-                for (int i = start; i < end; i++) {
-                    int pos = values[i].mField.getPosAtDepth(depth);
-                    if (pos != 1) {
-                        // Again, the log elements are stored in sorted order. so
-                        // once the position is > 1, we break;
-                        end = i;
-                        break;
-                    }
-                }
-                ranges.push_back(std::make_pair(start, end));
-                break;
-            }
-            case Position::LAST: {
-                // move the starting index to the first LAST field at the depth.
-                for (int i = start; i < end; i++) {
-                    if (values[i].mField.isLastPos(depth)) {
-                        start = i;
-                        break;
-                    }
-                }
-                ranges.push_back(std::make_pair(start, end));
-                break;
-            }
-            case Position::ANY: {
-                // ANY means all the children matchers match in any of the sub trees, it's a match
-                newStart = start;
-                newEnd = end;
-                // Here start is guaranteed to be a valid index.
-                int currentPos = values[start].mField.getPosAtDepth(depth);
-                // Now find all sub trees ranges.
-                for (int i = start; i < end; i++) {
-                    int newPos = values[i].mField.getPosAtDepth(depth);
-                    if (newPos != currentPos) {
-                        ranges.push_back(std::make_pair(newStart, i));
-                        newStart = i;
-                        currentPos = newPos;
-                    }
-                }
-                ranges.push_back(std::make_pair(newStart, end));
-                break;
-            }
-            case Position::ALL:
-                ALOGE("Not supported: field matcher with ALL position.");
-                break;
-            case Position::POSITION_UNKNOWN:
-                break;
-        }
-    } else {
-        // No position
-        ranges.push_back(std::make_pair(start, end));
-    }
-    // start and end are still pointing to the matched range.
-    switch (matcher.value_matcher_case()) {
-        case FieldValueMatcher::kMatchesTuple: {
-            ++depth;
-            // If any range matches all matchers, good.
-            for (const auto& range : ranges) {
-                bool matched = true;
-                for (const auto& subMatcher : matcher.matches_tuple().field_value_matcher()) {
-                    if (!matchesSimple(uidMap, subMatcher, values, range.first, range.second,
-                                       depth)) {
-                        matched = false;
-                        break;
-                    }
-                }
-                if (matched) return true;
-            }
-            return false;
-        }
-        // Finally, we get to the point of real value matching.
-        // If the field matcher ends with ANY, then we have [start, end) range > 1.
-        // In the following, we should return true, when ANY of the values matches.
-        case FieldValueMatcher::ValueMatcherCase::kEqBool: {
-            for (int i = start; i < end; i++) {
-                if ((values[i].mValue.getType() == INT &&
-                     (values[i].mValue.int_value != 0) == matcher.eq_bool()) ||
-                    (values[i].mValue.getType() == LONG &&
-                     (values[i].mValue.long_value != 0) == matcher.eq_bool())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kEqString: {
-            for (int i = start; i < end; i++) {
-                if (tryMatchString(uidMap, values[i], matcher.eq_string())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: {
-            const auto& str_list = matcher.neq_any_string();
-            for (int i = start; i < end; i++) {
-                bool notEqAll = true;
-                for (const auto& str : str_list.str_value()) {
-                    if (tryMatchString(uidMap, values[i], str)) {
-                        notEqAll = false;
-                        break;
-                    }
-                }
-                if (notEqAll) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
-            const auto& str_list = matcher.eq_any_string();
-            for (int i = start; i < end; i++) {
-                for (const auto& str : str_list.str_value()) {
-                    if (tryMatchString(uidMap, values[i], str)) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kEqInt: {
-            for (int i = start; i < end; i++) {
-                if (values[i].mValue.getType() == INT &&
-                    (matcher.eq_int() == values[i].mValue.int_value)) {
-                    return true;
-                }
-                // eq_int covers both int and long.
-                if (values[i].mValue.getType() == LONG &&
-                    (matcher.eq_int() == values[i].mValue.long_value)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kLtInt: {
-            for (int i = start; i < end; i++) {
-                if (values[i].mValue.getType() == INT &&
-                    (values[i].mValue.int_value < matcher.lt_int())) {
-                    return true;
-                }
-                // lt_int covers both int and long.
-                if (values[i].mValue.getType() == LONG &&
-                    (values[i].mValue.long_value < matcher.lt_int())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kGtInt: {
-            for (int i = start; i < end; i++) {
-                if (values[i].mValue.getType() == INT &&
-                    (values[i].mValue.int_value > matcher.gt_int())) {
-                    return true;
-                }
-                // gt_int covers both int and long.
-                if (values[i].mValue.getType() == LONG &&
-                    (values[i].mValue.long_value > matcher.gt_int())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kLtFloat: {
-            for (int i = start; i < end; i++) {
-                if (values[i].mValue.getType() == FLOAT &&
-                    (values[i].mValue.float_value < matcher.lt_float())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kGtFloat: {
-            for (int i = start; i < end; i++) {
-                if (values[i].mValue.getType() == FLOAT &&
-                    (values[i].mValue.float_value > matcher.gt_float())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kLteInt: {
-            for (int i = start; i < end; i++) {
-                if (values[i].mValue.getType() == INT &&
-                    (values[i].mValue.int_value <= matcher.lte_int())) {
-                    return true;
-                }
-                // lte_int covers both int and long.
-                if (values[i].mValue.getType() == LONG &&
-                    (values[i].mValue.long_value <= matcher.lte_int())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        case FieldValueMatcher::ValueMatcherCase::kGteInt: {
-            for (int i = start; i < end; i++) {
-                if (values[i].mValue.getType() == INT &&
-                    (values[i].mValue.int_value >= matcher.gte_int())) {
-                    return true;
-                }
-                // gte_int covers both int and long.
-                if (values[i].mValue.getType() == LONG &&
-                    (values[i].mValue.long_value >= matcher.gte_int())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        default:
-            return false;
-    }
-}
-
-bool matchesSimple(const sp<UidMap>& uidMap, const SimpleAtomMatcher& simpleMatcher,
-                   const LogEvent& event) {
-    if (event.GetTagId() != simpleMatcher.atom_id()) {
-        return false;
-    }
-
-    for (const auto& matcher : simpleMatcher.field_value_matcher()) {
-        if (!matchesSimple(uidMap, matcher, event.getValues(), 0, event.getValues().size(), 0)) {
-            return false;
-        }
-    }
-    return true;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
deleted file mode 100644
index 130b606..0000000
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "logd/LogEvent.h"
-
-#include <vector>
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "packages/UidMap.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-enum MatchingState {
-    kNotComputed = -1,
-    kNotMatched = 0,
-    kMatched = 1,
-};
-
-bool combinationMatch(const std::vector<int>& children, const LogicalOperation& operation,
-                      const std::vector<MatchingState>& matcherResults);
-
-bool matchesSimple(const sp<UidMap>& uidMap, const SimpleAtomMatcher& simpleMatcher,
-                   const LogEvent& wrapper);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metadata_util.cpp b/cmds/statsd/src/metadata_util.cpp
deleted file mode 100644
index 27ee59b..0000000
--- a/cmds/statsd/src/metadata_util.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include "FieldValue.h"
-#include "metadata_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using google::protobuf::RepeatedPtrField;
-
-void writeValueToProto(metadata::FieldValue* metadataFieldValue, const Value& value) {
-    std::string storage_value;
-    switch (value.getType()) {
-        case INT:
-            metadataFieldValue->set_value_int(value.int_value);
-            break;
-        case LONG:
-            metadataFieldValue->set_value_long(value.long_value);
-            break;
-        case FLOAT:
-            metadataFieldValue->set_value_float(value.float_value);
-            break;
-        case DOUBLE:
-            metadataFieldValue->set_value_double(value.double_value);
-            break;
-        case STRING:
-            metadataFieldValue->set_value_str(value.str_value.c_str());
-            break;
-        case STORAGE: // byte array
-            storage_value = ((char*) value.storage_value.data());
-            metadataFieldValue->set_value_storage(storage_value);
-            break;
-        default:
-            break;
-    }
-}
-
-void writeMetricDimensionKeyToMetadataDimensionKey(
-        const MetricDimensionKey& metricKey,
-        metadata::MetricDimensionKey* metadataMetricKey) {
-    for (const FieldValue& fieldValue : metricKey.getDimensionKeyInWhat().getValues()) {
-        metadata::FieldValue* metadataFieldValue = metadataMetricKey->add_dimension_key_in_what();
-        metadata::Field* metadataField = metadataFieldValue->mutable_field();
-        metadataField->set_tag(fieldValue.mField.getTag());
-        metadataField->set_field(fieldValue.mField.getField());
-        writeValueToProto(metadataFieldValue, fieldValue.mValue);
-    }
-
-    for (const FieldValue& fieldValue : metricKey.getStateValuesKey().getValues()) {
-        metadata::FieldValue* metadataFieldValue = metadataMetricKey->add_state_values_key();
-        metadata::Field* metadataField = metadataFieldValue->mutable_field();
-        metadataField->set_tag(fieldValue.mField.getTag());
-        metadataField->set_field(fieldValue.mField.getField());
-        writeValueToProto(metadataFieldValue, fieldValue.mValue);
-    }
-}
-
-void writeFieldValuesFromMetadata(
-        const RepeatedPtrField<metadata::FieldValue>& repeatedFieldValueList,
-        std::vector<FieldValue>* fieldValues) {
-    for (const metadata::FieldValue& metadataFieldValue : repeatedFieldValueList) {
-        Field field(metadataFieldValue.field().tag(), metadataFieldValue.field().field());
-        Value value;
-        switch (metadataFieldValue.value_case()) {
-            case metadata::FieldValue::ValueCase::kValueInt:
-                value = Value(metadataFieldValue.value_int());
-                break;
-            case metadata::FieldValue::ValueCase::kValueLong:
-                value = Value(metadataFieldValue.value_long());
-                break;
-            case metadata::FieldValue::ValueCase::kValueFloat:
-                value = Value(metadataFieldValue.value_float());
-                break;
-            case metadata::FieldValue::ValueCase::kValueDouble:
-                value = Value(metadataFieldValue.value_double());
-                break;
-            case metadata::FieldValue::ValueCase::kValueStr:
-                value = Value(metadataFieldValue.value_str());
-                break;
-            case metadata::FieldValue::ValueCase::kValueStorage:
-                value = Value(metadataFieldValue.value_storage());
-                break;
-            default:
-                break;
-        }
-        FieldValue fieldValue(field, value);
-        fieldValues->emplace_back(field, value);
-    }
-}
-
-MetricDimensionKey loadMetricDimensionKeyFromProto(
-        const metadata::MetricDimensionKey& metricDimensionKey) {
-    std::vector<FieldValue> dimKeyInWhatFieldValues;
-    writeFieldValuesFromMetadata(metricDimensionKey.dimension_key_in_what(),
-            &dimKeyInWhatFieldValues);
-    std::vector<FieldValue> stateValuesFieldValues;
-    writeFieldValuesFromMetadata(metricDimensionKey.state_values_key(), &stateValuesFieldValues);
-
-    HashableDimensionKey dimKeyInWhat(dimKeyInWhatFieldValues);
-    HashableDimensionKey stateValues(stateValuesFieldValues);
-    MetricDimensionKey metricKey(dimKeyInWhat, stateValues);
-    return metricKey;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/metadata_util.h b/cmds/statsd/src/metadata_util.h
deleted file mode 100644
index 84a39ff..0000000
--- a/cmds/statsd/src/metadata_util.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-#include "HashableDimensionKey.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"  // AlertMetadata
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void writeMetricDimensionKeyToMetadataDimensionKey(const MetricDimensionKey& metricKey,
-                                                   metadata::MetricDimensionKey* metadataMetricKey);
-
-MetricDimensionKey loadMetricDimensionKeyFromProto(
-        const metadata::MetricDimensionKey& metricDimensionKey);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
deleted file mode 100644
index a8ef54a..0000000
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "CountMetricProducer.h"
-
-#include <inttypes.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include "guardrail/StatsdStats.h"
-#include "metrics/parsing_utils/metrics_manager_util.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_COUNT_METRICS = 5;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-
-// for CountMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-// for CountMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_SLICE_BY_STATE = 6;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-// for CountBucketInfo
-const int FIELD_ID_COUNT = 3;
-const int FIELD_ID_BUCKET_NUM = 4;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
-
-CountMetricProducer::CountMetricProducer(
-        const ConfigKey& key, const CountMetric& metric, const int conditionIndex,
-        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const uint64_t protoHash, const int64_t timeBaseNs, const int64_t startTimeNs,
-        const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
-        const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
-        const vector<int>& slicedStateAtoms,
-        const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
-    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
-                     protoHash, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-                     stateGroupMap) {
-    if (metric.has_bucket()) {
-        mBucketSizeNs =
-                TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
-    } else {
-        mBucketSizeNs = LLONG_MAX;
-    }
-
-    if (metric.has_dimensions_in_what()) {
-        translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
-        mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
-    }
-
-    mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-
-    if (metric.links().size() > 0) {
-        for (const auto& link : metric.links()) {
-            Metric2Condition mc;
-            mc.conditionId = link.condition();
-            translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
-            translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
-            mMetric2ConditionLinks.push_back(mc);
-        }
-        mConditionSliced = true;
-    }
-
-    for (const auto& stateLink : metric.state_link()) {
-        Metric2State ms;
-        ms.stateAtomId = stateLink.state_atom_id();
-        translateFieldMatcher(stateLink.fields_in_what(), &ms.metricFields);
-        translateFieldMatcher(stateLink.fields_in_state(), &ms.stateFields);
-        mMetric2StateLinks.push_back(ms);
-    }
-
-    flushIfNeededLocked(startTimeNs);
-    // Adjust start for partial bucket
-    mCurrentBucketStartTimeNs = startTimeNs;
-
-    VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
-         (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-CountMetricProducer::~CountMetricProducer() {
-    VLOG("~CountMetricProducer() called");
-}
-
-bool CountMetricProducer::onConfigUpdatedLocked(
-        const StatsdConfig& config, const int configIndex, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!MetricProducer::onConfigUpdatedLocked(
-                config, configIndex, metricIndex, allAtomMatchingTrackers,
-                oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap,
-                trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
-                deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
-        return false;
-    }
-
-    const CountMetric& metric = config.count_metric(configIndex);
-    int trackerIndex;
-    // Update appropriate indices, specifically mConditionIndex and MetricsManager maps.
-    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, false,
-                                              allAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                              trackerToMetricMap, trackerIndex)) {
-        return false;
-    }
-
-    if (metric.has_condition() &&
-        !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                    metric.links(), allConditionTrackers, mConditionTrackerIndex,
-                                    conditionToMetricMap)) {
-        return false;
-    }
-    return true;
-}
-
-void CountMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
-                                         const HashableDimensionKey& primaryKey,
-                                         const FieldValue& oldState, const FieldValue& newState) {
-    VLOG("CountMetric %lld onStateChanged time %lld, State%d, key %s, %d -> %d",
-         (long long)mMetricId, (long long)eventTimeNs, atomId, primaryKey.toString().c_str(),
-         oldState.mValue.int_value, newState.mValue.int_value);
-}
-
-void CountMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
-    if (mCurrentSlicedCounter == nullptr ||
-        mCurrentSlicedCounter->size() == 0) {
-        return;
-    }
-
-    fprintf(out, "CountMetric %lld dimension size %lu\n", (long long)mMetricId,
-            (unsigned long)mCurrentSlicedCounter->size());
-    if (verbose) {
-        for (const auto& it : *mCurrentSlicedCounter) {
-            fprintf(out, "\t(what)%s\t(state)%s  %lld\n",
-                    it.first.getDimensionKeyInWhat().toString().c_str(),
-                    it.first.getStateValuesKey().toString().c_str(), (unsigned long long)it.second);
-        }
-    }
-}
-
-void CountMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
-                                                           const int64_t eventTime) {
-    VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-}
-
-
-void CountMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
-    mPastBuckets.clear();
-}
-
-void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
-                                             const bool include_current_partial_bucket,
-                                             const bool erase_data,
-                                             const DumpLatency dumpLatency,
-                                             std::set<string> *str_set,
-                                             ProtoOutputStream* protoOutput) {
-    if (include_current_partial_bucket) {
-        flushLocked(dumpTimeNs);
-    } else {
-        flushIfNeededLocked(dumpTimeNs);
-    }
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
-    protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
-
-    if (mPastBuckets.empty()) {
-        return;
-    }
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-
-    // Fills the dimension path if not slicing by ALL.
-    if (!mSliceByPositionALL) {
-        if (!mDimensionsInWhat.empty()) {
-            uint64_t dimenPathToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
-            writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
-            protoOutput->end(dimenPathToken);
-        }
-    }
-
-    uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_COUNT_METRICS);
-
-    for (const auto& counter : mPastBuckets) {
-        const MetricDimensionKey& dimensionKey = counter.first;
-        VLOG("  dimension key %s", dimensionKey.toString().c_str());
-
-        uint64_t wrapperToken =
-                protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
-        // First fill dimension.
-        if (mSliceByPositionALL) {
-            uint64_t dimensionToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
-            writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
-            protoOutput->end(dimensionToken);
-        } else {
-            writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
-                                           FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
-        }
-        // Then fill slice_by_state.
-        for (auto state : dimensionKey.getStateValuesKey().getValues()) {
-            uint64_t stateToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                     FIELD_ID_SLICE_BY_STATE);
-            writeStateToProto(state, protoOutput);
-            protoOutput->end(stateToken);
-        }
-        // Then fill bucket_info (CountBucketInfo).
-        for (const auto& bucket : counter.second) {
-            uint64_t bucketInfoToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
-            // Partial bucket.
-            if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
-                                   (long long)NanoToMillis(bucket.mBucketStartNs));
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
-                                   (long long)NanoToMillis(bucket.mBucketEndNs));
-            } else {
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
-                                   (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
-            }
-            protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_COUNT, (long long)bucket.mCount);
-            protoOutput->end(bucketInfoToken);
-            VLOG("\t bucket [%lld - %lld] count: %lld", (long long)bucket.mBucketStartNs,
-                 (long long)bucket.mBucketEndNs, (long long)bucket.mCount);
-        }
-        protoOutput->end(wrapperToken);
-    }
-
-    protoOutput->end(protoToken);
-
-    if (erase_data) {
-        mPastBuckets.clear();
-    }
-}
-
-void CountMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
-    flushIfNeededLocked(dropTimeNs);
-    StatsdStats::getInstance().noteBucketDropped(mMetricId);
-    mPastBuckets.clear();
-}
-
-void CountMetricProducer::onConditionChangedLocked(const bool conditionMet,
-                                                   const int64_t eventTime) {
-    VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
-    mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-}
-
-bool CountMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
-    if (mCurrentSlicedCounter->find(newKey) != mCurrentSlicedCounter->end()) {
-        return false;
-    }
-    // ===========GuardRail==============
-    // 1. Report the tuple count if the tuple count > soft limit
-    if (mCurrentSlicedCounter->size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
-        size_t newTupleCount = mCurrentSlicedCounter->size() + 1;
-        StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
-        // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
-        if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
-            ALOGE("CountMetric %lld dropping data for dimension key %s",
-                (long long)mMetricId, newKey.toString().c_str());
-            StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
-            return true;
-        }
-    }
-
-    return false;
-}
-
-void CountMetricProducer::onMatchedLogEventInternalLocked(
-        const size_t matcherIndex, const MetricDimensionKey& eventKey,
-        const ConditionKey& conditionKey, bool condition, const LogEvent& event,
-        const map<int, HashableDimensionKey>& statePrimaryKeys) {
-    int64_t eventTimeNs = event.GetElapsedTimestampNs();
-    flushIfNeededLocked(eventTimeNs);
-
-    if (!condition) {
-        return;
-    }
-
-    auto it = mCurrentSlicedCounter->find(eventKey);
-    if (it == mCurrentSlicedCounter->end()) {
-        // ===========GuardRail==============
-        if (hitGuardRailLocked(eventKey)) {
-            return;
-        }
-        // create a counter for the new key
-        (*mCurrentSlicedCounter)[eventKey] = 1;
-    } else {
-        // increment the existing value
-        auto& count = it->second;
-        count++;
-    }
-    for (auto& tracker : mAnomalyTrackers) {
-        int64_t countWholeBucket = mCurrentSlicedCounter->find(eventKey)->second;
-        auto prev = mCurrentFullCounters->find(eventKey);
-        if (prev != mCurrentFullCounters->end()) {
-            countWholeBucket += prev->second;
-        }
-        tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, mMetricId, eventKey,
-                                         countWholeBucket);
-    }
-
-    VLOG("metric %lld %s->%lld", (long long)mMetricId, eventKey.toString().c_str(),
-         (long long)(*mCurrentSlicedCounter)[eventKey]);
-}
-
-// When a new matched event comes in, we check if event falls into the current
-// bucket. If not, flush the old counter to past buckets and initialize the new bucket.
-void CountMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
-    int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
-    if (eventTimeNs < currentBucketEndTimeNs) {
-        return;
-    }
-
-    // Setup the bucket start time and number.
-    int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
-    int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
-    flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
-
-    mCurrentBucketNum += numBucketsForward;
-    VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
-         (long long)mCurrentBucketStartTimeNs);
-}
-
-void CountMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
-                                                   const int64_t& nextBucketStartTimeNs) {
-    int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
-    CountBucket info;
-    info.mBucketStartNs = mCurrentBucketStartTimeNs;
-    if (eventTimeNs < fullBucketEndTimeNs) {
-        info.mBucketEndNs = eventTimeNs;
-    } else {
-        info.mBucketEndNs = fullBucketEndTimeNs;
-    }
-    for (const auto& counter : *mCurrentSlicedCounter) {
-        info.mCount = counter.second;
-        auto& bucketList = mPastBuckets[counter.first];
-        bucketList.push_back(info);
-        VLOG("metric %lld, dump key value: %s -> %lld", (long long)mMetricId,
-             counter.first.toString().c_str(),
-             (long long)counter.second);
-    }
-
-    // If we have finished a full bucket, then send this to anomaly tracker.
-    if (eventTimeNs > fullBucketEndTimeNs) {
-        // Accumulate partial buckets with current value and then send to anomaly tracker.
-        if (mCurrentFullCounters->size() > 0) {
-            for (const auto& keyValuePair : *mCurrentSlicedCounter) {
-                (*mCurrentFullCounters)[keyValuePair.first] += keyValuePair.second;
-            }
-            for (auto& tracker : mAnomalyTrackers) {
-                tracker->addPastBucket(mCurrentFullCounters, mCurrentBucketNum);
-            }
-            mCurrentFullCounters = std::make_shared<DimToValMap>();
-        } else {
-            // Skip aggregating the partial buckets since there's no previous partial bucket.
-            for (auto& tracker : mAnomalyTrackers) {
-                tracker->addPastBucket(mCurrentSlicedCounter, mCurrentBucketNum);
-            }
-        }
-    } else {
-        // Accumulate partial bucket.
-        for (const auto& keyValuePair : *mCurrentSlicedCounter) {
-            (*mCurrentFullCounters)[keyValuePair.first] += keyValuePair.second;
-        }
-    }
-
-    StatsdStats::getInstance().noteBucketCount(mMetricId);
-    // Only resets the counters, but doesn't setup the times nor numbers.
-    // (Do not clear since the old one is still referenced in mAnomalyTrackers).
-    mCurrentSlicedCounter = std::make_shared<DimToValMap>();
-    mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
-}
-
-// Rough estimate of CountMetricProducer buffer stored. This number will be
-// greater than actual data size as it contains each dimension of
-// CountMetricData is  duplicated.
-size_t CountMetricProducer::byteSizeLocked() const {
-    size_t totalSize = 0;
-    for (const auto& pair : mPastBuckets) {
-        totalSize += pair.second.size() * kBucketSize;
-    }
-    return totalSize;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
deleted file mode 100644
index 0769ac4..0000000
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef COUNT_METRIC_PRODUCER_H
-#define COUNT_METRIC_PRODUCER_H
-
-#include <android/util/ProtoOutputStream.h>
-#include <gtest/gtest_prod.h>
-
-#include <unordered_map>
-
-#include "MetricProducer.h"
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/matcher_util.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct CountBucket {
-    int64_t mBucketStartNs;
-    int64_t mBucketEndNs;
-    int64_t mCount;
-};
-
-class CountMetricProducer : public MetricProducer {
-public:
-    CountMetricProducer(
-            const ConfigKey& key, const CountMetric& countMetric, const int conditionIndex,
-            const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-            const uint64_t protoHash, const int64_t timeBaseNs, const int64_t startTimeNs,
-            const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
-            const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
-                    eventDeactivationMap = {},
-            const vector<int>& slicedStateAtoms = {},
-            const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
-    virtual ~CountMetricProducer();
-
-    void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
-                        const HashableDimensionKey& primaryKey, const FieldValue& oldState,
-                        const FieldValue& newState) override;
-
-    MetricType getMetricType() const override {
-        return METRIC_TYPE_COUNT;
-    }
-
-protected:
-    void onMatchedLogEventInternalLocked(
-            const size_t matcherIndex, const MetricDimensionKey& eventKey,
-            const ConditionKey& conditionKey, bool condition, const LogEvent& event,
-            const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
-
-    void onDumpReportLocked(const int64_t dumpTimeNs,
-                            const bool include_current_partial_bucket,
-                            const bool erase_data,
-                            const DumpLatency dumpLatency,
-                            std::set<string> *str_set,
-                            android::util::ProtoOutputStream* protoOutput) override;
-
-    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
-    // Internal interface to handle condition change.
-    void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
-    // Internal interface to handle sliced condition change.
-    void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
-    // Internal function to calculate the current used bytes.
-    size_t byteSizeLocked() const override;
-
-    void dumpStatesLocked(FILE* out, bool verbose) const override;
-
-    void dropDataLocked(const int64_t dropTimeNs) override;
-
-    // Util function to flush the old packet.
-    void flushIfNeededLocked(const int64_t& newEventTime) override;
-
-    void flushCurrentBucketLocked(const int64_t& eventTimeNs,
-                                  const int64_t& nextBucketStartTimeNs) override;
-
-    bool onConfigUpdatedLocked(
-            const StatsdConfig& config, const int configIndex, const int metricIndex,
-            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-            const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-            const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-            const sp<EventMatcherWizard>& matcherWizard,
-            const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-            const std::unordered_map<int64_t, int>& conditionTrackerMap,
-            const sp<ConditionWizard>& wizard,
-            const std::unordered_map<int64_t, int>& metricToActivationMap,
-            std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-            std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-            std::vector<int>& metricsWithActivation) override;
-
-    std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets;
-
-    // The current bucket (may be a partial bucket).
-    std::shared_ptr<DimToValMap> mCurrentSlicedCounter = std::make_shared<DimToValMap>();
-
-    // The sum of previous partial buckets in the current full bucket (excluding the current
-    // partial bucket). This is only updated while flushing the current bucket.
-    std::shared_ptr<DimToValMap> mCurrentFullCounters = std::make_shared<DimToValMap>();
-
-    static const size_t kBucketSize = sizeof(CountBucket{});
-
-    bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
-    FRIEND_TEST(CountMetricProducerTest, TestNonDimensionalEvents);
-    FRIEND_TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition);
-    FRIEND_TEST(CountMetricProducerTest, TestEventsWithSlicedCondition);
-    FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced);
-    FRIEND_TEST(CountMetricProducerTest, TestFirstBucket);
-    FRIEND_TEST(CountMetricProducerTest, TestOneWeekTimeUnit);
-
-    FRIEND_TEST(CountMetricProducerTest_PartialBucket, TestSplitInCurrentBucket);
-    FRIEND_TEST(CountMetricProducerTest_PartialBucket, TestSplitInNextBucket);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#endif  // COUNT_METRIC_PRODUCER_H
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
deleted file mode 100644
index 001ad36..0000000
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false
-
-#include "Log.h"
-
-#include "DurationMetricProducer.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-#include "guardrail/StatsdStats.h"
-#include "metrics/parsing_utils/metrics_manager_util.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_DURATION_METRICS = 6;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for DurationMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-// for DurationMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-const int FIELD_ID_SLICE_BY_STATE = 6;
-// for DurationBucketInfo
-const int FIELD_ID_DURATION = 3;
-const int FIELD_ID_BUCKET_NUM = 4;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
-
-DurationMetricProducer::DurationMetricProducer(
-        const ConfigKey& key, const DurationMetric& metric, const int conditionIndex,
-        const vector<ConditionState>& initialConditionCache, const int whatIndex,
-        const int startIndex, const int stopIndex, const int stopAllIndex, const bool nesting,
-        const sp<ConditionWizard>& wizard, const uint64_t protoHash,
-        const FieldMatcher& internalDimensions, const int64_t timeBaseNs, const int64_t startTimeNs,
-        const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
-        const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
-        const vector<int>& slicedStateAtoms,
-        const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
-    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
-                     protoHash, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-                     stateGroupMap),
-      mAggregationType(metric.aggregation_type()),
-      mStartIndex(startIndex),
-      mStopIndex(stopIndex),
-      mStopAllIndex(stopAllIndex),
-      mNested(nesting),
-      mContainANYPositionInInternalDimensions(false) {
-    if (metric.has_bucket()) {
-        mBucketSizeNs =
-                TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
-    } else {
-        mBucketSizeNs = LLONG_MAX;
-    }
-
-    if (metric.has_dimensions_in_what()) {
-        translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
-        mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
-    }
-
-    if (internalDimensions.has_field()) {
-        translateFieldMatcher(internalDimensions, &mInternalDimensions);
-        mContainANYPositionInInternalDimensions = HasPositionANY(internalDimensions);
-    }
-    if (mContainANYPositionInInternalDimensions) {
-        ALOGE("Position ANY in internal dimension not supported.");
-    }
-    if (mContainANYPositionInDimensionsInWhat) {
-        ALOGE("Position ANY in dimension_in_what not supported.");
-    }
-
-    // Dimensions in what must be subset of internal dimensions
-    if (!subsetDimensions(mDimensionsInWhat, mInternalDimensions)) {
-        ALOGE("Dimensions in what must be a subset of the internal dimensions");
-        mValid = false;
-    }
-
-    mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-
-    if (metric.links().size() > 0) {
-        for (const auto& link : metric.links()) {
-            Metric2Condition mc;
-            mc.conditionId = link.condition();
-            translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
-            translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
-            if (!subsetDimensions(mc.metricFields, mInternalDimensions)) {
-                ALOGE(("Condition links must be a subset of the internal dimensions"));
-                mValid = false;
-            }
-            mMetric2ConditionLinks.push_back(mc);
-        }
-        mConditionSliced = true;
-    }
-    mUnSlicedPartCondition = ConditionState::kUnknown;
-
-    for (const auto& stateLink : metric.state_link()) {
-        Metric2State ms;
-        ms.stateAtomId = stateLink.state_atom_id();
-        translateFieldMatcher(stateLink.fields_in_what(), &ms.metricFields);
-        translateFieldMatcher(stateLink.fields_in_state(), &ms.stateFields);
-        if (!subsetDimensions(ms.metricFields, mInternalDimensions)) {
-            ALOGE(("State links must be a subset of the dimensions in what  internal dimensions"));
-            mValid = false;
-        }
-        mMetric2StateLinks.push_back(ms);
-    }
-
-    mUseWhatDimensionAsInternalDimension = equalDimensions(mDimensionsInWhat, mInternalDimensions);
-    if (mWizard != nullptr && mConditionTrackerIndex >= 0 &&
-            mMetric2ConditionLinks.size() == 1) {
-        mHasLinksToAllConditionDimensionsInTracker = mWizard->equalOutputDimensions(
-                mConditionTrackerIndex, mMetric2ConditionLinks.begin()->conditionFields);
-    }
-    flushIfNeededLocked(startTimeNs);
-    // Adjust start for partial bucket
-    mCurrentBucketStartTimeNs = startTimeNs;
-    VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
-         (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-
-    initTrueDimensions(whatIndex, startTimeNs);
-}
-
-DurationMetricProducer::~DurationMetricProducer() {
-    VLOG("~DurationMetric() called");
-}
-
-bool DurationMetricProducer::onConfigUpdatedLocked(
-        const StatsdConfig& config, const int configIndex, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!MetricProducer::onConfigUpdatedLocked(
-                config, configIndex, metricIndex, allAtomMatchingTrackers,
-                oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap,
-                trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
-                deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
-        return false;
-    }
-
-    const DurationMetric& metric = config.duration_metric(configIndex);
-    const auto& what_it = conditionTrackerMap.find(metric.what());
-    if (what_it == conditionTrackerMap.end()) {
-        ALOGE("DurationMetric's \"what\" is not present in the config");
-        return false;
-    }
-
-    const Predicate& durationWhat = config.predicate(what_it->second);
-    if (durationWhat.contents_case() != Predicate::ContentsCase::kSimplePredicate) {
-        ALOGE("DurationMetric's \"what\" must be a simple condition");
-        return false;
-    }
-
-    const SimplePredicate& simplePredicate = durationWhat.simple_predicate();
-
-    // Update indices: mStartIndex, mStopIndex, mStopAllIndex, mConditionIndex and MetricsManager
-    // maps.
-    if (!handleMetricWithAtomMatchingTrackers(simplePredicate.start(), metricIndex,
-                                              metric.has_dimensions_in_what(),
-                                              allAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                              trackerToMetricMap, mStartIndex)) {
-        ALOGE("Duration metrics must specify a valid start event matcher");
-        return false;
-    }
-
-    if (simplePredicate.has_stop() &&
-        !handleMetricWithAtomMatchingTrackers(simplePredicate.stop(), metricIndex,
-                                              metric.has_dimensions_in_what(),
-                                              allAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                              trackerToMetricMap, mStopIndex)) {
-        return false;
-    }
-
-    if (simplePredicate.has_stop_all() &&
-        !handleMetricWithAtomMatchingTrackers(simplePredicate.stop_all(), metricIndex,
-                                              metric.has_dimensions_in_what(),
-                                              allAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                              trackerToMetricMap, mStopAllIndex)) {
-        return false;
-    }
-
-    if (metric.has_condition() &&
-        !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                    metric.links(), allConditionTrackers, mConditionTrackerIndex,
-                                    conditionToMetricMap)) {
-        return false;
-    }
-
-    for (const auto& it : mCurrentSlicedDurationTrackerMap) {
-        it.second->onConfigUpdated(wizard, mConditionTrackerIndex);
-    }
-
-    return true;
-}
-
-void DurationMetricProducer::initTrueDimensions(const int whatIndex, const int64_t startTimeNs) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    // Currently whatIndex will only be -1 in tests. In the future, we might want to avoid creating
-    // a ConditionTracker if the condition is only used in the "what" of a duration metric. In that
-    // scenario, -1 can also be passed.
-    if (whatIndex == -1) {
-        return;
-    }
-    const map<HashableDimensionKey, int>* slicedWhatMap = mWizard->getSlicedDimensionMap(whatIndex);
-    for (const auto& [internalDimKey, count] : *slicedWhatMap) {
-        for (int i = 0; i < count; i++) {
-            // Fake start events.
-            handleMatchedLogEventValuesLocked(mStartIndex, internalDimKey.getValues(), startTimeNs);
-        }
-    }
-}
-
-sp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(
-        const Alert &alert, const sp<AlarmMonitor>& anomalyAlarmMonitor) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    if (mAggregationType == DurationMetric_AggregationType_SUM) {
-        if (alert.trigger_if_sum_gt() > alert.num_buckets() * mBucketSizeNs) {
-            ALOGW("invalid alert for SUM: threshold (%f) > possible recordable value (%d x %lld)",
-                  alert.trigger_if_sum_gt(), alert.num_buckets(), (long long)mBucketSizeNs);
-            return nullptr;
-        }
-    }
-    sp<AnomalyTracker> anomalyTracker =
-            new DurationAnomalyTracker(alert, mConfigKey, anomalyAlarmMonitor);
-    addAnomalyTrackerLocked(anomalyTracker);
-    return anomalyTracker;
-}
-
-// Adds an AnomalyTracker that has already been created.
-// Note: this gets called on config updates, and will only get called if the metric and the
-// associated alert are preserved, which means the AnomalyTracker must be a DurationAnomalyTracker.
-void DurationMetricProducer::addAnomalyTracker(sp<AnomalyTracker>& anomalyTracker) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    addAnomalyTrackerLocked(anomalyTracker);
-}
-
-void DurationMetricProducer::addAnomalyTrackerLocked(sp<AnomalyTracker>& anomalyTracker) {
-    mAnomalyTrackers.push_back(anomalyTracker);
-    for (const auto& [_, durationTracker] : mCurrentSlicedDurationTrackerMap) {
-        durationTracker->addAnomalyTracker(anomalyTracker);
-    }
-}
-void DurationMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
-                                            const HashableDimensionKey& primaryKey,
-                                            const FieldValue& oldState,
-                                            const FieldValue& newState) {
-    // Check if this metric has a StateMap. If so, map the new state value to
-    // the correct state group id.
-    FieldValue newStateCopy = newState;
-    mapStateValue(atomId, &newStateCopy);
-
-    flushIfNeededLocked(eventTimeNs);
-
-    // Each duration tracker is mapped to a different whatKey (a set of values from the
-    // dimensionsInWhat fields). We notify all trackers iff the primaryKey field values from the
-    // state change event are a subset of the tracker's whatKey field values.
-    //
-    // Ex. For a duration metric dimensioned on uid and tag:
-    // DurationTracker1 whatKey = uid: 1001, tag: 1
-    // DurationTracker2 whatKey = uid: 1002, tag 1
-    //
-    // If the state change primaryKey = uid: 1001, we only notify DurationTracker1 of a state
-    // change.
-    for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
-        if (!containsLinkedStateValues(whatIt.first, primaryKey, mMetric2StateLinks, atomId)) {
-            continue;
-        }
-        whatIt.second->onStateChanged(eventTimeNs, atomId, newStateCopy);
-    }
-}
-
-unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker(
-        const MetricDimensionKey& eventKey) const {
-    switch (mAggregationType) {
-        case DurationMetric_AggregationType_SUM:
-            return make_unique<OringDurationTracker>(
-                    mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, mNested,
-                    mCurrentBucketStartTimeNs, mCurrentBucketNum, mTimeBaseNs, mBucketSizeNs,
-                    mConditionSliced, mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
-        case DurationMetric_AggregationType_MAX_SPARSE:
-            return make_unique<MaxDurationTracker>(
-                    mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, mNested,
-                    mCurrentBucketStartTimeNs, mCurrentBucketNum, mTimeBaseNs, mBucketSizeNs,
-                    mConditionSliced, mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
-    }
-}
-
-// SlicedConditionChange optimization case 1:
-// 1. If combination condition, logical operation is AND, only one sliced child predicate.
-// 2. The links covers all dimension fields in the sliced child condition predicate.
-void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool condition,
-                                                                   const int64_t eventTime) {
-    if (mMetric2ConditionLinks.size() != 1 ||
-        !mHasLinksToAllConditionDimensionsInTracker) {
-        return;
-    }
-
-    bool  currentUnSlicedPartCondition = true;
-    if (!mWizard->IsSimpleCondition(mConditionTrackerIndex)) {
-        ConditionState unslicedPartState =
-            mWizard->getUnSlicedPartConditionState(mConditionTrackerIndex);
-        // When the unsliced part is still false, return directly.
-        if (mUnSlicedPartCondition == ConditionState::kFalse &&
-            unslicedPartState == ConditionState::kFalse) {
-            return;
-        }
-        mUnSlicedPartCondition = unslicedPartState;
-        currentUnSlicedPartCondition = mUnSlicedPartCondition > 0;
-    }
-
-    auto dimensionsChangedToTrue = mWizard->getChangedToTrueDimensions(mConditionTrackerIndex);
-    auto dimensionsChangedToFalse = mWizard->getChangedToFalseDimensions(mConditionTrackerIndex);
-
-    // The condition change is from the unsliced predicates.
-    // We need to find out the true dimensions from the sliced predicate and flip their condition
-    // state based on the new unsliced condition state.
-    if (dimensionsChangedToTrue == nullptr || dimensionsChangedToFalse == nullptr ||
-        (dimensionsChangedToTrue->empty() && dimensionsChangedToFalse->empty())) {
-        const map<HashableDimensionKey, int>* slicedConditionMap =
-                mWizard->getSlicedDimensionMap(mConditionTrackerIndex);
-        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
-            HashableDimensionKey linkedConditionDimensionKey;
-            getDimensionForCondition(whatIt.first.getValues(), mMetric2ConditionLinks[0],
-                                     &linkedConditionDimensionKey);
-            const auto& slicedConditionIt = slicedConditionMap->find(linkedConditionDimensionKey);
-            if (slicedConditionIt != slicedConditionMap->end() && slicedConditionIt->second > 0) {
-                whatIt.second->onConditionChanged(currentUnSlicedPartCondition, eventTime);
-            }
-        }
-    } else {
-        // Handle the condition change from the sliced predicate.
-        if (currentUnSlicedPartCondition) {
-            for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
-                HashableDimensionKey linkedConditionDimensionKey;
-                getDimensionForCondition(whatIt.first.getValues(), mMetric2ConditionLinks[0],
-                                         &linkedConditionDimensionKey);
-                if (dimensionsChangedToTrue->find(linkedConditionDimensionKey) !=
-                        dimensionsChangedToTrue->end()) {
-                    whatIt.second->onConditionChanged(true, eventTime);
-                }
-                if (dimensionsChangedToFalse->find(linkedConditionDimensionKey) !=
-                        dimensionsChangedToFalse->end()) {
-                    whatIt.second->onConditionChanged(false, eventTime);
-                }
-            }
-        }
-    }
-}
-
-void DurationMetricProducer::onSlicedConditionMayChangeInternalLocked(bool overallCondition,
-        const int64_t eventTimeNs) {
-    bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex);
-    if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker) {
-        onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTimeNs);
-        return;
-    }
-
-    // Now for each of the on-going event, check if the condition has changed for them.
-    for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
-        whatIt.second->onSlicedConditionMayChange(overallCondition, eventTimeNs);
-    }
-}
-
-void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
-                                                              const int64_t eventTime) {
-    VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-
-    if (!mIsActive) {
-        return;
-    }
-
-    flushIfNeededLocked(eventTime);
-
-    if (!mConditionSliced) {
-        return;
-    }
-
-    onSlicedConditionMayChangeInternalLocked(overallCondition, eventTime);
-}
-
-void DurationMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
-    MetricProducer::onActiveStateChangedLocked(eventTimeNs);
-
-    if (!mConditionSliced) {
-        if (ConditionState::kTrue != mCondition) {
-            return;
-        }
-
-        if (mIsActive) {
-            flushIfNeededLocked(eventTimeNs);
-        }
-
-        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
-            whatIt.second->onConditionChanged(mIsActive, eventTimeNs);
-        }
-    } else if (mIsActive) {
-        flushIfNeededLocked(eventTimeNs);
-        onSlicedConditionMayChangeInternalLocked(mIsActive, eventTimeNs);
-    } else { // mConditionSliced == true && !mIsActive
-        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
-            whatIt.second->onConditionChanged(mIsActive, eventTimeNs);
-        }
-    }
-}
-
-void DurationMetricProducer::onConditionChangedLocked(const bool conditionMet,
-                                                      const int64_t eventTime) {
-    VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
-    mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-
-    if (!mIsActive) {
-        return;
-    }
-
-    flushIfNeededLocked(eventTime);
-    for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
-        whatIt.second->onConditionChanged(conditionMet, eventTime);
-    }
-}
-
-void DurationMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
-    flushIfNeededLocked(dropTimeNs);
-    StatsdStats::getInstance().noteBucketDropped(mMetricId);
-    mPastBuckets.clear();
-}
-
-void DurationMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
-    flushIfNeededLocked(dumpTimeNs);
-    mPastBuckets.clear();
-}
-
-void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
-                                                const bool include_current_partial_bucket,
-                                                const bool erase_data,
-                                                const DumpLatency dumpLatency,
-                                                std::set<string> *str_set,
-                                                ProtoOutputStream* protoOutput) {
-    if (include_current_partial_bucket) {
-        flushLocked(dumpTimeNs);
-    } else {
-        flushIfNeededLocked(dumpTimeNs);
-    }
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
-    protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
-    if (mPastBuckets.empty()) {
-        VLOG(" Duration metric, empty return");
-        return;
-    }
-
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-
-    if (!mSliceByPositionALL) {
-        if (!mDimensionsInWhat.empty()) {
-            uint64_t dimenPathToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
-            writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
-            protoOutput->end(dimenPathToken);
-        }
-    }
-
-    uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS);
-
-    VLOG("Duration metric %lld dump report now...", (long long)mMetricId);
-
-    for (const auto& pair : mPastBuckets) {
-        const MetricDimensionKey& dimensionKey = pair.first;
-        VLOG("  dimension key %s", dimensionKey.toString().c_str());
-
-        uint64_t wrapperToken =
-                protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
-        // First fill dimension.
-        if (mSliceByPositionALL) {
-            uint64_t dimensionToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
-            writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
-            protoOutput->end(dimensionToken);
-        } else {
-            writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
-                                           FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
-        }
-        // Then fill slice_by_state.
-        for (auto state : dimensionKey.getStateValuesKey().getValues()) {
-            uint64_t stateToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                     FIELD_ID_SLICE_BY_STATE);
-            writeStateToProto(state, protoOutput);
-            protoOutput->end(stateToken);
-        }
-        // Then fill bucket_info (DurationBucketInfo).
-        for (const auto& bucket : pair.second) {
-            uint64_t bucketInfoToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
-            if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
-                                   (long long)NanoToMillis(bucket.mBucketStartNs));
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
-                                   (long long)NanoToMillis(bucket.mBucketEndNs));
-            } else {
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
-                                   (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
-            }
-            protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DURATION, (long long)bucket.mDuration);
-            protoOutput->end(bucketInfoToken);
-            VLOG("\t bucket [%lld - %lld] duration: %lld", (long long)bucket.mBucketStartNs,
-                 (long long)bucket.mBucketEndNs, (long long)bucket.mDuration);
-        }
-
-        protoOutput->end(wrapperToken);
-    }
-
-    protoOutput->end(protoToken);
-    if (erase_data) {
-        mPastBuckets.clear();
-    }
-}
-
-void DurationMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
-    int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
-
-    if (currentBucketEndTimeNs > eventTimeNs) {
-        return;
-    }
-    VLOG("flushing...........");
-    int numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
-    int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
-    flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
-
-    mCurrentBucketNum += numBucketsForward;
-}
-
-void DurationMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
-                                                      const int64_t& nextBucketStartTimeNs) {
-    for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin();
-            whatIt != mCurrentSlicedDurationTrackerMap.end();) {
-        if (whatIt->second->flushCurrentBucket(eventTimeNs, &mPastBuckets)) {
-            VLOG("erase bucket for key %s", whatIt->first.toString().c_str());
-            whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt);
-        } else {
-            ++whatIt;
-        }
-    }
-    StatsdStats::getInstance().noteBucketCount(mMetricId);
-    mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
-}
-
-void DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
-    if (mCurrentSlicedDurationTrackerMap.size() == 0) {
-        return;
-    }
-
-    fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId,
-            (unsigned long)mCurrentSlicedDurationTrackerMap.size());
-    if (verbose) {
-        for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) {
-            fprintf(out, "\t(what)%s\n", whatIt.first.toString().c_str());
-            whatIt.second->dumpStates(out, verbose);
-        }
-    }
-}
-
-bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
-    auto whatIt = mCurrentSlicedDurationTrackerMap.find(newKey.getDimensionKeyInWhat());
-    if (whatIt == mCurrentSlicedDurationTrackerMap.end()) {
-        // 1. Report the tuple count if the tuple count > soft limit
-        if (mCurrentSlicedDurationTrackerMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
-            size_t newTupleCount = mCurrentSlicedDurationTrackerMap.size() + 1;
-            StatsdStats::getInstance().noteMetricDimensionSize(
-                    mConfigKey, mMetricId, newTupleCount);
-            // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
-            if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
-                ALOGE("DurationMetric %lld dropping data for what dimension key %s",
-                    (long long)mMetricId, newKey.getDimensionKeyInWhat().toString().c_str());
-                StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-void DurationMetricProducer::handleStartEvent(const MetricDimensionKey& eventKey,
-                                              const ConditionKey& conditionKeys, bool condition,
-                                              const int64_t eventTimeNs,
-                                              const vector<FieldValue>& eventValues) {
-    const auto& whatKey = eventKey.getDimensionKeyInWhat();
-    auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatKey);
-    if (whatIt == mCurrentSlicedDurationTrackerMap.end()) {
-        if (hitGuardRailLocked(eventKey)) {
-            return;
-        }
-        mCurrentSlicedDurationTrackerMap[whatKey] = createDurationTracker(eventKey);
-    }
-
-    auto it = mCurrentSlicedDurationTrackerMap.find(whatKey);
-    if (mUseWhatDimensionAsInternalDimension) {
-        it->second->noteStart(whatKey, condition, eventTimeNs, conditionKeys);
-        return;
-    }
-
-    if (mInternalDimensions.empty()) {
-        it->second->noteStart(DEFAULT_DIMENSION_KEY, condition, eventTimeNs, conditionKeys);
-    } else {
-        HashableDimensionKey dimensionKey = DEFAULT_DIMENSION_KEY;
-        filterValues(mInternalDimensions, eventValues, &dimensionKey);
-        it->second->noteStart(dimensionKey, condition, eventTimeNs, conditionKeys);
-    }
-}
-
-void DurationMetricProducer::onMatchedLogEventInternalLocked(
-        const size_t matcherIndex, const MetricDimensionKey& eventKey,
-        const ConditionKey& conditionKeys, bool condition, const LogEvent& event,
-        const map<int, HashableDimensionKey>& statePrimaryKeys) {
-    ALOGW("Not used in duration tracker.");
-}
-
-void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
-                                                     const LogEvent& event) {
-    handleMatchedLogEventValuesLocked(matcherIndex, event.getValues(),
-                                      event.GetElapsedTimestampNs());
-}
-
-void DurationMetricProducer::handleMatchedLogEventValuesLocked(const size_t matcherIndex,
-                                                               const vector<FieldValue>& values,
-                                                               const int64_t eventTimeNs) {
-    if (eventTimeNs < mTimeBaseNs) {
-        return;
-    }
-
-    if (mIsActive) {
-        flushIfNeededLocked(eventTimeNs);
-    }
-
-    // Handles Stopall events.
-    if ((int)matcherIndex == mStopAllIndex) {
-        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
-            whatIt.second->noteStopAll(eventTimeNs);
-        }
-        return;
-    }
-
-    HashableDimensionKey dimensionInWhat = DEFAULT_DIMENSION_KEY;
-    if (!mDimensionsInWhat.empty()) {
-        filterValues(mDimensionsInWhat, values, &dimensionInWhat);
-    }
-
-    // Stores atom id to primary key pairs for each state atom that the metric is
-    // sliced by.
-    std::map<int, HashableDimensionKey> statePrimaryKeys;
-
-    // For states with primary fields, use MetricStateLinks to get the primary
-    // field values from the log event. These values will form a primary key
-    // that will be used to query StateTracker for the correct state value.
-    for (const auto& stateLink : mMetric2StateLinks) {
-        getDimensionForState(values, stateLink, &statePrimaryKeys[stateLink.stateAtomId]);
-    }
-
-    // For each sliced state, query StateTracker for the state value using
-    // either the primary key from the previous step or the DEFAULT_DIMENSION_KEY.
-    //
-    // Expected functionality: for any case where the MetricStateLinks are
-    // initialized incorrectly (ex. # of state links != # of primary fields, no
-    // links are provided for a state with primary fields, links are provided
-    // in the wrong order, etc.), StateTracker will simply return kStateUnknown
-    // when queried using an incorrect key.
-    HashableDimensionKey stateValuesKey = DEFAULT_DIMENSION_KEY;
-    for (auto atomId : mSlicedStateAtoms) {
-        FieldValue value;
-        if (statePrimaryKeys.find(atomId) != statePrimaryKeys.end()) {
-            // found a primary key for this state, query using the key
-            queryStateValue(atomId, statePrimaryKeys[atomId], &value);
-        } else {
-            // if no MetricStateLinks exist for this state atom,
-            // query using the default dimension key (empty HashableDimensionKey)
-            queryStateValue(atomId, DEFAULT_DIMENSION_KEY, &value);
-        }
-        mapStateValue(atomId, &value);
-        stateValuesKey.addValue(value);
-    }
-
-    // Handles Stop events.
-    if ((int)matcherIndex == mStopIndex) {
-        if (mUseWhatDimensionAsInternalDimension) {
-            auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
-            if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
-                whatIt->second->noteStop(dimensionInWhat, eventTimeNs, false);
-            }
-            return;
-        }
-
-        HashableDimensionKey internalDimensionKey = DEFAULT_DIMENSION_KEY;
-        if (!mInternalDimensions.empty()) {
-            filterValues(mInternalDimensions, values, &internalDimensionKey);
-        }
-
-        auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
-        if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
-            whatIt->second->noteStop(internalDimensionKey, eventTimeNs, false);
-        }
-        return;
-    }
-
-    bool condition;
-    ConditionKey conditionKey;
-    if (mConditionSliced) {
-        for (const auto& link : mMetric2ConditionLinks) {
-            getDimensionForCondition(values, link, &conditionKey[link.conditionId]);
-        }
-
-        auto conditionState =
-            mWizard->query(mConditionTrackerIndex, conditionKey,
-                           !mHasLinksToAllConditionDimensionsInTracker);
-        condition = conditionState == ConditionState::kTrue;
-    } else {
-        // TODO: The unknown condition state is not handled here, we should fix it.
-        condition = mCondition == ConditionState::kTrue;
-    }
-
-    condition = condition && mIsActive;
-
-    handleStartEvent(MetricDimensionKey(dimensionInWhat, stateValuesKey), conditionKey, condition,
-                     eventTimeNs, values);
-}
-
-size_t DurationMetricProducer::byteSizeLocked() const {
-    size_t totalSize = 0;
-    for (const auto& pair : mPastBuckets) {
-        totalSize += pair.second.size() * kBucketSize;
-    }
-    return totalSize;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
deleted file mode 100644
index 9fb586f..0000000
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-
-#include <unordered_map>
-
-#include <android/util/ProtoOutputStream.h>
-#include "../anomaly/DurationAnomalyTracker.h"
-#include "../condition/ConditionTracker.h"
-#include "../matchers/matcher_util.h"
-#include "MetricProducer.h"
-#include "duration_helper/DurationTracker.h"
-#include "duration_helper/MaxDurationTracker.h"
-#include "duration_helper/OringDurationTracker.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class DurationMetricProducer : public MetricProducer {
-public:
-    DurationMetricProducer(
-            const ConfigKey& key, const DurationMetric& durationMetric, const int conditionIndex,
-            const vector<ConditionState>& initialConditionCache, const int whatIndex,
-            const int startIndex, const int stopIndex, const int stopAllIndex, const bool nesting,
-            const sp<ConditionWizard>& wizard, const uint64_t protoHash,
-            const FieldMatcher& internalDimensions, const int64_t timeBaseNs,
-            const int64_t startTimeNs,
-            const unordered_map<int, shared_ptr<Activation>>& eventActivationMap = {},
-            const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap = {},
-            const vector<int>& slicedStateAtoms = {},
-            const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
-    virtual ~DurationMetricProducer();
-
-    sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
-                                         const sp<AlarmMonitor>& anomalyAlarmMonitor) override;
-
-    void addAnomalyTracker(sp<AnomalyTracker>& anomalyTracker) override;
-
-    void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
-                        const HashableDimensionKey& primaryKey, const FieldValue& oldState,
-                        const FieldValue& newState) override;
-
-    MetricType getMetricType() const override {
-        return METRIC_TYPE_DURATION;
-    }
-
-protected:
-    void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) override;
-
-    void onMatchedLogEventInternalLocked(
-            const size_t matcherIndex, const MetricDimensionKey& eventKey,
-            const ConditionKey& conditionKeys, bool condition, const LogEvent& event,
-            const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
-    // Initializes true dimensions of the 'what' predicate. Only to be called during initialization.
-    void initTrueDimensions(const int whatIndex, const int64_t startTimeNs);
-
-    void handleMatchedLogEventValuesLocked(const size_t matcherIndex,
-                                           const std::vector<FieldValue>& values,
-                                           const int64_t eventTimeNs);
-    void handleStartEvent(const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys,
-                          bool condition, const int64_t eventTimeNs,
-                          const vector<FieldValue>& eventValues);
-
-    void onDumpReportLocked(const int64_t dumpTimeNs,
-                            const bool include_current_partial_bucket,
-                            const bool erase_data,
-                            const DumpLatency dumpLatency,
-                            std::set<string> *str_set,
-                            android::util::ProtoOutputStream* protoOutput) override;
-
-    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
-    // Internal interface to handle condition change.
-    void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
-    // Internal interface to handle active state change.
-    void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
-
-    // Internal interface to handle sliced condition change.
-    void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
-    void onSlicedConditionMayChangeInternalLocked(bool overallCondition,
-                                                  const int64_t eventTimeNs);
-
-    void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const int64_t eventTime);
-    void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const int64_t eventTime);
-
-    // Internal function to calculate the current used bytes.
-    size_t byteSizeLocked() const override;
-
-    void dumpStatesLocked(FILE* out, bool verbose) const override;
-
-    void dropDataLocked(const int64_t dropTimeNs) override;
-
-    // Util function to flush the old packet.
-    void flushIfNeededLocked(const int64_t& eventTime);
-
-    void flushCurrentBucketLocked(const int64_t& eventTimeNs,
-                                  const int64_t& nextBucketStartTimeNs) override;
-
-    bool onConfigUpdatedLocked(
-            const StatsdConfig& config, const int configIndex, const int metricIndex,
-            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-            const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-            const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-            const sp<EventMatcherWizard>& matcherWizard,
-            const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-            const std::unordered_map<int64_t, int>& conditionTrackerMap,
-            const sp<ConditionWizard>& wizard,
-            const std::unordered_map<int64_t, int>& metricToActivationMap,
-            std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-            std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-            std::vector<int>& metricsWithActivation) override;
-
-    void addAnomalyTrackerLocked(sp<AnomalyTracker>& anomalyTracker);
-
-    const DurationMetric_AggregationType mAggregationType;
-
-    // Index of the SimpleAtomMatcher which defines the start.
-    int mStartIndex;
-
-    // Index of the SimpleAtomMatcher which defines the stop.
-    int mStopIndex;
-
-    // Index of the SimpleAtomMatcher which defines the stop all for all dimensions.
-    int mStopAllIndex;
-
-    // nest counting -- for the same key, stops must match the number of starts to make real stop
-    const bool mNested;
-
-    // The dimension from the atom predicate. e.g., uid, wakelock name.
-    vector<Matcher> mInternalDimensions;
-
-    bool mContainANYPositionInInternalDimensions;
-
-    // This boolean is true iff When mInternalDimensions == mDimensionsInWhat
-    bool mUseWhatDimensionAsInternalDimension;
-
-    // Caches the current unsliced part condition.
-    ConditionState mUnSlicedPartCondition;
-
-    // Save the past buckets and we can clear when the StatsLogReport is dumped.
-    std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets;
-
-    // The duration trackers in the current bucket.
-    std::unordered_map<HashableDimensionKey, std::unique_ptr<DurationTracker>>
-            mCurrentSlicedDurationTrackerMap;
-
-    // Helper function to create a duration tracker given the metric aggregation type.
-    std::unique_ptr<DurationTracker> createDurationTracker(
-            const MetricDimensionKey& eventKey) const;
-
-    // Util function to check whether the specified dimension hits the guardrail.
-    bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
-    static const size_t kBucketSize = sizeof(DurationBucket{});
-
-    FRIEND_TEST(DurationMetricTrackerTest, TestNoCondition);
-    FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedCondition);
-    FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState);
-    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicates);
-    FRIEND_TEST(DurationMetricTrackerTest, TestFirstBucket);
-
-    FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestSumDuration);
-    FRIEND_TEST(DurationMetricProducerTest_PartialBucket,
-                TestSumDurationWithSplitInFollowingBucket);
-    FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDuration);
-    FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket);
-
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateDurationMetrics);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlerts);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
deleted file mode 100644
index ca302c0..0000000
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "EventMetricProducer.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-#include "metrics/parsing_utils/metrics_manager_util.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_STRING;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_EVENT_METRICS = 4;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for EventMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-// for EventMetricData
-const int FIELD_ID_ELAPSED_TIMESTAMP_NANOS = 1;
-const int FIELD_ID_ATOMS = 2;
-
-EventMetricProducer::EventMetricProducer(
-        const ConfigKey& key, const EventMetric& metric, const int conditionIndex,
-        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const uint64_t protoHash, const int64_t startTimeNs,
-        const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
-        const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
-        const vector<int>& slicedStateAtoms,
-        const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
-    : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, initialConditionCache, wizard,
-                     protoHash, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-                     stateGroupMap) {
-    if (metric.links().size() > 0) {
-        for (const auto& link : metric.links()) {
-            Metric2Condition mc;
-            mc.conditionId = link.condition();
-            translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
-            translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
-            mMetric2ConditionLinks.push_back(mc);
-        }
-        mConditionSliced = true;
-    }
-    mProto = std::make_unique<ProtoOutputStream>();
-    VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
-         (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-EventMetricProducer::~EventMetricProducer() {
-    VLOG("~EventMetricProducer() called");
-}
-
-bool EventMetricProducer::onConfigUpdatedLocked(
-        const StatsdConfig& config, const int configIndex, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!MetricProducer::onConfigUpdatedLocked(
-                config, configIndex, metricIndex, allAtomMatchingTrackers,
-                oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap,
-                trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
-                deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
-        return false;
-    }
-
-    const EventMetric& metric = config.event_metric(configIndex);
-    int trackerIndex;
-    // Update appropriate indices, specifically mConditionIndex and MetricsManager maps.
-    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, false,
-                                              allAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                              trackerToMetricMap, trackerIndex)) {
-        return false;
-    }
-
-    if (metric.has_condition() &&
-        !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                    metric.links(), allConditionTrackers, mConditionTrackerIndex,
-                                    conditionToMetricMap)) {
-        return false;
-    }
-    return true;
-}
-
-void EventMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
-    mProto->clear();
-    StatsdStats::getInstance().noteBucketDropped(mMetricId);
-}
-
-void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
-                                                           const int64_t eventTime) {
-}
-
-std::unique_ptr<std::vector<uint8_t>> serializeProtoLocked(ProtoOutputStream& protoOutput) {
-    size_t bufferSize = protoOutput.size();
-
-    std::unique_ptr<std::vector<uint8_t>> buffer(new std::vector<uint8_t>(bufferSize));
-
-    size_t pos = 0;
-    sp<android::util::ProtoReader> reader = protoOutput.data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(&((*buffer)[pos]), reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-
-    return buffer;
-}
-
-void EventMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
-    mProto->clear();
-}
-
-void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
-                                             const bool include_current_partial_bucket,
-                                             const bool erase_data,
-                                             const DumpLatency dumpLatency,
-                                             std::set<string> *str_set,
-                                             ProtoOutputStream* protoOutput) {
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
-    protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-    if (mProto->size() <= 0) {
-        return;
-    }
-
-    size_t bufferSize = mProto->size();
-    VLOG("metric %lld dump report now... proto size: %zu ",
-        (long long)mMetricId, bufferSize);
-    std::unique_ptr<std::vector<uint8_t>> buffer = serializeProtoLocked(*mProto);
-
-    protoOutput->write(FIELD_TYPE_MESSAGE | FIELD_ID_EVENT_METRICS,
-                       reinterpret_cast<char*>(buffer.get()->data()), buffer.get()->size());
-
-    if (erase_data) {
-        mProto->clear();
-    }
-}
-
-void EventMetricProducer::onConditionChangedLocked(const bool conditionMet,
-                                                   const int64_t eventTime) {
-    VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
-    mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-}
-
-void EventMetricProducer::onMatchedLogEventInternalLocked(
-        const size_t matcherIndex, const MetricDimensionKey& eventKey,
-        const ConditionKey& conditionKey, bool condition, const LogEvent& event,
-        const map<int, HashableDimensionKey>& statePrimaryKeys) {
-    if (!condition) {
-        return;
-    }
-
-    uint64_t wrapperToken =
-            mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-    const int64_t elapsedTimeNs = truncateTimestampIfNecessary(event);
-    mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS, (long long) elapsedTimeNs);
-
-    uint64_t eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
-    event.ToProto(*mProto);
-    mProto->end(eventToken);
-    mProto->end(wrapperToken);
-}
-
-size_t EventMetricProducer::byteSizeLocked() const {
-    return mProto->bytesWritten();
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
deleted file mode 100644
index 3347d7b..0000000
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef EVENT_METRIC_PRODUCER_H
-#define EVENT_METRIC_PRODUCER_H
-
-#include <unordered_map>
-
-#include <android/util/ProtoOutputStream.h>
-
-#include "../condition/ConditionTracker.h"
-#include "../matchers/matcher_util.h"
-#include "MetricProducer.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class EventMetricProducer : public MetricProducer {
-public:
-    EventMetricProducer(
-            const ConfigKey& key, const EventMetric& eventMetric, const int conditionIndex,
-            const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-            const uint64_t protoHash, const int64_t startTimeNs,
-            const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
-            const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
-                    eventDeactivationMap = {},
-            const vector<int>& slicedStateAtoms = {},
-            const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
-    virtual ~EventMetricProducer();
-
-    MetricType getMetricType() const override {
-        return METRIC_TYPE_EVENT;
-    }
-
-private:
-    void onMatchedLogEventInternalLocked(
-            const size_t matcherIndex, const MetricDimensionKey& eventKey,
-            const ConditionKey& conditionKey, bool condition, const LogEvent& event,
-            const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-    void onDumpReportLocked(const int64_t dumpTimeNs,
-                            const bool include_current_partial_bucket,
-                            const bool erase_data,
-                            const DumpLatency dumpLatency,
-                            std::set<string> *str_set,
-                            android::util::ProtoOutputStream* protoOutput) override;
-    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
-    // Internal interface to handle condition change.
-    void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
-    // Internal interface to handle sliced condition change.
-    void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
-    bool onConfigUpdatedLocked(
-            const StatsdConfig& config, const int configIndex, const int metricIndex,
-            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-            const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-            const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-            const sp<EventMatcherWizard>& matcherWizard,
-            const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-            const std::unordered_map<int64_t, int>& conditionTrackerMap,
-            const sp<ConditionWizard>& wizard,
-            const std::unordered_map<int64_t, int>& metricToActivationMap,
-            std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-            std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-            std::vector<int>& metricsWithActivation) override;
-
-    void dropDataLocked(const int64_t dropTimeNs) override;
-
-    // Internal function to calculate the current used bytes.
-    size_t byteSizeLocked() const override;
-
-    void dumpStatesLocked(FILE* out, bool verbose) const override{};
-
-    // Maps to a EventMetricDataWrapper. Storing atom events in ProtoOutputStream
-    // is more space efficient than storing LogEvent.
-    std::unique_ptr<android::util::ProtoOutputStream> mProto;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#endif  // EVENT_METRIC_PRODUCER_H
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
deleted file mode 100644
index 2a37b58..0000000
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
-* Copyright (C) 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.
-*/
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "GaugeMetricProducer.h"
-
-#include "guardrail/StatsdStats.h"
-#include "metrics/parsing_utils/metrics_manager_util.h"
-#include "stats_log_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::string;
-using std::unordered_map;
-using std::vector;
-using std::make_shared;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_GAUGE_METRICS = 8;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for GaugeMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-const int FIELD_ID_SKIPPED = 2;
-// for SkippedBuckets
-const int FIELD_ID_SKIPPED_START_MILLIS = 3;
-const int FIELD_ID_SKIPPED_END_MILLIS = 4;
-const int FIELD_ID_SKIPPED_DROP_EVENT = 5;
-// for DumpEvent Proto
-const int FIELD_ID_BUCKET_DROP_REASON = 1;
-const int FIELD_ID_DROP_TIME = 2;
-// for GaugeMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-// for GaugeBucketInfo
-const int FIELD_ID_ATOM = 3;
-const int FIELD_ID_ELAPSED_ATOM_TIMESTAMP = 4;
-const int FIELD_ID_BUCKET_NUM = 6;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 7;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 8;
-
-GaugeMetricProducer::GaugeMetricProducer(
-        const ConfigKey& key, const GaugeMetric& metric, const int conditionIndex,
-        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const uint64_t protoHash, const int whatMatcherIndex,
-        const sp<EventMatcherWizard>& matcherWizard, const int pullTagId, const int triggerAtomId,
-        const int atomId, const int64_t timeBaseNs, const int64_t startTimeNs,
-        const sp<StatsPullerManager>& pullerManager,
-        const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
-        const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap)
-    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache, wizard,
-                     protoHash, eventActivationMap, eventDeactivationMap, /*slicedStateAtoms=*/{},
-                     /*stateGroupMap=*/{}),
-      mWhatMatcherIndex(whatMatcherIndex),
-      mEventMatcherWizard(matcherWizard),
-      mPullerManager(pullerManager),
-      mPullTagId(pullTagId),
-      mTriggerAtomId(triggerAtomId),
-      mAtomId(atomId),
-      mIsPulled(pullTagId != -1),
-      mMinBucketSizeNs(metric.min_bucket_size_nanos()),
-      mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
-                                                      : StatsdStats::kPullMaxDelayNs),
-      mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
-                                          StatsdStats::kAtomDimensionKeySizeLimitMap.end()
-                                  ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).first
-                                  : StatsdStats::kDimensionKeySizeSoftLimit),
-      mDimensionHardLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
-                                          StatsdStats::kAtomDimensionKeySizeLimitMap.end()
-                                  ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
-                                  : StatsdStats::kDimensionKeySizeHardLimit),
-      mGaugeAtomsPerDimensionLimit(metric.max_num_gauge_atoms_per_bucket()),
-      mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()) {
-    mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
-    mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
-    int64_t bucketSizeMills = 0;
-    if (metric.has_bucket()) {
-        bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
-    } else {
-        bucketSizeMills = TimeUnitToBucketSizeInMillis(ONE_HOUR);
-    }
-    mBucketSizeNs = bucketSizeMills * 1000000;
-
-    mSamplingType = metric.sampling_type();
-    if (!metric.gauge_fields_filter().include_all()) {
-        translateFieldMatcher(metric.gauge_fields_filter().fields(), &mFieldMatchers);
-    }
-
-    if (metric.has_dimensions_in_what()) {
-        translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
-        mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
-    }
-
-    if (metric.links().size() > 0) {
-        for (const auto& link : metric.links()) {
-            Metric2Condition mc;
-            mc.conditionId = link.condition();
-            translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
-            translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
-            mMetric2ConditionLinks.push_back(mc);
-        }
-        mConditionSliced = true;
-    }
-    mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-
-    flushIfNeededLocked(startTimeNs);
-    // Kicks off the puller immediately.
-    if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
-        mPullerManager->RegisterReceiver(mPullTagId, mConfigKey, this, getCurrentBucketEndTimeNs(),
-                                         mBucketSizeNs);
-    }
-
-    // Adjust start for partial first bucket and then pull if needed
-    mCurrentBucketStartTimeNs = startTimeNs;
-
-    VLOG("Gauge metric %lld created. bucket size %lld start_time: %lld sliced %d",
-         (long long)metric.id(), (long long)mBucketSizeNs, (long long)mTimeBaseNs,
-         mConditionSliced);
-}
-
-GaugeMetricProducer::~GaugeMetricProducer() {
-    VLOG("~GaugeMetricProducer() called");
-    if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
-        mPullerManager->UnRegisterReceiver(mPullTagId, mConfigKey, this);
-    }
-}
-
-bool GaugeMetricProducer::onConfigUpdatedLocked(
-        const StatsdConfig& config, const int configIndex, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!MetricProducer::onConfigUpdatedLocked(
-                config, configIndex, metricIndex, allAtomMatchingTrackers,
-                oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap,
-                trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
-                deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
-        return false;
-    }
-
-    const GaugeMetric& metric = config.gauge_metric(configIndex);
-    // Update appropriate indices: mWhatMatcherIndex, mConditionIndex and MetricsManager maps.
-    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, /*enforceOneAtom=*/false,
-                                              allAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                              trackerToMetricMap, mWhatMatcherIndex)) {
-        return false;
-    }
-
-    // Need to update maps since the index changed, but mTriggerAtomId will not change.
-    int triggerTrackerIndex;
-    if (metric.has_trigger_event() &&
-        !handleMetricWithAtomMatchingTrackers(metric.trigger_event(), metricIndex,
-                                              /*enforceOneAtom=*/true, allAtomMatchingTrackers,
-                                              newAtomMatchingTrackerMap, trackerToMetricMap,
-                                              triggerTrackerIndex)) {
-        return false;
-    }
-
-    if (metric.has_condition() &&
-        !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                    metric.links(), allConditionTrackers, mConditionTrackerIndex,
-                                    conditionToMetricMap)) {
-        return false;
-    }
-    sp<EventMatcherWizard> tmpEventWizard = mEventMatcherWizard;
-    mEventMatcherWizard = matcherWizard;
-    return true;
-}
-
-void GaugeMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
-    if (mCurrentSlicedBucket == nullptr ||
-        mCurrentSlicedBucket->size() == 0) {
-        return;
-    }
-
-    fprintf(out, "GaugeMetric %lld dimension size %lu\n", (long long)mMetricId,
-            (unsigned long)mCurrentSlicedBucket->size());
-    if (verbose) {
-        for (const auto& it : *mCurrentSlicedBucket) {
-            fprintf(out, "\t(what)%s\t(states)%s  %d atoms\n",
-                    it.first.getDimensionKeyInWhat().toString().c_str(),
-                    it.first.getStateValuesKey().toString().c_str(), (int)it.second.size());
-        }
-    }
-}
-
-void GaugeMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
-    flushIfNeededLocked(dumpTimeNs);
-    mPastBuckets.clear();
-    mSkippedBuckets.clear();
-}
-
-void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
-                                             const bool include_current_partial_bucket,
-                                             const bool erase_data,
-                                             const DumpLatency dumpLatency,
-                                             std::set<string> *str_set,
-                                             ProtoOutputStream* protoOutput) {
-    VLOG("Gauge metric %lld report now...", (long long)mMetricId);
-    if (include_current_partial_bucket) {
-        flushLocked(dumpTimeNs);
-    } else {
-        flushIfNeededLocked(dumpTimeNs);
-    }
-
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
-    protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
-    if (mPastBuckets.empty() && mSkippedBuckets.empty()) {
-        return;
-    }
-
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-
-    // Fills the dimension path if not slicing by ALL.
-    if (!mSliceByPositionALL) {
-        if (!mDimensionsInWhat.empty()) {
-            uint64_t dimenPathToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
-            writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
-            protoOutput->end(dimenPathToken);
-        }
-    }
-
-    uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_GAUGE_METRICS);
-
-    for (const auto& skippedBucket : mSkippedBuckets) {
-        uint64_t wrapperToken =
-                protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SKIPPED);
-        protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_START_MILLIS,
-                           (long long)(NanoToMillis(skippedBucket.bucketStartTimeNs)));
-        protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_END_MILLIS,
-                           (long long)(NanoToMillis(skippedBucket.bucketEndTimeNs)));
-
-        for (const auto& dropEvent : skippedBucket.dropEvents) {
-            uint64_t dropEventToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                         FIELD_ID_SKIPPED_DROP_EVENT);
-            protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_BUCKET_DROP_REASON, dropEvent.reason);
-            protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DROP_TIME, (long long) (NanoToMillis(dropEvent.dropTimeNs)));
-            protoOutput->end(dropEventToken);
-        }
-        protoOutput->end(wrapperToken);
-    }
-
-    for (const auto& pair : mPastBuckets) {
-        const MetricDimensionKey& dimensionKey = pair.first;
-
-        VLOG("Gauge dimension key %s", dimensionKey.toString().c_str());
-        uint64_t wrapperToken =
-                protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
-        // First fill dimension.
-        if (mSliceByPositionALL) {
-            uint64_t dimensionToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
-            writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
-            protoOutput->end(dimensionToken);
-        } else {
-            writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
-                                           FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
-        }
-
-        // Then fill bucket_info (GaugeBucketInfo).
-        for (const auto& bucket : pair.second) {
-            uint64_t bucketInfoToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
-
-            if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
-                                   (long long)NanoToMillis(bucket.mBucketStartNs));
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
-                                   (long long)NanoToMillis(bucket.mBucketEndNs));
-            } else {
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
-                                   (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
-            }
-
-            if (!bucket.mGaugeAtoms.empty()) {
-                for (const auto& atom : bucket.mGaugeAtoms) {
-                    uint64_t atomsToken =
-                        protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                           FIELD_ID_ATOM);
-                    writeFieldValueTreeToStream(mAtomId, *(atom.mFields), protoOutput);
-                    protoOutput->end(atomsToken);
-                }
-                for (const auto& atom : bucket.mGaugeAtoms) {
-                    protoOutput->write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED |
-                                               FIELD_ID_ELAPSED_ATOM_TIMESTAMP,
-                                       (long long)atom.mElapsedTimestampNs);
-                }
-            }
-            protoOutput->end(bucketInfoToken);
-            VLOG("Gauge \t bucket [%lld - %lld] includes %d atoms.",
-                 (long long)bucket.mBucketStartNs, (long long)bucket.mBucketEndNs,
-                 (int)bucket.mGaugeAtoms.size());
-        }
-        protoOutput->end(wrapperToken);
-    }
-    protoOutput->end(protoToken);
-
-
-    if (erase_data) {
-        mPastBuckets.clear();
-        mSkippedBuckets.clear();
-    }
-}
-
-void GaugeMetricProducer::prepareFirstBucketLocked() {
-    if (mIsActive && mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
-        pullAndMatchEventsLocked(mCurrentBucketStartTimeNs);
-    }
-}
-
-void GaugeMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
-    bool triggerPuller = false;
-    switch(mSamplingType) {
-        // When the metric wants to do random sampling and there is already one gauge atom for the
-        // current bucket, do not do it again.
-        case GaugeMetric::RANDOM_ONE_SAMPLE: {
-            triggerPuller = mCondition == ConditionState::kTrue && mCurrentSlicedBucket->empty();
-            break;
-        }
-        case GaugeMetric::CONDITION_CHANGE_TO_TRUE: {
-            triggerPuller = mCondition == ConditionState::kTrue;
-            break;
-        }
-        case GaugeMetric::FIRST_N_SAMPLES: {
-            triggerPuller = mCondition == ConditionState::kTrue;
-            break;
-        }
-        default:
-            break;
-    }
-    if (!triggerPuller) {
-        return;
-    }
-    vector<std::shared_ptr<LogEvent>> allData;
-    if (!mPullerManager->Pull(mPullTagId, mConfigKey, timestampNs, &allData)) {
-        ALOGE("Gauge Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
-        return;
-    }
-    const int64_t pullDelayNs = getElapsedRealtimeNs() - timestampNs;
-    StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
-    if (pullDelayNs > mMaxPullDelayNs) {
-        ALOGE("Pull finish too late for atom %d", mPullTagId);
-        StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
-        return;
-    }
-    for (const auto& data : allData) {
-        LogEvent localCopy = data->makeCopy();
-        localCopy.setElapsedTimestampNs(timestampNs);
-        if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) ==
-            MatchingState::kMatched) {
-            onMatchedLogEventLocked(mWhatMatcherIndex, localCopy);
-        }
-    }
-}
-
-void GaugeMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
-    MetricProducer::onActiveStateChangedLocked(eventTimeNs);
-    if (ConditionState::kTrue != mCondition || !mIsPulled) {
-        return;
-    }
-    if (mTriggerAtomId == -1 || (mIsActive && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE)) {
-        pullAndMatchEventsLocked(eventTimeNs);
-    }
-
-}
-
-void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
-                                                   const int64_t eventTimeNs) {
-    VLOG("GaugeMetric %lld onConditionChanged", (long long)mMetricId);
-
-    mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
-    if (!mIsActive) {
-        return;
-    }
-
-    flushIfNeededLocked(eventTimeNs);
-    if (mIsPulled && mTriggerAtomId == -1) {
-        pullAndMatchEventsLocked(eventTimeNs);
-    }  // else: Push mode. No need to proactively pull the gauge data.
-}
-
-void GaugeMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
-                                                           const int64_t eventTimeNs) {
-    VLOG("GaugeMetric %lld onSlicedConditionMayChange overall condition %d", (long long)mMetricId,
-         overallCondition);
-    mCondition = overallCondition ? ConditionState::kTrue : ConditionState::kFalse;
-    if (!mIsActive) {
-        return;
-    }
-
-    flushIfNeededLocked(eventTimeNs);
-    // If the condition is sliced, mCondition is true if any of the dimensions is true. And we will
-    // pull for every dimension.
-    if (mIsPulled && mTriggerAtomId == -1) {
-        pullAndMatchEventsLocked(eventTimeNs);
-    }  // else: Push mode. No need to proactively pull the gauge data.
-}
-
-std::shared_ptr<vector<FieldValue>> GaugeMetricProducer::getGaugeFields(const LogEvent& event) {
-    std::shared_ptr<vector<FieldValue>> gaugeFields;
-    if (mFieldMatchers.size() > 0) {
-        gaugeFields = std::make_shared<vector<FieldValue>>();
-        filterGaugeValues(mFieldMatchers, event.getValues(), gaugeFields.get());
-    } else {
-        gaugeFields = std::make_shared<vector<FieldValue>>(event.getValues());
-    }
-    // Trim all dimension fields from output. Dimensions will appear in output report and will
-    // benefit from dictionary encoding. For large pulled atoms, this can give the benefit of
-    // optional repeated field.
-    for (const auto& field : mDimensionsInWhat) {
-        for (auto it = gaugeFields->begin(); it != gaugeFields->end();) {
-            if (it->mField.matches(field)) {
-                it = gaugeFields->erase(it);
-            } else {
-                it++;
-            }
-        }
-    }
-    return gaugeFields;
-}
-
-void GaugeMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData,
-                                       bool pullSuccess, int64_t originalPullTimeNs) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    if (!pullSuccess || allData.size() == 0) {
-        return;
-    }
-    const int64_t pullDelayNs = getElapsedRealtimeNs() - originalPullTimeNs;
-    StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
-    if (pullDelayNs > mMaxPullDelayNs) {
-        ALOGE("Pull finish too late for atom %d", mPullTagId);
-        StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
-        return;
-    }
-    for (const auto& data : allData) {
-        if (mEventMatcherWizard->matchLogEvent(
-                *data, mWhatMatcherIndex) == MatchingState::kMatched) {
-            onMatchedLogEventLocked(mWhatMatcherIndex, *data);
-        }
-    }
-}
-
-bool GaugeMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
-    if (mCurrentSlicedBucket->find(newKey) != mCurrentSlicedBucket->end()) {
-        return false;
-    }
-    // 1. Report the tuple count if the tuple count > soft limit
-    if (mCurrentSlicedBucket->size() > mDimensionSoftLimit - 1) {
-        size_t newTupleCount = mCurrentSlicedBucket->size() + 1;
-        StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
-        // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
-        if (newTupleCount > mDimensionHardLimit) {
-            ALOGE("GaugeMetric %lld dropping data for dimension key %s",
-                (long long)mMetricId, newKey.toString().c_str());
-            StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
-            return true;
-        }
-    }
-
-    return false;
-}
-
-void GaugeMetricProducer::onMatchedLogEventInternalLocked(
-        const size_t matcherIndex, const MetricDimensionKey& eventKey,
-        const ConditionKey& conditionKey, bool condition, const LogEvent& event,
-        const map<int, HashableDimensionKey>& statePrimaryKeys) {
-    if (condition == false) {
-        return;
-    }
-    int64_t eventTimeNs = event.GetElapsedTimestampNs();
-    if (eventTimeNs < mCurrentBucketStartTimeNs) {
-        VLOG("Gauge Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
-             (long long)mCurrentBucketStartTimeNs);
-        return;
-    }
-    flushIfNeededLocked(eventTimeNs);
-
-    if (mTriggerAtomId == event.GetTagId()) {
-        pullAndMatchEventsLocked(eventTimeNs);
-        return;
-    }
-
-    // When gauge metric wants to randomly sample the output atom, we just simply use the first
-    // gauge in the given bucket.
-    if (mCurrentSlicedBucket->find(eventKey) != mCurrentSlicedBucket->end() &&
-        mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
-        return;
-    }
-    if (hitGuardRailLocked(eventKey)) {
-        return;
-    }
-    if ((*mCurrentSlicedBucket)[eventKey].size() >= mGaugeAtomsPerDimensionLimit) {
-        return;
-    }
-
-    const int64_t truncatedElapsedTimestampNs = truncateTimestampIfNecessary(event);
-    GaugeAtom gaugeAtom(getGaugeFields(event), truncatedElapsedTimestampNs);
-    (*mCurrentSlicedBucket)[eventKey].push_back(gaugeAtom);
-    // Anomaly detection on gauge metric only works when there is one numeric
-    // field specified.
-    if (mAnomalyTrackers.size() > 0) {
-        if (gaugeAtom.mFields->size() == 1) {
-            const Value& value = gaugeAtom.mFields->begin()->mValue;
-            long gaugeVal = 0;
-            if (value.getType() == INT) {
-                gaugeVal = (long)value.int_value;
-            } else if (value.getType() == LONG) {
-                gaugeVal = value.long_value;
-            }
-            for (auto& tracker : mAnomalyTrackers) {
-                tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, mMetricId,
-                                                 eventKey, gaugeVal);
-            }
-        }
-    }
-}
-
-void GaugeMetricProducer::updateCurrentSlicedBucketForAnomaly() {
-    for (const auto& slice : *mCurrentSlicedBucket) {
-        if (slice.second.empty()) {
-            continue;
-        }
-        const Value& value = slice.second.front().mFields->front().mValue;
-        long gaugeVal = 0;
-        if (value.getType() == INT) {
-            gaugeVal = (long)value.int_value;
-        } else if (value.getType() == LONG) {
-            gaugeVal = value.long_value;
-        }
-        (*mCurrentSlicedBucketForAnomaly)[slice.first] = gaugeVal;
-    }
-}
-
-void GaugeMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
-    flushIfNeededLocked(dropTimeNs);
-    StatsdStats::getInstance().noteBucketDropped(mMetricId);
-    mPastBuckets.clear();
-}
-
-// When a new matched event comes in, we check if event falls into the current
-// bucket. If not, flush the old counter to past buckets and initialize the new
-// bucket.
-// if data is pushed, onMatchedLogEvent will only be called through onConditionChanged() inside
-// the GaugeMetricProducer while holding the lock.
-void GaugeMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
-    int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
-
-    if (eventTimeNs < currentBucketEndTimeNs) {
-        VLOG("Gauge eventTime is %lld, less than next bucket start time %lld",
-             (long long)eventTimeNs, (long long)(mCurrentBucketStartTimeNs + mBucketSizeNs));
-        return;
-    }
-
-    // Adjusts the bucket start and end times.
-    int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
-    int64_t nextBucketNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
-    flushCurrentBucketLocked(eventTimeNs, nextBucketNs);
-
-    mCurrentBucketNum += numBucketsForward;
-    VLOG("Gauge metric %lld: new bucket start time: %lld", (long long)mMetricId,
-         (long long)mCurrentBucketStartTimeNs);
-}
-
-void GaugeMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
-                                                   const int64_t& nextBucketStartTimeNs) {
-    int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
-    int64_t bucketEndTime = eventTimeNs < fullBucketEndTimeNs ? eventTimeNs : fullBucketEndTimeNs;
-
-    GaugeBucket info;
-    info.mBucketStartNs = mCurrentBucketStartTimeNs;
-    info.mBucketEndNs = bucketEndTime;
-
-    // Add bucket to mPastBuckets if bucket is large enough.
-    // Otherwise, drop the bucket data and add bucket metadata to mSkippedBuckets.
-    bool isBucketLargeEnough = info.mBucketEndNs - mCurrentBucketStartTimeNs >= mMinBucketSizeNs;
-    if (isBucketLargeEnough) {
-        for (const auto& slice : *mCurrentSlicedBucket) {
-            info.mGaugeAtoms = slice.second;
-            auto& bucketList = mPastBuckets[slice.first];
-            bucketList.push_back(info);
-            VLOG("Gauge gauge metric %lld, dump key value: %s", (long long)mMetricId,
-                 slice.first.toString().c_str());
-        }
-    } else {
-        mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs;
-        mCurrentSkippedBucket.bucketEndTimeNs = bucketEndTime;
-        if (!maxDropEventsReached()) {
-            mCurrentSkippedBucket.dropEvents.emplace_back(
-                    buildDropEvent(eventTimeNs, BucketDropReason::BUCKET_TOO_SMALL));
-        }
-        mSkippedBuckets.emplace_back(mCurrentSkippedBucket);
-    }
-
-    // If we have anomaly trackers, we need to update the partial bucket values.
-    if (mAnomalyTrackers.size() > 0) {
-        updateCurrentSlicedBucketForAnomaly();
-
-        if (eventTimeNs > fullBucketEndTimeNs) {
-            // This is known to be a full bucket, so send this data to the anomaly tracker.
-            for (auto& tracker : mAnomalyTrackers) {
-                tracker->addPastBucket(mCurrentSlicedBucketForAnomaly, mCurrentBucketNum);
-            }
-            mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
-        }
-    }
-
-    StatsdStats::getInstance().noteBucketCount(mMetricId);
-    mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
-    mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
-    mCurrentSkippedBucket.reset();
-}
-
-size_t GaugeMetricProducer::byteSizeLocked() const {
-    size_t totalSize = 0;
-    for (const auto& pair : mPastBuckets) {
-        for (const auto& bucket : pair.second) {
-            totalSize += bucket.mGaugeAtoms.size() * sizeof(GaugeAtom);
-            for (const auto& atom : bucket.mGaugeAtoms) {
-                if (atom.mFields != nullptr) {
-                    totalSize += atom.mFields->size() * sizeof(FieldValue);
-                }
-            }
-        }
-    }
-    return totalSize;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
deleted file mode 100644
index 9bdaac9..0000000
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <unordered_map>
-
-#include <android/util/ProtoOutputStream.h>
-#include <gtest/gtest_prod.h>
-#include "../condition/ConditionTracker.h"
-#include "../external/PullDataReceiver.h"
-#include "../external/StatsPullerManager.h"
-#include "../matchers/matcher_util.h"
-#include "../matchers/EventMatcherWizard.h"
-#include "MetricProducer.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "../stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct GaugeAtom {
-    GaugeAtom(std::shared_ptr<vector<FieldValue>> fields, int64_t elapsedTimeNs)
-        : mFields(fields), mElapsedTimestampNs(elapsedTimeNs) {
-    }
-    std::shared_ptr<vector<FieldValue>> mFields;
-    int64_t mElapsedTimestampNs;
-};
-
-struct GaugeBucket {
-    int64_t mBucketStartNs;
-    int64_t mBucketEndNs;
-    std::vector<GaugeAtom> mGaugeAtoms;
-};
-
-typedef std::unordered_map<MetricDimensionKey, std::vector<GaugeAtom>>
-    DimToGaugeAtomsMap;
-
-// This gauge metric producer first register the puller to automatically pull the gauge at the
-// beginning of each bucket. If the condition is met, insert it to the bucket info. Otherwise
-// proactively pull the gauge when the condition is changed to be true. Therefore, the gauge metric
-// producer always reports the gauge at the earliest time of the bucket when the condition is met.
-class GaugeMetricProducer : public MetricProducer, public virtual PullDataReceiver {
-public:
-    GaugeMetricProducer(
-            const ConfigKey& key, const GaugeMetric& gaugeMetric, const int conditionIndex,
-            const vector<ConditionState>& initialConditionCache,
-            const sp<ConditionWizard>& conditionWizard, const uint64_t protoHash,
-            const int whatMatcherIndex, const sp<EventMatcherWizard>& matcherWizard,
-            const int pullTagId, const int triggerAtomId, const int atomId,
-            const int64_t timeBaseNs, const int64_t startTimeNs,
-            const sp<StatsPullerManager>& pullerManager,
-            const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
-            const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
-                    eventDeactivationMap = {});
-
-    virtual ~GaugeMetricProducer();
-
-    // Handles when the pulled data arrives.
-    void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
-                      bool pullSuccess, int64_t originalPullTimeNs) override;
-
-    // GaugeMetric needs to immediately trigger another pull when we create the partial bucket.
-    void notifyAppUpgrade(const int64_t& eventTimeNs) override {
-        std::lock_guard<std::mutex> lock(mMutex);
-
-        if (!mSplitBucketForAppUpgrade) {
-            return;
-        }
-        flushLocked(eventTimeNs);
-        if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
-            pullAndMatchEventsLocked(eventTimeNs);
-        }
-    };
-
-    // GaugeMetric needs to immediately trigger another pull when we create the partial bucket.
-    void onStatsdInitCompleted(const int64_t& eventTimeNs) override {
-        std::lock_guard<std::mutex> lock(mMutex);
-
-        flushLocked(eventTimeNs);
-        if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
-            pullAndMatchEventsLocked(eventTimeNs);
-        }
-    };
-
-    MetricType getMetricType() const override {
-        return METRIC_TYPE_GAUGE;
-    }
-
-protected:
-    void onMatchedLogEventInternalLocked(
-            const size_t matcherIndex, const MetricDimensionKey& eventKey,
-            const ConditionKey& conditionKey, bool condition, const LogEvent& event,
-            const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
-    void onDumpReportLocked(const int64_t dumpTimeNs,
-                            const bool include_current_partial_bucket,
-                            const bool erase_data,
-                            const DumpLatency dumpLatency,
-                            std::set<string> *str_set,
-                            android::util::ProtoOutputStream* protoOutput) override;
-    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
-    // Internal interface to handle condition change.
-    void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
-    // Internal interface to handle active state change.
-    void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
-
-    // Internal interface to handle sliced condition change.
-    void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
-    // Internal function to calculate the current used bytes.
-    size_t byteSizeLocked() const override;
-
-    void dumpStatesLocked(FILE* out, bool verbose) const override;
-
-    void dropDataLocked(const int64_t dropTimeNs) override;
-
-    // Util function to flush the old packet.
-    void flushIfNeededLocked(const int64_t& eventTime) override;
-
-    void flushCurrentBucketLocked(const int64_t& eventTimeNs,
-                                  const int64_t& nextBucketStartTimeNs) override;
-
-    void prepareFirstBucketLocked() override;
-
-    void pullAndMatchEventsLocked(const int64_t timestampNs);
-
-    bool onConfigUpdatedLocked(
-            const StatsdConfig& config, const int configIndex, const int metricIndex,
-            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-            const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-            const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-            const sp<EventMatcherWizard>& matcherWizard,
-            const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-            const std::unordered_map<int64_t, int>& conditionTrackerMap,
-            const sp<ConditionWizard>& wizard,
-            const std::unordered_map<int64_t, int>& metricToActivationMap,
-            std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-            std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-            std::vector<int>& metricsWithActivation) override;
-
-    int mWhatMatcherIndex;
-
-    sp<EventMatcherWizard> mEventMatcherWizard;
-
-    sp<StatsPullerManager> mPullerManager;
-    // tagId for pulled data. -1 if this is not pulled
-    const int mPullTagId;
-
-    // tagId for atoms that trigger the pulling, if any
-    const int mTriggerAtomId;
-
-    // tagId for output atom
-    const int mAtomId;
-
-    // if this is pulled metric
-    const bool mIsPulled;
-
-    // Save the past buckets and we can clear when the StatsLogReport is dumped.
-    std::unordered_map<MetricDimensionKey, std::vector<GaugeBucket>> mPastBuckets;
-
-    // The current partial bucket.
-    std::shared_ptr<DimToGaugeAtomsMap> mCurrentSlicedBucket;
-
-    // The current full bucket for anomaly detection. This is updated to the latest value seen for
-    // this slice (ie, for partial buckets, we use the last partial bucket in this full bucket).
-    std::shared_ptr<DimToValMap> mCurrentSlicedBucketForAnomaly;
-
-    const int64_t mMinBucketSizeNs;
-
-    // Translate Atom based bucket to single numeric value bucket for anomaly and updates the map
-    // for each slice with the latest value.
-    void updateCurrentSlicedBucketForAnomaly();
-
-    // Allowlist of fields to report. Empty means all are reported.
-    std::vector<Matcher> mFieldMatchers;
-
-    GaugeMetric::SamplingType mSamplingType;
-
-    const int64_t mMaxPullDelayNs;
-
-    // apply an allowlist on the original input
-    std::shared_ptr<vector<FieldValue>> getGaugeFields(const LogEvent& event);
-
-    // Util function to check whether the specified dimension hits the guardrail.
-    bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
-    static const size_t kBucketSize = sizeof(GaugeBucket{});
-
-    const size_t mDimensionSoftLimit;
-
-    const size_t mDimensionHardLimit;
-
-    const size_t mGaugeAtomsPerDimensionLimit;
-
-    const bool mSplitBucketForAppUpgrade;
-
-    FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition);
-    FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition);
-    FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition);
-    FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled);
-    FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection);
-    FRIEND_TEST(GaugeMetricProducerTest, TestFirstBucket);
-    FRIEND_TEST(GaugeMetricProducerTest, TestPullOnTrigger);
-    FRIEND_TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput);
-
-    FRIEND_TEST(GaugeMetricProducerTest_PartialBucket, TestPushedEvents);
-    FRIEND_TEST(GaugeMetricProducerTest_PartialBucket, TestPulled);
-
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateGaugeMetrics);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
deleted file mode 100644
index c68e61e..0000000
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "MetricProducer.h"
-
-#include "../guardrail/StatsdStats.h"
-#include "metrics/parsing_utils/metrics_manager_util.h"
-#include "state/StateTracker.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_ENUM;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-// for ActiveMetric
-const int FIELD_ID_ACTIVE_METRIC_ID = 1;
-const int FIELD_ID_ACTIVE_METRIC_ACTIVATION = 2;
-
-// for ActiveEventActivation
-const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_ATOM_MATCHER_INDEX = 1;
-const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS = 2;
-const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE = 3;
-
-MetricProducer::MetricProducer(
-        const int64_t& metricId, const ConfigKey& key, const int64_t timeBaseNs,
-        const int conditionIndex, const vector<ConditionState>& initialConditionCache,
-        const sp<ConditionWizard>& wizard, const uint64_t protoHash,
-        const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap,
-        const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
-                eventDeactivationMap,
-        const vector<int>& slicedStateAtoms,
-        const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
-    : mMetricId(metricId),
-      mProtoHash(protoHash),
-      mConfigKey(key),
-      mValid(true),
-      mTimeBaseNs(timeBaseNs),
-      mCurrentBucketStartTimeNs(timeBaseNs),
-      mCurrentBucketNum(0),
-      mCondition(initialCondition(conditionIndex, initialConditionCache)),
-      mConditionTrackerIndex(conditionIndex),
-      mConditionSliced(false),
-      mWizard(wizard),
-      mContainANYPositionInDimensionsInWhat(false),
-      mSliceByPositionALL(false),
-      mHasLinksToAllConditionDimensionsInTracker(false),
-      mEventActivationMap(eventActivationMap),
-      mEventDeactivationMap(eventDeactivationMap),
-      mIsActive(mEventActivationMap.empty()),
-      mSlicedStateAtoms(slicedStateAtoms),
-      mStateGroupMap(stateGroupMap) {
-}
-
-bool MetricProducer::onConfigUpdatedLocked(
-        const StatsdConfig& config, const int configIndex, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    sp<ConditionWizard> tmpWizard = mWizard;
-    mWizard = wizard;
-
-    unordered_map<int, shared_ptr<Activation>> newEventActivationMap;
-    unordered_map<int, vector<shared_ptr<Activation>>> newEventDeactivationMap;
-    if (!handleMetricActivationOnConfigUpdate(
-                config, mMetricId, metricIndex, metricToActivationMap, oldAtomMatchingTrackerMap,
-                newAtomMatchingTrackerMap, mEventActivationMap, activationAtomTrackerToMetricMap,
-                deactivationAtomTrackerToMetricMap, metricsWithActivation, newEventActivationMap,
-                newEventDeactivationMap)) {
-        return false;
-    }
-    mEventActivationMap = newEventActivationMap;
-    mEventDeactivationMap = newEventDeactivationMap;
-    mAnomalyTrackers.clear();
-    return true;
-}
-
-void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) {
-    if (!mIsActive) {
-        return;
-    }
-    int64_t eventTimeNs = event.GetElapsedTimestampNs();
-    // this is old event, maybe statsd restarted?
-    if (eventTimeNs < mTimeBaseNs) {
-        return;
-    }
-
-    bool condition;
-    ConditionKey conditionKey;
-    if (mConditionSliced) {
-        for (const auto& link : mMetric2ConditionLinks) {
-            getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
-        }
-        auto conditionState =
-            mWizard->query(mConditionTrackerIndex, conditionKey,
-                           !mHasLinksToAllConditionDimensionsInTracker);
-        condition = (conditionState == ConditionState::kTrue);
-    } else {
-        // TODO: The unknown condition state is not handled here, we should fix it.
-        condition = mCondition == ConditionState::kTrue;
-    }
-
-    // Stores atom id to primary key pairs for each state atom that the metric is
-    // sliced by.
-    std::map<int32_t, HashableDimensionKey> statePrimaryKeys;
-
-    // For states with primary fields, use MetricStateLinks to get the primary
-    // field values from the log event. These values will form a primary key
-    // that will be used to query StateTracker for the correct state value.
-    for (const auto& stateLink : mMetric2StateLinks) {
-        getDimensionForState(event.getValues(), stateLink,
-                             &statePrimaryKeys[stateLink.stateAtomId]);
-    }
-
-    // For each sliced state, query StateTracker for the state value using
-    // either the primary key from the previous step or the DEFAULT_DIMENSION_KEY.
-    //
-    // Expected functionality: for any case where the MetricStateLinks are
-    // initialized incorrectly (ex. # of state links != # of primary fields, no
-    // links are provided for a state with primary fields, links are provided
-    // in the wrong order, etc.), StateTracker will simply return kStateUnknown
-    // when queried using an incorrect key.
-    HashableDimensionKey stateValuesKey;
-    for (auto atomId : mSlicedStateAtoms) {
-        FieldValue value;
-        if (statePrimaryKeys.find(atomId) != statePrimaryKeys.end()) {
-            // found a primary key for this state, query using the key
-            queryStateValue(atomId, statePrimaryKeys[atomId], &value);
-        } else {
-            // if no MetricStateLinks exist for this state atom,
-            // query using the default dimension key (empty HashableDimensionKey)
-            queryStateValue(atomId, DEFAULT_DIMENSION_KEY, &value);
-        }
-        mapStateValue(atomId, &value);
-        stateValuesKey.addValue(value);
-    }
-
-    HashableDimensionKey dimensionInWhat;
-    filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhat);
-    MetricDimensionKey metricKey(dimensionInWhat, stateValuesKey);
-    onMatchedLogEventInternalLocked(matcherIndex, metricKey, conditionKey, condition, event,
-                                    statePrimaryKeys);
-}
-
-bool MetricProducer::evaluateActiveStateLocked(int64_t elapsedTimestampNs) {
-    bool isActive = mEventActivationMap.empty();
-    for (auto& it : mEventActivationMap) {
-        if (it.second->state == ActivationState::kActive &&
-            elapsedTimestampNs > it.second->ttl_ns + it.second->start_ns) {
-            it.second->state = ActivationState::kNotActive;
-        }
-        if (it.second->state == ActivationState::kActive) {
-            isActive = true;
-        }
-    }
-    return isActive;
-}
-
-void MetricProducer::flushIfExpire(int64_t elapsedTimestampNs) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    if (!mIsActive) {
-        return;
-    }
-    mIsActive = evaluateActiveStateLocked(elapsedTimestampNs);
-    if (!mIsActive) {
-        onActiveStateChangedLocked(elapsedTimestampNs);
-    }
-}
-
-void MetricProducer::activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs) {
-    auto it = mEventActivationMap.find(activationTrackerIndex);
-    if (it == mEventActivationMap.end()) {
-        return;
-    }
-    auto& activation = it->second;
-    if (ACTIVATE_ON_BOOT == activation->activationType) {
-        if (ActivationState::kNotActive == activation->state) {
-            activation->state = ActivationState::kActiveOnBoot;
-        }
-        // If the Activation is already active or set to kActiveOnBoot, do nothing.
-        return;
-    }
-    activation->start_ns = elapsedTimestampNs;
-    activation->state = ActivationState::kActive;
-    bool oldActiveState = mIsActive;
-    mIsActive = true;
-    if (!oldActiveState) { // Metric went from not active to active.
-        onActiveStateChangedLocked(elapsedTimestampNs);
-    }
-}
-
-void MetricProducer::cancelEventActivationLocked(int deactivationTrackerIndex) {
-    auto it = mEventDeactivationMap.find(deactivationTrackerIndex);
-    if (it == mEventDeactivationMap.end()) {
-        return;
-    }
-    for (auto activationToCancelIt : it->second)  {
-        activationToCancelIt->state = ActivationState::kNotActive;
-    }
-}
-
-void MetricProducer::loadActiveMetricLocked(const ActiveMetric& activeMetric,
-                                            int64_t currentTimeNs) {
-    if (mEventActivationMap.size() == 0) {
-        return;
-    }
-    for (int i = 0; i < activeMetric.activation_size(); i++) {
-        const auto& activeEventActivation = activeMetric.activation(i);
-        auto it = mEventActivationMap.find(activeEventActivation.atom_matcher_index());
-        if (it == mEventActivationMap.end()) {
-            ALOGE("Saved event activation not found");
-            continue;
-        }
-        auto& activation = it->second;
-        // If the event activation does not have a state, assume it is active.
-        if (!activeEventActivation.has_state() ||
-                activeEventActivation.state() == ActiveEventActivation::ACTIVE) {
-            // We don't want to change the ttl for future activations, so we set the start_ns
-            // such that start_ns + ttl_ns == currentTimeNs + remaining_ttl_nanos
-            activation->start_ns =
-                currentTimeNs + activeEventActivation.remaining_ttl_nanos() - activation->ttl_ns;
-            activation->state = ActivationState::kActive;
-            mIsActive = true;
-        } else if (activeEventActivation.state() == ActiveEventActivation::ACTIVATE_ON_BOOT) {
-            activation->state = ActivationState::kActiveOnBoot;
-        }
-    }
-}
-
-void MetricProducer::writeActiveMetricToProtoOutputStream(
-        int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
-    proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_METRIC_ID, (long long)mMetricId);
-    for (auto& it : mEventActivationMap) {
-        const int atom_matcher_index = it.first;
-        const std::shared_ptr<Activation>& activation = it.second;
-
-        if (ActivationState::kNotActive == activation->state ||
-                (ActivationState::kActive == activation->state &&
-                 activation->start_ns + activation->ttl_ns < currentTimeNs)) {
-            continue;
-        }
-
-        const uint64_t activationToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                FIELD_ID_ACTIVE_METRIC_ACTIVATION);
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_ATOM_MATCHER_INDEX,
-                atom_matcher_index);
-        if (ActivationState::kActive == activation->state) {
-            const int64_t remainingTtlNs =
-                    activation->start_ns + activation->ttl_ns - currentTimeNs;
-            proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
-                    (long long)remainingTtlNs);
-            proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
-                    ActiveEventActivation::ACTIVE);
-
-        } else if (ActivationState::kActiveOnBoot == activation->state) {
-            if (reason == DEVICE_SHUTDOWN || reason == TERMINATION_SIGNAL_RECEIVED) {
-                proto->write(
-                        FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
-                        (long long)activation->ttl_ns);
-                proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
-                                    ActiveEventActivation::ACTIVE);
-            } else if (reason == STATSCOMPANION_DIED) {
-                // We are saving because of system server death, not due to a device shutdown.
-                // Next time we load, we do not want to activate metrics that activate on boot.
-                proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
-                                                    ActiveEventActivation::ACTIVATE_ON_BOOT);
-            }
-        }
-        proto->end(activationToken);
-    }
-}
-
-void MetricProducer::queryStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
-                                     FieldValue* value) {
-    if (!StateManager::getInstance().getStateValue(atomId, queryKey, value)) {
-        value->mValue = Value(StateTracker::kStateUnknown);
-        value->mField.setTag(atomId);
-        ALOGW("StateTracker not found for state atom %d", atomId);
-        return;
-    }
-}
-
-void MetricProducer::mapStateValue(const int32_t atomId, FieldValue* value) {
-    // check if there is a state map for this atom
-    auto atomIt = mStateGroupMap.find(atomId);
-    if (atomIt == mStateGroupMap.end()) {
-        return;
-    }
-    auto valueIt = atomIt->second.find(value->mValue.int_value);
-    if (valueIt == atomIt->second.end()) {
-        // state map exists, but value was not put in a state group
-        // so set mValue to kStateUnknown
-        // TODO(tsaichristine): handle incomplete state maps
-        value->mValue.setInt(StateTracker::kStateUnknown);
-    } else {
-        // set mValue to group_id
-        value->mValue.setLong(valueIt->second);
-    }
-}
-
-HashableDimensionKey MetricProducer::getUnknownStateKey() {
-    HashableDimensionKey stateKey;
-    for (auto atom : mSlicedStateAtoms) {
-        FieldValue fieldValue;
-        fieldValue.mField.setTag(atom);
-        fieldValue.mValue.setInt(StateTracker::kStateUnknown);
-        stateKey.addValue(fieldValue);
-    }
-    return stateKey;
-}
-
-DropEvent MetricProducer::buildDropEvent(const int64_t dropTimeNs, const BucketDropReason reason) {
-    DropEvent event;
-    event.reason = reason;
-    event.dropTimeNs = dropTimeNs;
-    return event;
-}
-
-bool MetricProducer::maxDropEventsReached() {
-    return mCurrentSkippedBucket.dropEvents.size() >= StatsdStats::kMaxLoggedBucketDropEvents;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
deleted file mode 100644
index 7a1c008..0000000
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef METRIC_PRODUCER_H
-#define METRIC_PRODUCER_H
-
-#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
-#include <utils/RefBase.h>
-
-#include <unordered_map>
-
-#include "HashableDimensionKey.h"
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionWizard.h"
-#include "config/ConfigKey.h"
-#include "matchers/EventMatcherWizard.h"
-#include "matchers/matcher_util.h"
-#include "packages/PackageInfoListener.h"
-#include "state/StateListener.h"
-#include "state/StateManager.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Keep this in sync with DumpReportReason enum in stats_log.proto
-enum DumpReportReason {
-    DEVICE_SHUTDOWN = 1,
-    CONFIG_UPDATED = 2,
-    CONFIG_REMOVED = 3,
-    GET_DATA_CALLED = 4,
-    ADB_DUMP = 5,
-    CONFIG_RESET = 6,
-    STATSCOMPANION_DIED = 7,
-    TERMINATION_SIGNAL_RECEIVED = 8
-};
-
-// If the metric has no activation requirement, it will be active once the metric producer is
-// created.
-// If the metric needs to be activated by atoms, the metric producer will start
-// with kNotActive state, turn to kActive or kActiveOnBoot when the activation event arrives, become
-// kNotActive when it reaches the duration limit (timebomb). If the activation event arrives again
-// before or after it expires, the event producer will be re-activated and ttl will be reset.
-enum ActivationState {
-    kNotActive = 0,
-    kActive = 1,
-    kActiveOnBoot = 2,
-};
-
-enum DumpLatency {
-    // In some cases, we only have a short time range to do the dump, e.g. statsd is being killed.
-    // We might be able to return all the data in this mode. For instance, pull metrics might need
-    // to be pulled when the current bucket is requested.
-    FAST = 1,
-    // In other cases, it is fine for a dump to take more than a few milliseconds, e.g. config
-    // updates.
-    NO_TIME_CONSTRAINTS = 2
-};
-
-// Keep this in sync with BucketDropReason enum in stats_log.proto
-enum BucketDropReason {
-    // For ValueMetric, a bucket is dropped during a dump report request iff
-    // current bucket should be included, a pull is needed (pulled metric and
-    // condition is true), and we are under fast time constraints.
-    DUMP_REPORT_REQUESTED = 1,
-    EVENT_IN_WRONG_BUCKET = 2,
-    CONDITION_UNKNOWN = 3,
-    PULL_FAILED = 4,
-    PULL_DELAYED = 5,
-    DIMENSION_GUARDRAIL_REACHED = 6,
-    MULTIPLE_BUCKETS_SKIPPED = 7,
-    // Not an invalid bucket case, but the bucket is dropped.
-    BUCKET_TOO_SMALL = 8,
-    // Not an invalid bucket case, but the bucket is skipped.
-    NO_DATA = 9
-};
-
-enum MetricType {
-    METRIC_TYPE_EVENT = 1,
-    METRIC_TYPE_COUNT = 2,
-    METRIC_TYPE_DURATION = 3,
-    METRIC_TYPE_GAUGE = 4,
-    METRIC_TYPE_VALUE = 5,
-};
-struct Activation {
-    Activation(const ActivationType& activationType, const int64_t ttlNs)
-        : ttl_ns(ttlNs),
-          start_ns(0),
-          state(ActivationState::kNotActive),
-          activationType(activationType) {}
-
-    const int64_t ttl_ns;
-    int64_t start_ns;
-    ActivationState state;
-    const ActivationType activationType;
-};
-
-struct DropEvent {
-    // Reason for dropping the bucket and/or marking the bucket invalid.
-    BucketDropReason reason;
-    // The timestamp of the drop event.
-    int64_t dropTimeNs;
-};
-
-struct SkippedBucket {
-    // Start time of the dropped bucket.
-    int64_t bucketStartTimeNs;
-    // End time of the dropped bucket.
-    int64_t bucketEndTimeNs;
-    // List of events that invalidated this bucket.
-    std::vector<DropEvent> dropEvents;
-
-    void reset() {
-        bucketStartTimeNs = 0;
-        bucketEndTimeNs = 0;
-        dropEvents.clear();
-    }
-};
-
-// A MetricProducer is responsible for compute one single metrics, creating stats log report, and
-// writing the report to dropbox. MetricProducers should respond to package changes as required in
-// PackageInfoListener, but if none of the metrics are slicing by package name, then the update can
-// be a no-op.
-class MetricProducer : public virtual android::RefBase, public virtual StateListener {
-public:
-    MetricProducer(const int64_t& metricId, const ConfigKey& key, const int64_t timeBaseNs,
-                   const int conditionIndex, const vector<ConditionState>& initialConditionCache,
-                   const sp<ConditionWizard>& wizard, const uint64_t protoHash,
-                   const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap,
-                   const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
-                           eventDeactivationMap,
-                   const vector<int>& slicedStateAtoms,
-                   const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap);
-
-    virtual ~MetricProducer(){};
-
-    ConditionState initialCondition(const int conditionIndex,
-                                    const vector<ConditionState>& initialConditionCache) const {
-        return conditionIndex >= 0 ? initialConditionCache[conditionIndex] : ConditionState::kTrue;
-    }
-
-    // Update appropriate state on config updates. Primarily, all indices need to be updated.
-    // This metric and all of its dependencies are guaranteed to be preserved across the update.
-    // This function also updates several maps used by metricsManager.
-    // This function clears all anomaly trackers. All anomaly trackers need to be added again.
-    bool onConfigUpdated(
-            const StatsdConfig& config, const int configIndex, const int metricIndex,
-            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-            const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-            const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-            const sp<EventMatcherWizard>& matcherWizard,
-            const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-            const std::unordered_map<int64_t, int>& conditionTrackerMap,
-            const sp<ConditionWizard>& wizard,
-            const std::unordered_map<int64_t, int>& metricToActivationMap,
-            std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-            std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-            std::vector<int>& metricsWithActivation) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        return onConfigUpdatedLocked(config, configIndex, metricIndex, allAtomMatchingTrackers,
-                                     oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap,
-                                     matcherWizard, allConditionTrackers, conditionTrackerMap,
-                                     wizard, metricToActivationMap, trackerToMetricMap,
-                                     conditionToMetricMap, activationAtomTrackerToMetricMap,
-                                     deactivationAtomTrackerToMetricMap, metricsWithActivation);
-    };
-
-    /**
-     * Force a partial bucket split on app upgrade
-     */
-    virtual void notifyAppUpgrade(const int64_t& eventTimeNs) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        flushLocked(eventTimeNs);
-    };
-
-    void notifyAppRemoved(const int64_t& eventTimeNs) {
-        // Force buckets to split on removal also.
-        notifyAppUpgrade(eventTimeNs);
-    };
-
-    /**
-     * Force a partial bucket split on boot complete.
-     */
-    virtual void onStatsdInitCompleted(const int64_t& eventTimeNs) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        flushLocked(eventTimeNs);
-    }
-    // Consume the parsed stats log entry that already matched the "what" of the metric.
-    void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        onMatchedLogEventLocked(matcherIndex, event);
-    }
-
-    void onConditionChanged(const bool condition, const int64_t eventTime) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        onConditionChangedLocked(condition, eventTime);
-    }
-
-    void onSlicedConditionMayChange(bool overallCondition, const int64_t eventTime) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        onSlicedConditionMayChangeLocked(overallCondition, eventTime);
-    }
-
-    bool isConditionSliced() const {
-        std::lock_guard<std::mutex> lock(mMutex);
-        return mConditionSliced;
-    };
-
-    void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
-                        const HashableDimensionKey& primaryKey, const FieldValue& oldState,
-                        const FieldValue& newState){};
-
-    // Output the metrics data to [protoOutput]. All metrics reports end with the same timestamp.
-    // This method clears all the past buckets.
-    void onDumpReport(const int64_t dumpTimeNs,
-                      const bool include_current_partial_bucket,
-                      const bool erase_data,
-                      const DumpLatency dumpLatency,
-                      std::set<string> *str_set,
-                      android::util::ProtoOutputStream* protoOutput) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, erase_data,
-                dumpLatency, str_set, protoOutput);
-    }
-
-    virtual bool onConfigUpdatedLocked(
-            const StatsdConfig& config, const int configIndex, const int metricIndex,
-            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-            const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-            const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-            const sp<EventMatcherWizard>& matcherWizard,
-            const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-            const std::unordered_map<int64_t, int>& conditionTrackerMap,
-            const sp<ConditionWizard>& wizard,
-            const std::unordered_map<int64_t, int>& metricToActivationMap,
-            std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-            std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-            std::vector<int>& metricsWithActivation);
-
-    void clearPastBuckets(const int64_t dumpTimeNs) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        return clearPastBucketsLocked(dumpTimeNs);
-    }
-
-    void prepareFirstBucket() {
-        std::lock_guard<std::mutex> lock(mMutex);
-        prepareFirstBucketLocked();
-    }
-
-    // Returns the memory in bytes currently used to store this metric's data. Does not change
-    // state.
-    size_t byteSize() const {
-        std::lock_guard<std::mutex> lock(mMutex);
-        return byteSizeLocked();
-    }
-
-    void dumpStates(FILE* out, bool verbose) const {
-        std::lock_guard<std::mutex> lock(mMutex);
-        dumpStatesLocked(out, verbose);
-    }
-
-    // Let MetricProducer drop in-memory data to save memory.
-    // We still need to keep future data valid and anomaly tracking work, which means we will
-    // have to flush old data, informing anomaly trackers then safely drop old data.
-    // We still keep current bucket data for future metrics' validity.
-    void dropData(const int64_t dropTimeNs) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        dropDataLocked(dropTimeNs);
-    }
-
-    void loadActiveMetric(const ActiveMetric& activeMetric, int64_t currentTimeNs) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        loadActiveMetricLocked(activeMetric, currentTimeNs);
-    }
-
-    void activate(int activationTrackerIndex, int64_t elapsedTimestampNs) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        activateLocked(activationTrackerIndex, elapsedTimestampNs);
-    }
-
-    void cancelEventActivation(int deactivationTrackerIndex) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        cancelEventActivationLocked(deactivationTrackerIndex);
-    }
-
-    bool isActive() const {
-        std::lock_guard<std::mutex> lock(mMutex);
-        return isActiveLocked();
-    }
-
-    void flushIfExpire(int64_t elapsedTimestampNs);
-
-    void writeActiveMetricToProtoOutputStream(
-            int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
-    // Start: getters/setters
-    inline int64_t getMetricId() const {
-        return mMetricId;
-    }
-
-    inline uint64_t getProtoHash() const {
-        return mProtoHash;
-    }
-
-    virtual MetricType getMetricType() const = 0;
-
-    // For test only.
-    inline int64_t getCurrentBucketNum() const {
-        return mCurrentBucketNum;
-    }
-
-    int64_t getBucketSizeInNs() const {
-        std::lock_guard<std::mutex> lock(mMutex);
-        return mBucketSizeNs;
-    }
-
-    inline const std::vector<int> getSlicedStateAtoms() {
-        std::lock_guard<std::mutex> lock(mMutex);
-        return mSlicedStateAtoms;
-    }
-
-    inline bool isValid() const {
-        return mValid;
-    }
-
-    /* Adds an AnomalyTracker and returns it. */
-    virtual sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
-                                                 const sp<AlarmMonitor>& anomalyAlarmMonitor) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, mConfigKey);
-        mAnomalyTrackers.push_back(anomalyTracker);
-        return anomalyTracker;
-    }
-
-    /* Adds an AnomalyTracker that has already been created */
-    virtual void addAnomalyTracker(sp<AnomalyTracker>& anomalyTracker) {
-        std::lock_guard<std::mutex> lock(mMutex);
-        mAnomalyTrackers.push_back(anomalyTracker);
-    }
-    // End: getters/setters
-protected:
-    /**
-     * Flushes the current bucket if the eventTime is after the current bucket's end time.
-     */
-    virtual void flushIfNeededLocked(const int64_t& eventTime){};
-
-    /**
-     * For metrics that aggregate (ie, every metric producer except for EventMetricProducer),
-     * we need to be able to flush the current buckets on demand (ie, end the current bucket and
-     * start new bucket). If this function is called when eventTimeNs is greater than the current
-     * bucket's end timestamp, than we flush up to the end of the latest full bucket; otherwise,
-     * we assume that we want to flush a partial bucket. The bucket start timestamp and bucket
-     * number are not changed by this function. This method should only be called by
-     * flushIfNeededLocked or flushLocked or the app upgrade handler; the caller MUST update the
-     * bucket timestamp and bucket number as needed.
-     */
-    virtual void flushCurrentBucketLocked(const int64_t& eventTimeNs,
-                                          const int64_t& nextBucketStartTimeNs) {};
-
-    /**
-     * Flushes all the data including the current partial bucket.
-     */
-    virtual void flushLocked(const int64_t& eventTimeNs) {
-        flushIfNeededLocked(eventTimeNs);
-        flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
-    };
-
-    /*
-     * Individual metrics can implement their own business logic here. All pre-processing is done.
-     *
-     * [matcherIndex]: the index of the matcher which matched this event. This is interesting to
-     *                 DurationMetric, because it has start/stop/stop_all 3 matchers.
-     * [eventKey]: the extracted dimension key for the final output. if the metric doesn't have
-     *             dimensions, it will be DEFAULT_DIMENSION_KEY
-     * [conditionKey]: the keys of conditions which should be used to query the condition for this
-     *                 target event (from MetricConditionLink). This is passed to individual metrics
-     *                 because DurationMetric needs it to be cached.
-     * [condition]: whether condition is met. If condition is sliced, this is the result coming from
-     *              query with ConditionWizard; If condition is not sliced, this is the
-     *              nonSlicedCondition.
-     * [event]: the log event, just in case the metric needs its data, e.g., EventMetric.
-     */
-    virtual void onMatchedLogEventInternalLocked(
-            const size_t matcherIndex, const MetricDimensionKey& eventKey,
-            const ConditionKey& conditionKey, bool condition, const LogEvent& event,
-            const map<int, HashableDimensionKey>& statePrimaryKeys) = 0;
-
-    // Consume the parsed stats log entry that already matched the "what" of the metric.
-    virtual void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event);
-    virtual void onConditionChangedLocked(const bool condition, const int64_t eventTime) = 0;
-    virtual void onSlicedConditionMayChangeLocked(bool overallCondition,
-                                                  const int64_t eventTime) = 0;
-    virtual void onDumpReportLocked(const int64_t dumpTimeNs,
-                                    const bool include_current_partial_bucket,
-                                    const bool erase_data,
-                                    const DumpLatency dumpLatency,
-                                    std::set<string> *str_set,
-                                    android::util::ProtoOutputStream* protoOutput) = 0;
-    virtual void clearPastBucketsLocked(const int64_t dumpTimeNs) = 0;
-    virtual void prepareFirstBucketLocked(){};
-    virtual size_t byteSizeLocked() const = 0;
-    virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
-    virtual void dropDataLocked(const int64_t dropTimeNs) = 0;
-    void loadActiveMetricLocked(const ActiveMetric& activeMetric, int64_t currentTimeNs);
-    void activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs);
-    void cancelEventActivationLocked(int deactivationTrackerIndex);
-
-    bool evaluateActiveStateLocked(int64_t elapsedTimestampNs);
-
-    virtual void onActiveStateChangedLocked(const int64_t& eventTimeNs) {
-        if (!mIsActive) {
-            flushLocked(eventTimeNs);
-        }
-    }
-
-    inline bool isActiveLocked() const {
-        return mIsActive;
-    }
-
-    // Convenience to compute the current bucket's end time, which is always aligned with the
-    // start time of the metric.
-    int64_t getCurrentBucketEndTimeNs() const {
-        return mTimeBaseNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
-    }
-
-    int64_t getBucketNumFromEndTimeNs(const int64_t endNs) {
-        return (endNs - mTimeBaseNs) / mBucketSizeNs - 1;
-    }
-
-    // Query StateManager for original state value using the queryKey.
-    // The field and value are output.
-    void queryStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
-                         FieldValue* value);
-
-    // If a state map exists for the given atom, replace the original state
-    // value with the group id mapped to the value.
-    // If no state map exists, keep the original state value.
-    void mapStateValue(const int32_t atomId, FieldValue* value);
-
-    // Returns a HashableDimensionKey with unknown state value for each state
-    // atom.
-    HashableDimensionKey getUnknownStateKey();
-
-    DropEvent buildDropEvent(const int64_t dropTimeNs, const BucketDropReason reason);
-
-    // Returns true if the number of drop events in the current bucket has
-    // exceeded the maximum number allowed, which is currently capped at 10.
-    bool maxDropEventsReached();
-
-    const int64_t mMetricId;
-
-    // Hash of the Metric's proto bytes from StatsdConfig, including any activations.
-    // Used to determine if the definition of this metric has changed across a config update.
-    const uint64_t mProtoHash;
-
-    const ConfigKey mConfigKey;
-
-    bool mValid;
-
-    // The time when this metric producer was first created. The end time for the current bucket
-    // can be computed from this based on mCurrentBucketNum.
-    int64_t mTimeBaseNs;
-
-    // Start time may not be aligned with the start of statsd if there is an app upgrade in the
-    // middle of a bucket.
-    int64_t mCurrentBucketStartTimeNs;
-
-    // Used by anomaly detector to track which bucket we are in. This is not sent with the produced
-    // report.
-    int64_t mCurrentBucketNum;
-
-    int64_t mBucketSizeNs;
-
-    ConditionState mCondition;
-
-    int mConditionTrackerIndex;
-
-    bool mConditionSliced;
-
-    sp<ConditionWizard> mWizard;
-
-    bool mContainANYPositionInDimensionsInWhat;
-
-    bool mSliceByPositionALL;
-
-    vector<Matcher> mDimensionsInWhat;  // The dimensions_in_what defined in statsd_config
-
-    // True iff the metric to condition links cover all dimension fields in the condition tracker.
-    // This field is always false for combinational condition trackers.
-    bool mHasLinksToAllConditionDimensionsInTracker;
-
-    std::vector<Metric2Condition> mMetric2ConditionLinks;
-
-    std::vector<sp<AnomalyTracker>> mAnomalyTrackers;
-
-    mutable std::mutex mMutex;
-
-    // When the metric producer has multiple activations, these activations are ORed to determine
-    // whether the metric producer is ready to generate metrics.
-    std::unordered_map<int, std::shared_ptr<Activation>> mEventActivationMap;
-
-    // Maps index of atom matcher for deactivation to a list of Activation structs.
-    std::unordered_map<int, std::vector<std::shared_ptr<Activation>>> mEventDeactivationMap;
-
-    bool mIsActive;
-
-    // The slice_by_state atom ids defined in statsd_config.
-    const std::vector<int32_t> mSlicedStateAtoms;
-
-    // Maps atom ids and state values to group_ids (<atom_id, <value, group_id>>).
-    const std::unordered_map<int32_t, std::unordered_map<int, int64_t>> mStateGroupMap;
-
-    // MetricStateLinks defined in statsd_config that link fields in the state
-    // atom to fields in the "what" atom.
-    std::vector<Metric2State> mMetric2StateLinks;
-
-    SkippedBucket mCurrentSkippedBucket;
-    // Buckets that were invalidated and had their data dropped.
-    std::vector<SkippedBucket> mSkippedBuckets;
-
-    FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
-    FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
-    FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
-    FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
-    FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
-
-    FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
-    FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
-    FRIEND_TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
-
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
-
-    FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
-    FRIEND_TEST(StatsLogProcessorTest,
-            TestActivationOnBootMultipleActivationsDifferentActivationTypes);
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
-
-    FRIEND_TEST(MetricsManagerTest, TestInitialConditions);
-
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateMetricActivations);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateCountMetrics);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateEventMetrics);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateGaugeMetrics);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateDurationMetrics);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateMetricsMultipleTypes);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlerts);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#endif  // METRIC_PRODUCER_H
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
deleted file mode 100644
index f9b0a10..0000000
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "MetricsManager.h"
-
-#include <private/android_filesystem_config.h>
-
-#include "CountMetricProducer.h"
-#include "condition/CombinationConditionTracker.h"
-#include "condition/SimpleConditionTracker.h"
-#include "guardrail/StatsdStats.h"
-#include "matchers/CombinationAtomMatchingTracker.h"
-#include "matchers/SimpleAtomMatchingTracker.h"
-#include "parsing_utils/config_update_utils.h"
-#include "parsing_utils/metrics_manager_util.h"
-#include "state/StateManager.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "statslog_statsd.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-
-using std::set;
-using std::string;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const int FIELD_ID_METRICS = 1;
-const int FIELD_ID_ANNOTATIONS = 7;
-const int FIELD_ID_ANNOTATIONS_INT64 = 1;
-const int FIELD_ID_ANNOTATIONS_INT32 = 2;
-
-// for ActiveConfig
-const int FIELD_ID_ACTIVE_CONFIG_ID = 1;
-const int FIELD_ID_ACTIVE_CONFIG_UID = 2;
-const int FIELD_ID_ACTIVE_CONFIG_METRIC = 3;
-
-MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
-                               const int64_t timeBaseNs, const int64_t currentTimeNs,
-                               const sp<UidMap>& uidMap,
-                               const sp<StatsPullerManager>& pullerManager,
-                               const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                               const sp<AlarmMonitor>& periodicAlarmMonitor)
-    : mConfigKey(key),
-      mUidMap(uidMap),
-      mTtlNs(config.has_ttl_in_seconds() ? config.ttl_in_seconds() * NS_PER_SEC : -1),
-      mTtlEndNs(-1),
-      mLastReportTimeNs(currentTimeNs),
-      mLastReportWallClockNs(getWallClockNs()),
-      mPullerManager(pullerManager),
-      mWhitelistedAtomIds(config.whitelisted_atom_ids().begin(),
-                          config.whitelisted_atom_ids().end()),
-      mShouldPersistHistory(config.persist_locally()) {
-    // Init the ttl end timestamp.
-    refreshTtl(timeBaseNs);
-
-    mConfigValid = initStatsdConfig(
-            key, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchingTrackers, mAtomMatchingTrackerMap,
-            mAllConditionTrackers, mConditionTrackerMap, mAllMetricProducers, mMetricProducerMap,
-            mAllAnomalyTrackers, mAllPeriodicAlarmTrackers, mConditionToMetricMap,
-            mTrackerToMetricMap, mTrackerToConditionMap, mActivationAtomTrackerToMetricMap,
-            mDeactivationAtomTrackerToMetricMap, mAlertTrackerMap, mMetricIndexesWithActivation,
-            mStateProtoHashes, mNoReportMetricIds);
-
-    mHashStringsInReport = config.hash_strings_in_metric_report();
-    mVersionStringsInReport = config.version_strings_in_metric_report();
-    mInstallerInReport = config.installer_in_metric_report();
-
-    createAllLogSourcesFromConfig(config);
-    mPullerManager->RegisterPullUidProvider(mConfigKey, this);
-
-    // Store the sub-configs used.
-    for (const auto& annotation : config.annotation()) {
-        mAnnotations.emplace_back(annotation.field_int64(), annotation.field_int32());
-    }
-    verifyGuardrailsAndUpdateStatsdStats();
-    initializeConfigActiveStatus();
-}
-
-MetricsManager::~MetricsManager() {
-    for (auto it : mAllMetricProducers) {
-        for (int atomId : it->getSlicedStateAtoms()) {
-            StateManager::getInstance().unregisterListener(atomId, it);
-        }
-    }
-    mPullerManager->UnregisterPullUidProvider(mConfigKey, this);
-
-    VLOG("~MetricsManager()");
-}
-
-bool MetricsManager::updateConfig(const StatsdConfig& config, const int64_t timeBaseNs,
-                                  const int64_t currentTimeNs,
-                                  const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                                  const sp<AlarmMonitor>& periodicAlarmMonitor) {
-    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
-    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    vector<sp<ConditionTracker>> newConditionTrackers;
-    unordered_map<int64_t, int> newConditionTrackerMap;
-    map<int64_t, uint64_t> newStateProtoHashes;
-    vector<sp<MetricProducer>> newMetricProducers;
-    unordered_map<int64_t, int> newMetricProducerMap;
-    vector<sp<AnomalyTracker>> newAnomalyTrackers;
-    unordered_map<int64_t, int> newAlertTrackerMap;
-    vector<sp<AlarmTracker>> newPeriodicAlarmTrackers;
-    mTagIds.clear();
-    mConditionToMetricMap.clear();
-    mTrackerToMetricMap.clear();
-    mTrackerToConditionMap.clear();
-    mActivationAtomTrackerToMetricMap.clear();
-    mDeactivationAtomTrackerToMetricMap.clear();
-    mMetricIndexesWithActivation.clear();
-    mNoReportMetricIds.clear();
-    mConfigValid = updateStatsdConfig(
-            mConfigKey, config, mUidMap, mPullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseNs, currentTimeNs, mAllAtomMatchingTrackers, mAtomMatchingTrackerMap,
-            mAllConditionTrackers, mConditionTrackerMap, mAllMetricProducers, mMetricProducerMap,
-            mAllAnomalyTrackers, mAlertTrackerMap, mStateProtoHashes, mTagIds,
-            newAtomMatchingTrackers, newAtomMatchingTrackerMap, newConditionTrackers,
-            newConditionTrackerMap, newMetricProducers, newMetricProducerMap, newAnomalyTrackers,
-            newAlertTrackerMap, newPeriodicAlarmTrackers, mConditionToMetricMap,
-            mTrackerToMetricMap, mTrackerToConditionMap, mActivationAtomTrackerToMetricMap,
-            mDeactivationAtomTrackerToMetricMap, mMetricIndexesWithActivation, newStateProtoHashes,
-            mNoReportMetricIds);
-    mAllAtomMatchingTrackers = newAtomMatchingTrackers;
-    mAtomMatchingTrackerMap = newAtomMatchingTrackerMap;
-    mAllConditionTrackers = newConditionTrackers;
-    mConditionTrackerMap = newConditionTrackerMap;
-    mAllMetricProducers = newMetricProducers;
-    mMetricProducerMap = newMetricProducerMap;
-    mStateProtoHashes = newStateProtoHashes;
-    mAllAnomalyTrackers = newAnomalyTrackers;
-    mAlertTrackerMap = newAlertTrackerMap;
-    mAllPeriodicAlarmTrackers = newPeriodicAlarmTrackers;
-
-    mTtlNs = config.has_ttl_in_seconds() ? config.ttl_in_seconds() * NS_PER_SEC : -1;
-    refreshTtl(currentTimeNs);
-
-    mHashStringsInReport = config.hash_strings_in_metric_report();
-    mVersionStringsInReport = config.version_strings_in_metric_report();
-    mInstallerInReport = config.installer_in_metric_report();
-    mWhitelistedAtomIds.clear();
-    mWhitelistedAtomIds.insert(config.whitelisted_atom_ids().begin(),
-                               config.whitelisted_atom_ids().end());
-    mShouldPersistHistory = config.persist_locally();
-
-    // Store the sub-configs used.
-    mAnnotations.clear();
-    for (const auto& annotation : config.annotation()) {
-        mAnnotations.emplace_back(annotation.field_int64(), annotation.field_int32());
-    }
-
-    mAllowedUid.clear();
-    mAllowedPkg.clear();
-    mDefaultPullUids.clear();
-    mPullAtomUids.clear();
-    mPullAtomPackages.clear();
-    createAllLogSourcesFromConfig(config);
-
-    verifyGuardrailsAndUpdateStatsdStats();
-    initializeConfigActiveStatus();
-    return mConfigValid;
-}
-
-void MetricsManager::createAllLogSourcesFromConfig(const StatsdConfig& config) {
-    // Init allowed pushed atom uids.
-    if (config.allowed_log_source_size() == 0) {
-        mConfigValid = false;
-        ALOGE("Log source allowlist is empty! This config won't get any data. Suggest adding at "
-              "least AID_SYSTEM and AID_STATSD to the allowed_log_source field.");
-    } else {
-        for (const auto& source : config.allowed_log_source()) {
-            auto it = UidMap::sAidToUidMapping.find(source);
-            if (it != UidMap::sAidToUidMapping.end()) {
-                mAllowedUid.push_back(it->second);
-            } else {
-                mAllowedPkg.push_back(source);
-            }
-        }
-
-        if (mAllowedUid.size() + mAllowedPkg.size() > StatsdStats::kMaxLogSourceCount) {
-            ALOGE("Too many log sources. This is likely to be an error in the config.");
-            mConfigValid = false;
-        } else {
-            initAllowedLogSources();
-        }
-    }
-
-    // Init default allowed pull atom uids.
-    int numPullPackages = 0;
-    for (const string& pullSource : config.default_pull_packages()) {
-        auto it = UidMap::sAidToUidMapping.find(pullSource);
-        if (it != UidMap::sAidToUidMapping.end()) {
-            numPullPackages++;
-            mDefaultPullUids.insert(it->second);
-        } else {
-            ALOGE("Default pull atom packages must be in sAidToUidMapping");
-            mConfigValid = false;
-        }
-    }
-    // Init per-atom pull atom packages.
-    for (const PullAtomPackages& pullAtomPackages : config.pull_atom_packages()) {
-        int32_t atomId = pullAtomPackages.atom_id();
-        for (const string& pullPackage : pullAtomPackages.packages()) {
-            numPullPackages++;
-            auto it = UidMap::sAidToUidMapping.find(pullPackage);
-            if (it != UidMap::sAidToUidMapping.end()) {
-                mPullAtomUids[atomId].insert(it->second);
-            } else {
-                mPullAtomPackages[atomId].insert(pullPackage);
-            }
-        }
-    }
-    if (numPullPackages > StatsdStats::kMaxPullAtomPackages) {
-        ALOGE("Too many sources in default_pull_packages and pull_atom_packages. This is likely to "
-              "be an error in the config");
-        mConfigValid = false;
-    } else {
-        initPullAtomSources();
-    }
-}
-
-void MetricsManager::verifyGuardrailsAndUpdateStatsdStats() {
-    // Guardrail. Reject the config if it's too big.
-    if (mAllMetricProducers.size() > StatsdStats::kMaxMetricCountPerConfig ||
-        mAllConditionTrackers.size() > StatsdStats::kMaxConditionCountPerConfig ||
-        mAllAtomMatchingTrackers.size() > StatsdStats::kMaxMatcherCountPerConfig) {
-        ALOGE("This config is too big! Reject!");
-        mConfigValid = false;
-    }
-    if (mAllAnomalyTrackers.size() > StatsdStats::kMaxAlertCountPerConfig) {
-        ALOGE("This config has too many alerts! Reject!");
-        mConfigValid = false;
-    }
-    // no matter whether this config is valid, log it in the stats.
-    StatsdStats::getInstance().noteConfigReceived(
-            mConfigKey, mAllMetricProducers.size(), mAllConditionTrackers.size(),
-            mAllAtomMatchingTrackers.size(), mAllAnomalyTrackers.size(), mAnnotations,
-            mConfigValid);
-}
-
-void MetricsManager::initializeConfigActiveStatus() {
-    mIsAlwaysActive = (mMetricIndexesWithActivation.size() != mAllMetricProducers.size()) ||
-                      (mAllMetricProducers.size() == 0);
-    mIsActive = mIsAlwaysActive;
-    for (int metric : mMetricIndexesWithActivation) {
-        mIsActive |= mAllMetricProducers[metric]->isActive();
-    }
-    VLOG("mIsActive is initialized to %d", mIsActive);
-}
-
-void MetricsManager::initAllowedLogSources() {
-    std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
-    mAllowedLogSources.clear();
-    mAllowedLogSources.insert(mAllowedUid.begin(), mAllowedUid.end());
-
-    for (const auto& pkg : mAllowedPkg) {
-        auto uids = mUidMap->getAppUid(pkg);
-        mAllowedLogSources.insert(uids.begin(), uids.end());
-    }
-    if (DEBUG) {
-        for (const auto& uid : mAllowedLogSources) {
-            VLOG("Allowed uid %d", uid);
-        }
-    }
-}
-
-void MetricsManager::initPullAtomSources() {
-    std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
-    mCombinedPullAtomUids.clear();
-    for (const auto& [atomId, uids] : mPullAtomUids) {
-        mCombinedPullAtomUids[atomId].insert(uids.begin(), uids.end());
-    }
-    for (const auto& [atomId, packages] : mPullAtomPackages) {
-        for (const string& pkg : packages) {
-            set<int32_t> uids = mUidMap->getAppUid(pkg);
-            mCombinedPullAtomUids[atomId].insert(uids.begin(), uids.end());
-        }
-    }
-}
-
-bool MetricsManager::isConfigValid() const {
-    return mConfigValid;
-}
-
-void MetricsManager::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
-                                      const int64_t version) {
-    // Inform all metric producers.
-    for (const auto& it : mAllMetricProducers) {
-        it->notifyAppUpgrade(eventTimeNs);
-    }
-    // check if we care this package
-    if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) {
-        // We will re-initialize the whole list because we don't want to keep the multi mapping of
-        // UID<->pkg inside MetricsManager to reduce the memory usage.
-        initAllowedLogSources();
-    }
-
-    for (const auto& it : mPullAtomPackages) {
-        if (it.second.find(apk) != it.second.end()) {
-            initPullAtomSources();
-            return;
-        }
-    }
-}
-
-void MetricsManager::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk,
-                                      const int uid) {
-    // Inform all metric producers.
-    for (const auto& it : mAllMetricProducers) {
-        it->notifyAppRemoved(eventTimeNs);
-    }
-    // check if we care this package
-    if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) != mAllowedPkg.end()) {
-        // We will re-initialize the whole list because we don't want to keep the multi mapping of
-        // UID<->pkg inside MetricsManager to reduce the memory usage.
-        initAllowedLogSources();
-    }
-
-    for (const auto& it : mPullAtomPackages) {
-        if (it.second.find(apk) != it.second.end()) {
-            initPullAtomSources();
-            return;
-        }
-    }
-}
-
-void MetricsManager::onUidMapReceived(const int64_t& eventTimeNs) {
-    // Purposefully don't inform metric producers on a new snapshot
-    // because we don't need to flush partial buckets.
-    // This occurs if a new user is added/removed or statsd crashes.
-    initPullAtomSources();
-
-    if (mAllowedPkg.size() == 0) {
-        return;
-    }
-    initAllowedLogSources();
-}
-
-void MetricsManager::onStatsdInitCompleted(const int64_t& eventTimeNs) {
-    // Inform all metric producers.
-    for (const auto& it : mAllMetricProducers) {
-        it->onStatsdInitCompleted(eventTimeNs);
-    }
-}
-
-void MetricsManager::init() {
-    for (const auto& producer : mAllMetricProducers) {
-        producer->prepareFirstBucket();
-    }
-}
-
-vector<int32_t> MetricsManager::getPullAtomUids(int32_t atomId) {
-    std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
-    vector<int32_t> uids;
-    const auto& it = mCombinedPullAtomUids.find(atomId);
-    if (it != mCombinedPullAtomUids.end()) {
-        uids.insert(uids.end(), it->second.begin(), it->second.end());
-    }
-    uids.insert(uids.end(), mDefaultPullUids.begin(), mDefaultPullUids.end());
-    return uids;
-}
-
-void MetricsManager::dumpStates(FILE* out, bool verbose) {
-    fprintf(out, "ConfigKey %s, allowed source:", mConfigKey.ToString().c_str());
-    {
-        std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
-        for (const auto& source : mAllowedLogSources) {
-            fprintf(out, "%d ", source);
-        }
-    }
-    fprintf(out, "\n");
-    for (const auto& producer : mAllMetricProducers) {
-        producer->dumpStates(out, verbose);
-    }
-}
-
-void MetricsManager::dropData(const int64_t dropTimeNs) {
-    for (const auto& producer : mAllMetricProducers) {
-        producer->dropData(dropTimeNs);
-    }
-}
-
-void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs,
-                                  const bool include_current_partial_bucket,
-                                  const bool erase_data,
-                                  const DumpLatency dumpLatency,
-                                  std::set<string> *str_set,
-                                  ProtoOutputStream* protoOutput) {
-    VLOG("=========================Metric Reports Start==========================");
-    // one StatsLogReport per MetricProduer
-    for (const auto& producer : mAllMetricProducers) {
-        if (mNoReportMetricIds.find(producer->getMetricId()) == mNoReportMetricIds.end()) {
-            uint64_t token = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_METRICS);
-            if (mHashStringsInReport) {
-                producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
-                                       dumpLatency, str_set, protoOutput);
-            } else {
-                producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
-                                       dumpLatency, nullptr, protoOutput);
-            }
-            protoOutput->end(token);
-        } else {
-            producer->clearPastBuckets(dumpTimeStampNs);
-        }
-    }
-    for (const auto& annotation : mAnnotations) {
-        uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                            FIELD_ID_ANNOTATIONS);
-        protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ANNOTATIONS_INT64,
-                           (long long)annotation.first);
-        protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_ANNOTATIONS_INT32, annotation.second);
-        protoOutput->end(token);
-    }
-
-    // Do not update the timestamps when data is not cleared to avoid timestamps from being
-    // misaligned.
-    if (erase_data) {
-        mLastReportTimeNs = dumpTimeStampNs;
-        mLastReportWallClockNs = getWallClockNs();
-    }
-    VLOG("=========================Metric Reports End==========================");
-}
-
-
-bool MetricsManager::checkLogCredentials(const LogEvent& event) {
-    if (mWhitelistedAtomIds.find(event.GetTagId()) != mWhitelistedAtomIds.end()) {
-        return true;
-    }
-    std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
-    if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
-        VLOG("log source %d not on the whitelist", event.GetUid());
-        return false;
-    }
-    return true;
-}
-
-bool MetricsManager::eventSanityCheck(const LogEvent& event) {
-    if (event.GetTagId() == util::APP_BREADCRUMB_REPORTED) {
-        // Check that app breadcrumb reported fields are valid.
-        status_t err = NO_ERROR;
-
-        // Uid is 3rd from last field and must match the caller's uid,
-        // unless that caller is statsd itself (statsd is allowed to spoof uids).
-        long appHookUid = event.GetLong(event.size()-2, &err);
-        if (err != NO_ERROR) {
-            VLOG("APP_BREADCRUMB_REPORTED had error when parsing the uid");
-            return false;
-        }
-
-        // Because the uid within the LogEvent may have been mapped from
-        // isolated to host, map the loggerUid similarly before comparing.
-        int32_t loggerUid = mUidMap->getHostUidOrSelf(event.GetUid());
-        if (loggerUid != appHookUid && loggerUid != AID_STATSD) {
-            VLOG("APP_BREADCRUMB_REPORTED has invalid uid: claimed %ld but caller is %d",
-                 appHookUid, loggerUid);
-            return false;
-        }
-
-        // The state must be from 0,3. This part of code must be manually updated.
-        long appHookState = event.GetLong(event.size(), &err);
-        if (err != NO_ERROR) {
-            VLOG("APP_BREADCRUMB_REPORTED had error when parsing the state field");
-            return false;
-        } else if (appHookState < 0 || appHookState > 3) {
-            VLOG("APP_BREADCRUMB_REPORTED does not have valid state %ld", appHookState);
-            return false;
-        }
-    } else if (event.GetTagId() == util::DAVEY_OCCURRED) {
-        // Daveys can be logged from any app since they are logged in libs/hwui/JankTracker.cpp.
-        // Check that the davey duration is reasonable. Max length check is for privacy.
-        status_t err = NO_ERROR;
-
-        // Uid is the first field provided.
-        long jankUid = event.GetLong(1, &err);
-        if (err != NO_ERROR) {
-            VLOG("Davey occurred had error when parsing the uid");
-            return false;
-        }
-        int32_t loggerUid = event.GetUid();
-        if (loggerUid != jankUid && loggerUid != AID_STATSD) {
-            VLOG("DAVEY_OCCURRED has invalid uid: claimed %ld but caller is %d", jankUid,
-                 loggerUid);
-            return false;
-        }
-
-        long duration = event.GetLong(event.size(), &err);
-        if (err != NO_ERROR) {
-            VLOG("Davey occurred had error when parsing the duration");
-            return false;
-        } else if (duration > 100000) {
-            VLOG("Davey duration is unreasonably long: %ld", duration);
-            return false;
-        }
-    }
-
-    return true;
-}
-
-// Consume the stats log if it's interesting to this metric.
-void MetricsManager::onLogEvent(const LogEvent& event) {
-    if (!mConfigValid) {
-        return;
-    }
-
-    if (!checkLogCredentials(event)) {
-        return;
-    }
-
-    if (!eventSanityCheck(event)) {
-        return;
-    }
-
-    int tagId = event.GetTagId();
-    int64_t eventTimeNs = event.GetElapsedTimestampNs();
-
-    bool isActive = mIsAlwaysActive;
-
-    // Set of metrics that are still active after flushing.
-    unordered_set<int> activeMetricsIndices;
-
-    // Update state of all metrics w/ activation conditions as of eventTimeNs.
-    for (int metricIndex : mMetricIndexesWithActivation) {
-        const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
-        metric->flushIfExpire(eventTimeNs);
-        if (metric->isActive()) {
-            // If this metric w/ activation condition is still active after
-            // flushing, remember it.
-            activeMetricsIndices.insert(metricIndex);
-        }
-    }
-
-    mIsActive = isActive || !activeMetricsIndices.empty();
-
-    if (mTagIds.find(tagId) == mTagIds.end()) {
-        // Not interesting...
-        return;
-    }
-
-    vector<MatchingState> matcherCache(mAllAtomMatchingTrackers.size(),
-                                       MatchingState::kNotComputed);
-
-    // Evaluate all atom matchers.
-    for (auto& matcher : mAllAtomMatchingTrackers) {
-        matcher->onLogEvent(event, mAllAtomMatchingTrackers, matcherCache);
-    }
-
-    // Set of metrics that received an activation cancellation.
-    unordered_set<int> metricIndicesWithCanceledActivations;
-
-    // Determine which metric activations received a cancellation and cancel them.
-    for (const auto& it : mDeactivationAtomTrackerToMetricMap) {
-        if (matcherCache[it.first] == MatchingState::kMatched) {
-            for (int metricIndex : it.second) {
-                mAllMetricProducers[metricIndex]->cancelEventActivation(it.first);
-                metricIndicesWithCanceledActivations.insert(metricIndex);
-            }
-        }
-    }
-
-    // Determine whether any metrics are no longer active after cancelling metric activations.
-    for (const int metricIndex : metricIndicesWithCanceledActivations) {
-        const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
-        metric->flushIfExpire(eventTimeNs);
-        if (!metric->isActive()) {
-            activeMetricsIndices.erase(metricIndex);
-        }
-    }
-
-    isActive |= !activeMetricsIndices.empty();
-
-
-    // Determine which metric activations should be turned on and turn them on
-    for (const auto& it : mActivationAtomTrackerToMetricMap) {
-        if (matcherCache[it.first] == MatchingState::kMatched) {
-            for (int metricIndex : it.second) {
-                mAllMetricProducers[metricIndex]->activate(it.first, eventTimeNs);
-                isActive |= mAllMetricProducers[metricIndex]->isActive();
-            }
-        }
-    }
-
-    mIsActive = isActive;
-
-    // A bitmap to see which ConditionTracker needs to be re-evaluated.
-    vector<bool> conditionToBeEvaluated(mAllConditionTrackers.size(), false);
-
-    for (const auto& pair : mTrackerToConditionMap) {
-        if (matcherCache[pair.first] == MatchingState::kMatched) {
-            const auto& conditionList = pair.second;
-            for (const int conditionIndex : conditionList) {
-                conditionToBeEvaluated[conditionIndex] = true;
-            }
-        }
-    }
-
-    vector<ConditionState> conditionCache(mAllConditionTrackers.size(),
-                                          ConditionState::kNotEvaluated);
-    // A bitmap to track if a condition has changed value.
-    vector<bool> changedCache(mAllConditionTrackers.size(), false);
-    for (size_t i = 0; i < mAllConditionTrackers.size(); i++) {
-        if (conditionToBeEvaluated[i] == false) {
-            continue;
-        }
-        sp<ConditionTracker>& condition = mAllConditionTrackers[i];
-        condition->evaluateCondition(event, matcherCache, mAllConditionTrackers, conditionCache,
-                                     changedCache);
-    }
-
-    for (size_t i = 0; i < mAllConditionTrackers.size(); i++) {
-        if (changedCache[i] == false) {
-            continue;
-        }
-        auto pair = mConditionToMetricMap.find(i);
-        if (pair != mConditionToMetricMap.end()) {
-            auto& metricList = pair->second;
-            for (auto metricIndex : metricList) {
-                // Metric cares about non sliced condition, and it's changed.
-                // Push the new condition to it directly.
-                if (!mAllMetricProducers[metricIndex]->isConditionSliced()) {
-                    mAllMetricProducers[metricIndex]->onConditionChanged(conditionCache[i],
-                                                                         eventTimeNs);
-                    // Metric cares about sliced conditions, and it may have changed. Send
-                    // notification, and the metric can query the sliced conditions that are
-                    // interesting to it.
-                } else {
-                    mAllMetricProducers[metricIndex]->onSlicedConditionMayChange(conditionCache[i],
-                                                                                 eventTimeNs);
-                }
-            }
-        }
-    }
-
-    // For matched AtomMatchers, tell relevant metrics that a matched event has come.
-    for (size_t i = 0; i < mAllAtomMatchingTrackers.size(); i++) {
-        if (matcherCache[i] == MatchingState::kMatched) {
-            StatsdStats::getInstance().noteMatcherMatched(mConfigKey,
-                                                          mAllAtomMatchingTrackers[i]->getId());
-            auto pair = mTrackerToMetricMap.find(i);
-            if (pair != mTrackerToMetricMap.end()) {
-                auto& metricList = pair->second;
-                for (const int metricIndex : metricList) {
-                    // pushed metrics are never scheduled pulls
-                    mAllMetricProducers[metricIndex]->onMatchedLogEvent(i, event);
-                }
-            }
-        }
-    }
-}
-
-void MetricsManager::onAnomalyAlarmFired(
-        const int64_t& timestampNs,
-        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
-    for (const auto& itr : mAllAnomalyTrackers) {
-        itr->informAlarmsFired(timestampNs, alarmSet);
-    }
-}
-
-void MetricsManager::onPeriodicAlarmFired(
-        const int64_t& timestampNs,
-        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
-    for (const auto& itr : mAllPeriodicAlarmTrackers) {
-        itr->informAlarmsFired(timestampNs, alarmSet);
-    }
-}
-
-// Returns the total byte size of all metrics managed by a single config source.
-size_t MetricsManager::byteSize() {
-    size_t totalSize = 0;
-    for (const auto& metricProducer : mAllMetricProducers) {
-        totalSize += metricProducer->byteSize();
-    }
-    return totalSize;
-}
-
-void MetricsManager::loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs) {
-    if (config.metric_size() == 0) {
-        ALOGW("No active metric for config %s", mConfigKey.ToString().c_str());
-        return;
-    }
-
-    for (int i = 0; i < config.metric_size(); i++) {
-        const auto& activeMetric = config.metric(i);
-        for (int metricIndex : mMetricIndexesWithActivation) {
-            const auto& metric = mAllMetricProducers[metricIndex];
-            if (metric->getMetricId() == activeMetric.id()) {
-                VLOG("Setting active metric: %lld", (long long)metric->getMetricId());
-                metric->loadActiveMetric(activeMetric, currentTimeNs);
-                if (!mIsActive && metric->isActive()) {
-                    StatsdStats::getInstance().noteActiveStatusChanged(mConfigKey,
-                                                                       /*activate=*/ true);
-                }
-                mIsActive |= metric->isActive();
-            }
-        }
-    }
-}
-
-void MetricsManager::writeActiveConfigToProtoOutputStream(
-        int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
-    proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_CONFIG_ID, (long long)mConfigKey.GetId());
-    proto->write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVE_CONFIG_UID, mConfigKey.GetUid());
-    for (int metricIndex : mMetricIndexesWithActivation) {
-        const auto& metric = mAllMetricProducers[metricIndex];
-        const uint64_t metricToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                FIELD_ID_ACTIVE_CONFIG_METRIC);
-        metric->writeActiveMetricToProtoOutputStream(currentTimeNs, reason, proto);
-        proto->end(metricToken);
-    }
-}
-
-bool MetricsManager::writeMetadataToProto(int64_t currentWallClockTimeNs,
-                                          int64_t systemElapsedTimeNs,
-                                          metadata::StatsMetadata* statsMetadata) {
-    bool metadataWritten = false;
-    metadata::ConfigKey* configKey = statsMetadata->mutable_config_key();
-    configKey->set_config_id(mConfigKey.GetId());
-    configKey->set_uid(mConfigKey.GetUid());
-    for (const auto& anomalyTracker : mAllAnomalyTrackers) {
-        metadata::AlertMetadata* alertMetadata = statsMetadata->add_alert_metadata();
-        bool alertWritten = anomalyTracker->writeAlertMetadataToProto(currentWallClockTimeNs,
-                systemElapsedTimeNs, alertMetadata);
-        if (!alertWritten) {
-            statsMetadata->mutable_alert_metadata()->RemoveLast();
-        }
-        metadataWritten |= alertWritten;
-    }
-    return metadataWritten;
-}
-
-void MetricsManager::loadMetadata(const metadata::StatsMetadata& metadata,
-                                  int64_t currentWallClockTimeNs,
-                                  int64_t systemElapsedTimeNs) {
-    for (const metadata::AlertMetadata& alertMetadata : metadata.alert_metadata()) {
-        int64_t alertId = alertMetadata.alert_id();
-        auto it = mAlertTrackerMap.find(alertId);
-        if (it == mAlertTrackerMap.end()) {
-            ALOGE("No anomalyTracker found for alertId %lld", (long long) alertId);
-            continue;
-        }
-        mAllAnomalyTrackers[it->second]->loadAlertMetadata(alertMetadata,
-                                                           currentWallClockTimeNs,
-                                                           systemElapsedTimeNs);
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
deleted file mode 100644
index 0e56371..0000000
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "anomaly/AlarmMonitor.h"
-#include "anomaly/AlarmTracker.h"
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionTracker.h"
-#include "config/ConfigKey.h"
-#include "external/StatsPullerManager.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
-#include "logd/LogEvent.h"
-#include "matchers/AtomMatchingTracker.h"
-#include "metrics/MetricProducer.h"
-#include "packages/UidMap.h"
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// A MetricsManager is responsible for managing metrics from one single config source.
-class MetricsManager : public virtual android::RefBase, public virtual PullUidProvider {
-public:
-    MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const int64_t timeBaseNs,
-                   const int64_t currentTimeNs, const sp<UidMap>& uidMap,
-                   const sp<StatsPullerManager>& pullerManager,
-                   const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                   const sp<AlarmMonitor>& periodicAlarmMonitor);
-
-    virtual ~MetricsManager();
-
-    bool updateConfig(const StatsdConfig& config, const int64_t timeBaseNs,
-                      const int64_t currentTimeNs, const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                      const sp<AlarmMonitor>& periodicAlarmMonitor);
-
-    // Return whether the configuration is valid.
-    bool isConfigValid() const;
-
-    bool checkLogCredentials(const LogEvent& event);
-
-    bool eventSanityCheck(const LogEvent& event);
-
-    void onLogEvent(const LogEvent& event);
-
-    void onAnomalyAlarmFired(
-        const int64_t& timestampNs,
-        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
-
-    void onPeriodicAlarmFired(
-        const int64_t& timestampNs,
-        unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
-
-    void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
-                          const int64_t version);
-
-    void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid);
-
-    void onUidMapReceived(const int64_t& eventTimeNs);
-
-    void onStatsdInitCompleted(const int64_t& elapsedTimeNs);
-
-    void init();
-
-    vector<int32_t> getPullAtomUids(int32_t atomId) override;
-
-    bool shouldWriteToDisk() const {
-        return mNoReportMetricIds.size() != mAllMetricProducers.size();
-    }
-
-    bool shouldPersistLocalHistory() const {
-        return mShouldPersistHistory;
-    }
-
-    void dumpStates(FILE* out, bool verbose);
-
-    inline bool isInTtl(const int64_t timestampNs) const {
-        return mTtlNs <= 0 || timestampNs < mTtlEndNs;
-    };
-
-    inline bool hashStringInReport() const {
-        return mHashStringsInReport;
-    };
-
-    inline bool versionStringsInReport() const {
-        return mVersionStringsInReport;
-    };
-
-    inline bool installerInReport() const {
-        return mInstallerInReport;
-    };
-
-    void refreshTtl(const int64_t currentTimestampNs) {
-        if (mTtlNs > 0) {
-            mTtlEndNs = currentTimestampNs + mTtlNs;
-        }
-    };
-
-    // Returns the elapsed realtime when this metric manager last reported metrics. If this config
-    // has not yet dumped any reports, this is the time the metricsmanager was initialized.
-    inline int64_t getLastReportTimeNs() const {
-        return mLastReportTimeNs;
-    };
-
-    inline int64_t getLastReportWallClockNs() const {
-        return mLastReportWallClockNs;
-    };
-
-    inline size_t getNumMetrics() const {
-        return mAllMetricProducers.size();
-    }
-
-    virtual void dropData(const int64_t dropTimeNs);
-
-    virtual void onDumpReport(const int64_t dumpTimeNs,
-                              const bool include_current_partial_bucket,
-                              const bool erase_data,
-                              const DumpLatency dumpLatency,
-                              std::set<string> *str_set,
-                              android::util::ProtoOutputStream* protoOutput);
-
-    // Computes the total byte size of all metrics managed by a single config source.
-    // Does not change the state.
-    virtual size_t byteSize();
-
-    // Returns whether or not this config is active.
-    // The config is active if any metric in the config is active.
-    inline bool isActive() const {
-        return mIsActive;
-    }
-
-    void loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs);
-
-    void writeActiveConfigToProtoOutputStream(
-            int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
-
-    // Returns true if at least one piece of metadata is written.
-    bool writeMetadataToProto(int64_t currentWallClockTimeNs,
-                              int64_t systemElapsedTimeNs,
-                              metadata::StatsMetadata* statsMetadata);
-
-    void loadMetadata(const metadata::StatsMetadata& metadata,
-                      int64_t currentWallClockTimeNs,
-                      int64_t systemElapsedTimeNs);
-private:
-    // For test only.
-    inline int64_t getTtlEndNs() const { return mTtlEndNs; }
-
-    const ConfigKey mConfigKey;
-
-    sp<UidMap> mUidMap;
-
-    bool mConfigValid = false;
-
-    bool mHashStringsInReport = false;
-    bool mVersionStringsInReport = false;
-    bool mInstallerInReport = false;
-
-    int64_t mTtlNs;
-    int64_t mTtlEndNs;
-
-    int64_t mLastReportTimeNs;
-    int64_t mLastReportWallClockNs;
-
-    sp<StatsPullerManager> mPullerManager;
-
-    // The uid log sources from StatsdConfig.
-    std::vector<int32_t> mAllowedUid;
-
-    // The pkg log sources from StatsdConfig.
-    std::vector<std::string> mAllowedPkg;
-
-    // The combined uid sources (after translating pkg name to uid).
-    // Logs from uids that are not in the list will be ignored to avoid spamming.
-    std::set<int32_t> mAllowedLogSources;
-
-    // To guard access to mAllowedLogSources
-    mutable std::mutex mAllowedLogSourcesMutex;
-
-    std::set<int32_t> mWhitelistedAtomIds;
-
-    // We can pull any atom from these uids.
-    std::set<int32_t> mDefaultPullUids;
-
-    // Uids that specific atoms can pull from.
-    // This is a map<atom id, set<uids>>
-    std::map<int32_t, std::set<int32_t>> mPullAtomUids;
-
-    // Packages that specific atoms can be pulled from.
-    std::map<int32_t, std::set<std::string>> mPullAtomPackages;
-
-    // All uids to pull for this atom. NOTE: Does not include the default uids for memory.
-    std::map<int32_t, std::set<int32_t>> mCombinedPullAtomUids;
-
-    // Contains the annotations passed in with StatsdConfig.
-    std::list<std::pair<const int64_t, const int32_t>> mAnnotations;
-
-    bool mShouldPersistHistory;
-
-    // All event tags that are interesting to my metrics.
-    std::set<int> mTagIds;
-
-    // We only store the sp of AtomMatchingTracker, MetricProducer, and ConditionTracker in
-    // MetricsManager. There are relationships between them, and the relationships are denoted by
-    // index instead of pointers. The reasons for this are: (1) the relationship between them are
-    // complicated, so storing index instead of pointers reduces the risk that A holds B's sp, and B
-    // holds A's sp. (2) When we evaluate matcher results, or condition results, we can quickly get
-    // the related results from a cache using the index.
-
-    // Hold all the atom matchers from the config.
-    std::vector<sp<AtomMatchingTracker>> mAllAtomMatchingTrackers;
-
-    // Hold all the conditions from the config.
-    std::vector<sp<ConditionTracker>> mAllConditionTrackers;
-
-    // Hold all metrics from the config.
-    std::vector<sp<MetricProducer>> mAllMetricProducers;
-
-    // Hold all alert trackers.
-    std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers;
-
-    // Hold all periodic alarm trackers.
-    std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers;
-
-    // To make updating configs faster, we map the id of a AtomMatchingTracker, MetricProducer, and
-    // ConditionTracker to its index in the corresponding vector.
-
-    // Maps the id of an atom matching tracker to its index in mAllAtomMatchingTrackers.
-    std::unordered_map<int64_t, int> mAtomMatchingTrackerMap;
-
-    // Maps the id of a condition tracker to its index in mAllConditionTrackers.
-    std::unordered_map<int64_t, int> mConditionTrackerMap;
-
-    // Maps the id of a metric producer to its index in mAllMetricProducers.
-    std::unordered_map<int64_t, int> mMetricProducerMap;
-
-    // To make the log processing more efficient, we want to do as much filtering as possible
-    // before we go into individual trackers and conditions to match.
-
-    // 1st filter: check if the event tag id is in mTagIds.
-    // 2nd filter: if it is, we parse the event because there is at least one member is interested.
-    //             then pass to all AtomMatchingTrackers (itself also filter events by ids).
-    // 3nd filter: for AtomMatchingTrackers that matched this event, we pass this event to the
-    //             ConditionTrackers and MetricProducers that use this matcher.
-    // 4th filter: for ConditionTrackers that changed value due to this event, we pass
-    //             new conditions to  metrics that use this condition.
-
-    // The following map is initialized from the statsd_config.
-
-    // Maps from the index of the AtomMatchingTracker to index of MetricProducer.
-    std::unordered_map<int, std::vector<int>> mTrackerToMetricMap;
-
-    // Maps from AtomMatchingTracker to ConditionTracker
-    std::unordered_map<int, std::vector<int>> mTrackerToConditionMap;
-
-    // Maps from ConditionTracker to MetricProducer
-    std::unordered_map<int, std::vector<int>> mConditionToMetricMap;
-
-    // Maps from life span triggering event to MetricProducers.
-    std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap;
-
-    // Maps deactivation triggering event to MetricProducers.
-    std::unordered_map<int, std::vector<int>> mDeactivationAtomTrackerToMetricMap;
-
-    // Maps AlertIds to the index of the corresponding AnomalyTracker stored in mAllAnomalyTrackers.
-    // The map is used in LoadMetadata to more efficiently lookup AnomalyTrackers from an AlertId.
-    std::unordered_map<int64_t, int> mAlertTrackerMap;
-
-    std::vector<int> mMetricIndexesWithActivation;
-
-    void initAllowedLogSources();
-
-    void initPullAtomSources();
-
-    // Only called on config creation/update to initialize log sources from the config.
-    // Calls initAllowedLogSources and initPullAtomSources. Sets mConfigValid to false on error.
-    void createAllLogSourcesFromConfig(const StatsdConfig& config);
-
-    // Verifies the config meets guardrails and updates statsdStats.
-    // Sets mConfigValid to false on error. Should be called on config creation/update
-    void verifyGuardrailsAndUpdateStatsdStats();
-
-    // Initializes mIsAlwaysActive and mIsActive.
-    // Should be called on config creation/update.
-    void initializeConfigActiveStatus();
-
-    // The metrics that don't need to be uploaded or even reported.
-    std::set<int64_t> mNoReportMetricIds;
-
-   // The config is active if any metric in the config is active.
-    bool mIsActive;
-
-    // The config is always active if any metric in the config does not have an activation signal.
-    bool mIsAlwaysActive;
-
-    // Hashes of the States used in this config, keyed by the state id, used in config updates.
-    std::map<int64_t, uint64_t> mStateProtoHashes;
-
-    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions);
-    FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks);
-    FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
-    FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
-    FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
-    FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
-    FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents);
-
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
-    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
-
-    FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
-    FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
-    FRIEND_TEST(ConfigUpdateE2eAbTest, TestConfigTtl);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
-    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
-
-    FRIEND_TEST(MetricsManagerTest, TestLogSources);
-    FRIEND_TEST(MetricsManagerTest, TestLogSourcesOnConfigUpdate);
-
-    FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
-    FRIEND_TEST(StatsLogProcessorTest,
-            TestActivationOnBootMultipleActivationsDifferentActivationTypes);
-    FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
-
-    FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
-    FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
-    FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
-    FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
-    FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
-
-    FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
-    FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSuperset);
-    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
-
-    FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
-    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
-    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
-    FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
deleted file mode 100644
index 22fdf16..0000000
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ /dev/null
@@ -1,1282 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "ValueMetricProducer.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-#include "../guardrail/StatsdStats.h"
-#include "../stats_log_util.h"
-#include "metrics/parsing_utils/metrics_manager_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_DOUBLE;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-using std::map;
-using std::shared_ptr;
-using std::unordered_map;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for StatsLogReport
-const int FIELD_ID_ID = 1;
-const int FIELD_ID_VALUE_METRICS = 7;
-const int FIELD_ID_TIME_BASE = 9;
-const int FIELD_ID_BUCKET_SIZE = 10;
-const int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
-const int FIELD_ID_IS_ACTIVE = 14;
-// for ValueMetricDataWrapper
-const int FIELD_ID_DATA = 1;
-const int FIELD_ID_SKIPPED = 2;
-// for SkippedBuckets
-const int FIELD_ID_SKIPPED_START_MILLIS = 3;
-const int FIELD_ID_SKIPPED_END_MILLIS = 4;
-const int FIELD_ID_SKIPPED_DROP_EVENT = 5;
-// for DumpEvent Proto
-const int FIELD_ID_BUCKET_DROP_REASON = 1;
-const int FIELD_ID_DROP_TIME = 2;
-// for ValueMetricData
-const int FIELD_ID_DIMENSION_IN_WHAT = 1;
-const int FIELD_ID_BUCKET_INFO = 3;
-const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
-const int FIELD_ID_SLICE_BY_STATE = 6;
-// for ValueBucketInfo
-const int FIELD_ID_VALUE_INDEX = 1;
-const int FIELD_ID_VALUE_LONG = 2;
-const int FIELD_ID_VALUE_DOUBLE = 3;
-const int FIELD_ID_VALUES = 9;
-const int FIELD_ID_BUCKET_NUM = 4;
-const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
-const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
-const int FIELD_ID_CONDITION_TRUE_NS = 10;
-
-const Value ZERO_LONG((int64_t)0);
-const Value ZERO_DOUBLE((int64_t)0);
-
-// ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently
-ValueMetricProducer::ValueMetricProducer(
-        const ConfigKey& key, const ValueMetric& metric, const int conditionIndex,
-        const vector<ConditionState>& initialConditionCache,
-        const sp<ConditionWizard>& conditionWizard, const uint64_t protoHash,
-        const int whatMatcherIndex, const sp<EventMatcherWizard>& matcherWizard,
-        const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs,
-        const sp<StatsPullerManager>& pullerManager,
-        const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
-        const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
-        const vector<int>& slicedStateAtoms,
-        const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
-    : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, initialConditionCache,
-                     conditionWizard, protoHash, eventActivationMap, eventDeactivationMap,
-                     slicedStateAtoms, stateGroupMap),
-      mWhatMatcherIndex(whatMatcherIndex),
-      mEventMatcherWizard(matcherWizard),
-      mPullerManager(pullerManager),
-      mPullTagId(pullTagId),
-      mIsPulled(pullTagId != -1),
-      mMinBucketSizeNs(metric.min_bucket_size_nanos()),
-      mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
-                                          StatsdStats::kAtomDimensionKeySizeLimitMap.end()
-                                  ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).first
-                                  : StatsdStats::kDimensionKeySizeSoftLimit),
-      mDimensionHardLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
-                                          StatsdStats::kAtomDimensionKeySizeLimitMap.end()
-                                  ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
-                                  : StatsdStats::kDimensionKeySizeHardLimit),
-      mUseAbsoluteValueOnReset(metric.use_absolute_value_on_reset()),
-      mAggregationType(metric.aggregation_type()),
-      mUseDiff(metric.has_use_diff() ? metric.use_diff() : (mIsPulled ? true : false)),
-      mValueDirection(metric.value_direction()),
-      mSkipZeroDiffOutput(metric.skip_zero_diff_output()),
-      mUseZeroDefaultBase(metric.use_zero_default_base()),
-      mHasGlobalBase(false),
-      mCurrentBucketIsSkipped(false),
-      mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
-                                                      : StatsdStats::kPullMaxDelayNs),
-      mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()),
-      // Condition timer will be set later within the constructor after pulling events
-      mConditionTimer(false, timeBaseNs) {
-    int64_t bucketSizeMills = 0;
-    if (metric.has_bucket()) {
-        bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
-    } else {
-        bucketSizeMills = TimeUnitToBucketSizeInMillis(ONE_HOUR);
-    }
-
-    mBucketSizeNs = bucketSizeMills * 1000000;
-
-    translateFieldMatcher(metric.value_field(), &mFieldMatchers);
-
-    if (metric.has_dimensions_in_what()) {
-        translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
-        mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
-        mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
-    }
-
-    if (metric.links().size() > 0) {
-        for (const auto& link : metric.links()) {
-            Metric2Condition mc;
-            mc.conditionId = link.condition();
-            translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
-            translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
-            mMetric2ConditionLinks.push_back(mc);
-        }
-        mConditionSliced = true;
-    }
-
-    for (const auto& stateLink : metric.state_link()) {
-        Metric2State ms;
-        ms.stateAtomId = stateLink.state_atom_id();
-        translateFieldMatcher(stateLink.fields_in_what(), &ms.metricFields);
-        translateFieldMatcher(stateLink.fields_in_state(), &ms.stateFields);
-        mMetric2StateLinks.push_back(ms);
-    }
-
-    int64_t numBucketsForward = calcBucketsForwardCount(startTimeNs);
-    mCurrentBucketNum += numBucketsForward;
-
-    flushIfNeededLocked(startTimeNs);
-
-    if (mIsPulled) {
-        mPullerManager->RegisterReceiver(mPullTagId, mConfigKey, this, getCurrentBucketEndTimeNs(),
-                                         mBucketSizeNs);
-    }
-
-    // Only do this for partial buckets like first bucket. All other buckets should use
-    // flushIfNeeded to adjust start and end to bucket boundaries.
-    // Adjust start for partial bucket
-    mCurrentBucketStartTimeNs = startTimeNs;
-    mConditionTimer.newBucketStart(mCurrentBucketStartTimeNs);
-
-    // Now that activations are processed, start the condition timer if needed.
-    mConditionTimer.onConditionChanged(mIsActive && mCondition == ConditionState::kTrue,
-                                       mCurrentBucketStartTimeNs);
-
-    VLOG("value metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
-         (long long)mBucketSizeNs, (long long)mTimeBaseNs);
-}
-
-ValueMetricProducer::~ValueMetricProducer() {
-    VLOG("~ValueMetricProducer() called");
-    if (mIsPulled) {
-        mPullerManager->UnRegisterReceiver(mPullTagId, mConfigKey, this);
-    }
-}
-
-bool ValueMetricProducer::onConfigUpdatedLocked(
-        const StatsdConfig& config, const int configIndex, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!MetricProducer::onConfigUpdatedLocked(
-                config, configIndex, metricIndex, allAtomMatchingTrackers,
-                oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap,
-                trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
-                deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
-        return false;
-    }
-
-    const ValueMetric& metric = config.value_metric(configIndex);
-    // Update appropriate indices: mWhatMatcherIndex, mConditionIndex and MetricsManager maps.
-    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, /*enforceOneAtom=*/false,
-                                              allAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                              trackerToMetricMap, mWhatMatcherIndex)) {
-        return false;
-    }
-
-    if (metric.has_condition() &&
-        !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                    metric.links(), allConditionTrackers, mConditionTrackerIndex,
-                                    conditionToMetricMap)) {
-        return false;
-    }
-    sp<EventMatcherWizard> tmpEventWizard = mEventMatcherWizard;
-    mEventMatcherWizard = matcherWizard;
-    return true;
-}
-
-void ValueMetricProducer::onStateChanged(int64_t eventTimeNs, int32_t atomId,
-                                         const HashableDimensionKey& primaryKey,
-                                         const FieldValue& oldState, const FieldValue& newState) {
-    VLOG("ValueMetric %lld onStateChanged time %lld, State %d, key %s, %d -> %d",
-         (long long)mMetricId, (long long)eventTimeNs, atomId, primaryKey.toString().c_str(),
-         oldState.mValue.int_value, newState.mValue.int_value);
-
-    // If old and new states are in the same StateGroup, then we do not need to
-    // pull for this state change.
-    FieldValue oldStateCopy = oldState;
-    FieldValue newStateCopy = newState;
-    mapStateValue(atomId, &oldStateCopy);
-    mapStateValue(atomId, &newStateCopy);
-    if (oldStateCopy == newStateCopy) {
-        return;
-    }
-
-    // If condition is not true or metric is not active, we do not need to pull
-    // for this state change.
-    if (mCondition != ConditionState::kTrue || !mIsActive) {
-        return;
-    }
-
-    bool isEventLate = eventTimeNs < mCurrentBucketStartTimeNs;
-    if (isEventLate) {
-        VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
-             (long long)mCurrentBucketStartTimeNs);
-        invalidateCurrentBucket(eventTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
-        return;
-    }
-    mStateChangePrimaryKey.first = atomId;
-    mStateChangePrimaryKey.second = primaryKey;
-    if (mIsPulled) {
-        pullAndMatchEventsLocked(eventTimeNs);
-    }
-    mStateChangePrimaryKey.first = 0;
-    mStateChangePrimaryKey.second = DEFAULT_DIMENSION_KEY;
-    flushIfNeededLocked(eventTimeNs);
-}
-
-void ValueMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
-                                                           const int64_t eventTime) {
-    VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-}
-
-void ValueMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
-    StatsdStats::getInstance().noteBucketDropped(mMetricId);
-
-    // The current partial bucket is not flushed and does not require a pull,
-    // so the data is still valid.
-    flushIfNeededLocked(dropTimeNs);
-    clearPastBucketsLocked(dropTimeNs);
-}
-
-void ValueMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
-    mPastBuckets.clear();
-    mSkippedBuckets.clear();
-}
-
-void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
-                                             const bool include_current_partial_bucket,
-                                             const bool erase_data,
-                                             const DumpLatency dumpLatency,
-                                             std::set<string> *str_set,
-                                             ProtoOutputStream* protoOutput) {
-    VLOG("metric %lld dump report now...", (long long)mMetricId);
-    if (include_current_partial_bucket) {
-        // For pull metrics, we need to do a pull at bucket boundaries. If we do not do that the
-        // current bucket will have incomplete data and the next will have the wrong snapshot to do
-        // a diff against. If the condition is false, we are fine since the base data is reset and
-        // we are not tracking anything.
-        bool pullNeeded = mIsPulled && mCondition == ConditionState::kTrue;
-        if (pullNeeded) {
-            switch (dumpLatency) {
-                case FAST:
-                    invalidateCurrentBucket(dumpTimeNs, BucketDropReason::DUMP_REPORT_REQUESTED);
-                    break;
-                case NO_TIME_CONSTRAINTS:
-                    pullAndMatchEventsLocked(dumpTimeNs);
-                    break;
-            }
-        }
-        flushCurrentBucketLocked(dumpTimeNs, dumpTimeNs);
-    }
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
-    protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
-
-    if (mPastBuckets.empty() && mSkippedBuckets.empty()) {
-        return;
-    }
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-    // Fills the dimension path if not slicing by ALL.
-    if (!mSliceByPositionALL) {
-        if (!mDimensionsInWhat.empty()) {
-            uint64_t dimenPathToken =
-                    protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
-            writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
-            protoOutput->end(dimenPathToken);
-        }
-    }
-
-    uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_VALUE_METRICS);
-
-    for (const auto& skippedBucket : mSkippedBuckets) {
-        uint64_t wrapperToken =
-                protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SKIPPED);
-        protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_START_MILLIS,
-                           (long long)(NanoToMillis(skippedBucket.bucketStartTimeNs)));
-        protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_END_MILLIS,
-                           (long long)(NanoToMillis(skippedBucket.bucketEndTimeNs)));
-        for (const auto& dropEvent : skippedBucket.dropEvents) {
-            uint64_t dropEventToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                         FIELD_ID_SKIPPED_DROP_EVENT);
-            protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_BUCKET_DROP_REASON, dropEvent.reason);
-            protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DROP_TIME,
-                               (long long)(NanoToMillis(dropEvent.dropTimeNs)));
-            protoOutput->end(dropEventToken);
-        }
-        protoOutput->end(wrapperToken);
-    }
-
-    for (const auto& pair : mPastBuckets) {
-        const MetricDimensionKey& dimensionKey = pair.first;
-        VLOG("  dimension key %s", dimensionKey.toString().c_str());
-        uint64_t wrapperToken =
-                protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-
-        // First fill dimension.
-        if (mSliceByPositionALL) {
-            uint64_t dimensionToken =
-                    protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
-            writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
-            protoOutput->end(dimensionToken);
-        } else {
-            writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
-                                           FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
-        }
-
-        // Then fill slice_by_state.
-        for (auto state : dimensionKey.getStateValuesKey().getValues()) {
-            uint64_t stateToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                     FIELD_ID_SLICE_BY_STATE);
-            writeStateToProto(state, protoOutput);
-            protoOutput->end(stateToken);
-        }
-
-        // Then fill bucket_info (ValueBucketInfo).
-        for (const auto& bucket : pair.second) {
-            uint64_t bucketInfoToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
-
-            if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
-                                   (long long)NanoToMillis(bucket.mBucketStartNs));
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
-                                   (long long)NanoToMillis(bucket.mBucketEndNs));
-            } else {
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
-                                   (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
-            }
-            // We only write the condition timer value if the metric has a
-            // condition and/or is sliced by state.
-            // If the metric is sliced by state, the condition timer value is
-            // also sliced by state to reflect time spent in that state.
-            if (mConditionTrackerIndex >= 0 || !mSlicedStateAtoms.empty()) {
-                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_TRUE_NS,
-                                   (long long)bucket.mConditionTrueNs);
-            }
-            for (int i = 0; i < (int)bucket.valueIndex.size(); i++) {
-                int index = bucket.valueIndex[i];
-                const Value& value = bucket.values[i];
-                uint64_t valueToken = protoOutput->start(
-                        FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_VALUES);
-                protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_VALUE_INDEX,
-                                   index);
-                if (value.getType() == LONG) {
-                    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_VALUE_LONG,
-                                       (long long)value.long_value);
-                    VLOG("\t bucket [%lld - %lld] value %d: %lld", (long long)bucket.mBucketStartNs,
-                         (long long)bucket.mBucketEndNs, index, (long long)value.long_value);
-                } else if (value.getType() == DOUBLE) {
-                    protoOutput->write(FIELD_TYPE_DOUBLE | FIELD_ID_VALUE_DOUBLE,
-                                       value.double_value);
-                    VLOG("\t bucket [%lld - %lld] value %d: %.2f", (long long)bucket.mBucketStartNs,
-                         (long long)bucket.mBucketEndNs, index, value.double_value);
-                } else {
-                    VLOG("Wrong value type for ValueMetric output: %d", value.getType());
-                }
-                protoOutput->end(valueToken);
-            }
-            protoOutput->end(bucketInfoToken);
-        }
-        protoOutput->end(wrapperToken);
-    }
-    protoOutput->end(protoToken);
-
-    VLOG("metric %lld dump report now...", (long long)mMetricId);
-    if (erase_data) {
-        mPastBuckets.clear();
-        mSkippedBuckets.clear();
-    }
-}
-
-void ValueMetricProducer::invalidateCurrentBucketWithoutResetBase(const int64_t dropTimeNs,
-                                                                  const BucketDropReason reason) {
-    if (!mCurrentBucketIsSkipped) {
-        // Only report to StatsdStats once per invalid bucket.
-        StatsdStats::getInstance().noteInvalidatedBucket(mMetricId);
-    }
-
-    skipCurrentBucket(dropTimeNs, reason);
-}
-
-void ValueMetricProducer::invalidateCurrentBucket(const int64_t dropTimeNs,
-                                                  const BucketDropReason reason) {
-    invalidateCurrentBucketWithoutResetBase(dropTimeNs, reason);
-    resetBase();
-}
-
-void ValueMetricProducer::skipCurrentBucket(const int64_t dropTimeNs,
-                                            const BucketDropReason reason) {
-    if (!maxDropEventsReached()) {
-        mCurrentSkippedBucket.dropEvents.emplace_back(buildDropEvent(dropTimeNs, reason));
-    }
-    mCurrentBucketIsSkipped = true;
-}
-
-void ValueMetricProducer::resetBase() {
-    for (auto& slice : mCurrentBaseInfo) {
-        for (auto& baseInfo : slice.second.baseInfos) {
-            baseInfo.hasBase = false;
-        }
-    }
-    mHasGlobalBase = false;
-}
-
-// Handle active state change. Active state change is treated like a condition change:
-// - drop bucket if active state change event arrives too late
-// - if condition is true, pull data on active state changes
-// - ConditionTimer tracks changes based on AND of condition and active state.
-void ValueMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
-    bool isEventTooLate  = eventTimeNs < mCurrentBucketStartTimeNs;
-    if (isEventTooLate) {
-        // Drop bucket because event arrived too late, ie. we are missing data for this bucket.
-        StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
-        invalidateCurrentBucket(eventTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
-    }
-
-    // Call parent method once we've verified the validity of current bucket.
-    MetricProducer::onActiveStateChangedLocked(eventTimeNs);
-
-    if (ConditionState::kTrue != mCondition) {
-        return;
-    }
-
-    // Pull on active state changes.
-    if (!isEventTooLate) {
-        if (mIsPulled) {
-            pullAndMatchEventsLocked(eventTimeNs);
-        }
-        // When active state changes from true to false, clear diff base but don't
-        // reset other counters as we may accumulate more value in the bucket.
-        if (mUseDiff && !mIsActive) {
-            resetBase();
-        }
-    }
-
-    flushIfNeededLocked(eventTimeNs);
-
-    // Let condition timer know of new active state.
-    mConditionTimer.onConditionChanged(mIsActive, eventTimeNs);
-
-    updateCurrentSlicedBucketConditionTimers(mIsActive, eventTimeNs);
-}
-
-void ValueMetricProducer::onConditionChangedLocked(const bool condition,
-                                                   const int64_t eventTimeNs) {
-    ConditionState newCondition = condition ? ConditionState::kTrue : ConditionState::kFalse;
-    bool isEventTooLate  = eventTimeNs < mCurrentBucketStartTimeNs;
-
-    // If the config is not active, skip the event.
-    if (!mIsActive) {
-        mCondition = isEventTooLate ? ConditionState::kUnknown : newCondition;
-        return;
-    }
-
-    // If the event arrived late, mark the bucket as invalid and skip the event.
-    if (isEventTooLate) {
-        VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
-             (long long)mCurrentBucketStartTimeNs);
-        StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
-        StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
-        invalidateCurrentBucket(eventTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
-        mCondition = ConditionState::kUnknown;
-        mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
-
-        updateCurrentSlicedBucketConditionTimers(mCondition, eventTimeNs);
-        return;
-    }
-
-    // If the previous condition was unknown, mark the bucket as invalid
-    // because the bucket will contain partial data. For example, the condition
-    // change might happen close to the end of the bucket and we might miss a
-    // lot of data.
-    //
-    // We still want to pull to set the base.
-    if (mCondition == ConditionState::kUnknown) {
-        invalidateCurrentBucket(eventTimeNs, BucketDropReason::CONDITION_UNKNOWN);
-    }
-
-    // Pull and match for the following condition change cases:
-    // unknown/false -> true - condition changed
-    // true -> false - condition changed
-    // true -> true - old condition was true so we can flush the bucket at the
-    // end if needed.
-    //
-    // We don’t need to pull for unknown -> false or false -> false.
-    //
-    // onConditionChangedLocked might happen on bucket boundaries if this is
-    // called before #onDataPulled.
-    if (mIsPulled &&
-        (newCondition == ConditionState::kTrue || mCondition == ConditionState::kTrue)) {
-        pullAndMatchEventsLocked(eventTimeNs);
-    }
-
-    // For metrics that use diff, when condition changes from true to false,
-    // clear diff base but don't reset other counts because we may accumulate
-    // more value in the bucket.
-    if (mUseDiff &&
-        (mCondition == ConditionState::kTrue && newCondition == ConditionState::kFalse)) {
-        resetBase();
-    }
-
-    // Update condition state after pulling.
-    mCondition = newCondition;
-
-    flushIfNeededLocked(eventTimeNs);
-    mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
-
-    updateCurrentSlicedBucketConditionTimers(mCondition, eventTimeNs);
-}
-
-void ValueMetricProducer::updateCurrentSlicedBucketConditionTimers(bool newCondition,
-                                                                   int64_t eventTimeNs) {
-    if (mSlicedStateAtoms.empty()) {
-        return;
-    }
-
-    // Utilize the current state key of each DimensionsInWhat key to determine
-    // which condition timers to update.
-    //
-    // Assumes that the MetricDimensionKey exists in `mCurrentSlicedBucket`.
-    bool inPulledData;
-    for (const auto& [dimensionInWhatKey, dimensionInWhatInfo] : mCurrentBaseInfo) {
-        // If the new condition is true, turn ON the condition timer only if
-        // the DimensionInWhat key was present in the pulled data.
-        inPulledData = dimensionInWhatInfo.hasCurrentState;
-        mCurrentSlicedBucket[MetricDimensionKey(dimensionInWhatKey,
-                                                dimensionInWhatInfo.currentState)]
-                .conditionTimer.onConditionChanged(newCondition && inPulledData, eventTimeNs);
-    }
-}
-
-void ValueMetricProducer::prepareFirstBucketLocked() {
-    // Kicks off the puller immediately if condition is true and diff based.
-    if (mIsActive && mIsPulled && mCondition == ConditionState::kTrue && mUseDiff) {
-        pullAndMatchEventsLocked(mCurrentBucketStartTimeNs);
-    }
-}
-
-void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
-    vector<std::shared_ptr<LogEvent>> allData;
-    if (!mPullerManager->Pull(mPullTagId, mConfigKey, timestampNs, &allData)) {
-        ALOGE("Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
-        invalidateCurrentBucket(timestampNs, BucketDropReason::PULL_FAILED);
-        return;
-    }
-
-    accumulateEvents(allData, timestampNs, timestampNs);
-}
-
-int64_t ValueMetricProducer::calcPreviousBucketEndTime(const int64_t currentTimeNs) {
-    return mTimeBaseNs + ((currentTimeNs - mTimeBaseNs) / mBucketSizeNs) * mBucketSizeNs;
-}
-
-// By design, statsd pulls data at bucket boundaries using AlarmManager. These pulls are likely
-// to be delayed. Other events like condition changes or app upgrade which are not based on
-// AlarmManager might have arrived earlier and close the bucket.
-void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData,
-                                       bool pullSuccess, int64_t originalPullTimeNs) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    if (mCondition == ConditionState::kTrue) {
-        // If the pull failed, we won't be able to compute a diff.
-        if (!pullSuccess) {
-            invalidateCurrentBucket(originalPullTimeNs, BucketDropReason::PULL_FAILED);
-        } else {
-            bool isEventLate = originalPullTimeNs < getCurrentBucketEndTimeNs();
-            if (isEventLate) {
-                // If the event is late, we are in the middle of a bucket. Just
-                // process the data without trying to snap the data to the nearest bucket.
-                accumulateEvents(allData, originalPullTimeNs, originalPullTimeNs);
-            } else {
-                // For scheduled pulled data, the effective event time is snap to the nearest
-                // bucket end. In the case of waking up from a deep sleep state, we will
-                // attribute to the previous bucket end. If the sleep was long but not very
-                // long, we will be in the immediate next bucket. Previous bucket may get a
-                // larger number as we pull at a later time than real bucket end.
-                //
-                // If the sleep was very long, we skip more than one bucket before sleep. In
-                // this case, if the diff base will be cleared and this new data will serve as
-                // new diff base.
-                int64_t bucketEndTime = calcPreviousBucketEndTime(originalPullTimeNs) - 1;
-                StatsdStats::getInstance().noteBucketBoundaryDelayNs(
-                        mMetricId, originalPullTimeNs - bucketEndTime);
-                accumulateEvents(allData, originalPullTimeNs, bucketEndTime);
-            }
-        }
-    }
-
-    // We can probably flush the bucket. Since we used bucketEndTime when calling
-    // #onMatchedLogEventInternalLocked, the current bucket will not have been flushed.
-    flushIfNeededLocked(originalPullTimeNs);
-}
-
-void ValueMetricProducer::accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData,
-                                           int64_t originalPullTimeNs, int64_t eventElapsedTimeNs) {
-    bool isEventLate = eventElapsedTimeNs < mCurrentBucketStartTimeNs;
-    if (isEventLate) {
-        VLOG("Skip bucket end pull due to late arrival: %lld vs %lld",
-             (long long)eventElapsedTimeNs, (long long)mCurrentBucketStartTimeNs);
-        StatsdStats::getInstance().noteLateLogEventSkipped(mMetricId);
-        invalidateCurrentBucket(eventElapsedTimeNs, BucketDropReason::EVENT_IN_WRONG_BUCKET);
-        return;
-    }
-
-    const int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
-    const int64_t pullDelayNs = elapsedRealtimeNs - originalPullTimeNs;
-    StatsdStats::getInstance().notePullDelay(mPullTagId, pullDelayNs);
-    if (pullDelayNs > mMaxPullDelayNs) {
-        ALOGE("Pull finish too late for atom %d, longer than %lld", mPullTagId,
-              (long long)mMaxPullDelayNs);
-        StatsdStats::getInstance().notePullExceedMaxDelay(mPullTagId);
-        // We are missing one pull from the bucket which means we will not have a complete view of
-        // what's going on.
-        invalidateCurrentBucket(eventElapsedTimeNs, BucketDropReason::PULL_DELAYED);
-        return;
-    }
-
-    mMatchedMetricDimensionKeys.clear();
-    for (const auto& data : allData) {
-        LogEvent localCopy = data->makeCopy();
-        if (mEventMatcherWizard->matchLogEvent(localCopy, mWhatMatcherIndex) ==
-            MatchingState::kMatched) {
-            localCopy.setElapsedTimestampNs(eventElapsedTimeNs);
-            onMatchedLogEventLocked(mWhatMatcherIndex, localCopy);
-        }
-    }
-    // If a key that is:
-    // 1. Tracked in mCurrentSlicedBucket and
-    // 2. A superset of the current mStateChangePrimaryKey
-    // was not found in the new pulled data (i.e. not in mMatchedDimensionInWhatKeys)
-    // then we need to reset the base.
-    for (auto& [metricDimensionKey, currentValueBucket] : mCurrentSlicedBucket) {
-        const auto& whatKey = metricDimensionKey.getDimensionKeyInWhat();
-        bool presentInPulledData =
-                mMatchedMetricDimensionKeys.find(whatKey) != mMatchedMetricDimensionKeys.end();
-        if (!presentInPulledData && whatKey.contains(mStateChangePrimaryKey.second)) {
-            auto it = mCurrentBaseInfo.find(whatKey);
-            for (auto& baseInfo : it->second.baseInfos) {
-                baseInfo.hasBase = false;
-            }
-            // Set to false when DimensionInWhat key is not present in a pull.
-            // Used in onMatchedLogEventInternalLocked() to ensure the condition
-            // timer is turned on the next pull when data is present.
-            it->second.hasCurrentState = false;
-            // Turn OFF condition timer for keys not present in pulled data.
-            currentValueBucket.conditionTimer.onConditionChanged(false, eventElapsedTimeNs);
-        }
-    }
-    mMatchedMetricDimensionKeys.clear();
-    mHasGlobalBase = true;
-
-    // If we reach the guardrail, we might have dropped some data which means the bucket is
-    // incomplete.
-    //
-    // The base also needs to be reset. If we do not have the full data, we might
-    // incorrectly compute the diff when mUseZeroDefaultBase is true since an existing key
-    // might be missing from mCurrentSlicedBucket.
-    if (hasReachedGuardRailLimit()) {
-        invalidateCurrentBucket(eventElapsedTimeNs, BucketDropReason::DIMENSION_GUARDRAIL_REACHED);
-        mCurrentSlicedBucket.clear();
-    }
-}
-
-void ValueMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
-    if (mCurrentSlicedBucket.size() == 0) {
-        return;
-    }
-
-    fprintf(out, "ValueMetric %lld dimension size %lu\n", (long long)mMetricId,
-            (unsigned long)mCurrentSlicedBucket.size());
-    if (verbose) {
-        for (const auto& it : mCurrentSlicedBucket) {
-          for (const auto& interval : it.second.intervals) {
-              fprintf(out, "\t(what)%s\t(states)%s  (value)%s\n",
-                      it.first.getDimensionKeyInWhat().toString().c_str(),
-                      it.first.getStateValuesKey().toString().c_str(),
-                      interval.value.toString().c_str());
-          }
-        }
-    }
-}
-
-bool ValueMetricProducer::hasReachedGuardRailLimit() const {
-    return mCurrentSlicedBucket.size() >= mDimensionHardLimit;
-}
-
-bool ValueMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
-    // ===========GuardRail==============
-    // 1. Report the tuple count if the tuple count > soft limit
-    if (mCurrentSlicedBucket.find(newKey) != mCurrentSlicedBucket.end()) {
-        return false;
-    }
-    if (mCurrentSlicedBucket.size() > mDimensionSoftLimit - 1) {
-        size_t newTupleCount = mCurrentSlicedBucket.size() + 1;
-        StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
-        // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
-        if (hasReachedGuardRailLimit()) {
-            ALOGE("ValueMetric %lld dropping data for dimension key %s", (long long)mMetricId,
-                  newKey.toString().c_str());
-            StatsdStats::getInstance().noteHardDimensionLimitReached(mMetricId);
-            return true;
-        }
-    }
-
-    return false;
-}
-
-bool ValueMetricProducer::hitFullBucketGuardRailLocked(const MetricDimensionKey& newKey) {
-    // ===========GuardRail==============
-    // 1. Report the tuple count if the tuple count > soft limit
-    if (mCurrentFullBucket.find(newKey) != mCurrentFullBucket.end()) {
-        return false;
-    }
-    if (mCurrentFullBucket.size() > mDimensionSoftLimit - 1) {
-        size_t newTupleCount = mCurrentFullBucket.size() + 1;
-        // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
-        if (newTupleCount > mDimensionHardLimit) {
-            ALOGE("ValueMetric %lld dropping data for full bucket dimension key %s",
-                  (long long)mMetricId,
-                  newKey.toString().c_str());
-            return true;
-        }
-    }
-
-    return false;
-}
-
-bool getDoubleOrLong(const LogEvent& event, const Matcher& matcher, Value& ret) {
-    for (const FieldValue& value : event.getValues()) {
-        if (value.mField.matches(matcher)) {
-            switch (value.mValue.type) {
-                case INT:
-                    ret.setLong(value.mValue.int_value);
-                    break;
-                case LONG:
-                    ret.setLong(value.mValue.long_value);
-                    break;
-                case FLOAT:
-                    ret.setDouble(value.mValue.float_value);
-                    break;
-                case DOUBLE:
-                    ret.setDouble(value.mValue.double_value);
-                    break;
-                default:
-                    return false;
-                    break;
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-bool ValueMetricProducer::multipleBucketsSkipped(const int64_t numBucketsForward) {
-    // Skip buckets if this is a pulled metric or a pushed metric that is diffed.
-    return numBucketsForward > 1 && (mIsPulled || mUseDiff);
-}
-
-void ValueMetricProducer::onMatchedLogEventInternalLocked(
-        const size_t matcherIndex, const MetricDimensionKey& eventKey,
-        const ConditionKey& conditionKey, bool condition, const LogEvent& event,
-        const map<int, HashableDimensionKey>& statePrimaryKeys) {
-    auto whatKey = eventKey.getDimensionKeyInWhat();
-    auto stateKey = eventKey.getStateValuesKey();
-
-    // Skip this event if a state changed occurred for a different primary key.
-    auto it = statePrimaryKeys.find(mStateChangePrimaryKey.first);
-    // Check that both the atom id and the primary key are equal.
-    if (it != statePrimaryKeys.end() && it->second != mStateChangePrimaryKey.second) {
-        VLOG("ValueMetric skip event with primary key %s because state change primary key "
-             "is %s",
-             it->second.toString().c_str(), mStateChangePrimaryKey.second.toString().c_str());
-        return;
-    }
-
-    int64_t eventTimeNs = event.GetElapsedTimestampNs();
-    if (eventTimeNs < mCurrentBucketStartTimeNs) {
-        VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
-             (long long)mCurrentBucketStartTimeNs);
-        return;
-    }
-    mMatchedMetricDimensionKeys.insert(whatKey);
-
-    if (!mIsPulled) {
-        // We cannot flush without doing a pull first.
-        flushIfNeededLocked(eventTimeNs);
-    }
-
-    // We should not accumulate the data for pushed metrics when the condition is false.
-    bool shouldSkipForPushMetric = !mIsPulled && !condition;
-    // For pulled metrics, there are two cases:
-    // - to compute diffs, we need to process all the state changes
-    // - for non-diffs metrics, we should ignore the data if the condition wasn't true. If we have a
-    // state change from
-    //     + True -> True: we should process the data, it might be a bucket boundary
-    //     + True -> False: we als need to process the data.
-    bool shouldSkipForPulledMetric = mIsPulled && !mUseDiff
-            && mCondition != ConditionState::kTrue;
-    if (shouldSkipForPushMetric || shouldSkipForPulledMetric) {
-        VLOG("ValueMetric skip event because condition is false and we are not using diff (for "
-             "pulled metric)");
-        return;
-    }
-
-    if (hitGuardRailLocked(eventKey)) {
-        return;
-    }
-
-    const auto& returnVal =
-            mCurrentBaseInfo.emplace(whatKey, DimensionsInWhatInfo(getUnknownStateKey()));
-    DimensionsInWhatInfo& dimensionsInWhatInfo = returnVal.first->second;
-    const HashableDimensionKey oldStateKey = dimensionsInWhatInfo.currentState;
-    vector<BaseInfo>& baseInfos = dimensionsInWhatInfo.baseInfos;
-    if (baseInfos.size() < mFieldMatchers.size()) {
-        VLOG("Resizing number of intervals to %d", (int)mFieldMatchers.size());
-        baseInfos.resize(mFieldMatchers.size());
-    }
-
-    // Ensure we turn on the condition timer in the case where dimensions
-    // were missing on a previous pull due to a state change.
-    bool stateChange = oldStateKey != stateKey;
-    if (!dimensionsInWhatInfo.hasCurrentState) {
-        stateChange = true;
-        dimensionsInWhatInfo.hasCurrentState = true;
-    }
-
-    // We need to get the intervals stored with the previous state key so we can
-    // close these value intervals.
-    vector<Interval>& intervals =
-            mCurrentSlicedBucket[MetricDimensionKey(whatKey, oldStateKey)].intervals;
-    if (intervals.size() < mFieldMatchers.size()) {
-        VLOG("Resizing number of intervals to %d", (int)mFieldMatchers.size());
-        intervals.resize(mFieldMatchers.size());
-    }
-
-    // We only use anomaly detection under certain cases.
-    // N.B.: The anomaly detection cases were modified in order to fix an issue with value metrics
-    // containing multiple values. We tried to retain all previous behaviour, but we are unsure the
-    // previous behaviour was correct. At the time of the fix, anomaly detection had no owner.
-    // Whoever next works on it should look into the cases where it is triggered in this function.
-    // Discussion here: http://ag/6124370.
-    bool useAnomalyDetection = true;
-
-    dimensionsInWhatInfo.hasCurrentState = true;
-    dimensionsInWhatInfo.currentState = stateKey;
-    for (int i = 0; i < (int)mFieldMatchers.size(); i++) {
-        const Matcher& matcher = mFieldMatchers[i];
-        BaseInfo& baseInfo = baseInfos[i];
-        Interval& interval = intervals[i];
-        interval.valueIndex = i;
-        Value value;
-        if (!getDoubleOrLong(event, matcher, value)) {
-            VLOG("Failed to get value %d from event %s", i, event.ToString().c_str());
-            StatsdStats::getInstance().noteBadValueType(mMetricId);
-            return;
-        }
-        interval.seenNewData = true;
-
-        if (mUseDiff) {
-            if (!baseInfo.hasBase) {
-                if (mHasGlobalBase && mUseZeroDefaultBase) {
-                    // The bucket has global base. This key does not.
-                    // Optionally use zero as base.
-                    baseInfo.base = (value.type == LONG ? ZERO_LONG : ZERO_DOUBLE);
-                    baseInfo.hasBase = true;
-                } else {
-                    // no base. just update base and return.
-                    baseInfo.base = value;
-                    baseInfo.hasBase = true;
-                    // If we're missing a base, do not use anomaly detection on incomplete data
-                    useAnomalyDetection = false;
-                    // Continue (instead of return) here in order to set baseInfo.base and
-                    // baseInfo.hasBase for other baseInfos
-                    continue;
-                }
-            }
-
-            Value diff;
-            switch (mValueDirection) {
-                case ValueMetric::INCREASING:
-                    if (value >= baseInfo.base) {
-                        diff = value - baseInfo.base;
-                    } else if (mUseAbsoluteValueOnReset) {
-                        diff = value;
-                    } else {
-                        VLOG("Unexpected decreasing value");
-                        StatsdStats::getInstance().notePullDataError(mPullTagId);
-                        baseInfo.base = value;
-                        // If we've got bad data, do not use anomaly detection
-                        useAnomalyDetection = false;
-                        continue;
-                    }
-                    break;
-                case ValueMetric::DECREASING:
-                    if (baseInfo.base >= value) {
-                        diff = baseInfo.base - value;
-                    } else if (mUseAbsoluteValueOnReset) {
-                        diff = value;
-                    } else {
-                        VLOG("Unexpected increasing value");
-                        StatsdStats::getInstance().notePullDataError(mPullTagId);
-                        baseInfo.base = value;
-                        // If we've got bad data, do not use anomaly detection
-                        useAnomalyDetection = false;
-                        continue;
-                    }
-                    break;
-                case ValueMetric::ANY:
-                    diff = value - baseInfo.base;
-                    break;
-                default:
-                    break;
-            }
-            baseInfo.base = value;
-            value = diff;
-        }
-
-        if (interval.hasValue) {
-            switch (mAggregationType) {
-                case ValueMetric::SUM:
-                    // for AVG, we add up and take average when flushing the bucket
-                case ValueMetric::AVG:
-                    interval.value += value;
-                    break;
-                case ValueMetric::MIN:
-                    interval.value = std::min(value, interval.value);
-                    break;
-                case ValueMetric::MAX:
-                    interval.value = std::max(value, interval.value);
-                    break;
-                default:
-                    break;
-            }
-        } else {
-            interval.value = value;
-            interval.hasValue = true;
-        }
-        interval.sampleSize += 1;
-    }
-
-    // State change.
-    if (!mSlicedStateAtoms.empty() && stateChange) {
-        // Turn OFF the condition timer for the previous state key.
-        mCurrentSlicedBucket[MetricDimensionKey(whatKey, oldStateKey)]
-                .conditionTimer.onConditionChanged(false, eventTimeNs);
-
-        // Turn ON the condition timer for the new state key.
-        mCurrentSlicedBucket[MetricDimensionKey(whatKey, stateKey)]
-                .conditionTimer.onConditionChanged(true, eventTimeNs);
-    }
-
-    // Only trigger the tracker if all intervals are correct and we have not skipped the bucket due
-    // to MULTIPLE_BUCKETS_SKIPPED.
-    if (useAnomalyDetection && !multipleBucketsSkipped(calcBucketsForwardCount(eventTimeNs))) {
-        // TODO: propgate proper values down stream when anomaly support doubles
-        long wholeBucketVal = intervals[0].value.long_value;
-        auto prev = mCurrentFullBucket.find(eventKey);
-        if (prev != mCurrentFullBucket.end()) {
-            wholeBucketVal += prev->second;
-        }
-        for (auto& tracker : mAnomalyTrackers) {
-            tracker->detectAndDeclareAnomaly(eventTimeNs, mCurrentBucketNum, mMetricId, eventKey,
-                                             wholeBucketVal);
-        }
-    }
-}
-
-// For pulled metrics, we always need to make sure we do a pull before flushing the bucket
-// if mCondition is true!
-void ValueMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
-    int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
-    if (eventTimeNs < currentBucketEndTimeNs) {
-        VLOG("eventTime is %lld, less than current bucket end time %lld", (long long)eventTimeNs,
-             (long long)(currentBucketEndTimeNs));
-        return;
-    }
-    int64_t numBucketsForward = calcBucketsForwardCount(eventTimeNs);
-    int64_t nextBucketStartTimeNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
-    flushCurrentBucketLocked(eventTimeNs, nextBucketStartTimeNs);
-}
-
-int64_t ValueMetricProducer::calcBucketsForwardCount(const int64_t& eventTimeNs) const {
-    int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
-    if (eventTimeNs < currentBucketEndTimeNs) {
-        return 0;
-    }
-    return 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
-}
-
-void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs,
-                                                   const int64_t& nextBucketStartTimeNs) {
-    if (mCondition == ConditionState::kUnknown) {
-        StatsdStats::getInstance().noteBucketUnknownCondition(mMetricId);
-        invalidateCurrentBucketWithoutResetBase(eventTimeNs, BucketDropReason::CONDITION_UNKNOWN);
-    }
-
-    VLOG("finalizing bucket for %ld, dumping %d slices", (long)mCurrentBucketStartTimeNs,
-         (int)mCurrentSlicedBucket.size());
-
-    int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
-    int64_t bucketEndTime = fullBucketEndTimeNs;
-    int64_t numBucketsForward = calcBucketsForwardCount(eventTimeNs);
-
-    if (multipleBucketsSkipped(numBucketsForward)) {
-        VLOG("Skipping forward %lld buckets", (long long)numBucketsForward);
-        StatsdStats::getInstance().noteSkippedForwardBuckets(mMetricId);
-        // Something went wrong. Maybe the device was sleeping for a long time. It is better
-        // to mark the current bucket as invalid. The last pull might have been successful through.
-        invalidateCurrentBucketWithoutResetBase(eventTimeNs,
-                                                BucketDropReason::MULTIPLE_BUCKETS_SKIPPED);
-        // End the bucket at the next bucket start time so the entire interval is skipped.
-        bucketEndTime = nextBucketStartTimeNs;
-    } else if (eventTimeNs < fullBucketEndTimeNs) {
-        bucketEndTime = eventTimeNs;
-    }
-
-    // Close the current bucket.
-    int64_t conditionTrueDuration = mConditionTimer.newBucketStart(bucketEndTime);
-    bool isBucketLargeEnough = bucketEndTime - mCurrentBucketStartTimeNs >= mMinBucketSizeNs;
-    if (!isBucketLargeEnough) {
-        skipCurrentBucket(eventTimeNs, BucketDropReason::BUCKET_TOO_SMALL);
-    }
-    if (!mCurrentBucketIsSkipped) {
-        bool bucketHasData = false;
-        // The current bucket is large enough to keep.
-        for (auto& [metricDimensionKey, currentValueBucket] : mCurrentSlicedBucket) {
-            PastValueBucket bucket =
-                    buildPartialBucket(bucketEndTime, currentValueBucket.intervals);
-            if (!mSlicedStateAtoms.empty()) {
-                bucket.mConditionTrueNs =
-                        currentValueBucket.conditionTimer.newBucketStart(bucketEndTime);
-            } else {
-                bucket.mConditionTrueNs = conditionTrueDuration;
-            }
-            // it will auto create new vector of ValuebucketInfo if the key is not found.
-            if (bucket.valueIndex.size() > 0) {
-                auto& bucketList = mPastBuckets[metricDimensionKey];
-                bucketList.push_back(bucket);
-                bucketHasData = true;
-            }
-        }
-        if (!bucketHasData) {
-            skipCurrentBucket(eventTimeNs, BucketDropReason::NO_DATA);
-        }
-    }
-
-    if (mCurrentBucketIsSkipped) {
-        mCurrentSkippedBucket.bucketStartTimeNs = mCurrentBucketStartTimeNs;
-        mCurrentSkippedBucket.bucketEndTimeNs = bucketEndTime;
-        mSkippedBuckets.emplace_back(mCurrentSkippedBucket);
-    }
-
-    // This means that the current bucket was not flushed before a forced bucket split.
-    // This can happen if an app update or a dump report with include_current_partial_bucket is
-    // requested before we get a chance to flush the bucket due to receiving new data, either from
-    // the statsd socket or the StatsPullerManager.
-    if (bucketEndTime < nextBucketStartTimeNs) {
-        SkippedBucket bucketInGap;
-        bucketInGap.bucketStartTimeNs = bucketEndTime;
-        bucketInGap.bucketEndTimeNs = nextBucketStartTimeNs;
-        bucketInGap.dropEvents.emplace_back(
-                buildDropEvent(eventTimeNs, BucketDropReason::NO_DATA));
-        mSkippedBuckets.emplace_back(bucketInGap);
-    }
-    appendToFullBucket(eventTimeNs > fullBucketEndTimeNs);
-    initCurrentSlicedBucket(nextBucketStartTimeNs);
-    // Update the condition timer again, in case we skipped buckets.
-    mConditionTimer.newBucketStart(nextBucketStartTimeNs);
-
-    // NOTE: Update the condition timers in `mCurrentSlicedBucket` only when slicing
-    // by state. Otherwise, the "global" condition timer will be used.
-    if (!mSlicedStateAtoms.empty()) {
-        for (auto& [metricDimensionKey, currentValueBucket] : mCurrentSlicedBucket) {
-            currentValueBucket.conditionTimer.newBucketStart(nextBucketStartTimeNs);
-        }
-    }
-    mCurrentBucketNum += numBucketsForward;
-}
-
-PastValueBucket ValueMetricProducer::buildPartialBucket(int64_t bucketEndTime,
-                                                        const std::vector<Interval>& intervals) {
-    PastValueBucket bucket;
-    bucket.mBucketStartNs = mCurrentBucketStartTimeNs;
-    bucket.mBucketEndNs = bucketEndTime;
-    for (const auto& interval : intervals) {
-        if (interval.hasValue) {
-            // skip the output if the diff is zero
-            if (mSkipZeroDiffOutput && mUseDiff && interval.value.isZero()) {
-                continue;
-            }
-            bucket.valueIndex.push_back(interval.valueIndex);
-            if (mAggregationType != ValueMetric::AVG) {
-                bucket.values.push_back(interval.value);
-            } else {
-                double sum = interval.value.type == LONG ? (double)interval.value.long_value
-                                                         : interval.value.double_value;
-                bucket.values.push_back(Value((double)sum / interval.sampleSize));
-            }
-        }
-    }
-    return bucket;
-}
-
-void ValueMetricProducer::initCurrentSlicedBucket(int64_t nextBucketStartTimeNs) {
-    StatsdStats::getInstance().noteBucketCount(mMetricId);
-    // Cleanup data structure to aggregate values.
-    for (auto it = mCurrentSlicedBucket.begin(); it != mCurrentSlicedBucket.end();) {
-        bool obsolete = true;
-        for (auto& interval : it->second.intervals) {
-            interval.hasValue = false;
-            interval.sampleSize = 0;
-            if (interval.seenNewData) {
-                obsolete = false;
-            }
-            interval.seenNewData = false;
-        }
-
-        if (obsolete && !mSlicedStateAtoms.empty()) {
-            // When slicing by state, only delete the MetricDimensionKey when the
-            // state key in the MetricDimensionKey is not the current state key.
-            const HashableDimensionKey& dimensionInWhatKey = it->first.getDimensionKeyInWhat();
-            const auto& currentBaseInfoItr = mCurrentBaseInfo.find(dimensionInWhatKey);
-
-            if ((currentBaseInfoItr != mCurrentBaseInfo.end()) &&
-                (it->first.getStateValuesKey() == currentBaseInfoItr->second.currentState)) {
-                obsolete = false;
-            }
-        }
-        if (obsolete) {
-            it = mCurrentSlicedBucket.erase(it);
-        } else {
-            it++;
-        }
-        // TODO(b/157655103): remove mCurrentBaseInfo entries when obsolete
-    }
-
-    mCurrentBucketIsSkipped = false;
-    mCurrentSkippedBucket.reset();
-
-    // If we do not have a global base when the condition is true,
-    // we will have incomplete bucket for the next bucket.
-    if (mUseDiff && !mHasGlobalBase && mCondition) {
-        mCurrentBucketIsSkipped = false;
-    }
-    mCurrentBucketStartTimeNs = nextBucketStartTimeNs;
-    VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
-         (long long)mCurrentBucketStartTimeNs);
-}
-
-void ValueMetricProducer::appendToFullBucket(const bool isFullBucketReached) {
-    if (mCurrentBucketIsSkipped) {
-        if (isFullBucketReached) {
-            // If the bucket is invalid, we ignore the full bucket since it contains invalid data.
-            mCurrentFullBucket.clear();
-        }
-        // Current bucket is invalid, we do not add it to the full bucket.
-        return;
-    }
-
-    if (isFullBucketReached) {  // If full bucket, send to anomaly tracker.
-        // Accumulate partial buckets with current value and then send to anomaly tracker.
-        if (mCurrentFullBucket.size() > 0) {
-            for (const auto& slice : mCurrentSlicedBucket) {
-                if (hitFullBucketGuardRailLocked(slice.first) || slice.second.intervals.empty()) {
-                    continue;
-                }
-                // TODO: fix this when anomaly can accept double values
-                auto& interval = slice.second.intervals[0];
-                if (interval.hasValue) {
-                    mCurrentFullBucket[slice.first] += interval.value.long_value;
-                }
-            }
-            for (const auto& slice : mCurrentFullBucket) {
-                for (auto& tracker : mAnomalyTrackers) {
-                    if (tracker != nullptr) {
-                        tracker->addPastBucket(slice.first, slice.second, mCurrentBucketNum);
-                    }
-                }
-            }
-            mCurrentFullBucket.clear();
-        } else {
-            // Skip aggregating the partial buckets since there's no previous partial bucket.
-            for (const auto& slice : mCurrentSlicedBucket) {
-                for (auto& tracker : mAnomalyTrackers) {
-                    if (tracker != nullptr && !slice.second.intervals.empty()) {
-                        // TODO: fix this when anomaly can accept double values
-                        auto& interval = slice.second.intervals[0];
-                        if (interval.hasValue) {
-                            tracker->addPastBucket(slice.first, interval.value.long_value,
-                                                   mCurrentBucketNum);
-                        }
-                    }
-                }
-            }
-        }
-    } else {
-        // Accumulate partial bucket.
-        for (const auto& slice : mCurrentSlicedBucket) {
-            if (!slice.second.intervals.empty()) {
-                // TODO: fix this when anomaly can accept double values
-                auto& interval = slice.second.intervals[0];
-                if (interval.hasValue) {
-                    mCurrentFullBucket[slice.first] += interval.value.long_value;
-                }
-            }
-        }
-    }
-}
-
-size_t ValueMetricProducer::byteSizeLocked() const {
-    size_t totalSize = 0;
-    for (const auto& pair : mPastBuckets) {
-        totalSize += pair.second.size() * kBucketSize;
-    }
-    return totalSize;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
deleted file mode 100644
index ebd8fec..0000000
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-#include "anomaly/AnomalyTracker.h"
-#include "condition/ConditionTimer.h"
-#include "condition/ConditionTracker.h"
-#include "external/PullDataReceiver.h"
-#include "external/StatsPullerManager.h"
-#include "matchers/EventMatcherWizard.h"
-#include "stats_log_util.h"
-#include "MetricProducer.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct PastValueBucket {
-    int64_t mBucketStartNs;
-    int64_t mBucketEndNs;
-    std::vector<int> valueIndex;
-    std::vector<Value> values;
-    // If the metric has no condition, then this field is just wasted.
-    // When we tune statsd memory usage in the future, this is a candidate to optimize.
-    int64_t mConditionTrueNs;
-};
-
-// Aggregates values within buckets.
-//
-// There are different events that might complete a bucket
-// - a condition change
-// - an app upgrade
-// - an alarm set to the end of the bucket
-class ValueMetricProducer : public MetricProducer, public virtual PullDataReceiver {
-public:
-    ValueMetricProducer(
-            const ConfigKey& key, const ValueMetric& valueMetric, const int conditionIndex,
-            const vector<ConditionState>& initialConditionCache,
-            const sp<ConditionWizard>& conditionWizard, const uint64_t protoHash,
-            const int whatMatcherIndex, const sp<EventMatcherWizard>& matcherWizard,
-            const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs,
-            const sp<StatsPullerManager>& pullerManager,
-            const std::unordered_map<int, std::shared_ptr<Activation>>& eventActivationMap = {},
-            const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
-                    eventDeactivationMap = {},
-            const vector<int>& slicedStateAtoms = {},
-            const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
-
-    virtual ~ValueMetricProducer();
-
-    // Process data pulled on bucket boundary.
-    void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data,
-                      bool pullSuccess, int64_t originalPullTimeNs) override;
-
-    // ValueMetric needs special logic if it's a pulled atom.
-    void notifyAppUpgrade(const int64_t& eventTimeNs) override {
-        std::lock_guard<std::mutex> lock(mMutex);
-        if (!mSplitBucketForAppUpgrade) {
-            return;
-        }
-        if (mIsPulled && mCondition == ConditionState::kTrue) {
-            pullAndMatchEventsLocked(eventTimeNs);
-        }
-        flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
-    };
-
-    // ValueMetric needs special logic if it's a pulled atom.
-    void onStatsdInitCompleted(const int64_t& eventTimeNs) override {
-        std::lock_guard<std::mutex> lock(mMutex);
-        if (mIsPulled && mCondition == ConditionState::kTrue) {
-            pullAndMatchEventsLocked(eventTimeNs);
-        }
-        flushCurrentBucketLocked(eventTimeNs, eventTimeNs);
-    };
-
-    void onStateChanged(int64_t eventTimeNs, int32_t atomId, const HashableDimensionKey& primaryKey,
-                        const FieldValue& oldState, const FieldValue& newState) override;
-
-    MetricType getMetricType() const override {
-        return METRIC_TYPE_VALUE;
-    }
-
-protected:
-    void onMatchedLogEventInternalLocked(
-            const size_t matcherIndex, const MetricDimensionKey& eventKey,
-            const ConditionKey& conditionKey, bool condition, const LogEvent& event,
-            const std::map<int, HashableDimensionKey>& statePrimaryKeys) override;
-
-private:
-    void onDumpReportLocked(const int64_t dumpTimeNs,
-                            const bool include_current_partial_bucket,
-                            const bool erase_data,
-                            const DumpLatency dumpLatency,
-                            std::set<string> *str_set,
-                            android::util::ProtoOutputStream* protoOutput) override;
-    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
-
-    // Internal interface to handle active state change.
-    void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
-
-    // Internal interface to handle condition change.
-    void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
-
-    // Internal interface to handle sliced condition change.
-    void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
-
-    // Internal function to calculate the current used bytes.
-    size_t byteSizeLocked() const override;
-
-    void dumpStatesLocked(FILE* out, bool verbose) const override;
-
-    // For pulled metrics, this method should only be called if a pull has be done. Else we will
-    // not have complete data for the bucket.
-    void flushIfNeededLocked(const int64_t& eventTime) override;
-
-    // For pulled metrics, this method should only be called if a pulled have be done. Else we will
-    // not have complete data for the bucket.
-    void flushCurrentBucketLocked(const int64_t& eventTimeNs,
-                                  const int64_t& nextBucketStartTimeNs) override;
-
-    void prepareFirstBucketLocked() override;
-
-    void dropDataLocked(const int64_t dropTimeNs) override;
-
-    // Calculate previous bucket end time based on current time.
-    int64_t calcPreviousBucketEndTime(const int64_t currentTimeNs);
-
-    // Calculate how many buckets are present between the current bucket and eventTimeNs.
-    int64_t calcBucketsForwardCount(const int64_t& eventTimeNs) const;
-
-    // Mark the data as invalid.
-    void invalidateCurrentBucket(const int64_t dropTimeNs, const BucketDropReason reason);
-
-    void invalidateCurrentBucketWithoutResetBase(const int64_t dropTimeNs,
-                                                 const BucketDropReason reason);
-
-    // Skips the current bucket without notifying StatsdStats of the skipped bucket.
-    // This should only be called from #flushCurrentBucketLocked. Otherwise, a future event that
-    // causes the bucket to be invalidated will not notify StatsdStats.
-    void skipCurrentBucket(const int64_t dropTimeNs, const BucketDropReason reason);
-
-    bool onConfigUpdatedLocked(
-            const StatsdConfig& config, const int configIndex, const int metricIndex,
-            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-            const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-            const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-            const sp<EventMatcherWizard>& matcherWizard,
-            const std::vector<sp<ConditionTracker>>& allConditionTrackers,
-            const std::unordered_map<int64_t, int>& conditionTrackerMap,
-            const sp<ConditionWizard>& wizard,
-            const std::unordered_map<int64_t, int>& metricToActivationMap,
-            std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-            std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-            std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-            std::vector<int>& metricsWithActivation) override;
-
-    int mWhatMatcherIndex;
-
-    sp<EventMatcherWizard> mEventMatcherWizard;
-
-    sp<StatsPullerManager> mPullerManager;
-
-    // Value fields for matching.
-    std::vector<Matcher> mFieldMatchers;
-
-    // Value fields for matching.
-    std::set<HashableDimensionKey> mMatchedMetricDimensionKeys;
-
-    // Holds the atom id, primary key pair from a state change.
-    pair<int32_t, HashableDimensionKey> mStateChangePrimaryKey;
-
-    // tagId for pulled data. -1 if this is not pulled
-    const int mPullTagId;
-
-    // if this is pulled metric
-    const bool mIsPulled;
-
-    // Tracks the value information of one value field.
-    typedef struct {
-        // Index in multi value aggregation.
-        int valueIndex;
-        // Current value, depending on the aggregation type.
-        Value value;
-        // Number of samples collected.
-        int sampleSize;
-        // If this dimension has any non-tainted value. If not, don't report the
-        // dimension.
-        bool hasValue = false;
-        // Whether new data is seen in the bucket.
-        bool seenNewData = false;
-    } Interval;
-
-    // Internal state of an ongoing aggregation bucket.
-    typedef struct CurrentValueBucket {
-        // If the `MetricDimensionKey` state key is the current state key, then
-        // the condition timer will be updated later (e.g. condition/state/active
-        // state change) with the correct condition and time.
-        CurrentValueBucket() : intervals(), conditionTimer(ConditionTimer(false, 0)) {}
-        // Value information for each value field of the metric.
-        std::vector<Interval> intervals;
-        // Tracks how long the condition is true.
-        ConditionTimer conditionTimer;
-    } CurrentValueBucket;
-
-    // Holds base information for diffing values from one value field.
-    typedef struct {
-        // Holds current base value of the dimension. Take diff and update if necessary.
-        Value base;
-        // Whether there is a base to diff to.
-        bool hasBase;
-    } BaseInfo;
-
-    // State key and base information for a specific DimensionsInWhat key.
-    typedef struct DimensionsInWhatInfo {
-        DimensionsInWhatInfo(const HashableDimensionKey& stateKey)
-            : baseInfos(), currentState(stateKey), hasCurrentState(false) {
-        }
-        std::vector<BaseInfo> baseInfos;
-        // Last seen state value(s).
-        HashableDimensionKey currentState;
-        // Whether this dimensions in what key has a current state key.
-        bool hasCurrentState;
-    } DimensionsInWhatInfo;
-
-    // Tracks the internal state in the ongoing aggregation bucket for each DimensionsInWhat
-    // key and StateValuesKey pair.
-    std::unordered_map<MetricDimensionKey, CurrentValueBucket> mCurrentSlicedBucket;
-
-    // Tracks current state key and base information for each DimensionsInWhat key.
-    std::unordered_map<HashableDimensionKey, DimensionsInWhatInfo> mCurrentBaseInfo;
-
-    std::unordered_map<MetricDimensionKey, int64_t> mCurrentFullBucket;
-
-    // Save the past buckets and we can clear when the StatsLogReport is dumped.
-    std::unordered_map<MetricDimensionKey, std::vector<PastValueBucket>> mPastBuckets;
-
-    const int64_t mMinBucketSizeNs;
-
-    // Util function to check whether the specified dimension hits the guardrail.
-    bool hitGuardRailLocked(const MetricDimensionKey& newKey);
-
-    bool hasReachedGuardRailLimit() const;
-
-    bool hitFullBucketGuardRailLocked(const MetricDimensionKey& newKey);
-
-    void pullAndMatchEventsLocked(const int64_t timestampNs);
-
-    bool multipleBucketsSkipped(const int64_t numBucketsForward);
-
-    void accumulateEvents(const std::vector<std::shared_ptr<LogEvent>>& allData,
-                          int64_t originalPullTimeNs, int64_t eventElapsedTimeNs);
-
-    PastValueBucket buildPartialBucket(int64_t bucketEndTime,
-                                       const std::vector<Interval>& intervals);
-
-    void initCurrentSlicedBucket(int64_t nextBucketStartTimeNs);
-
-    void appendToFullBucket(const bool isFullBucketReached);
-
-    // Reset diff base and mHasGlobalBase
-    void resetBase();
-
-    // Updates the condition timers in the current sliced bucket when there is a
-    // condition change or an active state change.
-    void updateCurrentSlicedBucketConditionTimers(bool newCondition, int64_t eventTimeNs);
-
-    static const size_t kBucketSize = sizeof(PastValueBucket{});
-
-    const size_t mDimensionSoftLimit;
-
-    const size_t mDimensionHardLimit;
-
-    const bool mUseAbsoluteValueOnReset;
-
-    const ValueMetric::AggregationType mAggregationType;
-
-    const bool mUseDiff;
-
-    const ValueMetric::ValueDirection mValueDirection;
-
-    const bool mSkipZeroDiffOutput;
-
-    // If true, use a zero value as base to compute the diff.
-    // This is used for new keys which are present in the new data but was not
-    // present in the base data.
-    // The default base will only be used if we have a global base.
-    const bool mUseZeroDefaultBase;
-
-    // For pulled metrics, this is always set to true whenever a pull succeeds.
-    // It is set to false when a pull fails, or upon condition change to false.
-    // This is used to decide if we have the right base data to compute the
-    // diff against.
-    bool mHasGlobalBase;
-
-    // This is to track whether or not the bucket is skipped for any of the reasons listed in
-    // BucketDropReason, many of which make the bucket potentially invalid.
-    bool mCurrentBucketIsSkipped;
-
-    const int64_t mMaxPullDelayNs;
-
-    const bool mSplitBucketForAppUpgrade;
-
-    ConditionTimer mConditionTimer;
-
-    FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection);
-    FRIEND_TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange);
-    FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange);
-    FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition);
-    FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition);
-    FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2);
-    FRIEND_TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet);
-    FRIEND_TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime);
-    FRIEND_TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged);
-    FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary);
-    FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged);
-    FRIEND_TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled);
-    FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
-    FRIEND_TEST(ValueMetricProducerTest, TestFirstBucket);
-    FRIEND_TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff);
-    FRIEND_TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff);
-    FRIEND_TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsNoCondition);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering);
-    FRIEND_TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled);
-    FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateAvg);
-    FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMax);
-    FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMin);
-    FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateSum);
-    FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithCondition);
-    FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
-    FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded);
-    FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange);
-    FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket);
-    FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange);
-    FRIEND_TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate);
-    FRIEND_TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput);
-    FRIEND_TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue);
-    FRIEND_TEST(ValueMetricProducerTest, TestSlicedState);
-    FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithMap);
-    FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions);
-    FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithCondition);
-    FRIEND_TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey);
-    FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBase);
-    FRIEND_TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures);
-    FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithMultipleDimensions);
-    FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithMissingDataInStateChange);
-    FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithDataMissingInConditionChange);
-    FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithMissingDataThenFlushBucket);
-    FRIEND_TEST(ValueMetricProducerTest, TestSlicedStateWithNoPullOnBucketBoundary);
-
-    FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed);
-    FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed);
-    FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed);
-    FRIEND_TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit);
-    FRIEND_TEST(ValueMetricProducerTest_BucketDrop,
-                TestInvalidBucketWhenAccumulateEventWrongBucket);
-
-    FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestBucketBoundariesOnPartialBucket);
-    FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketInvalid);
-    FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated);
-    FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPushedEvents);
-    FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValue);
-    FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse);
-
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateValueMetrics);
-
-    friend class ValueMetricProducerTestHelper;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
deleted file mode 100644
index cf1f437..0000000
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef DURATION_TRACKER_H
-#define DURATION_TRACKER_H
-
-#include "anomaly/DurationAnomalyTracker.h"
-#include "condition/ConditionWizard.h"
-#include "config/ConfigKey.h"
-#include "stats_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-enum DurationState {
-    kStopped = 0,  // The event is stopped.
-    kStarted = 1,  // The event is on going.
-    kPaused = 2,   // The event is started, but condition is false, clock is paused. When condition
-                   // turns to true, kPaused will become kStarted.
-};
-
-// Hold duration information for one atom level duration in current on-going bucket.
-struct DurationInfo {
-    DurationState state;
-
-    // the number of starts seen.
-    int32_t startCount;
-
-    // most recent start time.
-    int64_t lastStartTime;
-    // existing duration in current bucket.
-    int64_t lastDuration;
-    // cache the HashableDimensionKeys we need to query the condition for this duration event.
-    ConditionKey conditionKeys;
-
-    DurationInfo() : state(kStopped), startCount(0), lastStartTime(0), lastDuration(0){};
-};
-
-struct DurationBucket {
-    int64_t mBucketStartNs;
-    int64_t mBucketEndNs;
-    int64_t mDuration;
-};
-
-struct DurationValues {
-    // Recorded duration for current partial bucket.
-    int64_t mDuration;
-
-    // Sum of past partial bucket durations in current full bucket.
-    // Used for anomaly detection.
-    int64_t mDurationFullBucket;
-};
-
-class DurationTracker {
-public:
-    DurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
-                    sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
-                    int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs,
-                    int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
-                    const std::vector<sp<AnomalyTracker>>& anomalyTrackers)
-        : mConfigKey(key),
-          mTrackerId(id),
-          mEventKey(eventKey),
-          mWizard(wizard),
-          mConditionTrackerIndex(conditionIndex),
-          mBucketSizeNs(bucketSizeNs),
-          mNested(nesting),
-          mCurrentBucketStartTimeNs(currentBucketStartNs),
-          mDuration(0),
-          mCurrentBucketNum(currentBucketNum),
-          mStartTimeNs(startTimeNs),
-          mConditionSliced(conditionSliced),
-          mHasLinksToAllConditionDimensionsInTracker(fullLink),
-          mAnomalyTrackers(anomalyTrackers){};
-
-    virtual ~DurationTracker(){};
-
-    void onConfigUpdated(const sp<ConditionWizard>& wizard, const int conditionTrackerIndex) {
-        sp<ConditionWizard> tmpWizard = mWizard;
-        mWizard = wizard;
-        mConditionTrackerIndex = conditionTrackerIndex;
-        mAnomalyTrackers.clear();
-    };
-
-    virtual void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
-                           const ConditionKey& conditionKey) = 0;
-    virtual void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
-                          const bool stopAll) = 0;
-    virtual void noteStopAll(const int64_t eventTime) = 0;
-
-    virtual void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) = 0;
-    virtual void onConditionChanged(bool condition, const int64_t timestamp) = 0;
-
-    virtual void onStateChanged(const int64_t timestamp, const int32_t atomId,
-                                const FieldValue& newState) = 0;
-
-    // Flush stale buckets if needed, and return true if the tracker has no on-going duration
-    // events, so that the owner can safely remove the tracker.
-    virtual bool flushIfNeeded(
-            int64_t timestampNs,
-            std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) = 0;
-
-    // Should only be called during an app upgrade or from this tracker's flushIfNeeded. If from
-    // an app upgrade, we assume that we're trying to form a partial bucket.
-    virtual bool flushCurrentBucket(
-            const int64_t& eventTimeNs,
-            std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) = 0;
-
-    // Predict the anomaly timestamp given the current status.
-    virtual int64_t predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
-                                              const int64_t currentTimestamp) const = 0;
-    // Dump internal states for debugging
-    virtual void dumpStates(FILE* out, bool verbose) const = 0;
-
-    virtual int64_t getCurrentStateKeyDuration() const = 0;
-
-    virtual int64_t getCurrentStateKeyFullBucketDuration() const = 0;
-
-    // Replace old value with new value for the given state atom.
-    virtual void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) = 0;
-
-    void addAnomalyTracker(sp<AnomalyTracker>& anomalyTracker) {
-        mAnomalyTrackers.push_back(anomalyTracker);
-    }
-
-protected:
-    int64_t getCurrentBucketEndTimeNs() const {
-        return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
-    }
-
-    // Starts the anomaly alarm.
-    void startAnomalyAlarm(const int64_t eventTime) {
-        for (auto& anomalyTracker : mAnomalyTrackers) {
-            if (anomalyTracker != nullptr) {
-                const int64_t alarmTimestampNs =
-                    predictAnomalyTimestampNs(*anomalyTracker, eventTime);
-                if (alarmTimestampNs > 0) {
-                    anomalyTracker->startAlarm(mEventKey, alarmTimestampNs);
-                }
-            }
-        }
-    }
-
-    // Stops the anomaly alarm. If it should have already fired, declare the anomaly now.
-    void stopAnomalyAlarm(const int64_t timestamp) {
-        for (auto& anomalyTracker : mAnomalyTrackers) {
-            if (anomalyTracker != nullptr) {
-                anomalyTracker->stopAlarm(mEventKey, timestamp);
-            }
-        }
-    }
-
-    void addPastBucketToAnomalyTrackers(const MetricDimensionKey eventKey,
-                                        const int64_t& bucketValue, const int64_t& bucketNum) {
-        for (auto& anomalyTracker : mAnomalyTrackers) {
-            if (anomalyTracker != nullptr) {
-                anomalyTracker->addPastBucket(eventKey, bucketValue, bucketNum);
-            }
-        }
-    }
-
-    void detectAndDeclareAnomaly(const int64_t& timestamp, const int64_t& currBucketNum,
-                                 const int64_t& currentBucketValue) {
-        for (auto& anomalyTracker : mAnomalyTrackers) {
-            if (anomalyTracker != nullptr) {
-                anomalyTracker->detectAndDeclareAnomaly(timestamp, currBucketNum, mTrackerId,
-                                                        mEventKey, currentBucketValue);
-            }
-        }
-    }
-
-    // Convenience to compute the current bucket's end time, which is always aligned with the
-    // start time of the metric.
-    int64_t getCurrentBucketEndTimeNs() {
-        return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
-    }
-
-    void setEventKey(const MetricDimensionKey& eventKey) {
-        mEventKey = eventKey;
-    }
-
-    // A reference to the DurationMetricProducer's config key.
-    const ConfigKey& mConfigKey;
-
-    const int64_t mTrackerId;
-
-    MetricDimensionKey mEventKey;
-
-    sp<ConditionWizard> mWizard;
-
-    int mConditionTrackerIndex;
-
-    const int64_t mBucketSizeNs;
-
-    const bool mNested;
-
-    int64_t mCurrentBucketStartTimeNs;
-
-    int64_t mDuration;  // current recorded duration result (for partial bucket)
-
-    // Recorded duration results for each state key in the current partial bucket.
-    std::unordered_map<HashableDimensionKey, DurationValues> mStateKeyDurationMap;
-
-    int64_t mCurrentBucketNum;
-
-    const int64_t mStartTimeNs;
-
-    const bool mConditionSliced;
-
-    bool mHasLinksToAllConditionDimensionsInTracker;
-
-    std::vector<sp<AnomalyTracker>> mAnomalyTrackers;
-
-    FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
-    FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
-    FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
-
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateDurationMetrics);
-    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlerts);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // DURATION_TRACKER_H
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
deleted file mode 100644
index 62f4982..0000000
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false
-
-#include "Log.h"
-#include "MaxDurationTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-MaxDurationTracker::MaxDurationTracker(const ConfigKey& key, const int64_t& id,
-                                       const MetricDimensionKey& eventKey,
-                                       sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
-                                       int64_t currentBucketStartNs, int64_t currentBucketNum,
-                                       int64_t startTimeNs, int64_t bucketSizeNs,
-                                       bool conditionSliced, bool fullLink,
-                                       const vector<sp<AnomalyTracker>>& anomalyTrackers)
-    : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
-                      currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink,
-                      anomalyTrackers) {
-}
-
-bool MaxDurationTracker::hitGuardRail(const HashableDimensionKey& newKey) {
-    // ===========GuardRail==============
-    if (mInfos.find(newKey) != mInfos.end()) {
-        // if the key existed, we are good!
-        return false;
-    }
-    // 1. Report the tuple count if the tuple count > soft limit
-    if (mInfos.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
-        size_t newTupleCount = mInfos.size() + 1;
-        StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mTrackerId, newTupleCount);
-        // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
-        if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
-            ALOGE("MaxDurTracker %lld dropping data for dimension key %s",
-                (long long)mTrackerId, newKey.toString().c_str());
-            return true;
-        }
-    }
-    return false;
-}
-
-void MaxDurationTracker::noteStart(const HashableDimensionKey& key, bool condition,
-                                   const int64_t eventTime, const ConditionKey& conditionKey) {
-    // this will construct a new DurationInfo if this key didn't exist.
-    if (hitGuardRail(key)) {
-        return;
-    }
-
-    DurationInfo& duration = mInfos[key];
-    if (mConditionSliced) {
-        duration.conditionKeys = conditionKey;
-    }
-    VLOG("MaxDuration: key %s start condition %d", key.toString().c_str(), condition);
-
-    switch (duration.state) {
-        case kStarted:
-            duration.startCount++;
-            break;
-        case kPaused:
-            duration.startCount++;
-            break;
-        case kStopped:
-            if (!condition) {
-                // event started, but we need to wait for the condition to become true.
-                duration.state = DurationState::kPaused;
-            } else {
-                duration.state = DurationState::kStarted;
-                duration.lastStartTime = eventTime;
-                startAnomalyAlarm(eventTime);
-            }
-            duration.startCount = 1;
-            break;
-    }
-}
-
-void MaxDurationTracker::noteStop(const HashableDimensionKey& key, const int64_t eventTime,
-                                  bool forceStop) {
-    VLOG("MaxDuration: key %s stop", key.toString().c_str());
-    if (mInfos.find(key) == mInfos.end()) {
-        // we didn't see a start event before. do nothing.
-        return;
-    }
-    DurationInfo& duration = mInfos[key];
-
-    switch (duration.state) {
-        case DurationState::kStopped:
-            // already stopped, do nothing.
-            break;
-        case DurationState::kStarted: {
-            duration.startCount--;
-            if (forceStop || !mNested || duration.startCount <= 0) {
-                stopAnomalyAlarm(eventTime);
-                duration.state = DurationState::kStopped;
-                int64_t durationTime = eventTime - duration.lastStartTime;
-                VLOG("Max, key %s, Stop %lld %lld %lld", key.toString().c_str(),
-                     (long long)duration.lastStartTime, (long long)eventTime,
-                     (long long)durationTime);
-                duration.lastDuration += durationTime;
-                if (anyStarted()) {
-                    // In case any other dimensions are still started, we need to keep the alarm
-                    // set.
-                    startAnomalyAlarm(eventTime);
-                }
-                VLOG("  record duration: %lld ", (long long)duration.lastDuration);
-            }
-            break;
-        }
-        case DurationState::kPaused: {
-            duration.startCount--;
-            if (forceStop || !mNested || duration.startCount <= 0) {
-                duration.state = DurationState::kStopped;
-            }
-            break;
-        }
-    }
-
-    if (duration.lastDuration > mDuration) {
-        mDuration = duration.lastDuration;
-        VLOG("Max: new max duration: %lld", (long long)mDuration);
-    }
-    // Once an atom duration ends, we erase it. Next time, if we see another atom event with the
-    // same name, they are still considered as different atom durations.
-    if (duration.state == DurationState::kStopped) {
-        mInfos.erase(key);
-    }
-}
-
-bool MaxDurationTracker::anyStarted() {
-    for (auto& pair : mInfos) {
-        if (pair.second.state == kStarted) {
-            return true;
-        }
-    }
-    return false;
-}
-
-void MaxDurationTracker::noteStopAll(const int64_t eventTime) {
-    std::set<HashableDimensionKey> keys;
-    for (const auto& pair : mInfos) {
-        keys.insert(pair.first);
-    }
-    for (auto& key : keys) {
-        noteStop(key, eventTime, true);
-    }
-}
-
-bool MaxDurationTracker::flushCurrentBucket(
-        const int64_t& eventTimeNs,
-        std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) {
-    VLOG("MaxDurationTracker flushing.....");
-
-    // adjust the bucket start time
-    int numBucketsForward = 0;
-    int64_t fullBucketEnd = getCurrentBucketEndTimeNs();
-    int64_t currentBucketEndTimeNs;
-    if (eventTimeNs >= fullBucketEnd) {
-        numBucketsForward = 1 + (eventTimeNs - fullBucketEnd) / mBucketSizeNs;
-        currentBucketEndTimeNs = fullBucketEnd;
-    } else {
-        // This must be a partial bucket.
-        currentBucketEndTimeNs = eventTimeNs;
-    }
-
-    bool hasPendingEvent =
-            false;  // has either a kStarted or kPaused event across bucket boundaries
-    // meaning we need to carry them over to the new bucket.
-    for (auto it = mInfos.begin(); it != mInfos.end();) {
-        if (it->second.state == DurationState::kStopped) {
-            // No need to keep buckets for events that were stopped before.
-            it = mInfos.erase(it);
-        } else {
-            ++it;
-            hasPendingEvent = true;
-        }
-    }
-
-    // mDuration is updated in noteStop to the maximum duration that ended in the current bucket.
-    if (mDuration != 0) {
-        DurationBucket info;
-        info.mBucketStartNs = mCurrentBucketStartTimeNs;
-        info.mBucketEndNs = currentBucketEndTimeNs;
-        info.mDuration = mDuration;
-        (*output)[mEventKey].push_back(info);
-        VLOG("  final duration for last bucket: %lld", (long long)mDuration);
-    }
-
-    if (numBucketsForward > 0) {
-        mCurrentBucketStartTimeNs = fullBucketEnd + (numBucketsForward - 1) * mBucketSizeNs;
-        mCurrentBucketNum += numBucketsForward;
-    } else {  // We must be forming a partial bucket.
-        mCurrentBucketStartTimeNs = eventTimeNs;
-    }
-
-    mDuration = 0;
-    // If this tracker has no pending events, tell owner to remove.
-    return !hasPendingEvent;
-}
-
-bool MaxDurationTracker::flushIfNeeded(
-        int64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
-    if (eventTimeNs < getCurrentBucketEndTimeNs()) {
-        return false;
-    }
-    return flushCurrentBucket(eventTimeNs, output);
-}
-
-void MaxDurationTracker::onSlicedConditionMayChange(bool overallCondition,
-                                                    const int64_t timestamp) {
-    // Now for each of the on-going event, check if the condition has changed for them.
-    for (auto& pair : mInfos) {
-        if (pair.second.state == kStopped) {
-            continue;
-        }
-        ConditionState conditionState = mWizard->query(
-            mConditionTrackerIndex, pair.second.conditionKeys,
-            !mHasLinksToAllConditionDimensionsInTracker);
-        bool conditionMet = (conditionState == ConditionState::kTrue);
-
-        VLOG("key: %s, condition: %d", pair.first.toString().c_str(), conditionMet);
-        noteConditionChanged(pair.first, conditionMet, timestamp);
-    }
-}
-
-void MaxDurationTracker::onStateChanged(const int64_t timestamp, const int32_t atomId,
-                                        const FieldValue& newState) {
-    ALOGE("MaxDurationTracker does not handle sliced state changes.");
-}
-
-void MaxDurationTracker::onConditionChanged(bool condition, const int64_t timestamp) {
-    for (auto& pair : mInfos) {
-        noteConditionChanged(pair.first, condition, timestamp);
-    }
-}
-
-void MaxDurationTracker::noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
-                                              const int64_t timestamp) {
-    auto it = mInfos.find(key);
-    if (it == mInfos.end()) {
-        return;
-    }
-
-    switch (it->second.state) {
-        case kStarted:
-            // If condition becomes false, kStarted -> kPaused. Record the current duration and
-            // stop anomaly alarm.
-            if (!conditionMet) {
-                stopAnomalyAlarm(timestamp);
-                it->second.state = DurationState::kPaused;
-                it->second.lastDuration += (timestamp - it->second.lastStartTime);
-                if (anyStarted()) {
-                    // In case any other dimensions are still started, we need to set the alarm.
-                    startAnomalyAlarm(timestamp);
-                }
-                VLOG("MaxDurationTracker Key: %s Started->Paused ", key.toString().c_str());
-            }
-            break;
-        case kStopped:
-            // Nothing to do if it's stopped.
-            break;
-        case kPaused:
-            // If condition becomes true, kPaused -> kStarted. and the start time is the condition
-            // change time.
-            if (conditionMet) {
-                it->second.state = DurationState::kStarted;
-                it->second.lastStartTime = timestamp;
-                startAnomalyAlarm(timestamp);
-                VLOG("MaxDurationTracker Key: %s Paused->Started", key.toString().c_str());
-            }
-            break;
-    }
-    // Note that we don't update mDuration here since it's only updated during noteStop.
-}
-
-int64_t MaxDurationTracker::predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
-                                                      const int64_t currentTimestamp) const {
-    // The allowed time we can continue in the current state is the
-    // (anomaly threshold) - max(elapsed time of the started mInfos).
-    int64_t maxElapsed = 0;
-    for (auto it = mInfos.begin(); it != mInfos.end(); ++it) {
-        if (it->second.state == DurationState::kStarted) {
-            int64_t duration =
-                    it->second.lastDuration + (currentTimestamp - it->second.lastStartTime);
-            if (duration > maxElapsed) {
-                maxElapsed = duration;
-            }
-        }
-    }
-    int64_t anomalyTimeNs = currentTimestamp + anomalyTracker.getAnomalyThreshold() - maxElapsed;
-    int64_t refractoryEndNs = anomalyTracker.getRefractoryPeriodEndsSec(mEventKey) * NS_PER_SEC;
-    return std::max(anomalyTimeNs, refractoryEndNs);
-}
-
-void MaxDurationTracker::dumpStates(FILE* out, bool verbose) const {
-    fprintf(out, "\t\t sub-durations %lu\n", (unsigned long)mInfos.size());
-    fprintf(out, "\t\t current duration %lld\n", (long long)mDuration);
-}
-
-int64_t MaxDurationTracker::getCurrentStateKeyDuration() const {
-    ALOGE("MaxDurationTracker does not handle sliced state changes.");
-    return -1;
-}
-
-int64_t MaxDurationTracker::getCurrentStateKeyFullBucketDuration() const {
-    ALOGE("MaxDurationTracker does not handle sliced state changes.");
-    return -1;
-}
-
-void MaxDurationTracker::updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) {
-    ALOGE("MaxDurationTracker does not handle sliced state changes.");
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
deleted file mode 100644
index be2707c..0000000
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef MAX_DURATION_TRACKER_H
-#define MAX_DURATION_TRACKER_H
-
-#include "DurationTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Tracks a pool of atom durations, and output the max duration for each bucket.
-// To get max duration, we need to keep track of each individual durations, and compare them when
-// they stop or bucket expires.
-class MaxDurationTracker : public DurationTracker {
-public:
-    MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
-                       sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
-                       int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs,
-                       int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
-                       const std::vector<sp<AnomalyTracker>>& anomalyTrackers);
-
-    MaxDurationTracker(const MaxDurationTracker& tracker) = default;
-
-    void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
-                   const ConditionKey& conditionKey) override;
-    void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
-                  const bool stopAll) override;
-    void noteStopAll(const int64_t eventTime) override;
-
-    bool flushIfNeeded(
-            int64_t timestampNs,
-            std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
-    bool flushCurrentBucket(
-            const int64_t& eventTimeNs,
-            std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>*) override;
-
-    void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
-    void onConditionChanged(bool condition, const int64_t timestamp) override;
-
-    void onStateChanged(const int64_t timestamp, const int32_t atomId,
-                        const FieldValue& newState) override;
-
-    int64_t predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
-                                      const int64_t currentTimestamp) const override;
-    void dumpStates(FILE* out, bool verbose) const override;
-
-    int64_t getCurrentStateKeyDuration() const override;
-
-    int64_t getCurrentStateKeyFullBucketDuration() const override;
-
-    void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState);
-
-private:
-    // Returns true if at least one of the mInfos is started.
-    bool anyStarted();
-
-    std::unordered_map<HashableDimensionKey, DurationInfo> mInfos;
-
-    void noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
-                              const int64_t timestamp);
-
-    // return true if we should not allow newKey to be tracked because we are above the threshold
-    bool hitGuardRail(const HashableDimensionKey& newKey);
-
-    FRIEND_TEST(MaxDurationTrackerTest, TestSimpleMaxDuration);
-    FRIEND_TEST(MaxDurationTrackerTest, TestCrossBucketBoundary);
-    FRIEND_TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition);
-    FRIEND_TEST(MaxDurationTrackerTest, TestStopAll);
-    FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyDetection);
-    FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // MAX_DURATION_TRACKER_H
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
deleted file mode 100644
index 247e2e0..0000000
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-#define DEBUG false
-#include "Log.h"
-#include "OringDurationTracker.h"
-#include "guardrail/StatsdStats.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::pair;
-
-OringDurationTracker::OringDurationTracker(
-        const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
-        sp<ConditionWizard> wizard, int conditionIndex, bool nesting, int64_t currentBucketStartNs,
-        int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
-        bool fullLink, const vector<sp<AnomalyTracker>>& anomalyTrackers)
-    : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
-                      currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink,
-                      anomalyTrackers),
-      mStarted(),
-      mPaused() {
-    mLastStartTime = 0;
-}
-
-bool OringDurationTracker::hitGuardRail(const HashableDimensionKey& newKey) {
-    // ===========GuardRail==============
-    // 1. Report the tuple count if the tuple count > soft limit
-    if (mConditionKeyMap.find(newKey) != mConditionKeyMap.end()) {
-        return false;
-    }
-    if (mConditionKeyMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
-        size_t newTupleCount = mConditionKeyMap.size() + 1;
-        StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mTrackerId, newTupleCount);
-        // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
-        if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
-            ALOGE("OringDurTracker %lld dropping data for dimension key %s",
-                (long long)mTrackerId, newKey.toString().c_str());
-            return true;
-        }
-    }
-    return false;
-}
-
-void OringDurationTracker::noteStart(const HashableDimensionKey& key, bool condition,
-                                     const int64_t eventTime, const ConditionKey& conditionKey) {
-    if (hitGuardRail(key)) {
-        return;
-    }
-    if (condition) {
-        if (mStarted.size() == 0) {
-            mLastStartTime = eventTime;
-            VLOG("record first start....");
-            startAnomalyAlarm(eventTime);
-        }
-        mStarted[key]++;
-    } else {
-        mPaused[key]++;
-    }
-
-    if (mConditionSliced && mConditionKeyMap.find(key) == mConditionKeyMap.end()) {
-        mConditionKeyMap[key] = conditionKey;
-    }
-    VLOG("Oring: %s start, condition %d", key.toString().c_str(), condition);
-}
-
-void OringDurationTracker::noteStop(const HashableDimensionKey& key, const int64_t timestamp,
-                                    const bool stopAll) {
-    VLOG("Oring: %s stop", key.toString().c_str());
-    auto it = mStarted.find(key);
-    if (it != mStarted.end()) {
-        (it->second)--;
-        if (stopAll || !mNested || it->second <= 0) {
-            mStarted.erase(it);
-            mConditionKeyMap.erase(key);
-        }
-        if (mStarted.empty()) {
-            mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
-                    (timestamp - mLastStartTime);
-            detectAndDeclareAnomaly(
-                    timestamp, mCurrentBucketNum,
-                    getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
-            VLOG("record duration %lld, total duration %lld for state key %s",
-                 (long long)timestamp - mLastStartTime, (long long)getCurrentStateKeyDuration(),
-                 mEventKey.getStateValuesKey().toString().c_str());
-        }
-    }
-
-    auto pausedIt = mPaused.find(key);
-    if (pausedIt != mPaused.end()) {
-        (pausedIt->second)--;
-        if (stopAll || !mNested || pausedIt->second <= 0) {
-            mPaused.erase(pausedIt);
-            mConditionKeyMap.erase(key);
-        }
-    }
-    if (mStarted.empty()) {
-        stopAnomalyAlarm(timestamp);
-    }
-}
-
-void OringDurationTracker::noteStopAll(const int64_t timestamp) {
-    if (!mStarted.empty()) {
-        mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
-                (timestamp - mLastStartTime);
-        VLOG("Oring Stop all: record duration %lld, total duration %lld for state key %s",
-             (long long)timestamp - mLastStartTime, (long long)getCurrentStateKeyDuration(),
-             mEventKey.getStateValuesKey().toString().c_str());
-        detectAndDeclareAnomaly(
-                timestamp, mCurrentBucketNum,
-                getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
-    }
-
-    stopAnomalyAlarm(timestamp);
-    mStarted.clear();
-    mPaused.clear();
-    mConditionKeyMap.clear();
-}
-
-bool OringDurationTracker::flushCurrentBucket(
-        const int64_t& eventTimeNs,
-        std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) {
-    VLOG("OringDurationTracker Flushing.............");
-
-    // Note that we have to mimic the bucket time changes we do in the
-    // MetricProducer#notifyAppUpgrade.
-
-    int numBucketsForward = 0;
-    int64_t fullBucketEnd = getCurrentBucketEndTimeNs();
-    int64_t currentBucketEndTimeNs;
-
-    if (eventTimeNs >= fullBucketEnd) {
-        numBucketsForward = 1 + (eventTimeNs - fullBucketEnd) / mBucketSizeNs;
-        currentBucketEndTimeNs = fullBucketEnd;
-    } else {
-        // This must be a partial bucket.
-        currentBucketEndTimeNs = eventTimeNs;
-    }
-
-    // Process the current bucket.
-    if (mStarted.size() > 0) {
-        // Calculate the duration for the current state key.
-        mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
-                (currentBucketEndTimeNs - mLastStartTime);
-    }
-    // Store DurationBucket info for each whatKey, stateKey pair.
-    // Note: The whatKey stored in mEventKey is constant for each DurationTracker, while the
-    // stateKey stored in mEventKey is only the current stateKey. mStateKeyDurationMap is used to
-    // store durations for each stateKey, so we need to flush the bucket by creating a
-    // DurationBucket for each stateKey.
-    for (auto& durationIt : mStateKeyDurationMap) {
-        if (durationIt.second.mDuration > 0) {
-            DurationBucket current_info;
-            current_info.mBucketStartNs = mCurrentBucketStartTimeNs;
-            current_info.mBucketEndNs = currentBucketEndTimeNs;
-            current_info.mDuration = durationIt.second.mDuration;
-            (*output)[MetricDimensionKey(mEventKey.getDimensionKeyInWhat(), durationIt.first)]
-                    .push_back(current_info);
-
-            durationIt.second.mDurationFullBucket += durationIt.second.mDuration;
-            VLOG("  duration: %lld", (long long)current_info.mDuration);
-        }
-
-        if (eventTimeNs > fullBucketEnd) {
-            // End of full bucket, can send to anomaly tracker now.
-            addPastBucketToAnomalyTrackers(
-                    MetricDimensionKey(mEventKey.getDimensionKeyInWhat(), durationIt.first),
-                    getCurrentStateKeyFullBucketDuration(), mCurrentBucketNum);
-            durationIt.second.mDurationFullBucket = 0;
-        }
-        durationIt.second.mDuration = 0;
-    }
-
-    if (mStarted.size() > 0) {
-        for (int i = 1; i < numBucketsForward; i++) {
-            DurationBucket info;
-            info.mBucketStartNs = fullBucketEnd + mBucketSizeNs * (i - 1);
-            info.mBucketEndNs = info.mBucketStartNs + mBucketSizeNs;
-            info.mDuration = mBucketSizeNs;
-            // Full duration buckets are attributed to the current stateKey.
-            (*output)[mEventKey].push_back(info);
-            // Safe to send these buckets to anomaly tracker since they must be full buckets.
-            // If it's a partial bucket, numBucketsForward would be 0.
-            addPastBucketToAnomalyTrackers(mEventKey, info.mDuration, mCurrentBucketNum + i);
-            VLOG("  add filling bucket with duration %lld", (long long)info.mDuration);
-        }
-    } else {
-        if (numBucketsForward >= 2) {
-            addPastBucketToAnomalyTrackers(mEventKey, 0, mCurrentBucketNum + numBucketsForward - 1);
-        }
-    }
-
-    if (numBucketsForward > 0) {
-        mCurrentBucketStartTimeNs = fullBucketEnd + (numBucketsForward - 1) * mBucketSizeNs;
-        mCurrentBucketNum += numBucketsForward;
-    } else {  // We must be forming a partial bucket.
-        mCurrentBucketStartTimeNs = eventTimeNs;
-    }
-    mLastStartTime = mCurrentBucketStartTimeNs;
-
-    // if all stopped, then tell owner it's safe to remove this tracker.
-    return mStarted.empty() && mPaused.empty();
-}
-
-bool OringDurationTracker::flushIfNeeded(
-        int64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
-    if (eventTimeNs < getCurrentBucketEndTimeNs()) {
-        return false;
-    }
-    return flushCurrentBucket(eventTimeNs, output);
-}
-
-void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition,
-                                                      const int64_t timestamp) {
-    vector<pair<HashableDimensionKey, int>> startedToPaused;
-    vector<pair<HashableDimensionKey, int>> pausedToStarted;
-    if (!mStarted.empty()) {
-        for (auto it = mStarted.begin(); it != mStarted.end();) {
-            const auto& key = it->first;
-            const auto& condIt = mConditionKeyMap.find(key);
-            if (condIt == mConditionKeyMap.end()) {
-                VLOG("Key %s dont have condition key", key.toString().c_str());
-                ++it;
-                continue;
-            }
-            ConditionState conditionState =
-                mWizard->query(mConditionTrackerIndex, condIt->second,
-                               !mHasLinksToAllConditionDimensionsInTracker);
-            if (conditionState != ConditionState::kTrue) {
-                startedToPaused.push_back(*it);
-                it = mStarted.erase(it);
-                VLOG("Key %s started -> paused", key.toString().c_str());
-            } else {
-                ++it;
-            }
-        }
-
-        if (mStarted.empty()) {
-            mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
-                    (timestamp - mLastStartTime);
-            VLOG("record duration %lld, total duration %lld for state key %s",
-                 (long long)(timestamp - mLastStartTime), (long long)getCurrentStateKeyDuration(),
-                 mEventKey.getStateValuesKey().toString().c_str());
-            detectAndDeclareAnomaly(
-                    timestamp, mCurrentBucketNum,
-                    getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
-        }
-    }
-
-    if (!mPaused.empty()) {
-        for (auto it = mPaused.begin(); it != mPaused.end();) {
-            const auto& key = it->first;
-            if (mConditionKeyMap.find(key) == mConditionKeyMap.end()) {
-                VLOG("Key %s dont have condition key", key.toString().c_str());
-                ++it;
-                continue;
-            }
-            ConditionState conditionState =
-                mWizard->query(mConditionTrackerIndex, mConditionKeyMap[key],
-                               !mHasLinksToAllConditionDimensionsInTracker);
-            if (conditionState == ConditionState::kTrue) {
-                pausedToStarted.push_back(*it);
-                it = mPaused.erase(it);
-                VLOG("Key %s paused -> started", key.toString().c_str());
-            } else {
-                ++it;
-            }
-        }
-
-        if (mStarted.empty() && pausedToStarted.size() > 0) {
-            mLastStartTime = timestamp;
-        }
-    }
-
-    if (mStarted.empty() && !pausedToStarted.empty()) {
-        startAnomalyAlarm(timestamp);
-    }
-    mStarted.insert(pausedToStarted.begin(), pausedToStarted.end());
-    mPaused.insert(startedToPaused.begin(), startedToPaused.end());
-
-    if (mStarted.empty()) {
-        stopAnomalyAlarm(timestamp);
-    }
-}
-
-void OringDurationTracker::onConditionChanged(bool condition, const int64_t timestamp) {
-    if (condition) {
-        if (!mPaused.empty()) {
-            VLOG("Condition true, all started");
-            if (mStarted.empty()) {
-                mLastStartTime = timestamp;
-            }
-            if (mStarted.empty() && !mPaused.empty()) {
-                startAnomalyAlarm(timestamp);
-            }
-            mStarted.insert(mPaused.begin(), mPaused.end());
-            mPaused.clear();
-        }
-    } else {
-        if (!mStarted.empty()) {
-            VLOG("Condition false, all paused");
-            mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration +=
-                    (timestamp - mLastStartTime);
-            mPaused.insert(mStarted.begin(), mStarted.end());
-            mStarted.clear();
-            detectAndDeclareAnomaly(
-                    timestamp, mCurrentBucketNum,
-                    getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration());
-        }
-    }
-    if (mStarted.empty()) {
-        stopAnomalyAlarm(timestamp);
-    }
-}
-
-void OringDurationTracker::onStateChanged(const int64_t timestamp, const int32_t atomId,
-                                          const FieldValue& newState) {
-    // Nothing needs to be done on a state change if we have not seen a start
-    // event, the metric is currently not active, or condition is false.
-    // For these cases, no keys are being tracked in mStarted, so update
-    // the current state key and return.
-    if (mStarted.empty()) {
-        updateCurrentStateKey(atomId, newState);
-        return;
-    }
-    // Add the current duration length to the previous state key and then update
-    // the last start time and current state key.
-    mStateKeyDurationMap[mEventKey.getStateValuesKey()].mDuration += (timestamp - mLastStartTime);
-    mLastStartTime = timestamp;
-    updateCurrentStateKey(atomId, newState);
-}
-
-int64_t OringDurationTracker::predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
-                                                        const int64_t eventTimestampNs) const {
-    // The anomaly threshold.
-    const int64_t thresholdNs = anomalyTracker.getAnomalyThreshold();
-
-    // The timestamp of the current bucket end.
-    const int64_t currentBucketEndNs = getCurrentBucketEndTimeNs();
-
-    // The past duration ns for the current bucket of the current stateKey.
-    int64_t currentStateBucketPastNs =
-            getCurrentStateKeyDuration() + getCurrentStateKeyFullBucketDuration();
-
-    // As we move into the future, old buckets get overwritten (so their old data is erased).
-    // Sum of past durations. Will change as we overwrite old buckets.
-    int64_t pastNs = currentStateBucketPastNs + anomalyTracker.getSumOverPastBuckets(mEventKey);
-
-    // The refractory period end timestamp for dimension mEventKey.
-    const int64_t refractoryPeriodEndNs =
-            anomalyTracker.getRefractoryPeriodEndsSec(mEventKey) * NS_PER_SEC;
-
-    // The anomaly should happen when accumulated wakelock duration is above the threshold and
-    // not within the refractory period.
-    int64_t anomalyTimestampNs =
-        std::max(eventTimestampNs + thresholdNs - pastNs, refractoryPeriodEndNs);
-    // If the predicted the anomaly timestamp is within the current bucket, return it directly.
-    if (anomalyTimestampNs <= currentBucketEndNs) {
-        return std::max(eventTimestampNs, anomalyTimestampNs);
-    }
-
-    // Remove the old bucket.
-    if (anomalyTracker.getNumOfPastBuckets() > 0) {
-        pastNs -= anomalyTracker.getPastBucketValue(
-                            mEventKey,
-                            mCurrentBucketNum - anomalyTracker.getNumOfPastBuckets());
-        // Add the remaining of the current bucket to the accumulated wakelock duration.
-        pastNs += (currentBucketEndNs - eventTimestampNs);
-    } else {
-        // The anomaly depends on only one bucket.
-        pastNs = 0;
-    }
-
-    // The anomaly will not happen in the current bucket. We need to iterate over the future buckets
-    // to predict the accumulated wakelock duration and determine the anomaly timestamp accordingly.
-    for (int futureBucketIdx = 1; futureBucketIdx <= anomalyTracker.getNumOfPastBuckets() + 1;
-            futureBucketIdx++) {
-        // The alarm candidate timestamp should meet two requirements:
-        // 1. the accumulated wakelock duration is above the threshold.
-        // 2. it is not within the refractory period.
-        // 3. the alarm timestamp falls in this bucket. Otherwise we need to flush the past buckets,
-        //    find the new alarm candidate timestamp and check these requirements again.
-        const int64_t bucketEndNs = currentBucketEndNs + futureBucketIdx * mBucketSizeNs;
-        int64_t anomalyTimestampNs =
-            std::max(bucketEndNs - mBucketSizeNs + thresholdNs - pastNs, refractoryPeriodEndNs);
-        if (anomalyTimestampNs <= bucketEndNs) {
-            return anomalyTimestampNs;
-        }
-        if (anomalyTracker.getNumOfPastBuckets() <= 0) {
-            continue;
-        }
-
-        // No valid alarm timestamp is found in this bucket. The clock moves to the end of the
-        // bucket. Update the pastNs.
-        pastNs += mBucketSizeNs;
-        // 1. If the oldest past bucket is still in the past bucket window, we could fetch the past
-        // bucket and erase it from pastNs.
-        // 2. If the oldest past bucket is the current bucket, we should compute the
-        //   wakelock duration in the current bucket and erase it from pastNs.
-        // 3. Otherwise all othe past buckets are ancient.
-        if (futureBucketIdx < anomalyTracker.getNumOfPastBuckets()) {
-            pastNs -= anomalyTracker.getPastBucketValue(
-                    mEventKey,
-                    mCurrentBucketNum - anomalyTracker.getNumOfPastBuckets() + futureBucketIdx);
-        } else if (futureBucketIdx == anomalyTracker.getNumOfPastBuckets()) {
-            pastNs -= (currentStateBucketPastNs + (currentBucketEndNs - eventTimestampNs));
-        }
-    }
-
-    return std::max(eventTimestampNs + thresholdNs, refractoryPeriodEndNs);
-}
-
-void OringDurationTracker::dumpStates(FILE* out, bool verbose) const {
-    fprintf(out, "\t\t started count %lu\n", (unsigned long)mStarted.size());
-    fprintf(out, "\t\t paused count %lu\n", (unsigned long)mPaused.size());
-    fprintf(out, "\t\t current duration %lld\n", (long long)getCurrentStateKeyDuration());
-}
-
-int64_t OringDurationTracker::getCurrentStateKeyDuration() const {
-    auto it = mStateKeyDurationMap.find(mEventKey.getStateValuesKey());
-    if (it == mStateKeyDurationMap.end()) {
-        return 0;
-    } else {
-        return it->second.mDuration;
-    }
-}
-
-int64_t OringDurationTracker::getCurrentStateKeyFullBucketDuration() const {
-    auto it = mStateKeyDurationMap.find(mEventKey.getStateValuesKey());
-    if (it == mStateKeyDurationMap.end()) {
-        return 0;
-    } else {
-        return it->second.mDurationFullBucket;
-    }
-}
-
-void OringDurationTracker::updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) {
-    HashableDimensionKey* stateValuesKey = mEventKey.getMutableStateValuesKey();
-    for (size_t i = 0; i < stateValuesKey->getValues().size(); i++) {
-        if (stateValuesKey->getValues()[i].mField.getTag() == atomId) {
-            stateValuesKey->mutableValue(i)->mValue = newState.mValue;
-        }
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
deleted file mode 100644
index 6eddee7..0000000
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ORING_DURATION_TRACKER_H
-#define ORING_DURATION_TRACKER_H
-
-#include "DurationTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Tracks the "Or'd" duration -- if 2 durations are overlapping, they won't be double counted.
-class OringDurationTracker : public DurationTracker {
-public:
-    OringDurationTracker(const ConfigKey& key, const int64_t& id,
-                         const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard,
-                         int conditionIndex, bool nesting, int64_t currentBucketStartNs,
-                         int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs,
-                         bool conditionSliced, bool fullLink,
-                         const std::vector<sp<AnomalyTracker>>& anomalyTrackers);
-
-    OringDurationTracker(const OringDurationTracker& tracker) = default;
-
-    void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
-                   const ConditionKey& conditionKey) override;
-    void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
-                  const bool stopAll) override;
-    void noteStopAll(const int64_t eventTime) override;
-
-    void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
-    void onConditionChanged(bool condition, const int64_t timestamp) override;
-
-    void onStateChanged(const int64_t timestamp, const int32_t atomId,
-                        const FieldValue& newState) override;
-
-    bool flushCurrentBucket(
-            const int64_t& eventTimeNs,
-            std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
-    bool flushIfNeeded(
-            int64_t timestampNs,
-            std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
-
-    int64_t predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
-                                      const int64_t currentTimestamp) const override;
-    void dumpStates(FILE* out, bool verbose) const override;
-
-    int64_t getCurrentStateKeyDuration() const override;
-
-    int64_t getCurrentStateKeyFullBucketDuration() const override;
-
-    void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState);
-
-private:
-    // We don't need to keep track of individual durations. The information that's needed is:
-    // 1) which keys are started. We record the first start time.
-    // 2) which keys are paused (started but condition was false)
-    // 3) whenever a key stops, we remove it from the started set. And if the set becomes empty,
-    //    it means everything has stopped, we then record the end time.
-    std::unordered_map<HashableDimensionKey, int> mStarted;
-    std::unordered_map<HashableDimensionKey, int> mPaused;
-    int64_t mLastStartTime;
-    std::unordered_map<HashableDimensionKey, ConditionKey> mConditionKeyMap;
-
-    // return true if we should not allow newKey to be tracked because we are above the threshold
-    bool hitGuardRail(const HashableDimensionKey& newKey);
-
-    FRIEND_TEST(OringDurationTrackerTest, TestDurationOverlap);
-    FRIEND_TEST(OringDurationTrackerTest, TestCrossBucketBoundary);
-    FRIEND_TEST(OringDurationTrackerTest, TestDurationConditionChange);
-    FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
-    FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
-    FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // ORING_DURATION_TRACKER_H
diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
deleted file mode 100644
index 39789cd..0000000
--- a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
+++ /dev/null
@@ -1,1118 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "config_update_utils.h"
-
-#include "external/StatsPullerManager.h"
-#include "hash.h"
-#include "matchers/EventMatcherWizard.h"
-#include "metrics_manager_util.h"
-
-using google::protobuf::MessageLite;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Recursive function to determine if a matcher needs to be updated. Populates matcherToUpdate.
-// Returns whether the function was successful or not.
-bool determineMatcherUpdateStatus(const StatsdConfig& config, const int matcherIdx,
-                                  const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-                                  const vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
-                                  const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-                                  vector<UpdateStatus>& matchersToUpdate,
-                                  vector<bool>& cycleTracker) {
-    // Have already examined this matcher.
-    if (matchersToUpdate[matcherIdx] != UPDATE_UNKNOWN) {
-        return true;
-    }
-
-    const AtomMatcher& matcher = config.atom_matcher(matcherIdx);
-    int64_t id = matcher.id();
-    // Check if new matcher.
-    const auto& oldAtomMatchingTrackerIt = oldAtomMatchingTrackerMap.find(id);
-    if (oldAtomMatchingTrackerIt == oldAtomMatchingTrackerMap.end()) {
-        matchersToUpdate[matcherIdx] = UPDATE_NEW;
-        return true;
-    }
-
-    // This is an existing matcher. Check if it has changed.
-    string serializedMatcher;
-    if (!matcher.SerializeToString(&serializedMatcher)) {
-        ALOGE("Unable to serialize matcher %lld", (long long)id);
-        return false;
-    }
-    uint64_t newProtoHash = Hash64(serializedMatcher);
-    if (newProtoHash != oldAtomMatchingTrackers[oldAtomMatchingTrackerIt->second]->getProtoHash()) {
-        matchersToUpdate[matcherIdx] = UPDATE_REPLACE;
-        return true;
-    }
-
-    switch (matcher.contents_case()) {
-        case AtomMatcher::ContentsCase::kSimpleAtomMatcher: {
-            matchersToUpdate[matcherIdx] = UPDATE_PRESERVE;
-            return true;
-        }
-        case AtomMatcher::ContentsCase::kCombination: {
-            // Recurse to check if children have changed.
-            cycleTracker[matcherIdx] = true;
-            UpdateStatus status = UPDATE_PRESERVE;
-            for (const int64_t childMatcherId : matcher.combination().matcher()) {
-                const auto& childIt = newAtomMatchingTrackerMap.find(childMatcherId);
-                if (childIt == newAtomMatchingTrackerMap.end()) {
-                    ALOGW("Matcher %lld not found in the config", (long long)childMatcherId);
-                    return false;
-                }
-                const int childIdx = childIt->second;
-                if (cycleTracker[childIdx]) {
-                    ALOGE("Cycle detected in matcher config");
-                    return false;
-                }
-                if (!determineMatcherUpdateStatus(
-                            config, childIdx, oldAtomMatchingTrackerMap, oldAtomMatchingTrackers,
-                            newAtomMatchingTrackerMap, matchersToUpdate, cycleTracker)) {
-                    return false;
-                }
-
-                if (matchersToUpdate[childIdx] == UPDATE_REPLACE) {
-                    status = UPDATE_REPLACE;
-                    break;
-                }
-            }
-            matchersToUpdate[matcherIdx] = status;
-            cycleTracker[matcherIdx] = false;
-            return true;
-        }
-        default: {
-            ALOGE("Matcher \"%lld\" malformed", (long long)id);
-            return false;
-        }
-    }
-    return true;
-}
-
-bool updateAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
-                                const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-                                const vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
-                                set<int>& allTagIds,
-                                unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-                                vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
-                                set<int64_t>& replacedMatchers) {
-    const int atomMatcherCount = config.atom_matcher_size();
-    vector<AtomMatcher> matcherProtos;
-    matcherProtos.reserve(atomMatcherCount);
-    newAtomMatchingTrackers.reserve(atomMatcherCount);
-
-    // Maps matcher id to their position in the config. For fast lookup of dependencies.
-    for (int i = 0; i < atomMatcherCount; i++) {
-        const AtomMatcher& matcher = config.atom_matcher(i);
-        if (newAtomMatchingTrackerMap.find(matcher.id()) != newAtomMatchingTrackerMap.end()) {
-            ALOGE("Duplicate atom matcher found for id %lld", (long long)matcher.id());
-            return false;
-        }
-        newAtomMatchingTrackerMap[matcher.id()] = i;
-        matcherProtos.push_back(matcher);
-    }
-
-    // For combination matchers, we need to determine if any children need to be updated.
-    vector<UpdateStatus> matchersToUpdate(atomMatcherCount, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(atomMatcherCount, false);
-    for (int i = 0; i < atomMatcherCount; i++) {
-        if (!determineMatcherUpdateStatus(config, i, oldAtomMatchingTrackerMap,
-                                          oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                          matchersToUpdate, cycleTracker)) {
-            return false;
-        }
-    }
-
-    for (int i = 0; i < atomMatcherCount; i++) {
-        const AtomMatcher& matcher = config.atom_matcher(i);
-        const int64_t id = matcher.id();
-        switch (matchersToUpdate[i]) {
-            case UPDATE_PRESERVE: {
-                const auto& oldAtomMatchingTrackerIt = oldAtomMatchingTrackerMap.find(id);
-                if (oldAtomMatchingTrackerIt == oldAtomMatchingTrackerMap.end()) {
-                    ALOGE("Could not find AtomMatcher %lld in the previous config, but expected it "
-                          "to be there",
-                          (long long)id);
-                    return false;
-                }
-                const sp<AtomMatchingTracker>& tracker =
-                        oldAtomMatchingTrackers[oldAtomMatchingTrackerIt->second];
-                if (!tracker->onConfigUpdated(matcherProtos[i], i, newAtomMatchingTrackerMap)) {
-                    ALOGW("Config update failed for matcher %lld", (long long)id);
-                    return false;
-                }
-                newAtomMatchingTrackers.push_back(tracker);
-                break;
-            }
-            case UPDATE_REPLACE:
-                replacedMatchers.insert(id);
-                [[fallthrough]];  // Intentionally fallthrough to create the new matcher.
-            case UPDATE_NEW: {
-                sp<AtomMatchingTracker> tracker = createAtomMatchingTracker(matcher, i, uidMap);
-                if (tracker == nullptr) {
-                    return false;
-                }
-                newAtomMatchingTrackers.push_back(tracker);
-                break;
-            }
-            default: {
-                ALOGE("Matcher \"%lld\" update state is unknown. This should never happen",
-                      (long long)id);
-                return false;
-            }
-        }
-    }
-
-    std::fill(cycleTracker.begin(), cycleTracker.end(), false);
-    for (auto& matcher : newAtomMatchingTrackers) {
-        if (!matcher->init(matcherProtos, newAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                           cycleTracker)) {
-            return false;
-        }
-        // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
-        const set<int>& tagIds = matcher->getAtomIds();
-        allTagIds.insert(tagIds.begin(), tagIds.end());
-    }
-
-    return true;
-}
-
-// Recursive function to determine if a condition needs to be updated. Populates conditionsToUpdate.
-// Returns whether the function was successful or not.
-bool determineConditionUpdateStatus(const StatsdConfig& config, const int conditionIdx,
-                                    const unordered_map<int64_t, int>& oldConditionTrackerMap,
-                                    const vector<sp<ConditionTracker>>& oldConditionTrackers,
-                                    const unordered_map<int64_t, int>& newConditionTrackerMap,
-                                    const set<int64_t>& replacedMatchers,
-                                    vector<UpdateStatus>& conditionsToUpdate,
-                                    vector<bool>& cycleTracker) {
-    // Have already examined this condition.
-    if (conditionsToUpdate[conditionIdx] != UPDATE_UNKNOWN) {
-        return true;
-    }
-
-    const Predicate& predicate = config.predicate(conditionIdx);
-    int64_t id = predicate.id();
-    // Check if new condition.
-    const auto& oldConditionTrackerIt = oldConditionTrackerMap.find(id);
-    if (oldConditionTrackerIt == oldConditionTrackerMap.end()) {
-        conditionsToUpdate[conditionIdx] = UPDATE_NEW;
-        return true;
-    }
-
-    // This is an existing condition. Check if it has changed.
-    string serializedCondition;
-    if (!predicate.SerializeToString(&serializedCondition)) {
-        ALOGE("Unable to serialize matcher %lld", (long long)id);
-        return false;
-    }
-    uint64_t newProtoHash = Hash64(serializedCondition);
-    if (newProtoHash != oldConditionTrackers[oldConditionTrackerIt->second]->getProtoHash()) {
-        conditionsToUpdate[conditionIdx] = UPDATE_REPLACE;
-        return true;
-    }
-
-    switch (predicate.contents_case()) {
-        case Predicate::ContentsCase::kSimplePredicate: {
-            // Need to check if any of the underlying matchers changed.
-            const SimplePredicate& simplePredicate = predicate.simple_predicate();
-            if (simplePredicate.has_start()) {
-                if (replacedMatchers.find(simplePredicate.start()) != replacedMatchers.end()) {
-                    conditionsToUpdate[conditionIdx] = UPDATE_REPLACE;
-                    return true;
-                }
-            }
-            if (simplePredicate.has_stop()) {
-                if (replacedMatchers.find(simplePredicate.stop()) != replacedMatchers.end()) {
-                    conditionsToUpdate[conditionIdx] = UPDATE_REPLACE;
-                    return true;
-                }
-            }
-            if (simplePredicate.has_stop_all()) {
-                if (replacedMatchers.find(simplePredicate.stop_all()) != replacedMatchers.end()) {
-                    conditionsToUpdate[conditionIdx] = UPDATE_REPLACE;
-                    return true;
-                }
-            }
-            conditionsToUpdate[conditionIdx] = UPDATE_PRESERVE;
-            return true;
-        }
-        case Predicate::ContentsCase::kCombination: {
-            // Need to recurse on the children to see if any of the child predicates changed.
-            cycleTracker[conditionIdx] = true;
-            UpdateStatus status = UPDATE_PRESERVE;
-            for (const int64_t childPredicateId : predicate.combination().predicate()) {
-                const auto& childIt = newConditionTrackerMap.find(childPredicateId);
-                if (childIt == newConditionTrackerMap.end()) {
-                    ALOGW("Predicate %lld not found in the config", (long long)childPredicateId);
-                    return false;
-                }
-                const int childIdx = childIt->second;
-                if (cycleTracker[childIdx]) {
-                    ALOGE("Cycle detected in predicate config");
-                    return false;
-                }
-                if (!determineConditionUpdateStatus(config, childIdx, oldConditionTrackerMap,
-                                                    oldConditionTrackers, newConditionTrackerMap,
-                                                    replacedMatchers, conditionsToUpdate,
-                                                    cycleTracker)) {
-                    return false;
-                }
-
-                if (conditionsToUpdate[childIdx] == UPDATE_REPLACE) {
-                    status = UPDATE_REPLACE;
-                    break;
-                }
-            }
-            conditionsToUpdate[conditionIdx] = status;
-            cycleTracker[conditionIdx] = false;
-            return true;
-        }
-        default: {
-            ALOGE("Predicate \"%lld\" malformed", (long long)id);
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool updateConditions(const ConfigKey& key, const StatsdConfig& config,
-                      const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                      const set<int64_t>& replacedMatchers,
-                      const unordered_map<int64_t, int>& oldConditionTrackerMap,
-                      const vector<sp<ConditionTracker>>& oldConditionTrackers,
-                      unordered_map<int64_t, int>& newConditionTrackerMap,
-                      vector<sp<ConditionTracker>>& newConditionTrackers,
-                      unordered_map<int, vector<int>>& trackerToConditionMap,
-                      vector<ConditionState>& conditionCache, set<int64_t>& replacedConditions) {
-    vector<Predicate> conditionProtos;
-    const int conditionTrackerCount = config.predicate_size();
-    conditionProtos.reserve(conditionTrackerCount);
-    newConditionTrackers.reserve(conditionTrackerCount);
-    conditionCache.assign(conditionTrackerCount, ConditionState::kNotEvaluated);
-
-    for (int i = 0; i < conditionTrackerCount; i++) {
-        const Predicate& condition = config.predicate(i);
-        if (newConditionTrackerMap.find(condition.id()) != newConditionTrackerMap.end()) {
-            ALOGE("Duplicate Predicate found!");
-            return false;
-        }
-        newConditionTrackerMap[condition.id()] = i;
-        conditionProtos.push_back(condition);
-    }
-
-    vector<UpdateStatus> conditionsToUpdate(conditionTrackerCount, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(conditionTrackerCount, false);
-    for (int i = 0; i < conditionTrackerCount; i++) {
-        if (!determineConditionUpdateStatus(config, i, oldConditionTrackerMap, oldConditionTrackers,
-                                            newConditionTrackerMap, replacedMatchers,
-                                            conditionsToUpdate, cycleTracker)) {
-            return false;
-        }
-    }
-
-    // Update status has been determined for all conditions. Now perform the update.
-    set<int> preservedConditions;
-    for (int i = 0; i < conditionTrackerCount; i++) {
-        const Predicate& predicate = config.predicate(i);
-        const int64_t id = predicate.id();
-        switch (conditionsToUpdate[i]) {
-            case UPDATE_PRESERVE: {
-                preservedConditions.insert(i);
-                const auto& oldConditionTrackerIt = oldConditionTrackerMap.find(id);
-                if (oldConditionTrackerIt == oldConditionTrackerMap.end()) {
-                    ALOGE("Could not find Predicate %lld in the previous config, but expected it "
-                          "to be there",
-                          (long long)id);
-                    return false;
-                }
-                const int oldIndex = oldConditionTrackerIt->second;
-                newConditionTrackers.push_back(oldConditionTrackers[oldIndex]);
-                break;
-            }
-            case UPDATE_REPLACE:
-                replacedConditions.insert(id);
-                [[fallthrough]];  // Intentionally fallthrough to create the new condition tracker.
-            case UPDATE_NEW: {
-                sp<ConditionTracker> tracker =
-                        createConditionTracker(key, predicate, i, atomMatchingTrackerMap);
-                if (tracker == nullptr) {
-                    return false;
-                }
-                newConditionTrackers.push_back(tracker);
-                break;
-            }
-            default: {
-                ALOGE("Condition \"%lld\" update state is unknown. This should never happen",
-                      (long long)id);
-                return false;
-            }
-        }
-    }
-
-    // Update indices of preserved predicates.
-    for (const int conditionIndex : preservedConditions) {
-        if (!newConditionTrackers[conditionIndex]->onConfigUpdated(
-                    conditionProtos, conditionIndex, newConditionTrackers, atomMatchingTrackerMap,
-                    newConditionTrackerMap)) {
-            ALOGE("Failed to update condition %lld",
-                  (long long)newConditionTrackers[conditionIndex]->getConditionId());
-            return false;
-        }
-    }
-
-    std::fill(cycleTracker.begin(), cycleTracker.end(), false);
-    for (int conditionIndex = 0; conditionIndex < conditionTrackerCount; conditionIndex++) {
-        const sp<ConditionTracker>& conditionTracker = newConditionTrackers[conditionIndex];
-        // Calling init on preserved conditions is OK. It is needed to fill the condition cache.
-        if (!conditionTracker->init(conditionProtos, newConditionTrackers, newConditionTrackerMap,
-                                    cycleTracker, conditionCache)) {
-            return false;
-        }
-        for (const int trackerIndex : conditionTracker->getAtomMatchingTrackerIndex()) {
-            vector<int>& conditionList = trackerToConditionMap[trackerIndex];
-            conditionList.push_back(conditionIndex);
-        }
-    }
-    return true;
-}
-
-bool updateStates(const StatsdConfig& config, const map<int64_t, uint64_t>& oldStateProtoHashes,
-                  unordered_map<int64_t, int>& stateAtomIdMap,
-                  unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-                  map<int64_t, uint64_t>& newStateProtoHashes, set<int64_t>& replacedStates) {
-    // Share with metrics_manager_util.
-    if (!initStates(config, stateAtomIdMap, allStateGroupMaps, newStateProtoHashes)) {
-        return false;
-    }
-
-    for (const auto& [stateId, stateHash] : oldStateProtoHashes) {
-        const auto& it = newStateProtoHashes.find(stateId);
-        if (it != newStateProtoHashes.end() && it->second != stateHash) {
-            replacedStates.insert(stateId);
-        }
-    }
-    return true;
-}
-// Returns true if any matchers in the metric activation were replaced.
-bool metricActivationDepsChange(const StatsdConfig& config,
-                                const unordered_map<int64_t, int>& metricToActivationMap,
-                                const int64_t metricId, const set<int64_t>& replacedMatchers) {
-    const auto& metricActivationIt = metricToActivationMap.find(metricId);
-    if (metricActivationIt == metricToActivationMap.end()) {
-        return false;
-    }
-    const MetricActivation& metricActivation = config.metric_activation(metricActivationIt->second);
-    for (int i = 0; i < metricActivation.event_activation_size(); i++) {
-        const EventActivation& activation = metricActivation.event_activation(i);
-        if (replacedMatchers.find(activation.atom_matcher_id()) != replacedMatchers.end()) {
-            return true;
-        }
-        if (activation.has_deactivation_atom_matcher_id()) {
-            if (replacedMatchers.find(activation.deactivation_atom_matcher_id()) !=
-                replacedMatchers.end()) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-bool determineMetricUpdateStatus(
-        const StatsdConfig& config, const MessageLite& metric, const int64_t metricId,
-        const MetricType metricType, const set<int64_t>& matcherDependencies,
-        const set<int64_t>& conditionDependencies,
-        const ::google::protobuf::RepeatedField<int64_t>& stateDependencies,
-        const ::google::protobuf::RepeatedPtrField<MetricConditionLink>& conditionLinks,
-        const unordered_map<int64_t, int>& oldMetricProducerMap,
-        const vector<sp<MetricProducer>>& oldMetricProducers,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        const set<int64_t>& replacedMatchers, const set<int64_t>& replacedConditions,
-        const set<int64_t>& replacedStates, UpdateStatus& updateStatus) {
-    // Check if new metric
-    const auto& oldMetricProducerIt = oldMetricProducerMap.find(metricId);
-    if (oldMetricProducerIt == oldMetricProducerMap.end()) {
-        updateStatus = UPDATE_NEW;
-        return true;
-    }
-
-    // This is an existing metric, check if it has changed.
-    uint64_t metricHash;
-    if (!getMetricProtoHash(config, metric, metricId, metricToActivationMap, metricHash)) {
-        return false;
-    }
-    const sp<MetricProducer> oldMetricProducer = oldMetricProducers[oldMetricProducerIt->second];
-    if (oldMetricProducer->getMetricType() != metricType ||
-        oldMetricProducer->getProtoHash() != metricHash) {
-        updateStatus = UPDATE_REPLACE;
-        return true;
-    }
-
-    // Take intersections of the matchers/predicates/states that the metric
-    // depends on with those that have been replaced. If a metric depends on any
-    // replaced component, it too must be replaced.
-    set<int64_t> intersection;
-    set_intersection(matcherDependencies.begin(), matcherDependencies.end(),
-                     replacedMatchers.begin(), replacedMatchers.end(),
-                     inserter(intersection, intersection.begin()));
-    if (intersection.size() > 0) {
-        updateStatus = UPDATE_REPLACE;
-        return true;
-    }
-    set_intersection(conditionDependencies.begin(), conditionDependencies.end(),
-                     replacedConditions.begin(), replacedConditions.end(),
-                     inserter(intersection, intersection.begin()));
-    if (intersection.size() > 0) {
-        updateStatus = UPDATE_REPLACE;
-        return true;
-    }
-    set_intersection(stateDependencies.begin(), stateDependencies.end(), replacedStates.begin(),
-                     replacedStates.end(), inserter(intersection, intersection.begin()));
-    if (intersection.size() > 0) {
-        updateStatus = UPDATE_REPLACE;
-        return true;
-    }
-
-    for (const auto& metricConditionLink : conditionLinks) {
-        if (replacedConditions.find(metricConditionLink.condition()) != replacedConditions.end()) {
-            updateStatus = UPDATE_REPLACE;
-            return true;
-        }
-    }
-
-    if (metricActivationDepsChange(config, metricToActivationMap, metricId, replacedMatchers)) {
-        updateStatus = UPDATE_REPLACE;
-        return true;
-    }
-
-    updateStatus = UPDATE_PRESERVE;
-    return true;
-}
-
-bool determineAllMetricUpdateStatuses(const StatsdConfig& config,
-                                      const unordered_map<int64_t, int>& oldMetricProducerMap,
-                                      const vector<sp<MetricProducer>>& oldMetricProducers,
-                                      const unordered_map<int64_t, int>& metricToActivationMap,
-                                      const set<int64_t>& replacedMatchers,
-                                      const set<int64_t>& replacedConditions,
-                                      const set<int64_t>& replacedStates,
-                                      vector<UpdateStatus>& metricsToUpdate) {
-    int metricIndex = 0;
-    for (int i = 0; i < config.count_metric_size(); i++, metricIndex++) {
-        const CountMetric& metric = config.count_metric(i);
-        set<int64_t> conditionDependencies;
-        if (metric.has_condition()) {
-            conditionDependencies.insert(metric.condition());
-        }
-        if (!determineMetricUpdateStatus(
-                    config, metric, metric.id(), METRIC_TYPE_COUNT, {metric.what()},
-                    conditionDependencies, metric.slice_by_state(), metric.links(),
-                    oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-                    replacedMatchers, replacedConditions, replacedStates,
-                    metricsToUpdate[metricIndex])) {
-            return false;
-        }
-    }
-    for (int i = 0; i < config.duration_metric_size(); i++, metricIndex++) {
-        const DurationMetric& metric = config.duration_metric(i);
-        set<int64_t> conditionDependencies({metric.what()});
-        if (metric.has_condition()) {
-            conditionDependencies.insert(metric.condition());
-        }
-        if (!determineMetricUpdateStatus(
-                    config, metric, metric.id(), METRIC_TYPE_DURATION, /*matcherDependencies=*/{},
-                    conditionDependencies, metric.slice_by_state(), metric.links(),
-                    oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-                    replacedMatchers, replacedConditions, replacedStates,
-                    metricsToUpdate[metricIndex])) {
-            return false;
-        }
-    }
-    for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) {
-        const EventMetric& metric = config.event_metric(i);
-        set<int64_t> conditionDependencies;
-        if (metric.has_condition()) {
-            conditionDependencies.insert(metric.condition());
-        }
-        if (!determineMetricUpdateStatus(
-                    config, metric, metric.id(), METRIC_TYPE_EVENT, {metric.what()},
-                    conditionDependencies, ::google::protobuf::RepeatedField<int64_t>(),
-                    metric.links(), oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-                    replacedMatchers, replacedConditions, replacedStates,
-                    metricsToUpdate[metricIndex])) {
-            return false;
-        }
-    }
-    for (int i = 0; i < config.value_metric_size(); i++, metricIndex++) {
-        const ValueMetric& metric = config.value_metric(i);
-        set<int64_t> conditionDependencies;
-        if (metric.has_condition()) {
-            conditionDependencies.insert(metric.condition());
-        }
-        if (!determineMetricUpdateStatus(
-                    config, metric, metric.id(), METRIC_TYPE_VALUE, {metric.what()},
-                    conditionDependencies, metric.slice_by_state(), metric.links(),
-                    oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-                    replacedMatchers, replacedConditions, replacedStates,
-                    metricsToUpdate[metricIndex])) {
-            return false;
-        }
-    }
-    for (int i = 0; i < config.gauge_metric_size(); i++, metricIndex++) {
-        const GaugeMetric& metric = config.gauge_metric(i);
-        set<int64_t> conditionDependencies;
-        if (metric.has_condition()) {
-            conditionDependencies.insert(metric.condition());
-        }
-        set<int64_t> matcherDependencies({metric.what()});
-        if (metric.has_trigger_event()) {
-            matcherDependencies.insert(metric.trigger_event());
-        }
-        if (!determineMetricUpdateStatus(
-                    config, metric, metric.id(), METRIC_TYPE_GAUGE, matcherDependencies,
-                    conditionDependencies, ::google::protobuf::RepeatedField<int64_t>(),
-                    metric.links(), oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-                    replacedMatchers, replacedConditions, replacedStates,
-                    metricsToUpdate[metricIndex])) {
-            return false;
-        }
-    }
-    return true;
-}
-
-// Called when a metric is preserved during a config update. Finds the metric in oldMetricProducers
-// and calls onConfigUpdated to update all indices.
-optional<sp<MetricProducer>> updateMetric(
-        const StatsdConfig& config, const int configIndex, const int metricIndex,
-        const int64_t metricId, const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& oldMetricProducerMap,
-        const vector<sp<MetricProducer>>& oldMetricProducers,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    const auto& oldMetricProducerIt = oldMetricProducerMap.find(metricId);
-    if (oldMetricProducerIt == oldMetricProducerMap.end()) {
-        ALOGE("Could not find Metric %lld in the previous config, but expected it "
-              "to be there",
-              (long long)metricId);
-        return nullopt;
-    }
-    const int oldIndex = oldMetricProducerIt->second;
-    sp<MetricProducer> producer = oldMetricProducers[oldIndex];
-    if (!producer->onConfigUpdated(config, configIndex, metricIndex, allAtomMatchingTrackers,
-                                   oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap,
-                                   matcherWizard, allConditionTrackers, conditionTrackerMap, wizard,
-                                   metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
-                                   activationAtomTrackerToMetricMap,
-                                   deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
-        return nullopt;
-    }
-    return {producer};
-}
-
-bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-                   const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
-                   const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-                   const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-                   const set<int64_t>& replacedMatchers,
-                   const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                   const unordered_map<int64_t, int>& conditionTrackerMap,
-                   const set<int64_t>& replacedConditions,
-                   vector<sp<ConditionTracker>>& allConditionTrackers,
-                   const vector<ConditionState>& initialConditionCache,
-                   const unordered_map<int64_t, int>& stateAtomIdMap,
-                   const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-                   const set<int64_t>& replacedStates,
-                   const unordered_map<int64_t, int>& oldMetricProducerMap,
-                   const vector<sp<MetricProducer>>& oldMetricProducers,
-                   unordered_map<int64_t, int>& newMetricProducerMap,
-                   vector<sp<MetricProducer>>& newMetricProducers,
-                   unordered_map<int, vector<int>>& conditionToMetricMap,
-                   unordered_map<int, vector<int>>& trackerToMetricMap,
-                   set<int64_t>& noReportMetricIds,
-                   unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-                   unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-                   vector<int>& metricsWithActivation, set<int64_t>& replacedMetrics) {
-    sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
-    sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchingTrackers);
-    const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
-                                config.event_metric_size() + config.gauge_metric_size() +
-                                config.value_metric_size();
-    newMetricProducers.reserve(allMetricsCount);
-
-    // Construct map from metric id to metric activation index. The map will be used to determine
-    // the metric activation corresponding to a metric.
-    unordered_map<int64_t, int> metricToActivationMap;
-    for (int i = 0; i < config.metric_activation_size(); i++) {
-        const MetricActivation& metricActivation = config.metric_activation(i);
-        int64_t metricId = metricActivation.metric_id();
-        if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
-            ALOGE("Metric %lld has multiple MetricActivations", (long long)metricId);
-            return false;
-        }
-        metricToActivationMap.insert({metricId, i});
-    }
-
-    vector<UpdateStatus> metricsToUpdate(allMetricsCount, UPDATE_UNKNOWN);
-    if (!determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                          metricToActivationMap, replacedMatchers,
-                                          replacedConditions, replacedStates, metricsToUpdate)) {
-        return false;
-    }
-
-    // Now, perform the update. Must iterate the metric types in the same order
-    int metricIndex = 0;
-    for (int i = 0; i < config.count_metric_size(); i++, metricIndex++) {
-        const CountMetric& metric = config.count_metric(i);
-        newMetricProducerMap[metric.id()] = metricIndex;
-        optional<sp<MetricProducer>> producer;
-        switch (metricsToUpdate[metricIndex]) {
-            case UPDATE_PRESERVE: {
-                producer = updateMetric(
-                        config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
-                        oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                        allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
-                        oldMetricProducers, metricToActivationMap, trackerToMetricMap,
-                        conditionToMetricMap, activationAtomTrackerToMetricMap,
-                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
-                break;
-            }
-            case UPDATE_REPLACE:
-                replacedMetrics.insert(metric.id());
-                [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
-            case UPDATE_NEW: {
-                producer = createCountMetricProducerAndUpdateMetadata(
-                        key, config, timeBaseNs, currentTimeNs, metric, metricIndex,
-                        allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
-                        conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
-                        allStateGroupMaps, metricToActivationMap, trackerToMetricMap,
-                        conditionToMetricMap, activationAtomTrackerToMetricMap,
-                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
-                break;
-            }
-            default: {
-                ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
-                      (long long)metric.id());
-                return false;
-            }
-        }
-        if (!producer) {
-            return false;
-        }
-        newMetricProducers.push_back(producer.value());
-    }
-    for (int i = 0; i < config.duration_metric_size(); i++, metricIndex++) {
-        const DurationMetric& metric = config.duration_metric(i);
-        newMetricProducerMap[metric.id()] = metricIndex;
-        optional<sp<MetricProducer>> producer;
-        switch (metricsToUpdate[metricIndex]) {
-            case UPDATE_PRESERVE: {
-                producer = updateMetric(
-                        config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
-                        oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                        allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
-                        oldMetricProducers, metricToActivationMap, trackerToMetricMap,
-                        conditionToMetricMap, activationAtomTrackerToMetricMap,
-                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
-                break;
-            }
-            case UPDATE_REPLACE:
-                replacedMetrics.insert(metric.id());
-                [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
-            case UPDATE_NEW: {
-                producer = createDurationMetricProducerAndUpdateMetadata(
-                        key, config, timeBaseNs, currentTimeNs, metric, metricIndex,
-                        allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
-                        conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
-                        allStateGroupMaps, metricToActivationMap, trackerToMetricMap,
-                        conditionToMetricMap, activationAtomTrackerToMetricMap,
-                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
-                break;
-            }
-            default: {
-                ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
-                      (long long)metric.id());
-                return false;
-            }
-        }
-        if (!producer) {
-            return false;
-        }
-        newMetricProducers.push_back(producer.value());
-    }
-    for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) {
-        const EventMetric& metric = config.event_metric(i);
-        newMetricProducerMap[metric.id()] = metricIndex;
-        optional<sp<MetricProducer>> producer;
-        switch (metricsToUpdate[metricIndex]) {
-            case UPDATE_PRESERVE: {
-                producer = updateMetric(
-                        config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
-                        oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                        allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
-                        oldMetricProducers, metricToActivationMap, trackerToMetricMap,
-                        conditionToMetricMap, activationAtomTrackerToMetricMap,
-                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
-                break;
-            }
-            case UPDATE_REPLACE:
-                replacedMetrics.insert(metric.id());
-                [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
-            case UPDATE_NEW: {
-                producer = createEventMetricProducerAndUpdateMetadata(
-                        key, config, timeBaseNs, metric, metricIndex, allAtomMatchingTrackers,
-                        newAtomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap,
-                        initialConditionCache, wizard, metricToActivationMap, trackerToMetricMap,
-                        conditionToMetricMap, activationAtomTrackerToMetricMap,
-                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
-                break;
-            }
-            default: {
-                ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
-                      (long long)metric.id());
-                return false;
-            }
-        }
-        if (!producer) {
-            return false;
-        }
-        newMetricProducers.push_back(producer.value());
-    }
-
-    for (int i = 0; i < config.value_metric_size(); i++, metricIndex++) {
-        const ValueMetric& metric = config.value_metric(i);
-        newMetricProducerMap[metric.id()] = metricIndex;
-        optional<sp<MetricProducer>> producer;
-        switch (metricsToUpdate[metricIndex]) {
-            case UPDATE_PRESERVE: {
-                producer = updateMetric(
-                        config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
-                        oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                        allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
-                        oldMetricProducers, metricToActivationMap, trackerToMetricMap,
-                        conditionToMetricMap, activationAtomTrackerToMetricMap,
-                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
-                break;
-            }
-            case UPDATE_REPLACE:
-                replacedMetrics.insert(metric.id());
-                [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
-            case UPDATE_NEW: {
-                producer = createValueMetricProducerAndUpdateMetadata(
-                        key, config, timeBaseNs, currentTimeNs, pullerManager, metric, metricIndex,
-                        allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
-                        conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
-                        stateAtomIdMap, allStateGroupMaps, metricToActivationMap,
-                        trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
-                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
-                break;
-            }
-            default: {
-                ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
-                      (long long)metric.id());
-                return false;
-            }
-        }
-        if (!producer) {
-            return false;
-        }
-        newMetricProducers.push_back(producer.value());
-    }
-
-    for (int i = 0; i < config.gauge_metric_size(); i++, metricIndex++) {
-        const GaugeMetric& metric = config.gauge_metric(i);
-        newMetricProducerMap[metric.id()] = metricIndex;
-        optional<sp<MetricProducer>> producer;
-        switch (metricsToUpdate[metricIndex]) {
-            case UPDATE_PRESERVE: {
-                producer = updateMetric(
-                        config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
-                        oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
-                        allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
-                        oldMetricProducers, metricToActivationMap, trackerToMetricMap,
-                        conditionToMetricMap, activationAtomTrackerToMetricMap,
-                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
-                break;
-            }
-            case UPDATE_REPLACE:
-                replacedMetrics.insert(metric.id());
-                [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
-            case UPDATE_NEW: {
-                producer = createGaugeMetricProducerAndUpdateMetadata(
-                        key, config, timeBaseNs, currentTimeNs, pullerManager, metric, metricIndex,
-                        allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
-                        conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
-                        metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
-                        activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                        metricsWithActivation);
-                break;
-            }
-            default: {
-                ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
-                      (long long)metric.id());
-                return false;
-            }
-        }
-        if (!producer) {
-            return false;
-        }
-        newMetricProducers.push_back(producer.value());
-    }
-
-    for (int i = 0; i < config.no_report_metric_size(); ++i) {
-        const int64_t noReportMetric = config.no_report_metric(i);
-        if (newMetricProducerMap.find(noReportMetric) == newMetricProducerMap.end()) {
-            ALOGW("no_report_metric %" PRId64 " not exist", noReportMetric);
-            return false;
-        }
-        noReportMetricIds.insert(noReportMetric);
-    }
-    const set<int> atomsAllowedFromAnyUid(config.whitelisted_atom_ids().begin(),
-                                          config.whitelisted_atom_ids().end());
-    for (int i = 0; i < allMetricsCount; i++) {
-        sp<MetricProducer> producer = newMetricProducers[i];
-        // Register metrics to StateTrackers
-        for (int atomId : producer->getSlicedStateAtoms()) {
-            // Register listener for atoms that use allowed_log_sources.
-            // Using atoms allowed from any uid as a sliced state atom is not allowed.
-            // Redo this check for all metrics in case the atoms allowed from any uid changed.
-            if (atomsAllowedFromAnyUid.find(atomId) != atomsAllowedFromAnyUid.end()) {
-                return false;
-                // Preserved metrics should've already registered.`
-            } else if (metricsToUpdate[i] != UPDATE_PRESERVE) {
-                StateManager::getInstance().registerListener(atomId, producer);
-            }
-        }
-    }
-
-    // Init new/replaced metrics.
-    for (size_t i = 0; i < newMetricProducers.size(); i++) {
-        if (metricsToUpdate[i] == UPDATE_REPLACE || metricsToUpdate[i] == UPDATE_NEW) {
-            newMetricProducers[i]->prepareFirstBucket();
-        }
-    }
-    return true;
-}
-
-bool determineAlertUpdateStatus(const Alert& alert,
-                                const unordered_map<int64_t, int>& oldAlertTrackerMap,
-                                const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
-                                const set<int64_t>& replacedMetrics, UpdateStatus& updateStatus) {
-    // Check if new alert.
-    const auto& oldAnomalyTrackerIt = oldAlertTrackerMap.find(alert.id());
-    if (oldAnomalyTrackerIt == oldAlertTrackerMap.end()) {
-        updateStatus = UPDATE_NEW;
-        return true;
-    }
-
-    // This is an existing alert, check if it has changed.
-    string serializedAlert;
-    if (!alert.SerializeToString(&serializedAlert)) {
-        ALOGW("Unable to serialize alert %lld", (long long)alert.id());
-        return false;
-    }
-    uint64_t newProtoHash = Hash64(serializedAlert);
-    const auto [success, oldProtoHash] =
-            oldAnomalyTrackers[oldAnomalyTrackerIt->second]->getProtoHash();
-    if (!success) {
-        return false;
-    }
-    if (newProtoHash != oldProtoHash) {
-        updateStatus = UPDATE_REPLACE;
-        return true;
-    }
-
-    // Check if the metric this alert relies on has changed.
-    if (replacedMetrics.find(alert.metric_id()) != replacedMetrics.end()) {
-        updateStatus = UPDATE_REPLACE;
-        return true;
-    }
-
-    updateStatus = UPDATE_PRESERVE;
-    return true;
-}
-
-bool updateAlerts(const StatsdConfig& config, const unordered_map<int64_t, int>& metricProducerMap,
-                  const set<int64_t>& replacedMetrics,
-                  const unordered_map<int64_t, int>& oldAlertTrackerMap,
-                  const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
-                  const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                  vector<sp<MetricProducer>>& allMetricProducers,
-                  unordered_map<int64_t, int>& newAlertTrackerMap,
-                  vector<sp<AnomalyTracker>>& newAnomalyTrackers) {
-    int alertCount = config.alert_size();
-    vector<UpdateStatus> alertUpdateStatuses(alertCount);
-    for (int i = 0; i < alertCount; i++) {
-        if (!determineAlertUpdateStatus(config.alert(i), oldAlertTrackerMap, oldAnomalyTrackers,
-                                        replacedMetrics, alertUpdateStatuses[i])) {
-            return false;
-        }
-    }
-
-    for (int i = 0; i < alertCount; i++) {
-        const Alert& alert = config.alert(i);
-        newAlertTrackerMap[alert.id()] = newAnomalyTrackers.size();
-        switch (alertUpdateStatuses[i]) {
-            case UPDATE_PRESERVE: {
-                // Find the alert and update it.
-                const auto& oldAnomalyTrackerIt = oldAlertTrackerMap.find(alert.id());
-                if (oldAnomalyTrackerIt == oldAlertTrackerMap.end()) {
-                    ALOGW("Could not find AnomalyTracker %lld in the previous config, but "
-                          "expected it to be there",
-                          (long long)alert.id());
-                    return false;
-                }
-                sp<AnomalyTracker> anomalyTracker = oldAnomalyTrackers[oldAnomalyTrackerIt->second];
-                anomalyTracker->onConfigUpdated();
-                // Add the alert to the relevant metric.
-                const auto& metricProducerIt = metricProducerMap.find(alert.metric_id());
-                if (metricProducerIt == metricProducerMap.end()) {
-                    ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
-                          (long long)alert.metric_id());
-                    return false;
-                }
-                allMetricProducers[metricProducerIt->second]->addAnomalyTracker(anomalyTracker);
-                newAnomalyTrackers.push_back(anomalyTracker);
-                break;
-            }
-            case UPDATE_REPLACE:
-            case UPDATE_NEW: {
-                optional<sp<AnomalyTracker>> anomalyTracker = createAnomalyTracker(
-                        alert, anomalyAlarmMonitor, metricProducerMap, allMetricProducers);
-                if (!anomalyTracker) {
-                    return false;
-                }
-                newAnomalyTrackers.push_back(anomalyTracker.value());
-                break;
-            }
-            default: {
-                ALOGE("Alert \"%lld\" update state is unknown. This should never happen",
-                      (long long)alert.id());
-                return false;
-            }
-        }
-    }
-    if (!initSubscribersForSubscriptionType(config, Subscription::ALERT, newAlertTrackerMap,
-                                            newAnomalyTrackers)) {
-        return false;
-    }
-    return true;
-}
-
-bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
-                        const sp<StatsPullerManager>& pullerManager,
-                        const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                        const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
-                        const int64_t currentTimeNs,
-                        const vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
-                        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-                        const vector<sp<ConditionTracker>>& oldConditionTrackers,
-                        const unordered_map<int64_t, int>& oldConditionTrackerMap,
-                        const vector<sp<MetricProducer>>& oldMetricProducers,
-                        const unordered_map<int64_t, int>& oldMetricProducerMap,
-                        const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
-                        const unordered_map<int64_t, int>& oldAlertTrackerMap,
-                        const map<int64_t, uint64_t>& oldStateProtoHashes, set<int>& allTagIds,
-                        vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
-                        unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-                        vector<sp<ConditionTracker>>& newConditionTrackers,
-                        unordered_map<int64_t, int>& newConditionTrackerMap,
-                        vector<sp<MetricProducer>>& newMetricProducers,
-                        unordered_map<int64_t, int>& newMetricProducerMap,
-                        vector<sp<AnomalyTracker>>& newAnomalyTrackers,
-                        unordered_map<int64_t, int>& newAlertTrackerMap,
-                        vector<sp<AlarmTracker>>& newPeriodicAlarmTrackers,
-                        unordered_map<int, vector<int>>& conditionToMetricMap,
-                        unordered_map<int, vector<int>>& trackerToMetricMap,
-                        unordered_map<int, vector<int>>& trackerToConditionMap,
-                        unordered_map<int, vector<int>>& activationTrackerToMetricMap,
-                        unordered_map<int, vector<int>>& deactivationTrackerToMetricMap,
-                        vector<int>& metricsWithActivation,
-                        map<int64_t, uint64_t>& newStateProtoHashes,
-                        set<int64_t>& noReportMetricIds) {
-    set<int64_t> replacedMatchers;
-    set<int64_t> replacedConditions;
-    set<int64_t> replacedStates;
-    set<int64_t> replacedMetrics;
-    vector<ConditionState> conditionCache;
-    unordered_map<int64_t, int> stateAtomIdMap;
-    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
-
-    if (!updateAtomMatchingTrackers(config, uidMap, oldAtomMatchingTrackerMap,
-                                    oldAtomMatchingTrackers, allTagIds, newAtomMatchingTrackerMap,
-                                    newAtomMatchingTrackers, replacedMatchers)) {
-        ALOGE("updateAtomMatchingTrackers failed");
-        return false;
-    }
-
-    if (!updateConditions(key, config, newAtomMatchingTrackerMap, replacedMatchers,
-                          oldConditionTrackerMap, oldConditionTrackers, newConditionTrackerMap,
-                          newConditionTrackers, trackerToConditionMap, conditionCache,
-                          replacedConditions)) {
-        ALOGE("updateConditions failed");
-        return false;
-    }
-
-    if (!updateStates(config, oldStateProtoHashes, stateAtomIdMap, allStateGroupMaps,
-                      newStateProtoHashes, replacedStates)) {
-        ALOGE("updateStates failed");
-        return false;
-    }
-    if (!updateMetrics(key, config, timeBaseNs, currentTimeNs, pullerManager,
-                       oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
-                       newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
-                       newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps,
-                       replacedStates, oldMetricProducerMap, oldMetricProducers,
-                       newMetricProducerMap, newMetricProducers, conditionToMetricMap,
-                       trackerToMetricMap, noReportMetricIds, activationTrackerToMetricMap,
-                       deactivationTrackerToMetricMap, metricsWithActivation, replacedMetrics)) {
-        ALOGE("updateMetrics failed");
-        return false;
-    }
-
-    if (!updateAlerts(config, newMetricProducerMap, replacedMetrics, oldAlertTrackerMap,
-                      oldAnomalyTrackers, anomalyAlarmMonitor, newMetricProducers,
-                      newAlertTrackerMap, newAnomalyTrackers)) {
-        ALOGE("updateAlerts failed");
-        return false;
-    }
-
-    // Alarms do not have any state, so we can reuse the initialization logic.
-    if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
-                    newPeriodicAlarmTrackers)) {
-        ALOGE("initAlarms failed");
-        return false;
-    }
-    return true;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h
deleted file mode 100644
index 8e2be68..0000000
--- a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#pragma once
-
-#include <vector>
-
-#include "anomaly/AlarmMonitor.h"
-#include "anomaly/AlarmTracker.h"
-#include "condition/ConditionTracker.h"
-#include "external/StatsPullerManager.h"
-#include "matchers/AtomMatchingTracker.h"
-#include "metrics/MetricProducer.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Helper functions for MetricsManager to update itself from a new StatsdConfig.
-// *Note*: only updateStatsdConfig() should be called from outside this file.
-// All other functions are intermediate steps, created to make unit testing easier.
-
-// Possible update states for a component. PRESERVE means we should keep the existing one.
-// REPLACE means we should create a new one because the existing one changed
-// NEW means we should create a new one because one does not currently exist.
-enum UpdateStatus {
-    UPDATE_UNKNOWN = 0,
-    UPDATE_PRESERVE = 1,
-    UPDATE_REPLACE = 2,
-    UPDATE_NEW = 3,
-};
-
-// Recursive function to determine if a matcher needs to be updated.
-// input:
-// [config]: the input StatsdConfig
-// [matcherIdx]: the index of the current matcher to be updated
-// [oldAtomMatchingTrackerMap]: matcher id to index mapping in the existing MetricsManager
-// [oldAtomMatchingTrackers]: stores the existing AtomMatchingTrackers
-// [newAtomMatchingTrackerMap]: matcher id to index mapping in the input StatsdConfig
-// output:
-// [matchersToUpdate]: vector of the update status of each matcher. The matcherIdx index will
-//                     be updated from UPDATE_UNKNOWN after this call.
-// [cycleTracker]: intermediate param used during recursion.
-// Returns whether the function was successful or not.
-bool determineMatcherUpdateStatus(
-        const StatsdConfig& config, const int matcherIdx,
-        const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const std::vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
-        const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        std::vector<UpdateStatus>& matchersToUpdate, std::vector<bool>& cycleTracker);
-
-// Updates the AtomMatchingTrackers.
-// input:
-// [config]: the input StatsdConfig
-// [oldAtomMatchingTrackerMap]: existing matcher id to index mapping
-// [oldAtomMatchingTrackers]: stores the existing AtomMatchingTrackers
-// output:
-// [allTagIds]: contains the set of all interesting tag ids to this config.
-// [newAtomMatchingTrackerMap]: new matcher id to index mapping
-// [newAtomMatchingTrackers]: stores the new AtomMatchingTrackers
-// [replacedMatchers]: set of matcher ids that changed and have been replaced
-bool updateAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
-                                const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-                                const std::vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
-                                std::set<int>& allTagIds,
-                                std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-                                std::vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
-                                std::set<int64_t>& replacedMatchers);
-
-// Recursive function to determine if a condition needs to be updated.
-// input:
-// [config]: the input StatsdConfig
-// [conditionIdx]: the index of the current condition to be updated
-// [oldConditionTrackerMap]: condition id to index mapping in the existing MetricsManager
-// [oldConditionTrackers]: stores the existing ConditionTrackers
-// [newConditionTrackerMap]: condition id to index mapping in the input StatsdConfig
-// [replacedMatchers]: set of replaced matcher ids. conditions using these matchers must be replaced
-// output:
-// [conditionsToUpdate]: vector of the update status of each condition. The conditionIdx index will
-//                       be updated from UPDATE_UNKNOWN after this call.
-// [cycleTracker]: intermediate param used during recursion.
-// Returns whether the function was successful or not.
-bool determineConditionUpdateStatus(const StatsdConfig& config, const int conditionIdx,
-                                    const std::unordered_map<int64_t, int>& oldConditionTrackerMap,
-                                    const std::vector<sp<ConditionTracker>>& oldConditionTrackers,
-                                    const std::unordered_map<int64_t, int>& newConditionTrackerMap,
-                                    const std::set<int64_t>& replacedMatchers,
-                                    std::vector<UpdateStatus>& conditionsToUpdate,
-                                    std::vector<bool>& cycleTracker);
-
-// Updates ConditionTrackers
-// input:
-// [config]: the input config
-// [atomMatchingTrackerMap]: AtomMatchingTracker name to index mapping from previous step.
-// [replacedMatchers]: ids of replaced matchers. conditions depending on these must also be replaced
-// [oldConditionTrackerMap]: existing matcher id to index mapping
-// [oldConditionTrackers]: stores the existing ConditionTrackers
-// output:
-// [newConditionTrackerMap]: new condition id to index mapping
-// [newConditionTrackers]: stores the sp to all the ConditionTrackers
-// [trackerToConditionMap]: contains the mapping from the index of an atom matcher
-//                          to indices of condition trackers that use the matcher
-// [conditionCache]: stores the current conditions for each ConditionTracker
-// [replacedConditions]: set of condition ids that have changed and have been replaced
-bool updateConditions(const ConfigKey& key, const StatsdConfig& config,
-                      const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                      const std::set<int64_t>& replacedMatchers,
-                      const std::unordered_map<int64_t, int>& oldConditionTrackerMap,
-                      const std::vector<sp<ConditionTracker>>& oldConditionTrackers,
-                      std::unordered_map<int64_t, int>& newConditionTrackerMap,
-                      std::vector<sp<ConditionTracker>>& newConditionTrackers,
-                      std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
-                      std::vector<ConditionState>& conditionCache,
-                      std::set<int64_t>& replacedConditions);
-
-bool updateStates(const StatsdConfig& config,
-                  const std::map<int64_t, uint64_t>& oldStateProtoHashes,
-                  std::unordered_map<int64_t, int>& stateAtomIdMap,
-                  std::unordered_map<int64_t, std::unordered_map<int, int64_t>>& allStateGroupMaps,
-                  std::map<int64_t, uint64_t>& newStateProtoHashes,
-                  std::set<int64_t>& replacedStates);
-
-// Function to determine the update status (preserve/replace/new) of all metrics in the config.
-// [config]: the input StatsdConfig
-// [oldMetricProducerMap]: metric id to index mapping in the existing MetricsManager
-// [oldMetricProducers]: stores the existing MetricProducers
-// [metricToActivationMap]:  map from metric id to metric activation index
-// [replacedMatchers]: set of replaced matcher ids. metrics using these matchers must be replaced
-// [replacedConditions]: set of replaced conditions. metrics using these conditions must be replaced
-// [replacedStates]: set of replaced state ids. metrics using these states must be replaced
-// output:
-// [metricsToUpdate]: update status of each metric. Will be changed from UPDATE_UNKNOWN
-// Returns whether the function was successful or not.
-bool determineAllMetricUpdateStatuses(const StatsdConfig& config,
-                                      const unordered_map<int64_t, int>& oldMetricProducerMap,
-                                      const vector<sp<MetricProducer>>& oldMetricProducers,
-                                      const unordered_map<int64_t, int>& metricToActivationMap,
-                                      const set<int64_t>& replacedMatchers,
-                                      const set<int64_t>& replacedConditions,
-                                      const set<int64_t>& replacedStates,
-                                      vector<UpdateStatus>& metricsToUpdate);
-
-// Update MetricProducers.
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input config
-// [timeBaseNs]: start time base for all metrics
-// [currentTimeNs]: time of the config update
-// [atomMatchingTrackerMap]: AtomMatchingTracker name to index mapping from previous step.
-// [replacedMatchers]: ids of replaced matchers. Metrics depending on these must also be replaced
-// [allAtomMatchingTrackers]: stores the sp of the atom matchers.
-// [conditionTrackerMap]: condition name to index mapping
-// [replacedConditions]: set of condition ids that have changed and have been replaced
-// [stateAtomIdMap]: contains the mapping from state ids to atom ids
-// [allStateGroupMaps]: contains the mapping from atom ids and state values to
-//                      state group ids for all states
-// output:
-// [allMetricProducers]: contains the list of sp to the MetricProducers created.
-// [conditionToMetricMap]: contains the mapping from condition tracker index to
-//                          the list of MetricProducer index
-// [trackerToMetricMap]: contains the mapping from log tracker to MetricProducer index.
-bool updateMetrics(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
-        const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const std::set<int64_t>& replacedMatchers,
-        const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const std::unordered_map<int64_t, int>& conditionTrackerMap,
-        const std::set<int64_t>& replacedConditions,
-        std::vector<sp<ConditionTracker>>& allConditionTrackers,
-        const std::vector<ConditionState>& initialConditionCache,
-        const std::unordered_map<int64_t, int>& stateAtomIdMap,
-        const std::unordered_map<int64_t, std::unordered_map<int, int64_t>>& allStateGroupMaps,
-        const std::set<int64_t>& replacedStates,
-        const std::unordered_map<int64_t, int>& oldMetricProducerMap,
-        const std::vector<sp<MetricProducer>>& oldMetricProducers,
-        std::unordered_map<int64_t, int>& newMetricProducerMap,
-        std::vector<sp<MetricProducer>>& newMetricProducers,
-        std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-        std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-        std::set<int64_t>& noReportMetricIds,
-        std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation, std::set<int64_t>& replacedMetrics);
-
-// Function to determine the update status (preserve/replace/new) of an alert.
-// [alert]: the input Alert
-// [oldAlertTrackerMap]: alert id to index mapping in the existing MetricsManager
-// [oldAnomalyTrackers]: stores the existing AnomalyTrackers
-// [replacedMetrics]: set of replaced metric ids. alerts using these metrics must be replaced
-// output:
-// [updateStatus]: update status of the alert. Will be changed from UPDATE_UNKNOWN
-// Returns whether the function was successful or not.
-bool determineAlertUpdateStatus(const Alert& alert,
-                                const std::unordered_map<int64_t, int>& oldAlertTrackerMap,
-                                const std::vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
-                                const std::set<int64_t>& replacedMetrics,
-                                UpdateStatus& updateStatus);
-
-// Update MetricProducers.
-// input:
-// [config]: the input config
-// [metricProducerMap]: metric id to index mapping in the new config
-// [replacedMetrics]: set of metric ids that have changed and were replaced
-// [oldAlertTrackerMap]: alert id to index mapping in the existing MetricsManager.
-// [oldAnomalyTrackers]: stores the existing AnomalyTrackers
-// [anomalyAlarmMonitor]: AlarmMonitor used for duration metric anomaly detection
-// [allMetricProducers]: stores the sp of the metric producers, AnomalyTrackers need to be added.
-// [stateAtomIdMap]: contains the mapping from state ids to atom ids
-// [allStateGroupMaps]: contains the mapping from atom ids and state values to
-//                      state group ids for all states
-// output:
-// [newAlertTrackerMap]: mapping of alert id to index in the new config
-// [newAnomalyTrackers]: contains the list of sp to the AnomalyTrackers created.
-bool updateAlerts(const StatsdConfig& config,
-                  const std::unordered_map<int64_t, int>& metricProducerMap,
-                  const std::set<int64_t>& replacedMetrics,
-                  const std::unordered_map<int64_t, int>& oldAlertTrackerMap,
-                  const std::vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
-                  const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                  std::vector<sp<MetricProducer>>& allMetricProducers,
-                  std::unordered_map<int64_t, int>& newAlertTrackerMap,
-                  std::vector<sp<AnomalyTracker>>& newAnomalyTrackers);
-
-// Updates the existing MetricsManager from a new StatsdConfig.
-// Parameters are the members of MetricsManager. See MetricsManager for declaration.
-bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
-                        const sp<StatsPullerManager>& pullerManager,
-                        const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                        const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
-                        const int64_t currentTimeNs,
-                        const std::vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
-                        const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-                        const std::vector<sp<ConditionTracker>>& oldConditionTrackers,
-                        const std::unordered_map<int64_t, int>& oldConditionTrackerMap,
-                        const std::vector<sp<MetricProducer>>& oldMetricProducers,
-                        const std::unordered_map<int64_t, int>& oldMetricProducerMap,
-                        const std::vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
-                        const std::unordered_map<int64_t, int>& oldAlertTrackerMap,
-                        const std::map<int64_t, uint64_t>& oldStateProtoHashes,
-                        std::set<int>& allTagIds,
-                        std::vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
-                        std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-                        std::vector<sp<ConditionTracker>>& newConditionTrackers,
-                        std::unordered_map<int64_t, int>& newConditionTrackerMap,
-                        std::vector<sp<MetricProducer>>& newMetricProducers,
-                        std::unordered_map<int64_t, int>& newMetricProducerMap,
-                        std::vector<sp<AnomalyTracker>>& newAlertTrackers,
-                        std::unordered_map<int64_t, int>& newAlertTrackerMap,
-                        std::vector<sp<AlarmTracker>>& newPeriodicAlarmTrackers,
-                        std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-                        std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-                        std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
-                        std::unordered_map<int, std::vector<int>>& activationTrackerToMetricMap,
-                        std::unordered_map<int, std::vector<int>>& deactivationTrackerToMetricMap,
-                        std::vector<int>& metricsWithActivation,
-                        std::map<int64_t, uint64_t>& newStateProtoHashes,
-                        std::set<int64_t>& noReportMetricIds);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
deleted file mode 100644
index bfa409c..0000000
--- a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
+++ /dev/null
@@ -1,1228 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "metrics_manager_util.h"
-
-#include <inttypes.h>
-
-#include "FieldValue.h"
-#include "condition/CombinationConditionTracker.h"
-#include "condition/SimpleConditionTracker.h"
-#include "external/StatsPullerManager.h"
-#include "hash.h"
-#include "matchers/CombinationAtomMatchingTracker.h"
-#include "matchers/EventMatcherWizard.h"
-#include "matchers/SimpleAtomMatchingTracker.h"
-#include "metrics/CountMetricProducer.h"
-#include "metrics/DurationMetricProducer.h"
-#include "metrics/EventMetricProducer.h"
-#include "metrics/GaugeMetricProducer.h"
-#include "metrics/MetricProducer.h"
-#include "metrics/ValueMetricProducer.h"
-#include "state/StateManager.h"
-#include "stats_util.h"
-
-using google::protobuf::MessageLite;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-bool hasLeafNode(const FieldMatcher& matcher) {
-    if (!matcher.has_field()) {
-        return false;
-    }
-    for (int i = 0; i < matcher.child_size(); ++i) {
-        if (hasLeafNode(matcher.child(i))) {
-            return true;
-        }
-    }
-    return true;
-}
-
-}  // namespace
-
-sp<AtomMatchingTracker> createAtomMatchingTracker(const AtomMatcher& logMatcher, const int index,
-                                                  const sp<UidMap>& uidMap) {
-    string serializedMatcher;
-    if (!logMatcher.SerializeToString(&serializedMatcher)) {
-        ALOGE("Unable to serialize matcher %lld", (long long)logMatcher.id());
-        return nullptr;
-    }
-    uint64_t protoHash = Hash64(serializedMatcher);
-    switch (logMatcher.contents_case()) {
-        case AtomMatcher::ContentsCase::kSimpleAtomMatcher:
-            return new SimpleAtomMatchingTracker(logMatcher.id(), index, protoHash,
-                                                 logMatcher.simple_atom_matcher(), uidMap);
-        case AtomMatcher::ContentsCase::kCombination:
-            return new CombinationAtomMatchingTracker(logMatcher.id(), index, protoHash);
-        default:
-            ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id());
-            return nullptr;
-    }
-}
-
-sp<ConditionTracker> createConditionTracker(
-        const ConfigKey& key, const Predicate& predicate, const int index,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap) {
-    string serializedPredicate;
-    if (!predicate.SerializeToString(&serializedPredicate)) {
-        ALOGE("Unable to serialize predicate %lld", (long long)predicate.id());
-        return nullptr;
-    }
-    uint64_t protoHash = Hash64(serializedPredicate);
-    switch (predicate.contents_case()) {
-        case Predicate::ContentsCase::kSimplePredicate: {
-            return new SimpleConditionTracker(key, predicate.id(), protoHash, index,
-                                              predicate.simple_predicate(), atomMatchingTrackerMap);
-        }
-        case Predicate::ContentsCase::kCombination: {
-            return new CombinationConditionTracker(predicate.id(), index, protoHash);
-        }
-        default:
-            ALOGE("Predicate \"%lld\" malformed", (long long)predicate.id());
-            return nullptr;
-    }
-}
-
-bool getMetricProtoHash(const StatsdConfig& config, const MessageLite& metric, const int64_t id,
-                        const unordered_map<int64_t, int>& metricToActivationMap,
-                        uint64_t& metricHash) {
-    string serializedMetric;
-    if (!metric.SerializeToString(&serializedMetric)) {
-        ALOGE("Unable to serialize metric %lld", (long long)id);
-        return false;
-    }
-    metricHash = Hash64(serializedMetric);
-
-    // Combine with activation hash, if applicable
-    const auto& metricActivationIt = metricToActivationMap.find(id);
-    if (metricActivationIt != metricToActivationMap.end()) {
-        string serializedActivation;
-        const MetricActivation& activation = config.metric_activation(metricActivationIt->second);
-        if (!activation.SerializeToString(&serializedActivation)) {
-            ALOGE("Unable to serialize metric activation for metric %lld", (long long)id);
-            return false;
-        }
-        metricHash = Hash64(to_string(metricHash).append(to_string(Hash64(serializedActivation))));
-    }
-    return true;
-}
-
-bool handleMetricWithAtomMatchingTrackers(
-        const int64_t matcherId, const int metricIndex, const bool enforceOneAtom,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap, int& logTrackerIndex) {
-    auto logTrackerIt = atomMatchingTrackerMap.find(matcherId);
-    if (logTrackerIt == atomMatchingTrackerMap.end()) {
-        ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)matcherId);
-        return false;
-    }
-    if (enforceOneAtom && allAtomMatchingTrackers[logTrackerIt->second]->getAtomIds().size() > 1) {
-        ALOGE("AtomMatcher \"%lld\" has more than one tag ids. When a metric has dimension, "
-              "the \"what\" can only be about one atom type. trigger_event matchers can also only "
-              "be about one atom type.",
-              (long long)matcherId);
-        return false;
-    }
-    logTrackerIndex = logTrackerIt->second;
-    auto& metric_list = trackerToMetricMap[logTrackerIndex];
-    metric_list.push_back(metricIndex);
-    return true;
-}
-
-bool handleMetricWithConditions(
-        const int64_t condition, const int metricIndex,
-        const unordered_map<int64_t, int>& conditionTrackerMap,
-        const ::google::protobuf::RepeatedPtrField<::android::os::statsd::MetricConditionLink>&
-                links,
-        const vector<sp<ConditionTracker>>& allConditionTrackers, int& conditionIndex,
-        unordered_map<int, vector<int>>& conditionToMetricMap) {
-    auto condition_it = conditionTrackerMap.find(condition);
-    if (condition_it == conditionTrackerMap.end()) {
-        ALOGW("cannot find Predicate \"%lld\" in the config", (long long)condition);
-        return false;
-    }
-
-    for (const auto& link : links) {
-        auto it = conditionTrackerMap.find(link.condition());
-        if (it == conditionTrackerMap.end()) {
-            ALOGW("cannot find Predicate \"%lld\" in the config", (long long)link.condition());
-            return false;
-        }
-    }
-    conditionIndex = condition_it->second;
-
-    // will create new vector if not exist before.
-    auto& metricList = conditionToMetricMap[condition_it->second];
-    metricList.push_back(metricIndex);
-    return true;
-}
-
-// Initializes state data structures for a metric.
-// input:
-// [config]: the input config
-// [stateIds]: the slice_by_state ids for this metric
-// [stateAtomIdMap]: this map contains the mapping from all state ids to atom ids
-// [allStateGroupMaps]: this map contains the mapping from state ids and state
-//                      values to state group ids for all states
-// output:
-// [slicedStateAtoms]: a vector of atom ids of all the slice_by_states
-// [stateGroupMap]: this map should contain the mapping from states ids and state
-//                      values to state group ids for all states that this metric
-//                      is interested in
-bool handleMetricWithStates(
-        const StatsdConfig& config, const ::google::protobuf::RepeatedField<int64_t>& stateIds,
-        const unordered_map<int64_t, int>& stateAtomIdMap,
-        const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-        vector<int>& slicedStateAtoms,
-        unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap) {
-    for (const auto& stateId : stateIds) {
-        auto it = stateAtomIdMap.find(stateId);
-        if (it == stateAtomIdMap.end()) {
-            ALOGW("cannot find State %" PRId64 " in the config", stateId);
-            return false;
-        }
-        int atomId = it->second;
-        slicedStateAtoms.push_back(atomId);
-
-        auto stateIt = allStateGroupMaps.find(stateId);
-        if (stateIt != allStateGroupMaps.end()) {
-            stateGroupMap[atomId] = stateIt->second;
-        }
-    }
-    return true;
-}
-
-bool handleMetricWithStateLink(const FieldMatcher& stateMatcher,
-                               const vector<Matcher>& dimensionsInWhat) {
-    vector<Matcher> stateMatchers;
-    translateFieldMatcher(stateMatcher, &stateMatchers);
-
-    return subsetDimensions(stateMatchers, dimensionsInWhat);
-}
-
-// Validates a metricActivation and populates state.
-// EventActivationMap and EventDeactivationMap are supplied to a MetricProducer
-//      to provide the producer with state about its activators and deactivators.
-// Returns false if there are errors.
-bool handleMetricActivation(
-        const StatsdConfig& config, const int64_t metricId, const int metricIndex,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation,
-        unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
-        unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap) {
-    // Check if metric has an associated activation
-    auto itr = metricToActivationMap.find(metricId);
-    if (itr == metricToActivationMap.end()) {
-        return true;
-    }
-
-    int activationIndex = itr->second;
-    const MetricActivation& metricActivation = config.metric_activation(activationIndex);
-
-    for (int i = 0; i < metricActivation.event_activation_size(); i++) {
-        const EventActivation& activation = metricActivation.event_activation(i);
-
-        auto itr = atomMatchingTrackerMap.find(activation.atom_matcher_id());
-        if (itr == atomMatchingTrackerMap.end()) {
-            ALOGE("Atom matcher not found for event activation.");
-            return false;
-        }
-
-        ActivationType activationType = (activation.has_activation_type())
-                                                ? activation.activation_type()
-                                                : metricActivation.activation_type();
-        std::shared_ptr<Activation> activationWrapper =
-                std::make_shared<Activation>(activationType, activation.ttl_seconds() * NS_PER_SEC);
-
-        int atomMatcherIndex = itr->second;
-        activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(metricIndex);
-        eventActivationMap.emplace(atomMatcherIndex, activationWrapper);
-
-        if (activation.has_deactivation_atom_matcher_id()) {
-            itr = atomMatchingTrackerMap.find(activation.deactivation_atom_matcher_id());
-            if (itr == atomMatchingTrackerMap.end()) {
-                ALOGE("Atom matcher not found for event deactivation.");
-                return false;
-            }
-            int deactivationAtomMatcherIndex = itr->second;
-            deactivationAtomTrackerToMetricMap[deactivationAtomMatcherIndex].push_back(metricIndex);
-            eventDeactivationMap[deactivationAtomMatcherIndex].push_back(activationWrapper);
-        }
-    }
-
-    metricsWithActivation.push_back(metricIndex);
-    return true;
-}
-
-// Validates a metricActivation and populates state.
-// Fills the new event activation/deactivation maps, preserving the existing activations
-// Returns false if there are errors.
-bool handleMetricActivationOnConfigUpdate(
-        const StatsdConfig& config, const int64_t metricId, const int metricIndex,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const unordered_map<int, shared_ptr<Activation>>& oldEventActivationMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation,
-        unordered_map<int, shared_ptr<Activation>>& newEventActivationMap,
-        unordered_map<int, vector<shared_ptr<Activation>>>& newEventDeactivationMap) {
-    // Check if metric has an associated activation.
-    const auto& itr = metricToActivationMap.find(metricId);
-    if (itr == metricToActivationMap.end()) {
-        return true;
-    }
-
-    int activationIndex = itr->second;
-    const MetricActivation& metricActivation = config.metric_activation(activationIndex);
-
-    for (int i = 0; i < metricActivation.event_activation_size(); i++) {
-        const int64_t activationMatcherId = metricActivation.event_activation(i).atom_matcher_id();
-
-        const auto& newActivationIt = newAtomMatchingTrackerMap.find(activationMatcherId);
-        if (newActivationIt == newAtomMatchingTrackerMap.end()) {
-            ALOGE("Atom matcher not found in new config for event activation.");
-            return false;
-        }
-        int newActivationMatcherIndex = newActivationIt->second;
-
-        // Find the old activation struct and copy it over.
-        const auto& oldActivationIt = oldAtomMatchingTrackerMap.find(activationMatcherId);
-        if (oldActivationIt == oldAtomMatchingTrackerMap.end()) {
-            ALOGE("Atom matcher not found in existing config for event activation.");
-            return false;
-        }
-        int oldActivationMatcherIndex = oldActivationIt->second;
-        const auto& oldEventActivationIt = oldEventActivationMap.find(oldActivationMatcherIndex);
-        if (oldEventActivationIt == oldEventActivationMap.end()) {
-            ALOGE("Could not find existing event activation to update");
-            return false;
-        }
-        newEventActivationMap.emplace(newActivationMatcherIndex, oldEventActivationIt->second);
-        activationAtomTrackerToMetricMap[newActivationMatcherIndex].push_back(metricIndex);
-
-        if (metricActivation.event_activation(i).has_deactivation_atom_matcher_id()) {
-            const int64_t deactivationMatcherId =
-                    metricActivation.event_activation(i).deactivation_atom_matcher_id();
-            const auto& newDeactivationIt = newAtomMatchingTrackerMap.find(deactivationMatcherId);
-            if (newDeactivationIt == newAtomMatchingTrackerMap.end()) {
-                ALOGE("Deactivation atom matcher not found in new config for event activation.");
-                return false;
-            }
-            int newDeactivationMatcherIndex = newDeactivationIt->second;
-            newEventDeactivationMap[newDeactivationMatcherIndex].push_back(
-                    oldEventActivationIt->second);
-            deactivationAtomTrackerToMetricMap[newDeactivationMatcherIndex].push_back(metricIndex);
-        }
-    }
-
-    metricsWithActivation.push_back(metricIndex);
-    return true;
-}
-
-optional<sp<MetricProducer>> createCountMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const int64_t currentTimeNs, const CountMetric& metric, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap,
-        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& stateAtomIdMap,
-        const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!metric.has_id() || !metric.has_what()) {
-        ALOGE("cannot find metric id or \"what\" in CountMetric \"%lld\"", (long long)metric.id());
-        return nullopt;
-    }
-    int trackerIndex;
-    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
-                                              metric.has_dimensions_in_what(),
-                                              allAtomMatchingTrackers, atomMatchingTrackerMap,
-                                              trackerToMetricMap, trackerIndex)) {
-        return nullopt;
-    }
-
-    int conditionIndex = -1;
-    if (metric.has_condition()) {
-        if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                        metric.links(), allConditionTrackers, conditionIndex,
-                                        conditionToMetricMap)) {
-            return nullopt;
-        }
-    } else {
-        if (metric.links_size() > 0) {
-            ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
-            return nullopt;
-        }
-    }
-
-    std::vector<int> slicedStateAtoms;
-    unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
-    if (metric.slice_by_state_size() > 0) {
-        if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
-                                    allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
-            return nullopt;
-        }
-    } else {
-        if (metric.state_link_size() > 0) {
-            ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
-            return nullopt;
-        }
-    }
-
-    unordered_map<int, shared_ptr<Activation>> eventActivationMap;
-    unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
-    if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
-                                atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
-                                deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                                eventActivationMap, eventDeactivationMap)) {
-        return nullopt;
-    }
-
-    uint64_t metricHash;
-    if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
-        return nullopt;
-    }
-
-    return {new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
-                                    metricHash, timeBaseNs, currentTimeNs, eventActivationMap,
-                                    eventDeactivationMap, slicedStateAtoms, stateGroupMap)};
-}
-
-optional<sp<MetricProducer>> createDurationMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const int64_t currentTimeNs, const DurationMetric& metric, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap,
-        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& stateAtomIdMap,
-        const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!metric.has_id() || !metric.has_what()) {
-        ALOGE("cannot find metric id or \"what\" in DurationMetric \"%lld\"",
-              (long long)metric.id());
-        return nullopt;
-    }
-    const auto& what_it = conditionTrackerMap.find(metric.what());
-    if (what_it == conditionTrackerMap.end()) {
-        ALOGE("DurationMetric's \"what\" is not present in the condition trackers");
-        return nullopt;
-    }
-
-    const int whatIndex = what_it->second;
-    const Predicate& durationWhat = config.predicate(whatIndex);
-    if (durationWhat.contents_case() != Predicate::ContentsCase::kSimplePredicate) {
-        ALOGE("DurationMetric's \"what\" must be a simple condition");
-        return nullopt;
-    }
-
-    const SimplePredicate& simplePredicate = durationWhat.simple_predicate();
-    bool nesting = simplePredicate.count_nesting();
-
-    int startIndex = -1, stopIndex = -1, stopAllIndex = -1;
-    if (!simplePredicate.has_start() ||
-        !handleMetricWithAtomMatchingTrackers(
-                simplePredicate.start(), metricIndex, metric.has_dimensions_in_what(),
-                allAtomMatchingTrackers, atomMatchingTrackerMap, trackerToMetricMap, startIndex)) {
-        ALOGE("Duration metrics must specify a valid start event matcher");
-        return nullopt;
-    }
-
-    if (simplePredicate.has_stop() &&
-        !handleMetricWithAtomMatchingTrackers(
-                simplePredicate.stop(), metricIndex, metric.has_dimensions_in_what(),
-                allAtomMatchingTrackers, atomMatchingTrackerMap, trackerToMetricMap, stopIndex)) {
-        return nullopt;
-    }
-
-    if (simplePredicate.has_stop_all() &&
-        !handleMetricWithAtomMatchingTrackers(simplePredicate.stop_all(), metricIndex,
-                                              metric.has_dimensions_in_what(),
-                                              allAtomMatchingTrackers, atomMatchingTrackerMap,
-                                              trackerToMetricMap, stopAllIndex)) {
-        return nullopt;
-    }
-
-    FieldMatcher internalDimensions = simplePredicate.dimensions();
-
-    int conditionIndex = -1;
-    if (metric.has_condition()) {
-        if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                        metric.links(), allConditionTrackers, conditionIndex,
-                                        conditionToMetricMap)) {
-            return nullopt;
-        }
-    } else if (metric.links_size() > 0) {
-        ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
-        return nullopt;
-    }
-
-    std::vector<int> slicedStateAtoms;
-    unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
-    if (metric.slice_by_state_size() > 0) {
-        if (metric.aggregation_type() == DurationMetric::MAX_SPARSE) {
-            ALOGE("DurationMetric with aggregation type MAX_SPARSE cannot be sliced by state");
-            return nullopt;
-        }
-        if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
-                                    allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
-            return nullopt;
-        }
-    } else if (metric.state_link_size() > 0) {
-        ALOGW("DurationMetric has a MetricStateLink but doesn't have a sliced state");
-        return nullopt;
-    }
-
-    // Check that all metric state links are a subset of dimensions_in_what fields.
-    std::vector<Matcher> dimensionsInWhat;
-    translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
-    for (const auto& stateLink : metric.state_link()) {
-        if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
-            ALOGW("DurationMetric's MetricStateLinks must be a subset of dimensions in what");
-            return nullopt;
-        }
-    }
-
-    unordered_map<int, shared_ptr<Activation>> eventActivationMap;
-    unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
-    if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
-                                atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
-                                deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                                eventActivationMap, eventDeactivationMap)) {
-        return nullopt;
-    }
-
-    uint64_t metricHash;
-    if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
-        return nullopt;
-    }
-
-    sp<MetricProducer> producer = new DurationMetricProducer(
-            key, metric, conditionIndex, initialConditionCache, whatIndex, startIndex, stopIndex,
-            stopAllIndex, nesting, wizard, metricHash, internalDimensions, timeBaseNs,
-            currentTimeNs, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
-            stateGroupMap);
-    if (!producer->isValid()) {
-        return nullopt;
-    }
-    return {producer};
-}
-
-optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const EventMetric& metric, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap,
-        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!metric.has_id() || !metric.has_what()) {
-        ALOGE("cannot find the metric name or what in config");
-        return nullopt;
-    }
-    int trackerIndex;
-    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, false,
-                                              allAtomMatchingTrackers, atomMatchingTrackerMap,
-                                              trackerToMetricMap, trackerIndex)) {
-        return nullopt;
-    }
-
-    int conditionIndex = -1;
-    if (metric.has_condition()) {
-        if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                        metric.links(), allConditionTrackers, conditionIndex,
-                                        conditionToMetricMap)) {
-            return nullopt;
-        }
-    } else {
-        if (metric.links_size() > 0) {
-            ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
-            return nullopt;
-        }
-    }
-
-    unordered_map<int, shared_ptr<Activation>> eventActivationMap;
-    unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
-    bool success = handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
-                                          atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
-                                          deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                                          eventActivationMap, eventDeactivationMap);
-    if (!success) return nullptr;
-
-    uint64_t metricHash;
-    if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
-        return nullopt;
-    }
-
-    return {new EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
-                                    metricHash, timeBaseNs, eventActivationMap,
-                                    eventDeactivationMap)};
-}
-
-optional<sp<MetricProducer>> createValueMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
-        const ValueMetric& metric, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap,
-        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const unordered_map<int64_t, int>& stateAtomIdMap,
-        const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!metric.has_id() || !metric.has_what()) {
-        ALOGE("cannot find metric id or \"what\" in ValueMetric \"%lld\"", (long long)metric.id());
-        return nullopt;
-    }
-    if (!metric.has_value_field()) {
-        ALOGE("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
-        return nullopt;
-    }
-    std::vector<Matcher> fieldMatchers;
-    translateFieldMatcher(metric.value_field(), &fieldMatchers);
-    if (fieldMatchers.size() < 1) {
-        ALOGE("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
-        return nullopt;
-    }
-
-    int trackerIndex;
-    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
-                                              metric.has_dimensions_in_what(),
-                                              allAtomMatchingTrackers, atomMatchingTrackerMap,
-                                              trackerToMetricMap, trackerIndex)) {
-        return nullopt;
-    }
-
-    sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex);
-    // If it is pulled atom, it should be simple matcher with one tagId.
-    if (atomMatcher->getAtomIds().size() != 1) {
-        return nullopt;
-    }
-    int atomTagId = *(atomMatcher->getAtomIds().begin());
-    int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
-
-    int conditionIndex = -1;
-    if (metric.has_condition()) {
-        if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                        metric.links(), allConditionTrackers, conditionIndex,
-                                        conditionToMetricMap)) {
-            return nullopt;
-        }
-    } else if (metric.links_size() > 0) {
-        ALOGE("metrics has a MetricConditionLink but doesn't have a condition");
-        return nullopt;
-    }
-
-    std::vector<int> slicedStateAtoms;
-    unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
-    if (metric.slice_by_state_size() > 0) {
-        if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
-                                    allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
-            return nullopt;
-        }
-    } else if (metric.state_link_size() > 0) {
-        ALOGE("ValueMetric has a MetricStateLink but doesn't have a sliced state");
-        return nullopt;
-    }
-
-    // Check that all metric state links are a subset of dimensions_in_what fields.
-    std::vector<Matcher> dimensionsInWhat;
-    translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
-    for (const auto& stateLink : metric.state_link()) {
-        if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
-            ALOGW("ValueMetric's MetricStateLinks must be a subset of the dimensions in what");
-            return nullopt;
-        }
-    }
-
-    unordered_map<int, shared_ptr<Activation>> eventActivationMap;
-    unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
-    if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
-                                          atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
-                                          deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                                          eventActivationMap, eventDeactivationMap)) {
-        return nullopt;
-    }
-
-    uint64_t metricHash;
-    if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
-        return nullopt;
-    }
-
-    return {new ValueMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
-                                    metricHash, trackerIndex, matcherWizard, pullTagId, timeBaseNs,
-                                    currentTimeNs, pullerManager, eventActivationMap,
-                                    eventDeactivationMap, slicedStateAtoms, stateGroupMap)};
-}
-
-optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
-        const GaugeMetric& metric, const int metricIndex,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        vector<sp<ConditionTracker>>& allConditionTrackers,
-        const unordered_map<int64_t, int>& conditionTrackerMap,
-        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const unordered_map<int64_t, int>& metricToActivationMap,
-        unordered_map<int, vector<int>>& trackerToMetricMap,
-        unordered_map<int, vector<int>>& conditionToMetricMap,
-        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-        vector<int>& metricsWithActivation) {
-    if (!metric.has_id() || !metric.has_what()) {
-        ALOGE("cannot find metric id or \"what\" in GaugeMetric \"%lld\"", (long long)metric.id());
-        return nullopt;
-    }
-
-    if ((!metric.gauge_fields_filter().has_include_all() ||
-         (metric.gauge_fields_filter().include_all() == false)) &&
-        !hasLeafNode(metric.gauge_fields_filter().fields())) {
-        ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
-        return nullopt;
-    }
-    if ((metric.gauge_fields_filter().has_include_all() &&
-         metric.gauge_fields_filter().include_all() == true) &&
-        hasLeafNode(metric.gauge_fields_filter().fields())) {
-        ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
-        return nullopt;
-    }
-
-    int trackerIndex;
-    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
-                                              metric.has_dimensions_in_what(),
-                                              allAtomMatchingTrackers, atomMatchingTrackerMap,
-                                              trackerToMetricMap, trackerIndex)) {
-        return nullopt;
-    }
-
-    sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex);
-    // For GaugeMetric atom, it should be simple matcher with one tagId.
-    if (atomMatcher->getAtomIds().size() != 1) {
-        return nullopt;
-    }
-    int atomTagId = *(atomMatcher->getAtomIds().begin());
-    int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
-
-    int triggerTrackerIndex;
-    int triggerAtomId = -1;
-    if (metric.has_trigger_event()) {
-        if (pullTagId == -1) {
-            ALOGW("Pull atom not specified for trigger");
-            return nullopt;
-        }
-        // trigger_event should be used with FIRST_N_SAMPLES
-        if (metric.sampling_type() != GaugeMetric::FIRST_N_SAMPLES) {
-            ALOGW("Gauge Metric with trigger event must have sampling type FIRST_N_SAMPLES");
-            return nullopt;
-        }
-        if (!handleMetricWithAtomMatchingTrackers(metric.trigger_event(), metricIndex,
-                                                  /*enforceOneAtom=*/true, allAtomMatchingTrackers,
-                                                  atomMatchingTrackerMap, trackerToMetricMap,
-                                                  triggerTrackerIndex)) {
-            return nullopt;
-        }
-        sp<AtomMatchingTracker> triggerAtomMatcher =
-                allAtomMatchingTrackers.at(triggerTrackerIndex);
-        triggerAtomId = *(triggerAtomMatcher->getAtomIds().begin());
-    }
-
-    if (!metric.has_trigger_event() && pullTagId != -1 &&
-        metric.sampling_type() == GaugeMetric::FIRST_N_SAMPLES) {
-        ALOGW("FIRST_N_SAMPLES is only for pushed event or pull_on_trigger");
-        return nullopt;
-    }
-
-    int conditionIndex = -1;
-    if (metric.has_condition()) {
-        if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
-                                        metric.links(), allConditionTrackers, conditionIndex,
-                                        conditionToMetricMap)) {
-            return nullopt;
-        }
-    } else {
-        if (metric.links_size() > 0) {
-            ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
-            return nullopt;
-        }
-    }
-
-    unordered_map<int, shared_ptr<Activation>> eventActivationMap;
-    unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
-    if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
-                                atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
-                                deactivationAtomTrackerToMetricMap, metricsWithActivation,
-                                eventActivationMap, eventDeactivationMap)) {
-        return nullopt;
-    }
-
-    uint64_t metricHash;
-    if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
-        return nullopt;
-    }
-
-    return {new GaugeMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
-                                    metricHash, trackerIndex, matcherWizard, pullTagId,
-                                    triggerAtomId, atomTagId, timeBaseNs, currentTimeNs,
-                                    pullerManager, eventActivationMap, eventDeactivationMap)};
-}
-
-optional<sp<AnomalyTracker>> createAnomalyTracker(
-        const Alert& alert, const sp<AlarmMonitor>& anomalyAlarmMonitor,
-        const unordered_map<int64_t, int>& metricProducerMap,
-        vector<sp<MetricProducer>>& allMetricProducers) {
-    const auto& itr = metricProducerMap.find(alert.metric_id());
-    if (itr == metricProducerMap.end()) {
-        ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
-              (long long)alert.metric_id());
-        return nullopt;
-    }
-    if (!alert.has_trigger_if_sum_gt()) {
-        ALOGW("invalid alert: missing threshold");
-        return nullopt;
-    }
-    if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
-        ALOGW("invalid alert: threshold=%f num_buckets= %d", alert.trigger_if_sum_gt(),
-              alert.num_buckets());
-        return nullopt;
-    }
-    const int metricIndex = itr->second;
-    sp<MetricProducer> metric = allMetricProducers[metricIndex];
-    sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert, anomalyAlarmMonitor);
-    if (anomalyTracker == nullptr) {
-        // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
-        return nullopt;
-    }
-    return {anomalyTracker};
-}
-
-bool initAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
-                              unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                              vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                              set<int>& allTagIds) {
-    vector<AtomMatcher> matcherConfigs;
-    const int atomMatcherCount = config.atom_matcher_size();
-    matcherConfigs.reserve(atomMatcherCount);
-    allAtomMatchingTrackers.reserve(atomMatcherCount);
-
-    for (int i = 0; i < atomMatcherCount; i++) {
-        const AtomMatcher& logMatcher = config.atom_matcher(i);
-        sp<AtomMatchingTracker> tracker = createAtomMatchingTracker(logMatcher, i, uidMap);
-        if (tracker == nullptr) {
-            return false;
-        }
-        allAtomMatchingTrackers.push_back(tracker);
-        if (atomMatchingTrackerMap.find(logMatcher.id()) != atomMatchingTrackerMap.end()) {
-            ALOGE("Duplicate AtomMatcher found!");
-            return false;
-        }
-        atomMatchingTrackerMap[logMatcher.id()] = i;
-        matcherConfigs.push_back(logMatcher);
-    }
-
-    vector<bool> stackTracker2(allAtomMatchingTrackers.size(), false);
-    for (auto& matcher : allAtomMatchingTrackers) {
-        if (!matcher->init(matcherConfigs, allAtomMatchingTrackers, atomMatchingTrackerMap,
-                           stackTracker2)) {
-            return false;
-        }
-        // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
-        const set<int>& tagIds = matcher->getAtomIds();
-        allTagIds.insert(tagIds.begin(), tagIds.end());
-    }
-    return true;
-}
-
-bool initConditions(const ConfigKey& key, const StatsdConfig& config,
-                    const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                    unordered_map<int64_t, int>& conditionTrackerMap,
-                    vector<sp<ConditionTracker>>& allConditionTrackers,
-                    unordered_map<int, std::vector<int>>& trackerToConditionMap,
-                    vector<ConditionState>& initialConditionCache) {
-    vector<Predicate> conditionConfigs;
-    const int conditionTrackerCount = config.predicate_size();
-    conditionConfigs.reserve(conditionTrackerCount);
-    allConditionTrackers.reserve(conditionTrackerCount);
-    initialConditionCache.assign(conditionTrackerCount, ConditionState::kNotEvaluated);
-
-    for (int i = 0; i < conditionTrackerCount; i++) {
-        const Predicate& condition = config.predicate(i);
-        sp<ConditionTracker> tracker =
-                createConditionTracker(key, condition, i, atomMatchingTrackerMap);
-        if (tracker == nullptr) {
-            return false;
-        }
-        allConditionTrackers.push_back(tracker);
-        if (conditionTrackerMap.find(condition.id()) != conditionTrackerMap.end()) {
-            ALOGE("Duplicate Predicate found!");
-            return false;
-        }
-        conditionTrackerMap[condition.id()] = i;
-        conditionConfigs.push_back(condition);
-    }
-
-    vector<bool> stackTracker(allConditionTrackers.size(), false);
-    for (size_t i = 0; i < allConditionTrackers.size(); i++) {
-        auto& conditionTracker = allConditionTrackers[i];
-        if (!conditionTracker->init(conditionConfigs, allConditionTrackers, conditionTrackerMap,
-                                    stackTracker, initialConditionCache)) {
-            return false;
-        }
-        for (const int trackerIndex : conditionTracker->getAtomMatchingTrackerIndex()) {
-            auto& conditionList = trackerToConditionMap[trackerIndex];
-            conditionList.push_back(i);
-        }
-    }
-    return true;
-}
-
-bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
-                unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-                map<int64_t, uint64_t>& stateProtoHashes) {
-    for (int i = 0; i < config.state_size(); i++) {
-        const State& state = config.state(i);
-        const int64_t stateId = state.id();
-        stateAtomIdMap[stateId] = state.atom_id();
-
-        string serializedState;
-        if (!state.SerializeToString(&serializedState)) {
-            ALOGE("Unable to serialize state %lld", (long long)stateId);
-            return false;
-        }
-        stateProtoHashes[stateId] = Hash64(serializedState);
-
-        const StateMap& stateMap = state.map();
-        for (auto group : stateMap.group()) {
-            for (auto value : group.value()) {
-                allStateGroupMaps[stateId][value] = group.group_id();
-            }
-        }
-    }
-
-    return true;
-}
-
-bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
-                 const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
-                 const unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                 const unordered_map<int64_t, int>& conditionTrackerMap,
-                 const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                 const unordered_map<int64_t, int>& stateAtomIdMap,
-                 const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-                 vector<sp<ConditionTracker>>& allConditionTrackers,
-                 const vector<ConditionState>& initialConditionCache,
-                 vector<sp<MetricProducer>>& allMetricProducers,
-                 unordered_map<int, vector<int>>& conditionToMetricMap,
-                 unordered_map<int, vector<int>>& trackerToMetricMap,
-                 unordered_map<int64_t, int>& metricMap, std::set<int64_t>& noReportMetricIds,
-                 unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
-                 unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
-                 vector<int>& metricsWithActivation) {
-    sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
-    sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchingTrackers);
-    const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
-                                config.event_metric_size() + config.gauge_metric_size() +
-                                config.value_metric_size();
-    allMetricProducers.reserve(allMetricsCount);
-
-    // Construct map from metric id to metric activation index. The map will be used to determine
-    // the metric activation corresponding to a metric.
-    unordered_map<int64_t, int> metricToActivationMap;
-    for (int i = 0; i < config.metric_activation_size(); i++) {
-        const MetricActivation& metricActivation = config.metric_activation(i);
-        int64_t metricId = metricActivation.metric_id();
-        if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
-            ALOGE("Metric %lld has multiple MetricActivations", (long long)metricId);
-            return false;
-        }
-        metricToActivationMap.insert({metricId, i});
-    }
-
-    // Build MetricProducers for each metric defined in config.
-    // build CountMetricProducer
-    for (int i = 0; i < config.count_metric_size(); i++) {
-        int metricIndex = allMetricProducers.size();
-        const CountMetric& metric = config.count_metric(i);
-        metricMap.insert({metric.id(), metricIndex});
-        optional<sp<MetricProducer>> producer = createCountMetricProducerAndUpdateMetadata(
-                key, config, timeBaseTimeNs, currentTimeNs, metric, metricIndex,
-                allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
-                conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
-                allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
-                activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                metricsWithActivation);
-        if (!producer) {
-            return false;
-        }
-        allMetricProducers.push_back(producer.value());
-    }
-
-    // build DurationMetricProducer
-    for (int i = 0; i < config.duration_metric_size(); i++) {
-        int metricIndex = allMetricProducers.size();
-        const DurationMetric& metric = config.duration_metric(i);
-        metricMap.insert({metric.id(), metricIndex});
-
-        optional<sp<MetricProducer>> producer = createDurationMetricProducerAndUpdateMetadata(
-                key, config, timeBaseTimeNs, currentTimeNs, metric, metricIndex,
-                allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
-                conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
-                allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
-                activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                metricsWithActivation);
-        if (!producer) {
-            return false;
-        }
-        allMetricProducers.push_back(producer.value());
-    }
-
-    // build EventMetricProducer
-    for (int i = 0; i < config.event_metric_size(); i++) {
-        int metricIndex = allMetricProducers.size();
-        const EventMetric& metric = config.event_metric(i);
-        metricMap.insert({metric.id(), metricIndex});
-        optional<sp<MetricProducer>> producer = createEventMetricProducerAndUpdateMetadata(
-                key, config, timeBaseTimeNs, metric, metricIndex, allAtomMatchingTrackers,
-                atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap,
-                initialConditionCache, wizard, metricToActivationMap, trackerToMetricMap,
-                conditionToMetricMap, activationAtomTrackerToMetricMap,
-                deactivationAtomTrackerToMetricMap, metricsWithActivation);
-        if (!producer) {
-            return false;
-        }
-        allMetricProducers.push_back(producer.value());
-    }
-
-    // build ValueMetricProducer
-    for (int i = 0; i < config.value_metric_size(); i++) {
-        int metricIndex = allMetricProducers.size();
-        const ValueMetric& metric = config.value_metric(i);
-        metricMap.insert({metric.id(), metricIndex});
-        optional<sp<MetricProducer>> producer = createValueMetricProducerAndUpdateMetadata(
-                key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex,
-                allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
-                conditionTrackerMap, initialConditionCache, wizard, matcherWizard, stateAtomIdMap,
-                allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
-                activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                metricsWithActivation);
-        if (!producer) {
-            return false;
-        }
-        allMetricProducers.push_back(producer.value());
-    }
-
-    // Gauge metrics.
-    for (int i = 0; i < config.gauge_metric_size(); i++) {
-        int metricIndex = allMetricProducers.size();
-        const GaugeMetric& metric = config.gauge_metric(i);
-        metricMap.insert({metric.id(), metricIndex});
-        optional<sp<MetricProducer>> producer = createGaugeMetricProducerAndUpdateMetadata(
-                key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex,
-                allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
-                conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
-                metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
-                activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-                metricsWithActivation);
-        if (!producer) {
-            return false;
-        }
-        allMetricProducers.push_back(producer.value());
-    }
-    for (int i = 0; i < config.no_report_metric_size(); ++i) {
-        const auto no_report_metric = config.no_report_metric(i);
-        if (metricMap.find(no_report_metric) == metricMap.end()) {
-            ALOGW("no_report_metric %" PRId64 " not exist", no_report_metric);
-            return false;
-        }
-        noReportMetricIds.insert(no_report_metric);
-    }
-
-    const set<int> whitelistedAtomIds(config.whitelisted_atom_ids().begin(),
-                                      config.whitelisted_atom_ids().end());
-    for (const auto& it : allMetricProducers) {
-        // Register metrics to StateTrackers
-        for (int atomId : it->getSlicedStateAtoms()) {
-            // Register listener for non-whitelisted atoms only. Using whitelisted atom as a sliced
-            // state atom is not allowed.
-            if (whitelistedAtomIds.find(atomId) == whitelistedAtomIds.end()) {
-                StateManager::getInstance().registerListener(atomId, it);
-            } else {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-bool initAlerts(const StatsdConfig& config, const unordered_map<int64_t, int>& metricProducerMap,
-                unordered_map<int64_t, int>& alertTrackerMap,
-                const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                vector<sp<MetricProducer>>& allMetricProducers,
-                vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
-    for (int i = 0; i < config.alert_size(); i++) {
-        const Alert& alert = config.alert(i);
-        alertTrackerMap.insert(std::make_pair(alert.id(), allAnomalyTrackers.size()));
-        optional<sp<AnomalyTracker>> anomalyTracker = createAnomalyTracker(
-                alert, anomalyAlarmMonitor, metricProducerMap, allMetricProducers);
-        if (!anomalyTracker) {
-            return false;
-        }
-        allAnomalyTrackers.push_back(anomalyTracker.value());
-    }
-    if (!initSubscribersForSubscriptionType(config, Subscription::ALERT, alertTrackerMap,
-                                            allAnomalyTrackers)) {
-        return false;
-    }
-    return true;
-}
-
-bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
-                const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
-                const int64_t currentTimeNs, vector<sp<AlarmTracker>>& allAlarmTrackers) {
-    unordered_map<int64_t, int> alarmTrackerMap;
-    int64_t startMillis = timeBaseNs / 1000 / 1000;
-    int64_t currentTimeMillis = currentTimeNs / 1000 / 1000;
-    for (int i = 0; i < config.alarm_size(); i++) {
-        const Alarm& alarm = config.alarm(i);
-        if (alarm.offset_millis() <= 0) {
-            ALOGW("Alarm offset_millis should be larger than 0.");
-            return false;
-        }
-        if (alarm.period_millis() <= 0) {
-            ALOGW("Alarm period_millis should be larger than 0.");
-            return false;
-        }
-        alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
-        allAlarmTrackers.push_back(
-                new AlarmTracker(startMillis, currentTimeMillis, alarm, key, periodicAlarmMonitor));
-    }
-    if (!initSubscribersForSubscriptionType(config, Subscription::ALARM, alarmTrackerMap,
-                                            allAlarmTrackers)) {
-        return false;
-    }
-    return true;
-}
-
-bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
-                      const sp<StatsPullerManager>& pullerManager,
-                      const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                      const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
-                      const int64_t currentTimeNs, set<int>& allTagIds,
-                      vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                      unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                      vector<sp<ConditionTracker>>& allConditionTrackers,
-                      unordered_map<int64_t, int>& conditionTrackerMap,
-                      vector<sp<MetricProducer>>& allMetricProducers,
-                      unordered_map<int64_t, int>& metricProducerMap,
-                      vector<sp<AnomalyTracker>>& allAnomalyTrackers,
-                      vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
-                      unordered_map<int, std::vector<int>>& conditionToMetricMap,
-                      unordered_map<int, std::vector<int>>& trackerToMetricMap,
-                      unordered_map<int, std::vector<int>>& trackerToConditionMap,
-                      unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-                      unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-                      unordered_map<int64_t, int>& alertTrackerMap,
-                      vector<int>& metricsWithActivation, map<int64_t, uint64_t>& stateProtoHashes,
-                      set<int64_t>& noReportMetricIds) {
-    vector<ConditionState> initialConditionCache;
-    unordered_map<int64_t, int> stateAtomIdMap;
-    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
-
-    if (!initAtomMatchingTrackers(config, uidMap, atomMatchingTrackerMap, allAtomMatchingTrackers,
-                                  allTagIds)) {
-        ALOGE("initAtomMatchingTrackers failed");
-        return false;
-    }
-    VLOG("initAtomMatchingTrackers succeed...");
-
-    if (!initConditions(key, config, atomMatchingTrackerMap, conditionTrackerMap,
-                        allConditionTrackers, trackerToConditionMap, initialConditionCache)) {
-        ALOGE("initConditionTrackers failed");
-        return false;
-    }
-
-    if (!initStates(config, stateAtomIdMap, allStateGroupMaps, stateProtoHashes)) {
-        ALOGE("initStates failed");
-        return false;
-    }
-    if (!initMetrics(key, config, timeBaseNs, currentTimeNs, pullerManager, atomMatchingTrackerMap,
-                     conditionTrackerMap, allAtomMatchingTrackers, stateAtomIdMap,
-                     allStateGroupMaps, allConditionTrackers, initialConditionCache,
-                     allMetricProducers, conditionToMetricMap, trackerToMetricMap,
-                     metricProducerMap, noReportMetricIds, activationAtomTrackerToMetricMap,
-                     deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
-        ALOGE("initMetricProducers failed");
-        return false;
-    }
-    if (!initAlerts(config, metricProducerMap, alertTrackerMap, anomalyAlarmMonitor,
-                    allMetricProducers, allAnomalyTrackers)) {
-        ALOGE("initAlerts failed");
-        return false;
-    }
-    if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
-                    allPeriodicAlarmTrackers)) {
-        ALOGE("initAlarms failed");
-        return false;
-    }
-
-    return true;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h
deleted file mode 100644
index 84e1e4e..0000000
--- a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "anomaly/AlarmTracker.h"
-#include "condition/ConditionTracker.h"
-#include "external/StatsPullerManager.h"
-#include "matchers/AtomMatchingTracker.h"
-#include "metrics/MetricProducer.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Helper functions for creating, validating, and updating config components from StatsdConfig.
-// Should only be called from metrics_manager_util and config_update_utils.
-
-// Create a AtomMatchingTracker.
-// input:
-// [logMatcher]: the input AtomMatcher from the StatsdConfig
-// [index]: the index of the matcher
-// output:
-// new AtomMatchingTracker, or null if the tracker is unable to be created
-sp<AtomMatchingTracker> createAtomMatchingTracker(const AtomMatcher& logMatcher, const int index,
-                                                  const sp<UidMap>& uidMap);
-
-// Create a ConditionTracker.
-// input:
-// [predicate]: the input Predicate from the StatsdConfig
-// [index]: the index of the condition tracker
-// [atomMatchingTrackerMap]: map of atom matcher id to its index in allAtomMatchingTrackers
-// output:
-// new ConditionTracker, or null if the tracker is unable to be created
-sp<ConditionTracker> createConditionTracker(
-        const ConfigKey& key, const Predicate& predicate, const int index,
-        const unordered_map<int64_t, int>& atomMatchingTrackerMap);
-
-// Get the hash of a metric, combining the activation if the metric has one.
-bool getMetricProtoHash(const StatsdConfig& config, const google::protobuf::MessageLite& metric,
-                        const int64_t id,
-                        const std::unordered_map<int64_t, int>& metricToActivationMap,
-                        uint64_t& metricHash);
-
-// 1. Validates matcher existence
-// 2. Enforces matchers with dimensions and those used for trigger_event are about one atom
-// 3. Gets matcher index and updates tracker to metric map
-bool handleMetricWithAtomMatchingTrackers(
-        const int64_t matcherId, const int metricIndex, const bool enforceOneAtom,
-        const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        std::unordered_map<int, std::vector<int>>& trackerToMetricMap, int& logTrackerIndex);
-
-// 1. Validates condition existence, including those in links
-// 2. Gets condition index and updates condition to metric map
-bool handleMetricWithConditions(
-        const int64_t condition, const int metricIndex,
-        const std::unordered_map<int64_t, int>& conditionTrackerMap,
-        const ::google::protobuf::RepeatedPtrField<::android::os::statsd::MetricConditionLink>&
-                links,
-        const std::vector<sp<ConditionTracker>>& allConditionTrackers, int& conditionIndex,
-        std::unordered_map<int, std::vector<int>>& conditionToMetricMap);
-
-// Validates a metricActivation and populates state.
-// Fills the new event activation/deactivation maps, preserving the existing activations.
-// Returns false if there are errors.
-bool handleMetricActivationOnConfigUpdate(
-        const StatsdConfig& config, const int64_t metricId, const int metricIndex,
-        const std::unordered_map<int64_t, int>& metricToActivationMap,
-        const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
-        const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
-        const std::unordered_map<int, shared_ptr<Activation>>& oldEventActivationMap,
-        std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation,
-        std::unordered_map<int, shared_ptr<Activation>>& newEventActivationMap,
-        std::unordered_map<int, std::vector<shared_ptr<Activation>>>& newEventDeactivationMap);
-
-// Creates a CountMetricProducer and updates the vectors/maps used by MetricsManager with
-// the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
-optional<sp<MetricProducer>> createCountMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const int64_t currentTimeNs, const CountMetric& metric, const int metricIndex,
-        const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        std::vector<sp<ConditionTracker>>& allConditionTrackers,
-        const std::unordered_map<int64_t, int>& conditionTrackerMap,
-        const std::vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const std::unordered_map<int64_t, int>& stateAtomIdMap,
-        const std::unordered_map<int64_t, std::unordered_map<int, int64_t>>& allStateGroupMaps,
-        const std::unordered_map<int64_t, int>& metricToActivationMap,
-        std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-        std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation);
-
-// Creates a DurationMetricProducer and updates the vectors/maps used by MetricsManager with
-// the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
-optional<sp<MetricProducer>> createDurationMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const int64_t currentTimeNs, const DurationMetric& metric, const int metricIndex,
-        const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        std::vector<sp<ConditionTracker>>& allConditionTrackers,
-        const std::unordered_map<int64_t, int>& conditionTrackerMap,
-        const std::vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const std::unordered_map<int64_t, int>& stateAtomIdMap,
-        const std::unordered_map<int64_t, std::unordered_map<int, int64_t>>& allStateGroupMaps,
-        const std::unordered_map<int64_t, int>& metricToActivationMap,
-        std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-        std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation);
-
-// Creates an EventMetricProducer and updates the vectors/maps used by MetricsManager with
-// the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
-optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const EventMetric& metric, const int metricIndex,
-        const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        std::vector<sp<ConditionTracker>>& allConditionTrackers,
-        const std::unordered_map<int64_t, int>& conditionTrackerMap,
-        const std::vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const std::unordered_map<int64_t, int>& metricToActivationMap,
-        std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-        std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation);
-
-// Creates a CountMetricProducer and updates the vectors/maps used by MetricsManager with
-// the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
-optional<sp<MetricProducer>> createValueMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
-        const ValueMetric& metric, const int metricIndex,
-        const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        std::vector<sp<ConditionTracker>>& allConditionTrackers,
-        const std::unordered_map<int64_t, int>& conditionTrackerMap,
-        const std::vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const std::unordered_map<int64_t, int>& stateAtomIdMap,
-        const std::unordered_map<int64_t, std::unordered_map<int, int64_t>>& allStateGroupMaps,
-        const std::unordered_map<int64_t, int>& metricToActivationMap,
-        std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-        std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation);
-
-// Creates a GaugeMetricProducer and updates the vectors/maps used by MetricsManager with
-// the appropriate indices. Returns an sp to the producer, or nullopt if there was an error.
-optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
-        const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
-        const GaugeMetric& metric, const int metricIndex,
-        const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        std::vector<sp<ConditionTracker>>& allConditionTrackers,
-        const std::unordered_map<int64_t, int>& conditionTrackerMap,
-        const std::vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
-        const sp<EventMatcherWizard>& matcherWizard,
-        const std::unordered_map<int64_t, int>& metricToActivationMap,
-        std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-        std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation);
-
-// Creates an AnomalyTracker and adds it to the appropriate metric.
-// Returns an sp to the AnomalyTracker, or nullopt if there was an error.
-optional<sp<AnomalyTracker>> createAnomalyTracker(
-        const Alert& alert, const sp<AlarmMonitor>& anomalyAlarmMonitor,
-        const std::unordered_map<int64_t, int>& metricProducerMap,
-        std::vector<sp<MetricProducer>>& allMetricProducers);
-
-// Templated function for adding subscriptions to alarms or alerts. Returns true if successful.
-template <typename T>
-bool initSubscribersForSubscriptionType(const StatsdConfig& config,
-                                        const Subscription_RuleType ruleType,
-                                        const std::unordered_map<int64_t, int>& ruleMap,
-                                        std::vector<T>& allRules) {
-    for (int i = 0; i < config.subscription_size(); ++i) {
-        const Subscription& subscription = config.subscription(i);
-        if (subscription.rule_type() != ruleType) {
-            continue;
-        }
-        if (subscription.subscriber_information_case() ==
-            Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
-            ALOGW("subscription \"%lld\" has no subscriber info.\"", (long long)subscription.id());
-            return false;
-        }
-        const auto& itr = ruleMap.find(subscription.rule_id());
-        if (itr == ruleMap.end()) {
-            ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
-                  (long long)subscription.id(), (long long)subscription.rule_id());
-            return false;
-        }
-        const int ruleIndex = itr->second;
-        allRules[ruleIndex]->addSubscription(subscription);
-    }
-    return true;
-}
-
-// Helper functions for MetricsManager to initialize from StatsdConfig.
-// *Note*: only initStatsdConfig() should be called from outside.
-// All other functions are intermediate
-// steps, created to make unit tests easier. And most of the parameters in these
-// functions are temporary objects in the initialization phase.
-
-// Initialize the AtomMatchingTrackers.
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input StatsdConfig
-// output:
-// [atomMatchingTrackerMap]: this map should contain matcher name to index mapping
-// [allAtomMatchingTrackers]: should store the sp to all the AtomMatchingTracker
-// [allTagIds]: contains the set of all interesting tag ids to this config.
-bool initAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
-                              std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                              std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                              std::set<int>& allTagIds);
-
-// Initialize ConditionTrackers
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input config
-// [atomMatchingTrackerMap]: AtomMatchingTracker name to index mapping from previous step.
-// output:
-// [conditionTrackerMap]: this map should contain condition name to index mapping
-// [allConditionTrackers]: stores the sp to all the ConditionTrackers
-// [trackerToConditionMap]: contain the mapping from index of
-//                        log tracker to condition trackers that use the log tracker
-// [initialConditionCache]: stores the initial conditions for each ConditionTracker
-bool initConditions(const ConfigKey& key, const StatsdConfig& config,
-                    const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                    std::unordered_map<int64_t, int>& conditionTrackerMap,
-                    std::vector<sp<ConditionTracker>>& allConditionTrackers,
-                    std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
-                    std::vector<ConditionState>& initialConditionCache);
-
-// Initialize State maps using State protos in the config. These maps will
-// eventually be passed to MetricProducers to initialize their state info.
-// input:
-// [config]: the input config
-// output:
-// [stateAtomIdMap]: this map should contain the mapping from state ids to atom ids
-// [allStateGroupMaps]: this map should contain the mapping from states ids and state
-//                      values to state group ids for all states
-// [stateProtoHashes]: contains a map of state id to the hash of the State proto from the config
-bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
-                unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-                std::map<int64_t, uint64_t>& stateProtoHashes);
-
-// Initialize MetricProducers.
-// input:
-// [key]: the config key that this config belongs to
-// [config]: the input config
-// [timeBaseSec]: start time base for all metrics
-// [atomMatchingTrackerMap]: AtomMatchingTracker name to index mapping from previous step.
-// [conditionTrackerMap]: condition name to index mapping
-// [stateAtomIdMap]: contains the mapping from state ids to atom ids
-// [allStateGroupMaps]: contains the mapping from atom ids and state values to
-//                      state group ids for all states
-// output:
-// [allMetricProducers]: contains the list of sp to the MetricProducers created.
-// [conditionToMetricMap]: contains the mapping from condition tracker index to
-//                          the list of MetricProducer index
-// [trackerToMetricMap]: contains the mapping from log tracker to MetricProducer index.
-bool initMetrics(
-        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
-        const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
-        const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-        const std::unordered_map<int64_t, int>& conditionTrackerMap,
-        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-        const unordered_map<int64_t, int>& stateAtomIdMap,
-        const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
-        vector<sp<ConditionTracker>>& allConditionTrackers,
-        const std::vector<ConditionState>& initialConditionCache,
-        std::vector<sp<MetricProducer>>& allMetricProducers,
-        std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-        std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-        std::set<int64_t>& noReportMetricIds,
-        std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-        std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-        std::vector<int>& metricsWithActivation);
-
-// Initialize alarms
-// Is called both on initialize new configs and config updates since alarms do not have any state.
-bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
-                const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
-                const int64_t currentTimeNs, std::vector<sp<AlarmTracker>>& allAlarmTrackers);
-
-// Initialize MetricsManager from StatsdConfig.
-// Parameters are the members of MetricsManager. See MetricsManager for declaration.
-bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
-                      const sp<StatsPullerManager>& pullerManager,
-                      const sp<AlarmMonitor>& anomalyAlarmMonitor,
-                      const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
-                      const int64_t currentTimeNs, std::set<int>& allTagIds,
-                      std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                      std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
-                      std::vector<sp<ConditionTracker>>& allConditionTrackers,
-                      std::unordered_map<int64_t, int>& conditionTrackerMap,
-                      std::vector<sp<MetricProducer>>& allMetricProducers,
-                      std::unordered_map<int64_t, int>& metricProducerMap,
-                      vector<sp<AnomalyTracker>>& allAnomalyTrackers,
-                      vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
-                      std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
-                      std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
-                      std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
-                      std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
-                      std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
-                      std::unordered_map<int64_t, int>& alertTrackerMap,
-                      std::vector<int>& metricsWithActivation,
-                      std::map<int64_t, uint64_t>& stateProtoHashes,
-                      std::set<int64_t>& noReportMetricIds);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/packages/PackageInfoListener.h b/cmds/statsd/src/packages/PackageInfoListener.h
deleted file mode 100644
index 1bc84c5..0000000
--- a/cmds/statsd/src/packages/PackageInfoListener.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef STATSD_PACKAGE_INFO_LISTENER_H
-#define STATSD_PACKAGE_INFO_LISTENER_H
-
-#include <utils/RefBase.h>
-
-#include <string>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class PackageInfoListener : public virtual android::RefBase {
-public:
-    // Uid map will notify this listener that the app with apk name and uid has been upgraded to
-    // the specified version.
-    virtual void notifyAppUpgrade(const int64_t& eventTimeNs, const std::string& apk,
-                                  const int uid, const int64_t version) = 0;
-
-    // Notify interested listeners that the given apk and uid combination no longer exits.
-    virtual void notifyAppRemoved(const int64_t& eventTimeNs, const std::string& apk,
-                                  const int uid) = 0;
-
-    // Notify the listener that the UidMap snapshot is available.
-    virtual void onUidMapReceived(const int64_t& eventTimeNs) = 0;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // STATSD_PACKAGE_INFO_LISTENER_H
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
deleted file mode 100644
index acf40c8..0000000
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, versionCode 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.
- */
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "hash.h"
-#include "stats_log_util.h"
-#include "guardrail/StatsdStats.h"
-#include "packages/UidMap.h"
-
-#include <inttypes.h>
-
-using namespace android;
-
-using android::base::StringPrintf;
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_UINT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const int FIELD_ID_SNAPSHOT_PACKAGE_NAME = 1;
-const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION = 2;
-const int FIELD_ID_SNAPSHOT_PACKAGE_UID = 3;
-const int FIELD_ID_SNAPSHOT_PACKAGE_DELETED = 4;
-const int FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH = 5;
-const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING = 6;
-const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH = 7;
-const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER = 8;
-const int FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH = 9;
-const int FIELD_ID_SNAPSHOT_TIMESTAMP = 1;
-const int FIELD_ID_SNAPSHOT_PACKAGE_INFO = 2;
-const int FIELD_ID_SNAPSHOTS = 1;
-const int FIELD_ID_CHANGES = 2;
-const int FIELD_ID_CHANGE_DELETION = 1;
-const int FIELD_ID_CHANGE_TIMESTAMP = 2;
-const int FIELD_ID_CHANGE_PACKAGE = 3;
-const int FIELD_ID_CHANGE_UID = 4;
-const int FIELD_ID_CHANGE_NEW_VERSION = 5;
-const int FIELD_ID_CHANGE_PREV_VERSION = 6;
-const int FIELD_ID_CHANGE_PACKAGE_HASH = 7;
-const int FIELD_ID_CHANGE_NEW_VERSION_STRING = 8;
-const int FIELD_ID_CHANGE_PREV_VERSION_STRING = 9;
-const int FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH = 10;
-const int FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH = 11;
-
-UidMap::UidMap() : mBytesUsed(0) {}
-
-UidMap::~UidMap() {}
-
-sp<UidMap> UidMap::getInstance() {
-    static sp<UidMap> sInstance = new UidMap();
-    return sInstance;
-}
-
-bool UidMap::hasApp(int uid, const string& packageName) const {
-    lock_guard<mutex> lock(mMutex);
-
-    auto it = mMap.find(std::make_pair(uid, packageName));
-    return it != mMap.end() && !it->second.deleted;
-}
-
-string UidMap::normalizeAppName(const string& appName) const {
-    string normalizedName = appName;
-    std::transform(normalizedName.begin(), normalizedName.end(), normalizedName.begin(), ::tolower);
-    return normalizedName;
-}
-
-std::set<string> UidMap::getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const {
-    lock_guard<mutex> lock(mMutex);
-    return getAppNamesFromUidLocked(uid,returnNormalized);
-}
-
-std::set<string> UidMap::getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const {
-    std::set<string> names;
-    for (const auto& kv : mMap) {
-        if (kv.first.first == uid && !kv.second.deleted) {
-            names.insert(returnNormalized ? normalizeAppName(kv.first.second) : kv.first.second);
-        }
-    }
-    return names;
-}
-
-int64_t UidMap::getAppVersion(int uid, const string& packageName) const {
-    lock_guard<mutex> lock(mMutex);
-
-    auto it = mMap.find(std::make_pair(uid, packageName));
-    if (it == mMap.end() || it->second.deleted) {
-        return 0;
-    }
-    return it->second.versionCode;
-}
-
-void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
-                       const vector<int64_t>& versionCode, const vector<String16>& versionString,
-                       const vector<String16>& packageName, const vector<String16>& installer) {
-    wp<PackageInfoListener> broadcast = NULL;
-    {
-        lock_guard<mutex> lock(mMutex);  // Exclusively lock for updates.
-
-        std::unordered_map<std::pair<int, string>, AppData, PairHash> deletedApps;
-
-        // Copy all the deleted apps.
-        for (const auto& kv : mMap) {
-            if (kv.second.deleted) {
-                deletedApps[kv.first] = kv.second;
-            }
-        }
-
-        mMap.clear();
-        for (size_t j = 0; j < uid.size(); j++) {
-            string package = string(String8(packageName[j]).string());
-            mMap[std::make_pair(uid[j], package)] =
-                    AppData(versionCode[j], string(String8(versionString[j]).string()),
-                            string(String8(installer[j]).string()));
-        }
-
-        for (const auto& kv : deletedApps) {
-            auto mMapIt = mMap.find(kv.first);
-            if (mMapIt != mMap.end()) {
-                // Insert this deleted app back into the current map.
-                mMap[kv.first] = kv.second;
-            }
-        }
-
-        ensureBytesUsedBelowLimit();
-        StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
-        broadcast = mSubscriber;
-    }
-    // To avoid invoking callback while holding the internal lock. we get a copy of the listener
-    // and invoke the callback. It's still possible that after we copy the listener, it removes
-    // itself before we call it. It's then the listener's job to handle it (expect the callback to
-    // be called after listener is removed, and the listener should properly ignore it).
-    auto strongPtr = broadcast.promote();
-    if (strongPtr != NULL) {
-        strongPtr->onUidMapReceived(timestamp);
-    }
-}
-
-void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid,
-                       const int64_t& versionCode, const String16& versionString,
-                       const String16& installer) {
-    wp<PackageInfoListener> broadcast = NULL;
-    string appName = string(String8(app_16).string());
-    {
-        lock_guard<mutex> lock(mMutex);
-        int32_t prevVersion = 0;
-        string prevVersionString = "";
-        string newVersionString = string(String8(versionString).string());
-        bool found = false;
-        auto it = mMap.find(std::make_pair(uid, appName));
-        if (it != mMap.end()) {
-            found = true;
-            prevVersion = it->second.versionCode;
-            prevVersionString = it->second.versionString;
-            it->second.versionCode = versionCode;
-            it->second.versionString = newVersionString;
-            it->second.installer = string(String8(installer).string());
-            it->second.deleted = false;
-        }
-        if (!found) {
-            // Otherwise, we need to add an app at this uid.
-            mMap[std::make_pair(uid, appName)] =
-                    AppData(versionCode, newVersionString, string(String8(installer).string()));
-        } else {
-            // Only notify the listeners if this is an app upgrade. If this app is being installed
-            // for the first time, then we don't notify the listeners.
-            // It's also OK to split again if we're forming a partial bucket after re-installing an
-            // app after deletion.
-            broadcast = mSubscriber;
-        }
-        mChanges.emplace_back(false, timestamp, appName, uid, versionCode, newVersionString,
-                              prevVersion, prevVersionString);
-        mBytesUsed += kBytesChangeRecord;
-        ensureBytesUsedBelowLimit();
-        StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
-        StatsdStats::getInstance().setUidMapChanges(mChanges.size());
-    }
-
-    auto strongPtr = broadcast.promote();
-    if (strongPtr != NULL) {
-        strongPtr->notifyAppUpgrade(timestamp, appName, uid, versionCode);
-    }
-}
-
-void UidMap::ensureBytesUsedBelowLimit() {
-    size_t limit;
-    if (maxBytesOverride <= 0) {
-        limit = StatsdStats::kMaxBytesUsedUidMap;
-    } else {
-        limit = maxBytesOverride;
-    }
-    while (mBytesUsed > limit) {
-        ALOGI("Bytes used %zu is above limit %zu, need to delete something", mBytesUsed, limit);
-        if (mChanges.size() > 0) {
-            mBytesUsed -= kBytesChangeRecord;
-            mChanges.pop_front();
-            StatsdStats::getInstance().noteUidMapDropped(1);
-        }
-    }
-}
-
-void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid) {
-    wp<PackageInfoListener> broadcast = NULL;
-    string app = string(String8(app_16).string());
-    {
-        lock_guard<mutex> lock(mMutex);
-
-        int64_t prevVersion = 0;
-        string prevVersionString = "";
-        auto key = std::make_pair(uid, app);
-        auto it = mMap.find(key);
-        if (it != mMap.end() && !it->second.deleted) {
-            prevVersion = it->second.versionCode;
-            prevVersionString = it->second.versionString;
-            it->second.deleted = true;
-            mDeletedApps.push_back(key);
-        }
-        if (mDeletedApps.size() > StatsdStats::kMaxDeletedAppsInUidMap) {
-            // Delete the oldest one.
-            auto oldest = mDeletedApps.front();
-            mDeletedApps.pop_front();
-            mMap.erase(oldest);
-            StatsdStats::getInstance().noteUidMapAppDeletionDropped();
-        }
-        mChanges.emplace_back(true, timestamp, app, uid, 0, "", prevVersion, prevVersionString);
-        mBytesUsed += kBytesChangeRecord;
-        ensureBytesUsedBelowLimit();
-        StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
-        StatsdStats::getInstance().setUidMapChanges(mChanges.size());
-        broadcast = mSubscriber;
-    }
-
-    auto strongPtr = broadcast.promote();
-    if (strongPtr != NULL) {
-        strongPtr->notifyAppRemoved(timestamp, app, uid);
-    }
-}
-
-void UidMap::setListener(wp<PackageInfoListener> listener) {
-    lock_guard<mutex> lock(mMutex);  // Lock for updates
-    mSubscriber = listener;
-}
-
-void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) {
-    lock_guard<mutex> lock(mIsolatedMutex);
-
-    mIsolatedUidMap[isolatedUid] = parentUid;
-}
-
-void UidMap::removeIsolatedUid(int isolatedUid) {
-    lock_guard<mutex> lock(mIsolatedMutex);
-
-    auto it = mIsolatedUidMap.find(isolatedUid);
-    if (it != mIsolatedUidMap.end()) {
-        mIsolatedUidMap.erase(it);
-    }
-}
-
-int UidMap::getHostUidOrSelf(int uid) const {
-    lock_guard<mutex> lock(mIsolatedMutex);
-
-    auto it = mIsolatedUidMap.find(uid);
-    if (it != mIsolatedUidMap.end()) {
-        return it->second;
-    }
-    return uid;
-}
-
-void UidMap::clearOutput() {
-    mChanges.clear();
-    // Also update the guardrail trackers.
-    StatsdStats::getInstance().setUidMapChanges(0);
-    mBytesUsed = 0;
-    StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
-}
-
-int64_t UidMap::getMinimumTimestampNs() {
-    int64_t m = 0;
-    for (const auto& kv : mLastUpdatePerConfigKey) {
-        if (m == 0) {
-            m = kv.second;
-        } else if (kv.second < m) {
-            m = kv.second;
-        }
-    }
-    return m;
-}
-
-size_t UidMap::getBytesUsed() const {
-    return mBytesUsed;
-}
-
-void UidMap::writeUidMapSnapshot(int64_t timestamp, bool includeVersionStrings,
-                                 bool includeInstaller, const std::set<int32_t>& interestingUids,
-                                 std::set<string>* str_set, ProtoOutputStream* proto) {
-    lock_guard<mutex> lock(mMutex);
-
-    writeUidMapSnapshotLocked(timestamp, includeVersionStrings, includeInstaller, interestingUids,
-                              str_set, proto);
-}
-
-void UidMap::writeUidMapSnapshotLocked(int64_t timestamp, bool includeVersionStrings,
-                                       bool includeInstaller,
-                                       const std::set<int32_t>& interestingUids,
-                                       std::set<string>* str_set, ProtoOutputStream* proto) {
-    proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_TIMESTAMP, (long long)timestamp);
-    for (const auto& kv : mMap) {
-        if (!interestingUids.empty() &&
-            interestingUids.find(kv.first.first) == interestingUids.end()) {
-            continue;
-        }
-        uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                      FIELD_ID_SNAPSHOT_PACKAGE_INFO);
-        if (str_set != nullptr) {
-            str_set->insert(kv.first.second);
-            proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH,
-                         (long long)Hash64(kv.first.second));
-            if (includeVersionStrings) {
-                str_set->insert(kv.second.versionString);
-                proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING_HASH,
-                             (long long)Hash64(kv.second.versionString));
-            }
-            if (includeInstaller) {
-                str_set->insert(kv.second.installer);
-                proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER_HASH,
-                             (long long)Hash64(kv.second.installer));
-            }
-        } else {
-            proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_NAME, kv.first.second);
-            if (includeVersionStrings) {
-                proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_VERSION_STRING,
-                             kv.second.versionString);
-            }
-            if (includeInstaller) {
-                proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_INSTALLER,
-                             kv.second.installer);
-            }
-        }
-
-        proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION,
-                     (long long)kv.second.versionCode);
-        proto->write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_UID, kv.first.first);
-        proto->write(FIELD_TYPE_BOOL | FIELD_ID_SNAPSHOT_PACKAGE_DELETED, kv.second.deleted);
-        proto->end(token);
-    }
-}
-
-void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key, std::set<string>* str_set,
-                          bool includeVersionStrings, bool includeInstaller,
-                          ProtoOutputStream* proto) {
-    lock_guard<mutex> lock(mMutex);  // Lock for updates
-
-    for (const ChangeRecord& record : mChanges) {
-        if (record.timestampNs > mLastUpdatePerConfigKey[key]) {
-            uint64_t changesToken =
-                    proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CHANGES);
-            proto->write(FIELD_TYPE_BOOL | FIELD_ID_CHANGE_DELETION, (bool)record.deletion);
-            proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_TIMESTAMP,
-                         (long long)record.timestampNs);
-            if (str_set != nullptr) {
-                str_set->insert(record.package);
-                proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PACKAGE_HASH,
-                             (long long)Hash64(record.package));
-                if (includeVersionStrings) {
-                    str_set->insert(record.versionString);
-                    proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_NEW_VERSION_STRING_HASH,
-                                 (long long)Hash64(record.versionString));
-                    str_set->insert(record.prevVersionString);
-                    proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PREV_VERSION_STRING_HASH,
-                                 (long long)Hash64(record.prevVersionString));
-                }
-            } else {
-                proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PACKAGE, record.package);
-                if (includeVersionStrings) {
-                    proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_NEW_VERSION_STRING,
-                                 record.versionString);
-                    proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PREV_VERSION_STRING,
-                                 record.prevVersionString);
-                }
-            }
-
-            proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_UID, (int)record.uid);
-            proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_NEW_VERSION, (long long)record.version);
-            proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_PREV_VERSION,
-                         (long long)record.prevVersion);
-            proto->end(changesToken);
-        }
-    }
-
-    // Write snapshot from current uid map state.
-    uint64_t snapshotsToken =
-            proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SNAPSHOTS);
-    writeUidMapSnapshotLocked(timestamp, includeVersionStrings, includeInstaller,
-                              std::set<int32_t>() /*empty uid set means including every uid*/,
-                              str_set, proto);
-    proto->end(snapshotsToken);
-
-    int64_t prevMin = getMinimumTimestampNs();
-    mLastUpdatePerConfigKey[key] = timestamp;
-    int64_t newMin = getMinimumTimestampNs();
-
-    if (newMin > prevMin) {  // Delete anything possible now that the minimum has
-                             // moved forward.
-        int64_t cutoff_nanos = newMin;
-        for (auto it_changes = mChanges.begin(); it_changes != mChanges.end();) {
-            if (it_changes->timestampNs < cutoff_nanos) {
-                mBytesUsed -= kBytesChangeRecord;
-                it_changes = mChanges.erase(it_changes);
-            } else {
-                ++it_changes;
-            }
-        }
-    }
-    StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
-    StatsdStats::getInstance().setUidMapChanges(mChanges.size());
-}
-
-void UidMap::printUidMap(int out) const {
-    lock_guard<mutex> lock(mMutex);
-
-    for (const auto& kv : mMap) {
-        if (!kv.second.deleted) {
-            dprintf(out, "%s, v%" PRId64 ", %s, %s (%i)\n", kv.first.second.c_str(),
-                    kv.second.versionCode, kv.second.versionString.c_str(),
-                    kv.second.installer.c_str(), kv.first.first);
-        }
-    }
-}
-
-void UidMap::OnConfigUpdated(const ConfigKey& key) {
-    mLastUpdatePerConfigKey[key] = -1;
-}
-
-void UidMap::OnConfigRemoved(const ConfigKey& key) {
-    mLastUpdatePerConfigKey.erase(key);
-}
-
-set<int32_t> UidMap::getAppUid(const string& package) const {
-    lock_guard<mutex> lock(mMutex);
-
-    set<int32_t> results;
-    for (const auto& kv : mMap) {
-        if (kv.first.second == package && !kv.second.deleted) {
-            results.insert(kv.first.first);
-        }
-    }
-    return results;
-}
-
-// Note not all the following AIDs are used as uids. Some are used only for gids.
-// It's ok to leave them in the map, but we won't ever see them in the log's uid field.
-// App's uid starts from 10000, and will not overlap with the following AIDs.
-const std::map<string, uint32_t> UidMap::sAidToUidMapping = {{"AID_ROOT", 0},
-                                                             {"AID_SYSTEM", 1000},
-                                                             {"AID_RADIO", 1001},
-                                                             {"AID_BLUETOOTH", 1002},
-                                                             {"AID_GRAPHICS", 1003},
-                                                             {"AID_INPUT", 1004},
-                                                             {"AID_AUDIO", 1005},
-                                                             {"AID_CAMERA", 1006},
-                                                             {"AID_LOG", 1007},
-                                                             {"AID_COMPASS", 1008},
-                                                             {"AID_MOUNT", 1009},
-                                                             {"AID_WIFI", 1010},
-                                                             {"AID_ADB", 1011},
-                                                             {"AID_INSTALL", 1012},
-                                                             {"AID_MEDIA", 1013},
-                                                             {"AID_DHCP", 1014},
-                                                             {"AID_SDCARD_RW", 1015},
-                                                             {"AID_VPN", 1016},
-                                                             {"AID_KEYSTORE", 1017},
-                                                             {"AID_USB", 1018},
-                                                             {"AID_DRM", 1019},
-                                                             {"AID_MDNSR", 1020},
-                                                             {"AID_GPS", 1021},
-                                                             // {"AID_UNUSED1", 1022},
-                                                             {"AID_MEDIA_RW", 1023},
-                                                             {"AID_MTP", 1024},
-                                                             // {"AID_UNUSED2", 1025},
-                                                             {"AID_DRMRPC", 1026},
-                                                             {"AID_NFC", 1027},
-                                                             {"AID_SDCARD_R", 1028},
-                                                             {"AID_CLAT", 1029},
-                                                             {"AID_LOOP_RADIO", 1030},
-                                                             {"AID_MEDIA_DRM", 1031},
-                                                             {"AID_PACKAGE_INFO", 1032},
-                                                             {"AID_SDCARD_PICS", 1033},
-                                                             {"AID_SDCARD_AV", 1034},
-                                                             {"AID_SDCARD_ALL", 1035},
-                                                             {"AID_LOGD", 1036},
-                                                             {"AID_SHARED_RELRO", 1037},
-                                                             {"AID_DBUS", 1038},
-                                                             {"AID_TLSDATE", 1039},
-                                                             {"AID_MEDIA_EX", 1040},
-                                                             {"AID_AUDIOSERVER", 1041},
-                                                             {"AID_METRICS_COLL", 1042},
-                                                             {"AID_METRICSD", 1043},
-                                                             {"AID_WEBSERV", 1044},
-                                                             {"AID_DEBUGGERD", 1045},
-                                                             {"AID_MEDIA_CODEC", 1046},
-                                                             {"AID_CAMERASERVER", 1047},
-                                                             {"AID_FIREWALL", 1048},
-                                                             {"AID_TRUNKS", 1049},
-                                                             {"AID_NVRAM", 1050},
-                                                             {"AID_DNS", 1051},
-                                                             {"AID_DNS_TETHER", 1052},
-                                                             {"AID_WEBVIEW_ZYGOTE", 1053},
-                                                             {"AID_VEHICLE_NETWORK", 1054},
-                                                             {"AID_MEDIA_AUDIO", 1055},
-                                                             {"AID_MEDIA_VIDEO", 1056},
-                                                             {"AID_MEDIA_IMAGE", 1057},
-                                                             {"AID_TOMBSTONED", 1058},
-                                                             {"AID_MEDIA_OBB", 1059},
-                                                             {"AID_ESE", 1060},
-                                                             {"AID_OTA_UPDATE", 1061},
-                                                             {"AID_AUTOMOTIVE_EVS", 1062},
-                                                             {"AID_LOWPAN", 1063},
-                                                             {"AID_HSM", 1064},
-                                                             {"AID_RESERVED_DISK", 1065},
-                                                             {"AID_STATSD", 1066},
-                                                             {"AID_INCIDENTD", 1067},
-                                                             {"AID_SECURE_ELEMENT", 1068},
-                                                             {"AID_LMKD", 1069},
-                                                             {"AID_LLKD", 1070},
-                                                             {"AID_IORAPD", 1071},
-                                                             {"AID_GPU_SERVICE", 1072},
-                                                             {"AID_NETWORK_STACK", 1073},
-                                                             {"AID_GSID", 1074},
-                                                             {"AID_FSVERITY_CERT", 1075},
-                                                             {"AID_CREDSTORE", 1076},
-                                                             {"AID_EXTERNAL_STORAGE", 1077},
-                                                             {"AID_EXT_DATA_RW", 1078},
-                                                             {"AID_EXT_OBB_RW", 1079},
-                                                             {"AID_CONTEXT_HUB", 1080},
-                                                             {"AID_SHELL", 2000},
-                                                             {"AID_CACHE", 2001},
-                                                             {"AID_DIAG", 2002}};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
deleted file mode 100644
index 622321b..0000000
--- a/cmds/statsd/src/packages/UidMap.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "config/ConfigKey.h"
-#include "packages/PackageInfoListener.h"
-#include "stats_util.h"
-
-#include <gtest/gtest_prod.h>
-#include <stdio.h>
-#include <utils/RefBase.h>
-#include <utils/String16.h>
-
-#include <list>
-#include <mutex>
-#include <set>
-#include <string>
-#include <unordered_map>
-
-using namespace android;
-using namespace std;
-
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-struct AppData {
-    int64_t versionCode;
-    string versionString;
-    string installer;
-    bool deleted;
-
-    // Empty constructor needed for unordered map.
-    AppData() {
-    }
-
-    AppData(const int64_t v, const string& versionString, const string& installer)
-        : versionCode(v), versionString(versionString), installer(installer), deleted(false){};
-};
-
-// When calling appendUidMap, we retrieve all the ChangeRecords since the last
-// timestamp we called appendUidMap for this configuration key.
-struct ChangeRecord {
-    const bool deletion;
-    const int64_t timestampNs;
-    const string package;
-    const int32_t uid;
-    const int64_t version;
-    const int64_t prevVersion;
-    const string versionString;
-    const string prevVersionString;
-
-    ChangeRecord(const bool isDeletion, const int64_t timestampNs, const string& package,
-                 const int32_t uid, const int64_t version, const string versionString,
-                 const int64_t prevVersion, const string prevVersionString)
-        : deletion(isDeletion),
-          timestampNs(timestampNs),
-          package(package),
-          uid(uid),
-          version(version),
-          prevVersion(prevVersion),
-          versionString(versionString),
-          prevVersionString(prevVersionString) {
-    }
-};
-
-const unsigned int kBytesChangeRecord = sizeof(struct ChangeRecord);
-
-// UidMap keeps track of what the corresponding app name (APK name) and version code for every uid
-// at any given moment. This map must be updated by StatsCompanionService.
-class UidMap : public virtual android::RefBase {
-public:
-    UidMap();
-    ~UidMap();
-    static const std::map<std::string, uint32_t> sAidToUidMapping;
-
-    static sp<UidMap> getInstance();
-    /*
-     * All three inputs must be the same size, and the jth element in each array refers to the same
-     * tuple, ie. uid[j] corresponds to packageName[j] with versionCode[j].
-     */
-    void updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
-                   const vector<int64_t>& versionCode, const vector<String16>& versionString,
-                   const vector<String16>& packageName, const vector<String16>& installer);
-
-    void updateApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid,
-                   const int64_t& versionCode, const String16& versionString,
-                   const String16& installer);
-    void removeApp(const int64_t& timestamp, const String16& packageName, const int32_t& uid);
-
-    // Returns true if the given uid contains the specified app (eg. com.google.android.gms).
-    bool hasApp(int uid, const string& packageName) const;
-
-    // Returns the app names from uid.
-    std::set<string> getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const;
-
-    int64_t getAppVersion(int uid, const string& packageName) const;
-
-    // Helper for debugging contents of this uid map. Can be triggered with:
-    // adb shell cmd stats print-uid-map
-    void printUidMap(int outFd) const;
-
-    // Command for indicating to the map that StatsLogProcessor should be notified if an app is
-    // updated. This allows metric producers and managers to distinguish when the same uid or app
-    // represents a different version of an app.
-    void setListener(wp<PackageInfoListener> listener);
-
-    // Informs uid map that a config is added/updated. Used for keeping mConfigKeys up to date.
-    void OnConfigUpdated(const ConfigKey& key);
-
-    // Informs uid map that a config is removed. Used for keeping mConfigKeys up to date.
-    void OnConfigRemoved(const ConfigKey& key);
-
-    void assignIsolatedUid(int isolatedUid, int parentUid);
-    void removeIsolatedUid(int isolatedUid);
-
-    // Returns the host uid if it exists. Otherwise, returns the same uid that was passed-in.
-    virtual int getHostUidOrSelf(int uid) const;
-
-    // Gets all snapshots and changes that have occurred since the last output.
-    // If every config key has received a change or snapshot record, then this
-    // record is deleted.
-    void appendUidMap(const int64_t& timestamp, const ConfigKey& key, std::set<string>* str_set,
-                      bool includeVersionStrings, bool includeInstaller,
-                      ProtoOutputStream* proto);
-
-    // Forces the output to be cleared. We still generate a snapshot based on the current state.
-    // This results in extra data uploaded but helps us reconstruct the uid mapping on the server
-    // in case we lose a previous upload.
-    void clearOutput();
-
-    // Get currently cached value of memory used by UID map.
-    size_t getBytesUsed() const;
-
-    virtual std::set<int32_t> getAppUid(const string& package) const;
-
-    // Write current PackageInfoSnapshot to ProtoOutputStream.
-    // interestingUids: If not empty, only write the package info for these uids. If empty, write
-    //                  package info for all uids.
-    // str_set: if not null, add new string to the set and write str_hash to proto
-    //          if null, write string to proto.
-    void writeUidMapSnapshot(int64_t timestamp, bool includeVersionStrings, bool includeInstaller,
-                             const std::set<int32_t>& interestingUids, std::set<string>* str_set,
-                             ProtoOutputStream* proto);
-
-private:
-    std::set<string> getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const;
-    string normalizeAppName(const string& appName) const;
-
-    void writeUidMapSnapshotLocked(int64_t timestamp, bool includeVersionStrings,
-                                   bool includeInstaller, const std::set<int32_t>& interestingUids,
-                                   std::set<string>* str_set, ProtoOutputStream* proto);
-
-    mutable mutex mMutex;
-    mutable mutex mIsolatedMutex;
-
-    struct PairHash {
-        size_t operator()(std::pair<int, string> p) const noexcept {
-            std::hash<std::string> hash_fn;
-            return hash_fn(std::to_string(p.first) + p.second);
-        }
-    };
-    // Maps uid and package name to application data.
-    std::unordered_map<std::pair<int, string>, AppData, PairHash> mMap;
-
-    // Maps isolated uid to the parent uid. Any metrics for an isolated uid will instead contribute
-    // to the parent uid.
-    std::unordered_map<int, int> mIsolatedUidMap;
-
-    // Record the changes that can be provided with the uploads.
-    std::list<ChangeRecord> mChanges;
-
-    // Store which uid and apps represent deleted ones.
-    std::list<std::pair<int, string>> mDeletedApps;
-
-    // Notify StatsLogProcessor if there's an upgrade/removal in any app.
-    wp<PackageInfoListener> mSubscriber;
-
-    // Mapping of config keys we're aware of to the epoch time they last received an update. This
-    // lets us know it's safe to delete events older than the oldest update. The value is nanosec.
-    // Value of -1 denotes this config key has never received an upload.
-    std::unordered_map<ConfigKey, int64_t> mLastUpdatePerConfigKey;
-
-    // Returns the minimum value from mConfigKeys.
-    int64_t getMinimumTimestampNs();
-
-    // If our current used bytes is above the limit, then we clear out the earliest snapshot. If
-    // there are no more snapshots, then we clear out the earliest delta. We repeat the deletions
-    // until the memory consumed by mOutput is below the specified limit.
-    void ensureBytesUsedBelowLimit();
-
-    // Override used for testing the max memory allowed by uid map. 0 means we use the value
-    // specified in StatsdStats.h with the rest of the guardrails.
-    size_t maxBytesOverride = 0;
-
-    // Cache the size of mOutput;
-    size_t mBytesUsed;
-
-    // Allows unit-test to access private methods.
-    FRIEND_TEST(UidMapTest, TestClearingOutput);
-    FRIEND_TEST(UidMapTest, TestRemovedAppRetained);
-    FRIEND_TEST(UidMapTest, TestRemovedAppOverGuardrail);
-    FRIEND_TEST(UidMapTest, TestOutputIncludesAtLeastOneSnapshot);
-    FRIEND_TEST(UidMapTest, TestMemoryComputed);
-    FRIEND_TEST(UidMapTest, TestMemoryGuardrail);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp
deleted file mode 100644
index 9d8f0c2..0000000
--- a/cmds/statsd/src/shell/ShellSubscriber.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "ShellSubscriber.h"
-
-#include <android-base/file.h>
-
-#include "matchers/matcher_util.h"
-#include "stats_log_util.h"
-
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const static int FIELD_ID_ATOM = 1;
-
-void ShellSubscriber::startNewSubscription(int in, int out, int timeoutSec) {
-    int myToken = claimToken();
-    VLOG("ShellSubscriber: new subscription %d has come in", myToken);
-    mSubscriptionShouldEnd.notify_one();
-
-    shared_ptr<SubscriptionInfo> mySubscriptionInfo = make_shared<SubscriptionInfo>(in, out);
-    if (!readConfig(mySubscriptionInfo)) return;
-
-    {
-        std::unique_lock<std::mutex> lock(mMutex);
-        mSubscriptionInfo = mySubscriptionInfo;
-        spawnHelperThread(myToken);
-        waitForSubscriptionToEndLocked(mySubscriptionInfo, myToken, lock, timeoutSec);
-
-        if (mSubscriptionInfo == mySubscriptionInfo) {
-            mSubscriptionInfo = nullptr;
-        }
-
-    }
-}
-
-void ShellSubscriber::spawnHelperThread(int myToken) {
-    std::thread t([this, myToken] { pullAndSendHeartbeats(myToken); });
-    t.detach();
-}
-
-void ShellSubscriber::waitForSubscriptionToEndLocked(shared_ptr<SubscriptionInfo> myInfo,
-                                                     int myToken,
-                                                     std::unique_lock<std::mutex>& lock,
-                                                     int timeoutSec) {
-    if (timeoutSec > 0) {
-        mSubscriptionShouldEnd.wait_for(lock, timeoutSec * 1s, [this, myToken, &myInfo] {
-            return mToken != myToken || !myInfo->mClientAlive;
-        });
-    } else {
-        mSubscriptionShouldEnd.wait(lock, [this, myToken, &myInfo] {
-            return mToken != myToken || !myInfo->mClientAlive;
-        });
-    }
-}
-
-// Atomically claim the next token. Token numbers denote subscriber ordering.
-int ShellSubscriber::claimToken() {
-    std::unique_lock<std::mutex> lock(mMutex);
-    int myToken = ++mToken;
-    return myToken;
-}
-
-// Read and parse single config. There should only one config per input.
-bool ShellSubscriber::readConfig(shared_ptr<SubscriptionInfo> subscriptionInfo) {
-    // Read the size of the config.
-    size_t bufferSize;
-    if (!android::base::ReadFully(subscriptionInfo->mInputFd, &bufferSize, sizeof(bufferSize))) {
-        return false;
-    }
-
-    // Read the config.
-    vector<uint8_t> buffer(bufferSize);
-    if (!android::base::ReadFully(subscriptionInfo->mInputFd, buffer.data(), bufferSize)) {
-        return false;
-    }
-
-    // Parse the config.
-    ShellSubscription config;
-    if (!config.ParseFromArray(buffer.data(), bufferSize)) {
-        return false;
-    }
-
-    // Update SubscriptionInfo with state from config
-    for (const auto& pushed : config.pushed()) {
-        subscriptionInfo->mPushedMatchers.push_back(pushed);
-    }
-
-    for (const auto& pulled : config.pulled()) {
-        vector<string> packages;
-        vector<int32_t> uids;
-        for (const string& pkg : pulled.packages()) {
-            auto it = UidMap::sAidToUidMapping.find(pkg);
-            if (it != UidMap::sAidToUidMapping.end()) {
-                uids.push_back(it->second);
-            } else {
-                packages.push_back(pkg);
-            }
-        }
-
-        subscriptionInfo->mPulledInfo.emplace_back(pulled.matcher(), pulled.freq_millis(), packages,
-                                                   uids);
-        VLOG("adding matcher for pulled atom %d", pulled.matcher().atom_id());
-    }
-
-    return true;
-}
-
-void ShellSubscriber::pullAndSendHeartbeats(int myToken) {
-    VLOG("ShellSubscriber: helper thread %d starting", myToken);
-    while (true) {
-        int64_t sleepTimeMs = INT_MAX;
-        {
-            std::lock_guard<std::mutex> lock(mMutex);
-            if (!mSubscriptionInfo || mToken != myToken) {
-                VLOG("ShellSubscriber: helper thread %d done!", myToken);
-                return;
-            }
-
-            int64_t nowMillis = getElapsedRealtimeMillis();
-            int64_t nowNanos = getElapsedRealtimeNs();
-            for (PullInfo& pullInfo : mSubscriptionInfo->mPulledInfo) {
-                if (pullInfo.mPrevPullElapsedRealtimeMs + pullInfo.mInterval >= nowMillis) {
-                    continue;
-                }
-
-                vector<int32_t> uids;
-                getUidsForPullAtom(&uids, pullInfo);
-
-                vector<std::shared_ptr<LogEvent>> data;
-                mPullerMgr->Pull(pullInfo.mPullerMatcher.atom_id(), uids, nowNanos, &data);
-                VLOG("Pulled %zu atoms with id %d", data.size(), pullInfo.mPullerMatcher.atom_id());
-                writePulledAtomsLocked(data, pullInfo.mPullerMatcher);
-
-                pullInfo.mPrevPullElapsedRealtimeMs = nowMillis;
-            }
-
-            // Send a heartbeat, consisting of a data size of 0, if perfd hasn't recently received
-            // data from statsd. When it receives the data size of 0, perfd will not expect any
-            // atoms and recheck whether the subscription should end.
-            if (nowMillis - mLastWriteMs > kMsBetweenHeartbeats) {
-                attemptWriteToPipeLocked(/*dataSize=*/0);
-            }
-
-            // Determine how long to sleep before doing more work.
-            for (PullInfo& pullInfo : mSubscriptionInfo->mPulledInfo) {
-                int64_t nextPullTime = pullInfo.mPrevPullElapsedRealtimeMs + pullInfo.mInterval;
-                int64_t timeBeforePull = nextPullTime - nowMillis; // guaranteed to be non-negative
-                if (timeBeforePull < sleepTimeMs) sleepTimeMs = timeBeforePull;
-            }
-            int64_t timeBeforeHeartbeat = (mLastWriteMs + kMsBetweenHeartbeats) - nowMillis;
-            if (timeBeforeHeartbeat < sleepTimeMs) sleepTimeMs = timeBeforeHeartbeat;
-        }
-
-        VLOG("ShellSubscriber: helper thread %d sleeping for %lld ms", myToken,
-             (long long)sleepTimeMs);
-        std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
-    }
-}
-
-void ShellSubscriber::getUidsForPullAtom(vector<int32_t>* uids, const PullInfo& pullInfo) {
-    uids->insert(uids->end(), pullInfo.mPullUids.begin(), pullInfo.mPullUids.end());
-    // This is slow. Consider storing the uids per app and listening to uidmap updates.
-    for (const string& pkg : pullInfo.mPullPackages) {
-        set<int32_t> uidsForPkg = mUidMap->getAppUid(pkg);
-        uids->insert(uids->end(), uidsForPkg.begin(), uidsForPkg.end());
-    }
-    uids->push_back(DEFAULT_PULL_UID);
-}
-
-void ShellSubscriber::writePulledAtomsLocked(const vector<std::shared_ptr<LogEvent>>& data,
-                                             const SimpleAtomMatcher& matcher) {
-    mProto.clear();
-    int count = 0;
-    for (const auto& event : data) {
-        if (matchesSimple(mUidMap, matcher, *event)) {
-            count++;
-            uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
-                                              util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
-            event->ToProto(mProto);
-            mProto.end(atomToken);
-        }
-    }
-
-    if (count > 0) attemptWriteToPipeLocked(mProto.size());
-}
-
-void ShellSubscriber::onLogEvent(const LogEvent& event) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    if (!mSubscriptionInfo) return;
-
-    mProto.clear();
-    for (const auto& matcher : mSubscriptionInfo->mPushedMatchers) {
-        if (matchesSimple(mUidMap, matcher, event)) {
-            uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
-                                              util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
-            event.ToProto(mProto);
-            mProto.end(atomToken);
-            attemptWriteToPipeLocked(mProto.size());
-        }
-    }
-}
-
-// Tries to write the atom encoded in mProto to the pipe. If the write fails
-// because the read end of the pipe has closed, signals to other threads that
-// the subscription should end.
-void ShellSubscriber::attemptWriteToPipeLocked(size_t dataSize) {
-    // First, write the payload size.
-    if (!android::base::WriteFully(mSubscriptionInfo->mOutputFd, &dataSize, sizeof(dataSize))) {
-        mSubscriptionInfo->mClientAlive = false;
-        mSubscriptionShouldEnd.notify_one();
-        return;
-    }
-
-    // Then, write the payload if this is not just a heartbeat.
-    if (dataSize > 0 && !mProto.flush(mSubscriptionInfo->mOutputFd)) {
-        mSubscriptionInfo->mClientAlive = false;
-        mSubscriptionShouldEnd.notify_one();
-        return;
-    }
-
-    mLastWriteMs = getElapsedRealtimeMillis();
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/shell/ShellSubscriber.h b/cmds/statsd/src/shell/ShellSubscriber.h
deleted file mode 100644
index 4c05fa7..0000000
--- a/cmds/statsd/src/shell/ShellSubscriber.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include <android/util/ProtoOutputStream.h>
-#include <private/android_filesystem_config.h>
-
-#include <condition_variable>
-#include <mutex>
-#include <thread>
-
-#include "external/StatsPullerManager.h"
-#include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Handles atoms subscription via shell cmd.
- *
- * A shell subscription lasts *until shell exits*. Unlike config based clients, a shell client
- * communicates with statsd via file descriptors. They can subscribe pushed and pulled atoms.
- * The atoms are sent back to the client in real time, as opposed to keeping the data in memory.
- * Shell clients do not subscribe aggregated metrics, as they are responsible for doing the
- * aggregation after receiving the atom events.
- *
- * Shell clients pass ShellSubscription in the proto binary format. Clients can update the
- * subscription by sending a new subscription. The new subscription would replace the old one.
- * Input data stream format is:
- *
- * |size_t|subscription proto|size_t|subscription proto|....
- *
- * statsd sends the events back in Atom proto binary format. Each Atom message is preceded
- * with sizeof(size_t) bytes indicating the size of the proto message payload.
- *
- * The stream would be in the following format:
- * |size_t|shellData proto|size_t|shellData proto|....
- *
- * Only one shell subscriber is allowed at a time because each shell subscriber blocks one thread
- * until it exits.
- */
-class ShellSubscriber : public virtual RefBase {
-public:
-    ShellSubscriber(sp<UidMap> uidMap, sp<StatsPullerManager> pullerMgr)
-        : mUidMap(uidMap), mPullerMgr(pullerMgr){};
-
-    void startNewSubscription(int inFd, int outFd, int timeoutSec);
-
-    void onLogEvent(const LogEvent& event);
-
-private:
-    struct PullInfo {
-        PullInfo(const SimpleAtomMatcher& matcher, int64_t interval,
-                 const std::vector<std::string>& packages, const std::vector<int32_t>& uids)
-            : mPullerMatcher(matcher),
-              mInterval(interval),
-              mPrevPullElapsedRealtimeMs(0),
-              mPullPackages(packages),
-              mPullUids(uids) {
-        }
-        SimpleAtomMatcher mPullerMatcher;
-        int64_t mInterval;
-        int64_t mPrevPullElapsedRealtimeMs;
-        std::vector<std::string> mPullPackages;
-        std::vector<int32_t> mPullUids;
-    };
-
-    struct SubscriptionInfo {
-        SubscriptionInfo(const int& inputFd, const int& outputFd)
-            : mInputFd(inputFd), mOutputFd(outputFd), mClientAlive(true) {
-        }
-
-        int mInputFd;
-        int mOutputFd;
-        std::vector<SimpleAtomMatcher> mPushedMatchers;
-        std::vector<PullInfo> mPulledInfo;
-        bool mClientAlive;
-    };
-
-    int claimToken();
-
-    bool readConfig(std::shared_ptr<SubscriptionInfo> subscriptionInfo);
-
-    void spawnHelperThread(int myToken);
-
-    void waitForSubscriptionToEndLocked(std::shared_ptr<SubscriptionInfo> myInfo,
-                                        int myToken,
-                                        std::unique_lock<std::mutex>& lock,
-                                        int timeoutSec);
-
-    // Helper thread that pulls atoms at a regular frequency and sends
-    // heartbeats to perfd if statsd hasn't recently sent any data. Statsd must
-    // send heartbeats for perfd to escape a blocking read call and recheck if
-    // the user has terminated the subscription.
-    void pullAndSendHeartbeats(int myToken);
-
-    void writePulledAtomsLocked(const vector<std::shared_ptr<LogEvent>>& data,
-                                const SimpleAtomMatcher& matcher);
-
-    void getUidsForPullAtom(vector<int32_t>* uids, const PullInfo& pullInfo);
-
-    void attemptWriteToPipeLocked(size_t dataSize);
-
-    sp<UidMap> mUidMap;
-
-    sp<StatsPullerManager> mPullerMgr;
-
-    android::util::ProtoOutputStream mProto;
-
-    mutable std::mutex mMutex;
-
-    std::condition_variable mSubscriptionShouldEnd;
-
-    std::shared_ptr<SubscriptionInfo> mSubscriptionInfo = nullptr;
-
-    int mToken = 0;
-
-    const int32_t DEFAULT_PULL_UID = AID_SYSTEM;
-
-    // Tracks when we last send data to perfd. We need that time to determine
-    // when next to send a heartbeat.
-    int64_t mLastWriteMs = 0;
-    const int64_t kMsBetweenHeartbeats = 1000;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/shell/shell_config.proto b/cmds/statsd/src/shell/shell_config.proto
deleted file mode 100644
index 07d0310..0000000
--- a/cmds/statsd/src/shell/shell_config.proto
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.os";
-option java_outer_classname = "ShellConfig";
-
-import "frameworks/base/cmds/statsd/src/statsd_config.proto";
-
-message PulledAtomSubscription {
-    optional SimpleAtomMatcher matcher = 1;
-
-    /* gap between two pulls in milliseconds */
-    optional int32 freq_millis = 2;
-
-    /* Packages that the pull is requested from */
-    repeated string packages = 3;
-}
-
-message ShellSubscription {
-    repeated SimpleAtomMatcher pushed = 1;
-    repeated PulledAtomSubscription pulled = 2;
-}
\ No newline at end of file
diff --git a/cmds/statsd/src/shell/shell_data.proto b/cmds/statsd/src/shell/shell_data.proto
deleted file mode 100644
index ec41cbc..0000000
--- a/cmds/statsd/src/shell/shell_data.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.os.statsd";
-option java_outer_classname = "ShellDataProto";
-
-import "frameworks/proto_logging/stats/atoms.proto";
-
-// The output of shell subscription, including both pulled and pushed subscriptions.
-message ShellData {
-    repeated Atom atom = 1;
-}
diff --git a/cmds/statsd/src/socket/StatsSocketListener.cpp b/cmds/statsd/src/socket/StatsSocketListener.cpp
deleted file mode 100755
index b877cc9..0000000
--- a/cmds/statsd/src/socket/StatsSocketListener.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include <ctype.h>
-#include <limits.h>
-#include <stdio.h>
-#include <sys/cdefs.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <cutils/sockets.h>
-
-#include "StatsSocketListener.h"
-#include "guardrail/StatsdStats.h"
-#include "stats_log_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsSocketListener::StatsSocketListener(std::shared_ptr<LogEventQueue> queue)
-    : SocketListener(getLogSocket(), false /*start listen*/), mQueue(queue) {
-}
-
-StatsSocketListener::~StatsSocketListener() {
-}
-
-bool StatsSocketListener::onDataAvailable(SocketClient* cli) {
-    static bool name_set;
-    if (!name_set) {
-        prctl(PR_SET_NAME, "statsd.writer");
-        name_set = true;
-    }
-
-    // + 1 to ensure null terminator if MAX_PAYLOAD buffer is received
-    char buffer[sizeof(android_log_header_t) + LOGGER_ENTRY_MAX_PAYLOAD + 1];
-    struct iovec iov = {buffer, sizeof(buffer) - 1};
-
-    alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))];
-    struct msghdr hdr = {
-            NULL, 0, &iov, 1, control, sizeof(control), 0,
-    };
-
-    int socket = cli->getSocket();
-
-    // To clear the entire buffer is secure/safe, but this contributes to 1.68%
-    // overhead under logging load. We are safe because we check counts, but
-    // still need to clear null terminator
-    // memset(buffer, 0, sizeof(buffer));
-    ssize_t n = recvmsg(socket, &hdr, 0);
-    if (n <= (ssize_t)(sizeof(android_log_header_t))) {
-        return false;
-    }
-
-    buffer[n] = 0;
-
-    struct ucred* cred = NULL;
-
-    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
-    while (cmsg != NULL) {
-        if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
-            cred = (struct ucred*)CMSG_DATA(cmsg);
-            break;
-        }
-        cmsg = CMSG_NXTHDR(&hdr, cmsg);
-    }
-
-    struct ucred fake_cred;
-    if (cred == NULL) {
-        cred = &fake_cred;
-        cred->pid = 0;
-        cred->uid = DEFAULT_OVERFLOWUID;
-    }
-
-    uint8_t* ptr = ((uint8_t*)buffer) + sizeof(android_log_header_t);
-    n -= sizeof(android_log_header_t);
-
-    // When a log failed to write to statsd socket (e.g., due ot EBUSY), a special message would
-    // be sent to statsd when the socket communication becomes available again.
-    // The format is android_log_event_int_t with a single integer in the payload indicating the
-    // number of logs that failed. (*FORMAT MUST BE IN SYNC WITH system/core/libstats*)
-    // Note that all normal stats logs are in the format of event_list, so there won't be confusion.
-    //
-    // TODO(b/80538532): In addition to log it in StatsdStats, we should properly reset the config.
-    if (n == sizeof(android_log_event_long_t)) {
-        android_log_event_long_t* long_event = reinterpret_cast<android_log_event_long_t*>(ptr);
-        if (long_event->payload.type == EVENT_TYPE_LONG) {
-            int64_t composed_long = long_event->payload.data;
-
-            // format:
-            // |last_tag|dropped_count|
-            int32_t dropped_count = (int32_t)(0xffffffff & composed_long);
-            int32_t last_atom_tag = (int32_t)((0xffffffff00000000 & (uint64_t)composed_long) >> 32);
-
-            ALOGE("Found dropped events: %d error %d last atom tag %d from uid %d", dropped_count,
-                  long_event->header.tag, last_atom_tag, cred->uid);
-            StatsdStats::getInstance().noteLogLost((int32_t)getWallClockSec(), dropped_count,
-                                                   long_event->header.tag, last_atom_tag, cred->uid,
-                                                   cred->pid);
-            return true;
-        }
-    }
-
-    // move past the 4-byte StatsEventTag
-    uint8_t* msg = ptr + sizeof(uint32_t);
-    uint32_t len = n - sizeof(uint32_t);
-    uint32_t uid = cred->uid;
-    uint32_t pid = cred->pid;
-
-    int64_t oldestTimestamp;
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(uid, pid);
-    logEvent->parseBuffer(msg, len);
-
-    if (!mQueue->push(std::move(logEvent), &oldestTimestamp)) {
-        StatsdStats::getInstance().noteEventQueueOverflow(oldestTimestamp);
-    }
-
-    return true;
-}
-
-int StatsSocketListener::getLogSocket() {
-    static const char socketName[] = "statsdw";
-    int sock = android_get_control_socket(socketName);
-
-    if (sock < 0) {  // statsd started up in init.sh
-        sock = socket_local_server(socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM);
-
-        int on = 1;
-        if (setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
-            return -1;
-        }
-    }
-    return sock;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/socket/StatsSocketListener.h b/cmds/statsd/src/socket/StatsSocketListener.h
deleted file mode 100644
index 2167a56..0000000
--- a/cmds/statsd/src/socket/StatsSocketListener.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#pragma once
-
-#include <sysutils/SocketListener.h>
-#include <utils/RefBase.h>
-#include "logd/LogEventQueue.h"
-
-// DEFAULT_OVERFLOWUID is defined in linux/highuid.h, which is not part of
-// the uapi headers for userspace to use.  This value is filled in on the
-// out-of-band socket credentials if the OS fails to find one available.
-// One of the causes of this is if SO_PASSCRED is set, all the packets before
-// that point will have this value.  We also use it in a fake credential if
-// no socket credentials are supplied.
-#ifndef DEFAULT_OVERFLOWUID
-#define DEFAULT_OVERFLOWUID 65534
-#endif
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsSocketListener : public SocketListener, public virtual android::RefBase {
-public:
-    explicit StatsSocketListener(std::shared_ptr<LogEventQueue> queue);
-
-    virtual ~StatsSocketListener();
-
-protected:
-    virtual bool onDataAvailable(SocketClient* cli);
-
-private:
-    static int getLogSocket();
-    /**
-     * Who is going to get the events when they're read.
-     */
-    std::shared_ptr<LogEventQueue> mQueue;
-};
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/state/StateListener.h b/cmds/statsd/src/state/StateListener.h
deleted file mode 100644
index 6388001..0000000
--- a/cmds/statsd/src/state/StateListener.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019, 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.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-
-#include "HashableDimensionKey.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StateListener : public virtual RefBase {
-public:
-    StateListener(){};
-
-    virtual ~StateListener(){};
-
-    /**
-     * Interface for handling a state change.
-     *
-     * The old and new state values map to the original state values.
-     * StateTrackers only track the original state values and are unaware
-     * of higher-level state groups. MetricProducers hold information on
-     * state groups and are responsible for mapping original state values to
-     * the correct state group.
-     *
-     * [eventTimeNs]: Time of the state change log event.
-     * [atomId]: The id of the state atom
-     * [primaryKey]: The primary field values of the state atom
-     * [oldState]: Previous state value before state change
-     * [newState]: Current state value after state change
-     */
-    virtual void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
-                                const HashableDimensionKey& primaryKey, const FieldValue& oldState,
-                                const FieldValue& newState) = 0;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/state/StateManager.cpp b/cmds/statsd/src/state/StateManager.cpp
deleted file mode 100644
index c29afeb..0000000
--- a/cmds/statsd/src/state/StateManager.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2019, 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "StateManager.h"
-
-#include <private/android_filesystem_config.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StateManager::StateManager()
-    : mAllowedPkg({
-              "com.android.systemui",
-      }) {
-}
-
-StateManager& StateManager::getInstance() {
-    static StateManager sStateManager;
-    return sStateManager;
-}
-
-void StateManager::clear() {
-    mStateTrackers.clear();
-}
-
-void StateManager::onLogEvent(const LogEvent& event) {
-    // Only process state events from uids in AID_* and packages that are whitelisted in
-    // mAllowedPkg.
-    // Whitelisted AIDs are AID_ROOT and all AIDs in [1000, 2000)
-    if (event.GetUid() == AID_ROOT || (event.GetUid() >= 1000 && event.GetUid() < 2000) ||
-        mAllowedLogSources.find(event.GetUid()) != mAllowedLogSources.end()) {
-        if (mStateTrackers.find(event.GetTagId()) != mStateTrackers.end()) {
-            mStateTrackers[event.GetTagId()]->onLogEvent(event);
-        }
-    }
-}
-
-void StateManager::registerListener(const int32_t atomId, wp<StateListener> listener) {
-    // Check if state tracker already exists.
-    if (mStateTrackers.find(atomId) == mStateTrackers.end()) {
-        mStateTrackers[atomId] = new StateTracker(atomId);
-    }
-    mStateTrackers[atomId]->registerListener(listener);
-}
-
-void StateManager::unregisterListener(const int32_t atomId, wp<StateListener> listener) {
-    std::unique_lock<std::mutex> lock(mMutex);
-
-    // Hold the sp<> until the lock is released so that ~StateTracker() is
-    // not called while the lock is held.
-    sp<StateTracker> toRemove;
-
-    // Unregister listener from correct StateTracker
-    auto it = mStateTrackers.find(atomId);
-    if (it != mStateTrackers.end()) {
-        it->second->unregisterListener(listener);
-
-        // Remove the StateTracker if it has no listeners
-        if (it->second->getListenersCount() == 0) {
-            toRemove = it->second;
-            mStateTrackers.erase(it);
-        }
-    } else {
-        ALOGE("StateManager cannot unregister listener, StateTracker for atom %d does not exist",
-              atomId);
-    }
-    lock.unlock();
-}
-
-bool StateManager::getStateValue(const int32_t atomId, const HashableDimensionKey& key,
-                                 FieldValue* output) const {
-    auto it = mStateTrackers.find(atomId);
-    if (it != mStateTrackers.end()) {
-        return it->second->getStateValue(key, output);
-    }
-    return false;
-}
-
-void StateManager::updateLogSources(const sp<UidMap>& uidMap) {
-    mAllowedLogSources.clear();
-    for (const auto& pkg : mAllowedPkg) {
-        auto uids = uidMap->getAppUid(pkg);
-        mAllowedLogSources.insert(uids.begin(), uids.end());
-    }
-}
-
-void StateManager::notifyAppChanged(const string& apk, const sp<UidMap>& uidMap) {
-    if (mAllowedPkg.find(apk) != mAllowedPkg.end()) {
-        updateLogSources(uidMap);
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/state/StateManager.h b/cmds/statsd/src/state/StateManager.h
deleted file mode 100644
index 18c404c..0000000
--- a/cmds/statsd/src/state/StateManager.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2019, 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.
- */
-#pragma once
-
-#include <inttypes.h>
-#include <utils/RefBase.h>
-
-#include <set>
-#include <string>
-#include <unordered_map>
-
-#include "HashableDimensionKey.h"
-#include "packages/UidMap.h"
-#include "state/StateListener.h"
-#include "state/StateTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * This class is NOT thread safe.
- * It should only be used while StatsLogProcessor's lock is held.
- */
-class StateManager : public virtual RefBase {
-public:
-    StateManager();
-
-    ~StateManager(){};
-
-    // Returns a pointer to the single, shared StateManager object.
-    static StateManager& getInstance();
-
-    // Unregisters all listeners and removes all trackers from StateManager.
-    void clear();
-
-    // Notifies the correct StateTracker of an event.
-    void onLogEvent(const LogEvent& event);
-
-    // Notifies the StateTracker for the given atomId to register listener.
-    // If the correct StateTracker does not exist, a new StateTracker is created.
-    // Note: StateTrackers can be created for non-state atoms. They are essentially empty and
-    // do not perform any actions.
-    void registerListener(const int32_t atomId, wp<StateListener> listener);
-
-    // Notifies the correct StateTracker to unregister a listener
-    // and removes the tracker if it no longer has any listeners.
-    void unregisterListener(const int32_t atomId, wp<StateListener> listener);
-
-    // Returns true if the StateTracker exists and queries for the
-    // original state value mapped to the given query key. The state value is
-    // stored and output in a FieldValue class.
-    // Returns false if the StateTracker doesn't exist.
-    bool getStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
-                       FieldValue* output) const;
-
-    // Updates mAllowedLogSources with the latest uids for the packages that are allowed to log.
-    void updateLogSources(const sp<UidMap>& uidMap);
-
-    void notifyAppChanged(const string& apk, const sp<UidMap>& uidMap);
-
-    inline int getStateTrackersCount() const {
-        return mStateTrackers.size();
-    }
-
-    inline int getListenersCount(const int32_t atomId) const {
-        auto it = mStateTrackers.find(atomId);
-        if (it != mStateTrackers.end()) {
-            return it->second->getListenersCount();
-        }
-        return -1;
-    }
-
-private:
-    mutable std::mutex mMutex;
-
-    // Maps state atom ids to StateTrackers
-    std::unordered_map<int32_t, sp<StateTracker>> mStateTrackers;
-
-    // The package names that can log state events.
-    const std::set<std::string> mAllowedPkg;
-
-    // The combined uid sources (after translating pkg name to uid).
-    // State events from uids that are not in the list will be ignored to avoid state pollution.
-    std::set<int32_t> mAllowedLogSources;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/state/StateTracker.cpp b/cmds/statsd/src/state/StateTracker.cpp
deleted file mode 100644
index 41e525c..0000000
--- a/cmds/statsd/src/state/StateTracker.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2019, 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.
- */
-
-#define DEBUG true  // STOPSHIP if true
-#include "Log.h"
-
-#include "stats_util.h"
-
-#include "StateTracker.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StateTracker::StateTracker(const int32_t atomId) : mField(atomId, 0) {
-}
-
-void StateTracker::onLogEvent(const LogEvent& event) {
-    const int64_t eventTimeNs = event.GetElapsedTimestampNs();
-
-    // Parse event for primary field values i.e. primary key.
-    HashableDimensionKey primaryKey;
-    filterPrimaryKey(event.getValues(), &primaryKey);
-
-    FieldValue newState;
-    if (!getStateFieldValueFromLogEvent(event, &newState)) {
-        ALOGE("StateTracker error extracting state from log event. Missing exclusive state field.");
-        clearStateForPrimaryKey(eventTimeNs, primaryKey);
-        return;
-    }
-
-    mField.setField(newState.mField.getField());
-
-    if (newState.mValue.getType() != INT) {
-        ALOGE("StateTracker error extracting state from log event. Type: %d",
-              newState.mValue.getType());
-        clearStateForPrimaryKey(eventTimeNs, primaryKey);
-        return;
-    }
-
-    if (int resetState = event.getResetState(); resetState != -1) {
-        VLOG("StateTracker new reset state: %d", resetState);
-        const FieldValue resetStateFieldValue(mField, Value(resetState));
-        handleReset(eventTimeNs, resetStateFieldValue);
-        return;
-    }
-
-    const bool nested = newState.mAnnotations.isNested();
-    StateValueInfo* stateValueInfo = &mStateMap[primaryKey];
-    updateStateForPrimaryKey(eventTimeNs, primaryKey, newState, nested, stateValueInfo);
-}
-
-void StateTracker::registerListener(wp<StateListener> listener) {
-    mListeners.insert(listener);
-}
-
-void StateTracker::unregisterListener(wp<StateListener> listener) {
-    mListeners.erase(listener);
-}
-
-bool StateTracker::getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const {
-    output->mField = mField;
-
-    if (const auto it = mStateMap.find(queryKey); it != mStateMap.end()) {
-        output->mValue = it->second.state;
-        return true;
-    }
-
-    // Set the state value to kStateUnknown if query key is not found in state map.
-    output->mValue = kStateUnknown;
-    return false;
-}
-
-void StateTracker::handleReset(const int64_t eventTimeNs, const FieldValue& newState) {
-    VLOG("StateTracker handle reset");
-    for (auto& [primaryKey, stateValueInfo] : mStateMap) {
-        updateStateForPrimaryKey(eventTimeNs, primaryKey, newState,
-                                 false /* nested; treat this state change as not nested */,
-                                 &stateValueInfo);
-    }
-}
-
-void StateTracker::clearStateForPrimaryKey(const int64_t eventTimeNs,
-                                           const HashableDimensionKey& primaryKey) {
-    VLOG("StateTracker clear state for primary key");
-    const std::unordered_map<HashableDimensionKey, StateValueInfo>::iterator it =
-            mStateMap.find(primaryKey);
-
-    // If there is no entry for the primaryKey in mStateMap, then the state is already
-    // kStateUnknown.
-    const FieldValue state(mField, Value(kStateUnknown));
-    if (it != mStateMap.end()) {
-        updateStateForPrimaryKey(eventTimeNs, primaryKey, state,
-                                 false /* nested; treat this state change as not nested */,
-                                 &it->second);
-    }
-}
-
-void StateTracker::updateStateForPrimaryKey(const int64_t eventTimeNs,
-                                            const HashableDimensionKey& primaryKey,
-                                            const FieldValue& newState, const bool nested,
-                                            StateValueInfo* stateValueInfo) {
-    FieldValue oldState;
-    oldState.mField = mField;
-    oldState.mValue.setInt(stateValueInfo->state);
-    const int32_t oldStateValue = stateValueInfo->state;
-    const int32_t newStateValue = newState.mValue.int_value;
-
-    if (kStateUnknown == newStateValue) {
-        mStateMap.erase(primaryKey);
-    }
-
-    // Update state map for non-nested counting case.
-    // Every state event triggers a state overwrite.
-    if (!nested) {
-        stateValueInfo->state = newStateValue;
-        stateValueInfo->count = 1;
-
-        // Notify listeners if state has changed.
-        if (oldStateValue != newStateValue) {
-            notifyListeners(eventTimeNs, primaryKey, oldState, newState);
-        }
-        return;
-    }
-
-    // Update state map for nested counting case.
-    //
-    // Nested counting is only allowed for binary state events such as ON/OFF or
-    // ACQUIRE/RELEASE. For example, WakelockStateChanged might have the state
-    // events: ON, ON, OFF. The state will still be ON until we see the same
-    // number of OFF events as ON events.
-    //
-    // In atoms.proto, a state atom with nested counting enabled
-    // must only have 2 states. There is no enforcemnt here of this requirement.
-    // The atom must be logged correctly.
-    if (kStateUnknown == newStateValue) {
-        if (kStateUnknown != oldStateValue) {
-            notifyListeners(eventTimeNs, primaryKey, oldState, newState);
-        }
-    } else if (oldStateValue == kStateUnknown) {
-        stateValueInfo->state = newStateValue;
-        stateValueInfo->count = 1;
-        notifyListeners(eventTimeNs, primaryKey, oldState, newState);
-    } else if (oldStateValue == newStateValue) {
-        stateValueInfo->count++;
-    } else if (--stateValueInfo->count == 0) {
-        stateValueInfo->state = newStateValue;
-        stateValueInfo->count = 1;
-        notifyListeners(eventTimeNs, primaryKey, oldState, newState);
-    }
-}
-
-void StateTracker::notifyListeners(const int64_t eventTimeNs,
-                                   const HashableDimensionKey& primaryKey,
-                                   const FieldValue& oldState, const FieldValue& newState) {
-    for (auto l : mListeners) {
-        auto sl = l.promote();
-        if (sl != nullptr) {
-            sl->onStateChanged(eventTimeNs, mField.getTag(), primaryKey, oldState, newState);
-        }
-    }
-}
-
-bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output) {
-    const int exclusiveStateFieldIndex = event.getExclusiveStateFieldIndex();
-    if (-1 == exclusiveStateFieldIndex) {
-        ALOGE("error extracting state from log event. Missing exclusive state field.");
-        return false;
-    }
-
-    *output = event.getValues()[exclusiveStateFieldIndex];
-    return true;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h
deleted file mode 100644
index abd579e..0000000
--- a/cmds/statsd/src/state/StateTracker.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019, 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.
- */
-#pragma once
-
-#include <utils/RefBase.h>
-#include "HashableDimensionKey.h"
-#include "logd/LogEvent.h"
-
-#include "state/StateListener.h"
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StateTracker : public virtual RefBase {
-public:
-    StateTracker(const int32_t atomId);
-
-    virtual ~StateTracker(){};
-
-    // Updates state map and notifies all listeners if a state change occurs.
-    // Checks if a state change has occurred by getting the state value from
-    // the log event and comparing the old and new states.
-    void onLogEvent(const LogEvent& event);
-
-    // Adds new listeners to set of StateListeners. If a listener is already
-    // registered, it is ignored.
-    void registerListener(wp<StateListener> listener);
-
-    void unregisterListener(wp<StateListener> listener);
-
-    // The output is a FieldValue object that has mStateField as the field and
-    // the original state value (found using the given query key) as the value.
-    //
-    // If the key isn't mapped to a state or the key size doesn't match the
-    // number of primary fields, the output value is set to kStateUnknown.
-    bool getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const;
-
-    inline int getListenersCount() const {
-        return mListeners.size();
-    }
-
-    const static int kStateUnknown = -1;
-
-private:
-    struct StateValueInfo {
-        int32_t state = kStateUnknown;  // state value
-        int count = 0;                  // nested count (only used for binary states)
-    };
-
-    Field mField;
-
-    // Maps primary key to state value info
-    std::unordered_map<HashableDimensionKey, StateValueInfo> mStateMap;
-
-    // Set of all StateListeners (objects listening for state changes)
-    std::set<wp<StateListener>> mListeners;
-
-    // Reset all state values in map to the given state.
-    void handleReset(const int64_t eventTimeNs, const FieldValue& newState);
-
-    // Clears the state value mapped to the given primary key by setting it to kStateUnknown.
-    void clearStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey);
-
-    // Update the StateMap based on the received state value.
-    void updateStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey,
-                                  const FieldValue& newState, const bool nested,
-                                  StateValueInfo* stateValueInfo);
-
-    // Notify registered state listeners of state change.
-    void notifyListeners(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey,
-                         const FieldValue& oldState, const FieldValue& newState);
-};
-
-bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
deleted file mode 100644
index bb07963..0000000
--- a/cmds/statsd/src/stats_log.proto
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.os";
-option java_outer_classname = "StatsLog";
-
-import "frameworks/proto_logging/stats/atoms.proto";
-
-message DimensionsValue {
-  optional int32 field = 1;
-
-  oneof value {
-    string value_str = 2;
-    int32 value_int = 3;
-    int64 value_long = 4;
-    bool value_bool = 5;
-    float value_float = 6;
-    DimensionsValueTuple value_tuple = 7;
-    uint64 value_str_hash = 8;
-  }
-}
-
-message DimensionsValueTuple {
-  repeated DimensionsValue dimensions_value = 1;
-}
-
-message StateValue {
-  optional int32 atom_id = 1;
-
-  oneof contents {
-    int64 group_id = 2;
-    int32 value = 3;
-  }
-}
-
-message EventMetricData {
-  optional int64 elapsed_timestamp_nanos = 1;
-
-  optional Atom atom = 2;
-
-  optional int64 wall_clock_timestamp_nanos = 3 [deprecated = true];
-}
-
-message CountBucketInfo {
-  optional int64 start_bucket_elapsed_nanos = 1;
-
-  optional int64 end_bucket_elapsed_nanos = 2;
-
-  optional int64 count = 3;
-
-  optional int64 bucket_num = 4;
-
-  optional int64 start_bucket_elapsed_millis = 5;
-
-  optional int64 end_bucket_elapsed_millis = 6;
-}
-
-message CountMetricData {
-  optional DimensionsValue dimensions_in_what = 1;
-
-  repeated StateValue slice_by_state = 6;
-
-  repeated CountBucketInfo bucket_info = 3;
-
-  repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
-  optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
-  repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message DurationBucketInfo {
-  optional int64 start_bucket_elapsed_nanos = 1;
-
-  optional int64 end_bucket_elapsed_nanos = 2;
-
-  optional int64 duration_nanos = 3;
-
-  optional int64 bucket_num = 4;
-
-  optional int64 start_bucket_elapsed_millis = 5;
-
-  optional int64 end_bucket_elapsed_millis = 6;
-}
-
-message DurationMetricData {
-  optional DimensionsValue dimensions_in_what = 1;
-
-  repeated StateValue slice_by_state = 6;
-
-  repeated DurationBucketInfo bucket_info = 3;
-
-  repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
-  optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
-  repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message ValueBucketInfo {
-  optional int64 start_bucket_elapsed_nanos = 1;
-
-  optional int64 end_bucket_elapsed_nanos = 2;
-
-  optional int64 value = 3 [deprecated = true];
-
-  oneof single_value {
-      int64 value_long = 7 [deprecated = true];
-
-      double value_double = 8 [deprecated = true];
-  }
-
-  message Value {
-      optional int32 index = 1;
-      oneof value {
-          int64 value_long = 2;
-          double value_double = 3;
-      }
-  }
-
-  repeated Value values = 9;
-
-  optional int64 bucket_num = 4;
-
-  optional int64 start_bucket_elapsed_millis = 5;
-
-  optional int64 end_bucket_elapsed_millis = 6;
-
-  optional int64 condition_true_nanos = 10;
-}
-
-message ValueMetricData {
-  optional DimensionsValue dimensions_in_what = 1;
-
-  repeated StateValue slice_by_state = 6;
-
-  repeated ValueBucketInfo bucket_info = 3;
-
-  repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
-  optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
-  repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message GaugeBucketInfo {
-  optional int64 start_bucket_elapsed_nanos = 1;
-
-  optional int64 end_bucket_elapsed_nanos = 2;
-
-  repeated Atom atom = 3;
-
-  repeated int64 elapsed_timestamp_nanos = 4;
-
-  repeated int64 wall_clock_timestamp_nanos = 5 [deprecated = true];
-
-  optional int64 bucket_num = 6;
-
-  optional int64 start_bucket_elapsed_millis = 7;
-
-  optional int64 end_bucket_elapsed_millis = 8;
-}
-
-message GaugeMetricData {
-  optional DimensionsValue dimensions_in_what = 1;
-
-  // Currently unsupported
-  repeated StateValue slice_by_state = 6;
-
-  repeated GaugeBucketInfo bucket_info = 3;
-
-  repeated DimensionsValue dimension_leaf_values_in_what = 4;
-
-  optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
-
-  repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
-}
-
-message StatsLogReport {
-  optional int64 metric_id = 1;
-
-  // Fields 2 and 3 are reserved.
-
-  // Keep this in sync with BucketDropReason enum in MetricProducer.h.
-  enum BucketDropReason {
-      // For ValueMetric, a bucket is dropped during a dump report request iff
-      // current bucket should be included, a pull is needed (pulled metric and
-      // condition is true), and we are under fast time constraints.
-      DUMP_REPORT_REQUESTED = 1;
-      EVENT_IN_WRONG_BUCKET = 2;
-      CONDITION_UNKNOWN = 3;
-      PULL_FAILED = 4;
-      PULL_DELAYED = 5;
-      DIMENSION_GUARDRAIL_REACHED = 6;
-      MULTIPLE_BUCKETS_SKIPPED = 7;
-      // Not an invalid bucket case, but the bucket is dropped.
-      BUCKET_TOO_SMALL = 8;
-      // Not an invalid bucket case, but the bucket is skipped.
-      NO_DATA = 9;
-  };
-
-  message DropEvent {
-      optional BucketDropReason drop_reason = 1;
-
-      optional int64 drop_time_millis = 2;
-  }
-
-  message SkippedBuckets {
-      optional int64 start_bucket_elapsed_nanos = 1;
-
-      optional int64 end_bucket_elapsed_nanos = 2;
-
-      optional int64 start_bucket_elapsed_millis = 3;
-
-      optional int64 end_bucket_elapsed_millis = 4;
-
-      // The number of drop events is capped by StatsdStats::kMaxLoggedBucketDropEvents.
-      // The current maximum is 10 drop events.
-      repeated DropEvent drop_event = 5;
-  }
-
-  message EventMetricDataWrapper {
-    repeated EventMetricData data = 1;
-  }
-  message CountMetricDataWrapper {
-    repeated CountMetricData data = 1;
-  }
-  message DurationMetricDataWrapper {
-    repeated DurationMetricData data = 1;
-  }
-  message ValueMetricDataWrapper {
-    repeated ValueMetricData data = 1;
-    repeated SkippedBuckets skipped = 2;
-  }
-
-  message GaugeMetricDataWrapper {
-    repeated GaugeMetricData data = 1;
-    repeated SkippedBuckets skipped = 2;
-  }
-
-  oneof data {
-    EventMetricDataWrapper event_metrics = 4;
-    CountMetricDataWrapper count_metrics = 5;
-    DurationMetricDataWrapper duration_metrics = 6;
-    ValueMetricDataWrapper value_metrics = 7;
-    GaugeMetricDataWrapper gauge_metrics = 8;
-  }
-
-  optional int64 time_base_elapsed_nano_seconds = 9;
-
-  optional int64 bucket_size_nano_seconds = 10;
-
-  optional DimensionsValue dimensions_path_in_what = 11;
-
-  optional DimensionsValue dimensions_path_in_condition = 12 [deprecated = true];
-
-  // DO NOT USE field 13.
-
-  optional bool is_active = 14;
-}
-
-message UidMapping {
-    message PackageInfoSnapshot {
-        message PackageInfo {
-            optional string name = 1;
-
-            optional int64 version = 2;
-
-            optional int32 uid = 3;
-
-            optional bool deleted = 4;
-
-            optional uint64 name_hash = 5;
-
-            optional string version_string = 6;
-
-            optional uint64 version_string_hash = 7;
-
-            optional string installer = 8;
-
-            optional uint64 installer_hash = 9;
-        }
-        optional int64 elapsed_timestamp_nanos = 1;
-
-        repeated PackageInfo package_info = 2;
-    }
-    repeated PackageInfoSnapshot snapshots = 1;
-
-    message Change {
-        optional bool deletion = 1;
-
-        optional int64 elapsed_timestamp_nanos = 2;
-        optional string app = 3;
-        optional int32 uid = 4;
-
-        optional int64 new_version = 5;
-        optional int64 prev_version = 6;
-        optional uint64 app_hash = 7;
-        optional string new_version_string = 8;
-        optional string prev_version_string = 9;
-        optional uint64 new_version_string_hash = 10;
-        optional uint64 prev_version_string_hash = 11;
-    }
-    repeated Change changes = 2;
-}
-
-message ConfigMetricsReport {
-  repeated StatsLogReport metrics = 1;
-
-  optional UidMapping uid_map = 2;
-
-  optional int64 last_report_elapsed_nanos = 3;
-
-  optional int64 current_report_elapsed_nanos = 4;
-
-  optional int64 last_report_wall_clock_nanos = 5;
-
-  optional int64 current_report_wall_clock_nanos = 6;
-
-  message Annotation {
-      optional int64 field_int64 = 1;
-      optional int32 field_int32 = 2;
-  }
-  repeated Annotation annotation = 7;
-
-  enum DumpReportReason {
-      DEVICE_SHUTDOWN = 1;
-      CONFIG_UPDATED = 2;
-      CONFIG_REMOVED = 3;
-      GET_DATA_CALLED = 4;
-      ADB_DUMP = 5;
-      CONFIG_RESET = 6;
-      STATSCOMPANION_DIED = 7;
-      TERMINATION_SIGNAL_RECEIVED = 8;
-  }
-  optional DumpReportReason dump_report_reason = 8;
-
-  repeated string strings = 9;
-}
-
-message ConfigMetricsReportList {
-  message ConfigKey {
-    optional int32 uid = 1;
-    optional int64 id = 2;
-  }
-  optional ConfigKey config_key = 1;
-
-  repeated ConfigMetricsReport reports = 2;
-
-  reserved 10;
-}
-
-message StatsdStatsReport {
-    optional int32 stats_begin_time_sec = 1;
-
-    optional int32 stats_end_time_sec = 2;
-
-    message MatcherStats {
-        optional int64 id = 1;
-        optional int32 matched_times = 2;
-    }
-
-    message ConditionStats {
-        optional int64 id = 1;
-        optional int32 max_tuple_counts = 2;
-    }
-
-    message MetricStats {
-        optional int64 id = 1;
-        optional int32 max_tuple_counts = 2;
-    }
-
-    message AlertStats {
-        optional int64 id = 1;
-        optional int32 alerted_times = 2;
-    }
-
-    message ConfigStats {
-        optional int32 uid = 1;
-        optional int64 id = 2;
-        optional int32 creation_time_sec = 3;
-        optional int32 deletion_time_sec = 4;
-        optional int32 reset_time_sec = 19;
-        optional int32 metric_count = 5;
-        optional int32 condition_count = 6;
-        optional int32 matcher_count = 7;
-        optional int32 alert_count = 8;
-        optional bool is_valid = 9;
-        repeated int32 broadcast_sent_time_sec = 10;
-        repeated int32 data_drop_time_sec = 11;
-        repeated int64 data_drop_bytes = 21;
-        repeated int32 dump_report_time_sec = 12;
-        repeated int32 dump_report_data_size = 20;
-        repeated MatcherStats matcher_stats = 13;
-        repeated ConditionStats condition_stats = 14;
-        repeated MetricStats metric_stats = 15;
-        repeated AlertStats alert_stats = 16;
-        repeated MetricStats metric_dimension_in_condition_stats = 17 [deprecated = true];
-        message Annotation {
-            optional int64 field_int64 = 1;
-            optional int32 field_int32 = 2;
-        }
-        repeated Annotation annotation = 18;
-        repeated int32 activation_time_sec = 22;
-        repeated int32 deactivation_time_sec = 23;
-    }
-
-    repeated ConfigStats config_stats = 3;
-
-    message AtomStats {
-        optional int32 tag = 1;
-        optional int32 count = 2;
-        optional int32 error_count = 3;
-    }
-
-    repeated AtomStats atom_stats = 7;
-
-    message UidMapStats {
-        optional int32 changes = 1;
-        optional int32 bytes_used = 2;
-        optional int32 dropped_changes = 3;
-        optional int32 deleted_apps = 4;
-    }
-    optional UidMapStats uidmap_stats = 8;
-
-    message AnomalyAlarmStats {
-        optional int32 alarms_registered = 1;
-    }
-    optional AnomalyAlarmStats anomaly_alarm_stats = 9;
-
-    message PulledAtomStats {
-        optional int32 atom_id = 1;
-        optional int64 total_pull = 2;
-        optional int64 total_pull_from_cache = 3;
-        optional int64 min_pull_interval_sec = 4;
-        optional int64 average_pull_time_nanos = 5;
-        optional int64 max_pull_time_nanos = 6;
-        optional int64 average_pull_delay_nanos = 7;
-        optional int64 max_pull_delay_nanos = 8;
-        optional int64 data_error = 9;
-        optional int64 pull_timeout = 10;
-        optional int64 pull_exceed_max_delay = 11;
-        optional int64 pull_failed = 12;
-        optional int64 stats_companion_pull_failed = 13 [deprecated = true];
-        optional int64 stats_companion_pull_binder_transaction_failed = 14 [deprecated = true];
-        optional int64 empty_data = 15;
-        optional int64 registered_count = 16;
-        optional int64 unregistered_count = 17;
-        optional int32 atom_error_count = 18;
-        optional int64 binder_call_failed = 19;
-        optional int64 failed_uid_provider_not_found = 20;
-        optional int64 puller_not_found = 21;
-        message PullTimeoutMetadata {
-          optional int64 pull_timeout_uptime_millis = 1;
-          optional int64 pull_timeout_elapsed_millis = 2;
-        }
-        repeated PullTimeoutMetadata pull_atom_metadata = 22;
-    }
-    repeated PulledAtomStats pulled_atom_stats = 10;
-
-    message AtomMetricStats {
-      optional int64 metric_id = 1;
-      optional int64 hard_dimension_limit_reached = 2;
-      optional int64 late_log_event_skipped = 3;
-      optional int64 skipped_forward_buckets = 4;
-      optional int64 bad_value_type = 5;
-      optional int64 condition_change_in_next_bucket = 6;
-      optional int64 invalidated_bucket = 7;
-      optional int64 bucket_dropped = 8;
-      optional int64 min_bucket_boundary_delay_ns = 9;
-      optional int64 max_bucket_boundary_delay_ns = 10;
-      optional int64 bucket_unknown_condition = 11;
-      optional int64 bucket_count = 12;
-    }
-    repeated AtomMetricStats atom_metric_stats = 17;
-
-    message LoggerErrorStats {
-        optional int32 logger_disconnection_sec = 1;
-        optional int32 error_code = 2;
-    }
-    repeated LoggerErrorStats logger_error_stats = 11;
-
-    message PeriodicAlarmStats {
-        optional int32 alarms_registered = 1;
-    }
-    optional PeriodicAlarmStats periodic_alarm_stats = 12;
-
-    message  SkippedLogEventStats {
-        optional int32 tag = 1;
-        optional int64 elapsed_timestamp_nanos = 2;
-    }
-    repeated SkippedLogEventStats skipped_log_event_stats = 13;
-
-    repeated int64 log_loss_stats = 14;
-
-    repeated int32 system_restart_sec = 15;
-
-    message LogLossStats {
-        optional int32 detected_time_sec = 1;
-        optional int32 count = 2;
-        optional int32 last_error = 3;
-        optional int32 last_tag = 4;
-        optional int32 uid = 5;
-        optional int32 pid = 6;
-    }
-    repeated LogLossStats detected_log_loss = 16;
-
-    message EventQueueOverflow {
-        optional int32 count = 1;
-        optional int64 max_queue_history_ns = 2;
-        optional int64 min_queue_history_ns = 3;
-    }
-
-    optional EventQueueOverflow queue_overflow = 18;
-
-    message ActivationBroadcastGuardrail {
-        optional int32 uid = 1;
-        repeated int32 guardrail_met_sec = 2;
-    }
-
-    repeated ActivationBroadcastGuardrail activation_guardrail_stats = 19;
-}
-
-message AlertTriggerDetails {
-    message MetricValue {
-        optional int64 metric_id = 1;
-        optional DimensionsValue dimension_in_what = 2;
-        optional DimensionsValue dimension_in_condition = 3 [deprecated = true];
-        optional int64 value = 4;
-    }
-    oneof value {
-        MetricValue trigger_metric = 1;
-        EventMetricData trigger_event = 2;
-    }
-    optional UidMapping.PackageInfoSnapshot package_info = 3;
-}
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
deleted file mode 100644
index 423bae8..0000000
--- a/cmds/statsd/src/stats_log_util.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "hash.h"
-#include "stats_log_util.h"
-
-#include <aidl/android/os/IStatsCompanionService.h>
-#include <private/android_filesystem_config.h>
-#include <set>
-#include <utils/SystemClock.h>
-
-#include "statscompanion_util.h"
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_BOOL;
-using android::util::FIELD_TYPE_FIXED64;
-using android::util::FIELD_TYPE_FLOAT;
-using android::util::FIELD_TYPE_INT32;
-using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_MESSAGE;
-using android::util::FIELD_TYPE_STRING;
-using android::util::FIELD_TYPE_UINT64;
-using android::util::ProtoOutputStream;
-
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-using std::string;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// for DimensionsValue Proto
-const int DIMENSIONS_VALUE_FIELD = 1;
-const int DIMENSIONS_VALUE_VALUE_STR = 2;
-const int DIMENSIONS_VALUE_VALUE_INT = 3;
-const int DIMENSIONS_VALUE_VALUE_LONG = 4;
-// const int DIMENSIONS_VALUE_VALUE_BOOL = 5; // logd doesn't have bool data type.
-const int DIMENSIONS_VALUE_VALUE_FLOAT = 6;
-const int DIMENSIONS_VALUE_VALUE_TUPLE = 7;
-const int DIMENSIONS_VALUE_VALUE_STR_HASH = 8;
-
-const int DIMENSIONS_VALUE_TUPLE_VALUE = 1;
-
-// for StateValue Proto
-const int STATE_VALUE_ATOM_ID = 1;
-const int STATE_VALUE_CONTENTS_GROUP_ID = 2;
-const int STATE_VALUE_CONTENTS_VALUE = 3;
-
-// for PulledAtomStats proto
-const int FIELD_ID_PULLED_ATOM_STATS = 10;
-const int FIELD_ID_PULL_ATOM_ID = 1;
-const int FIELD_ID_TOTAL_PULL = 2;
-const int FIELD_ID_TOTAL_PULL_FROM_CACHE = 3;
-const int FIELD_ID_MIN_PULL_INTERVAL_SEC = 4;
-const int FIELD_ID_AVERAGE_PULL_TIME_NANOS = 5;
-const int FIELD_ID_MAX_PULL_TIME_NANOS = 6;
-const int FIELD_ID_AVERAGE_PULL_DELAY_NANOS = 7;
-const int FIELD_ID_MAX_PULL_DELAY_NANOS = 8;
-const int FIELD_ID_DATA_ERROR = 9;
-const int FIELD_ID_PULL_TIMEOUT = 10;
-const int FIELD_ID_PULL_EXCEED_MAX_DELAY = 11;
-const int FIELD_ID_PULL_FAILED = 12;
-const int FIELD_ID_EMPTY_DATA = 15;
-const int FIELD_ID_PULL_REGISTERED_COUNT = 16;
-const int FIELD_ID_PULL_UNREGISTERED_COUNT = 17;
-const int FIELD_ID_ATOM_ERROR_COUNT = 18;
-const int FIELD_ID_BINDER_CALL_FAIL_COUNT = 19;
-const int FIELD_ID_PULL_UID_PROVIDER_NOT_FOUND = 20;
-const int FIELD_ID_PULLER_NOT_FOUND = 21;
-const int FIELD_ID_PULL_TIMEOUT_METADATA = 22;
-const int FIELD_ID_PULL_TIMEOUT_METADATA_UPTIME_MILLIS = 1;
-const int FIELD_ID_PULL_TIMEOUT_METADATA_ELAPSED_MILLIS = 2;
-
-// for AtomMetricStats proto
-const int FIELD_ID_ATOM_METRIC_STATS = 17;
-const int FIELD_ID_METRIC_ID = 1;
-const int FIELD_ID_HARD_DIMENSION_LIMIT_REACHED = 2;
-const int FIELD_ID_LATE_LOG_EVENT_SKIPPED = 3;
-const int FIELD_ID_SKIPPED_FORWARD_BUCKETS = 4;
-const int FIELD_ID_BAD_VALUE_TYPE = 5;
-const int FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET = 6;
-const int FIELD_ID_INVALIDATED_BUCKET = 7;
-const int FIELD_ID_BUCKET_DROPPED = 8;
-const int FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS = 9;
-const int FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS = 10;
-const int FIELD_ID_BUCKET_UNKNOWN_CONDITION = 11;
-const int FIELD_ID_BUCKET_COUNT = 12;
-
-namespace {
-
-void writeDimensionToProtoHelper(const std::vector<FieldValue>& dims, size_t* index, int depth,
-                                 int prefix, std::set<string> *str_set,
-                                 ProtoOutputStream* protoOutput) {
-    size_t count = dims.size();
-    while (*index < count) {
-        const auto& dim = dims[*index];
-        const int valueDepth = dim.mField.getDepth();
-        const int valuePrefix = dim.mField.getPrefix(depth);
-        const int fieldNum = dim.mField.getPosAtDepth(depth);
-        if (valueDepth > 2) {
-            ALOGE("Depth > 2 not supported");
-            return;
-        }
-
-        if (depth == valueDepth && valuePrefix == prefix) {
-            uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                 DIMENSIONS_VALUE_TUPLE_VALUE);
-            protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
-            switch (dim.mValue.getType()) {
-                case INT:
-                    protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_VALUE_INT,
-                                       dim.mValue.int_value);
-                    break;
-                case LONG:
-                    protoOutput->write(FIELD_TYPE_INT64 | DIMENSIONS_VALUE_VALUE_LONG,
-                                       (long long)dim.mValue.long_value);
-                    break;
-                case FLOAT:
-                    protoOutput->write(FIELD_TYPE_FLOAT | DIMENSIONS_VALUE_VALUE_FLOAT,
-                                       dim.mValue.float_value);
-                    break;
-                case STRING:
-                    if (str_set == nullptr) {
-                        protoOutput->write(FIELD_TYPE_STRING | DIMENSIONS_VALUE_VALUE_STR,
-                                           dim.mValue.str_value);
-                    } else {
-                        str_set->insert(dim.mValue.str_value);
-                        protoOutput->write(
-                                FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
-                                (long long)Hash64(dim.mValue.str_value));
-                    }
-                    break;
-                default:
-                    break;
-            }
-            if (token != 0) {
-                protoOutput->end(token);
-            }
-            (*index)++;
-        } else if (valueDepth > depth && valuePrefix == prefix) {
-            // Writing the sub tree
-            uint64_t dimensionToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | DIMENSIONS_VALUE_TUPLE_VALUE);
-            protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
-            uint64_t tupleToken =
-                    protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
-            writeDimensionToProtoHelper(dims, index, valueDepth, dim.mField.getPrefix(valueDepth),
-                                        str_set, protoOutput);
-            protoOutput->end(tupleToken);
-            protoOutput->end(dimensionToken);
-        } else {
-            // Done with the prev sub tree
-            return;
-        }
-    }
-}
-
-void writeDimensionLeafToProtoHelper(const std::vector<FieldValue>& dims,
-                                     const int dimensionLeafField,
-                                     size_t* index, int depth,
-                                     int prefix, std::set<string> *str_set,
-                                     ProtoOutputStream* protoOutput) {
-    size_t count = dims.size();
-    while (*index < count) {
-        const auto& dim = dims[*index];
-        const int valueDepth = dim.mField.getDepth();
-        const int valuePrefix = dim.mField.getPrefix(depth);
-        if (valueDepth > 2) {
-            ALOGE("Depth > 2 not supported");
-            return;
-        }
-
-        if (depth == valueDepth && valuePrefix == prefix) {
-            uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                dimensionLeafField);
-            switch (dim.mValue.getType()) {
-                case INT:
-                    protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_VALUE_INT,
-                                       dim.mValue.int_value);
-                    break;
-                case LONG:
-                    protoOutput->write(FIELD_TYPE_INT64 | DIMENSIONS_VALUE_VALUE_LONG,
-                                       (long long)dim.mValue.long_value);
-                    break;
-                case FLOAT:
-                    protoOutput->write(FIELD_TYPE_FLOAT | DIMENSIONS_VALUE_VALUE_FLOAT,
-                                       dim.mValue.float_value);
-                    break;
-                case STRING:
-                    if (str_set == nullptr) {
-                        protoOutput->write(FIELD_TYPE_STRING | DIMENSIONS_VALUE_VALUE_STR,
-                                           dim.mValue.str_value);
-                    } else {
-                        str_set->insert(dim.mValue.str_value);
-                        protoOutput->write(
-                                FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
-                                (long long)Hash64(dim.mValue.str_value));
-                    }
-                    break;
-                default:
-                    break;
-            }
-            if (token != 0) {
-                protoOutput->end(token);
-            }
-            (*index)++;
-        } else if (valueDepth > depth && valuePrefix == prefix) {
-            writeDimensionLeafToProtoHelper(dims, dimensionLeafField,
-                                            index, valueDepth, dim.mField.getPrefix(valueDepth),
-                                            str_set, protoOutput);
-        } else {
-            // Done with the prev sub tree
-            return;
-        }
-    }
-}
-
-void writeDimensionPathToProtoHelper(const std::vector<Matcher>& fieldMatchers,
-                                     size_t* index, int depth, int prefix,
-                                     ProtoOutputStream* protoOutput) {
-    size_t count = fieldMatchers.size();
-    while (*index < count) {
-        const Field& field = fieldMatchers[*index].mMatcher;
-        const int valueDepth = field.getDepth();
-        const int valuePrefix = field.getPrefix(depth);
-        const int fieldNum = field.getPosAtDepth(depth);
-        if (valueDepth > 2) {
-            ALOGE("Depth > 2 not supported");
-            return;
-        }
-
-        if (depth == valueDepth && valuePrefix == prefix) {
-            uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                 DIMENSIONS_VALUE_TUPLE_VALUE);
-            protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
-            if (token != 0) {
-                protoOutput->end(token);
-            }
-            (*index)++;
-        } else if (valueDepth > depth && valuePrefix == prefix) {
-            // Writing the sub tree
-            uint64_t dimensionToken = protoOutput->start(
-                    FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | DIMENSIONS_VALUE_TUPLE_VALUE);
-            protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
-            uint64_t tupleToken =
-                    protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
-            writeDimensionPathToProtoHelper(fieldMatchers, index, valueDepth,
-                                            field.getPrefix(valueDepth), protoOutput);
-            protoOutput->end(tupleToken);
-            protoOutput->end(dimensionToken);
-        } else {
-            // Done with the prev sub tree
-            return;
-        }
-    }
-}
-
-}  // namespace
-
-void writeDimensionToProto(const HashableDimensionKey& dimension, std::set<string> *str_set,
-                           ProtoOutputStream* protoOutput) {
-    if (dimension.getValues().size() == 0) {
-        return;
-    }
-    protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD,
-                       dimension.getValues()[0].mField.getTag());
-    uint64_t topToken = protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
-    size_t index = 0;
-    writeDimensionToProtoHelper(dimension.getValues(), &index, 0, 0, str_set, protoOutput);
-    protoOutput->end(topToken);
-}
-
-void writeDimensionLeafNodesToProto(const HashableDimensionKey& dimension,
-                                    const int dimensionLeafFieldId,
-                                    std::set<string> *str_set,
-                                    ProtoOutputStream* protoOutput) {
-    if (dimension.getValues().size() == 0) {
-        return;
-    }
-    size_t index = 0;
-    writeDimensionLeafToProtoHelper(dimension.getValues(), dimensionLeafFieldId,
-                                    &index, 0, 0, str_set, protoOutput);
-}
-
-void writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers,
-                               ProtoOutputStream* protoOutput) {
-    if (fieldMatchers.size() == 0) {
-        return;
-    }
-    protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD,
-                       fieldMatchers[0].mMatcher.getTag());
-    uint64_t topToken = protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
-    size_t index = 0;
-    writeDimensionPathToProtoHelper(fieldMatchers, &index, 0, 0, protoOutput);
-    protoOutput->end(topToken);
-}
-
-// Supported Atoms format
-// XYZ_Atom {
-//     repeated SubMsg field_1 = 1;
-//     SubMsg2 field_2 = 2;
-//     int32/float/string/int63 field_3 = 3;
-// }
-// logd's msg format, doesn't allow us to distinguish between the 2 cases below
-// Case (1):
-// Atom {
-//   SubMsg {
-//     int i = 1;
-//     int j = 2;
-//   }
-//   repeated SubMsg
-// }
-//
-// and case (2):
-// Atom {
-//   SubMsg {
-//     repeated int i = 1;
-//     repeated int j = 2;
-//   }
-//   optional SubMsg = 1;
-// }
-//
-//
-void writeFieldValueTreeToStreamHelper(int tagId, const std::vector<FieldValue>& dims,
-                                       size_t* index, int depth, int prefix,
-                                       ProtoOutputStream* protoOutput) {
-    size_t count = dims.size();
-    while (*index < count) {
-        const auto& dim = dims[*index];
-        const int valueDepth = dim.mField.getDepth();
-        const int valuePrefix = dim.mField.getPrefix(depth);
-        const int fieldNum = dim.mField.getPosAtDepth(depth);
-        if (valueDepth > 2) {
-            ALOGE("Depth > 2 not supported");
-            return;
-        }
-
-        if (depth == valueDepth && valuePrefix == prefix) {
-            switch (dim.mValue.getType()) {
-                case INT:
-                    protoOutput->write(FIELD_TYPE_INT32 | fieldNum, dim.mValue.int_value);
-                    break;
-                case LONG:
-                    protoOutput->write(FIELD_TYPE_INT64 | fieldNum,
-                                       (long long)dim.mValue.long_value);
-                    break;
-                case FLOAT:
-                    protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value);
-                    break;
-                case STRING: {
-                    protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
-                    break;
-                }
-                case STORAGE:
-                    protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum,
-                                       (const char*)dim.mValue.storage_value.data(),
-                                       dim.mValue.storage_value.size());
-                    break;
-                default:
-                    break;
-            }
-            (*index)++;
-        } else if (valueDepth > depth && valuePrefix == prefix) {
-            // Writing the sub tree
-            uint64_t msg_token = 0ULL;
-            if (valueDepth == depth + 2) {
-                msg_token =
-                        protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | fieldNum);
-            } else if (valueDepth == depth + 1) {
-                msg_token = protoOutput->start(FIELD_TYPE_MESSAGE | fieldNum);
-            }
-            // Directly jump to the leaf value because the repeated position field is implied
-            // by the position of the sub msg in the parent field.
-            writeFieldValueTreeToStreamHelper(tagId, dims, index, valueDepth,
-                                              dim.mField.getPrefix(valueDepth), protoOutput);
-            if (msg_token != 0) {
-                protoOutput->end(msg_token);
-            }
-        } else {
-            // Done with the prev sub tree
-            return;
-        }
-    }
-}
-
-void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& values,
-                                 util::ProtoOutputStream* protoOutput) {
-    uint64_t atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | tagId);
-
-    size_t index = 0;
-    writeFieldValueTreeToStreamHelper(tagId, values, &index, 0, 0, protoOutput);
-    protoOutput->end(atomToken);
-}
-
-void writeStateToProto(const FieldValue& state, util::ProtoOutputStream* protoOutput) {
-    protoOutput->write(FIELD_TYPE_INT32 | STATE_VALUE_ATOM_ID, state.mField.getTag());
-
-    switch (state.mValue.getType()) {
-        case INT:
-            protoOutput->write(FIELD_TYPE_INT32 | STATE_VALUE_CONTENTS_VALUE,
-                               state.mValue.int_value);
-            break;
-        case LONG:
-            protoOutput->write(FIELD_TYPE_INT64 | STATE_VALUE_CONTENTS_GROUP_ID,
-                               state.mValue.long_value);
-            break;
-        default:
-            break;
-    }
-}
-
-int64_t TimeUnitToBucketSizeInMillisGuardrailed(int uid, TimeUnit unit) {
-    int64_t bucketSizeMillis = TimeUnitToBucketSizeInMillis(unit);
-    if (bucketSizeMillis > 1000 && bucketSizeMillis < 5 * 60 * 1000LL && uid != AID_SHELL &&
-        uid != AID_ROOT) {
-        bucketSizeMillis = 5 * 60 * 1000LL;
-    }
-    return bucketSizeMillis;
-}
-
-int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit) {
-    switch (unit) {
-        case ONE_MINUTE:
-            return 60 * 1000LL;
-        case FIVE_MINUTES:
-            return 5 * 60 * 1000LL;
-        case TEN_MINUTES:
-            return 10 * 60 * 1000LL;
-        case THIRTY_MINUTES:
-            return 30 * 60 * 1000LL;
-        case ONE_HOUR:
-            return 60 * 60 * 1000LL;
-        case THREE_HOURS:
-            return 3 * 60 * 60 * 1000LL;
-        case SIX_HOURS:
-            return 6 * 60 * 60 * 1000LL;
-        case TWELVE_HOURS:
-            return 12 * 60 * 60 * 1000LL;
-        case ONE_DAY:
-            return 24 * 60 * 60 * 1000LL;
-        case ONE_WEEK:
-            return 7 * 24 * 60 * 60 * 1000LL;
-        case CTS:
-            return 1000;
-        case TIME_UNIT_UNSPECIFIED:
-        default:
-            return -1;
-    }
-}
-
-void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>& pair,
-                              util::ProtoOutputStream* protoOutput) {
-    uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_PULLED_ATOM_STATS |
-                                         FIELD_COUNT_REPEATED);
-    protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_PULL_ATOM_ID, (int32_t)pair.first);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TOTAL_PULL, (long long)pair.second.totalPull);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TOTAL_PULL_FROM_CACHE,
-                       (long long)pair.second.totalPullFromCache);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MIN_PULL_INTERVAL_SEC,
-                       (long long)pair.second.minPullIntervalSec);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_AVERAGE_PULL_TIME_NANOS,
-                       (long long)pair.second.avgPullTimeNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_PULL_TIME_NANOS,
-                       (long long)pair.second.maxPullTimeNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_AVERAGE_PULL_DELAY_NANOS,
-                       (long long)pair.second.avgPullDelayNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_PULL_DELAY_NANOS,
-                       (long long)pair.second.maxPullDelayNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DATA_ERROR, (long long)pair.second.dataError);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT,
-                       (long long)pair.second.pullTimeout);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_EXCEED_MAX_DELAY,
-                       (long long)pair.second.pullExceedMaxDelay);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_FAILED,
-                       (long long)pair.second.pullFailed);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_EMPTY_DATA,
-                       (long long)pair.second.emptyData);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_REGISTERED_COUNT,
-                       (long long) pair.second.registeredCount);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_UNREGISTERED_COUNT,
-                       (long long) pair.second.unregisteredCount);
-    protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_ERROR_COUNT, pair.second.atomErrorCount);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BINDER_CALL_FAIL_COUNT,
-                       (long long)pair.second.binderCallFailCount);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_UID_PROVIDER_NOT_FOUND,
-                       (long long)pair.second.pullUidProviderNotFound);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULLER_NOT_FOUND,
-                       (long long)pair.second.pullerNotFound);
-    for (const auto& pullTimeoutMetadata : pair.second.pullTimeoutMetadata) {
-        uint64_t timeoutMetadataToken = protoOutput->start(FIELD_TYPE_MESSAGE |
-                                                           FIELD_ID_PULL_TIMEOUT_METADATA |
-                                                           FIELD_COUNT_REPEATED);
-        protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT_METADATA_UPTIME_MILLIS,
-                           pullTimeoutMetadata.pullTimeoutUptimeMillis);
-        protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_TIMEOUT_METADATA_ELAPSED_MILLIS,
-                           pullTimeoutMetadata.pullTimeoutElapsedMillis);
-        protoOutput->end(timeoutMetadataToken);
-    }
-    protoOutput->end(token);
-}
-
-void writeAtomMetricStatsToStream(const std::pair<int64_t, StatsdStats::AtomMetricStats> &pair,
-                                  util::ProtoOutputStream *protoOutput) {
-    uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_METRIC_STATS |
-                                        FIELD_COUNT_REPEATED);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_ID, (long long)pair.first);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_HARD_DIMENSION_LIMIT_REACHED,
-                       (long long)pair.second.hardDimensionLimitReached);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_LATE_LOG_EVENT_SKIPPED,
-                       (long long)pair.second.lateLogEventSkipped);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_SKIPPED_FORWARD_BUCKETS,
-                       (long long)pair.second.skippedForwardBuckets);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BAD_VALUE_TYPE,
-                       (long long)pair.second.badValueType);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET,
-                       (long long)pair.second.conditionChangeInNextBucket);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_INVALIDATED_BUCKET,
-                       (long long)pair.second.invalidatedBucket);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_DROPPED,
-                       (long long)pair.second.bucketDropped);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS,
-                       (long long)pair.second.minBucketBoundaryDelayNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS,
-                       (long long)pair.second.maxBucketBoundaryDelayNs);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_UNKNOWN_CONDITION,
-                       (long long)pair.second.bucketUnknownCondition);
-    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_COUNT,
-                       (long long)pair.second.bucketCount);
-    protoOutput->end(token);
-}
-
-int64_t getElapsedRealtimeNs() {
-    return ::android::elapsedRealtimeNano();
-}
-
-int64_t getElapsedRealtimeSec() {
-    return ::android::elapsedRealtimeNano() / NS_PER_SEC;
-}
-
-int64_t getElapsedRealtimeMillis() {
-    return ::android::elapsedRealtime();
-}
-
-int64_t getSystemUptimeMillis() {
-    return ::android::uptimeMillis();
-}
-
-int64_t getWallClockNs() {
-    return time(nullptr) * NS_PER_SEC;
-}
-
-int64_t getWallClockSec() {
-    return time(nullptr);
-}
-
-int64_t getWallClockMillis() {
-    return time(nullptr) * MS_PER_SEC;
-}
-
-int64_t truncateTimestampIfNecessary(const LogEvent& event) {
-    if (event.shouldTruncateTimestamp() ||
-        (event.GetTagId() >= StatsdStats::kTimestampTruncationStartTag &&
-         event.GetTagId() <= StatsdStats::kTimestampTruncationEndTag)) {
-        return event.GetElapsedTimestampNs() / NS_PER_SEC / (5 * 60) * NS_PER_SEC * (5 * 60);
-    } else {
-        return event.GetElapsedTimestampNs();
-    }
-}
-
-int64_t NanoToMillis(const int64_t nano) {
-    return nano / 1000000;
-}
-
-int64_t MillisToNano(const int64_t millis) {
-    return millis * 1000000;
-}
-
-bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid) {
-    shared_ptr<IStatsCompanionService> scs = getStatsCompanionService();
-    if (scs == nullptr) {
-        return false;
-    }
-
-    bool success;
-    ::ndk::ScopedAStatus status = scs->checkPermission(string(permission), pid, uid, &success);
-    if (!status.isOk()) {
-        return false;
-    }
-
-    return success;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
deleted file mode 100644
index 10e065e..0000000
--- a/cmds/statsd/src/stats_log_util.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include <android/util/ProtoOutputStream.h>
-
-#include "FieldValue.h"
-#include "HashableDimensionKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-
-using android::util::ProtoOutputStream;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& values,
-                                 ProtoOutputStream* protoOutput);
-void writeDimensionToProto(const HashableDimensionKey& dimension, std::set<string> *str_set,
-                           ProtoOutputStream* protoOutput);
-
-void writeDimensionLeafNodesToProto(const HashableDimensionKey& dimension,
-                                    const int dimensionLeafFieldId,
-                                    std::set<string> *str_set,
-                                    ProtoOutputStream* protoOutput);
-
-void writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers,
-                               ProtoOutputStream* protoOutput);
-
-void writeStateToProto(const FieldValue& state, ProtoOutputStream* protoOutput);
-
-// Convert the TimeUnit enum to the bucket size in millis with a guardrail on
-// bucket size.
-int64_t TimeUnitToBucketSizeInMillisGuardrailed(int uid, TimeUnit unit);
-
-// Convert the TimeUnit enum to the bucket size in millis.
-int64_t TimeUnitToBucketSizeInMillis(TimeUnit unit);
-
-// Gets the elapsed timestamp in ns.
-int64_t getElapsedRealtimeNs();
-
-// Gets the elapsed timestamp in millis.
-int64_t getElapsedRealtimeMillis();
-
-// Gets the elapsed timestamp in seconds.
-int64_t getElapsedRealtimeSec();
-
-// Gets the system uptime in millis.
-int64_t getSystemUptimeMillis();
-
-// Gets the wall clock timestamp in ns.
-int64_t getWallClockNs();
-
-// Gets the wall clock timestamp in millis.
-int64_t getWallClockMillis();
-
-// Gets the wall clock timestamp in seconds.
-int64_t getWallClockSec();
-
-int64_t NanoToMillis(const int64_t nano);
-
-int64_t MillisToNano(const int64_t millis);
-
-// Helper function to write PulledAtomStats to ProtoOutputStream
-void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>& pair,
-                              ProtoOutputStream* protoOutput);
-
-// Helper function to write AtomMetricStats to ProtoOutputStream
-void writeAtomMetricStatsToStream(const std::pair<int64_t, StatsdStats::AtomMetricStats> &pair,
-                                  ProtoOutputStream *protoOutput);
-
-template<class T>
-bool parseProtoOutputStream(ProtoOutputStream& protoOutput, T* message) {
-    std::string pbBytes;
-    sp<android::util::ProtoReader> reader = protoOutput.data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-         pbBytes.append(reinterpret_cast<const char*>(reader->readBuffer()), toRead);
-        reader->move(toRead);
-    }
-    return message->ParseFromArray(pbBytes.c_str(), pbBytes.size());
-}
-
-// Checks the truncate timestamp annotation as well as the restricted range of 300,000 - 304,999.
-// Returns the truncated timestamp to the nearest 5 minutes if needed.
-int64_t truncateTimestampIfNecessary(const LogEvent& event);
-
-// Checks permission for given pid and uid.
-bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid);
-
-inline bool isVendorPulledAtom(int atomId) {
-    return atomId >= StatsdStats::kVendorPulledAtomStartTag && atomId < StatsdStats::kMaxAtomTag;
-}
-
-inline bool isPulledAtom(int atomId) {
-    return atomId >= StatsdStats::kPullAtomStartTag && atomId < StatsdStats::kVendorAtomStartTag;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/stats_util.h b/cmds/statsd/src/stats_util.h
deleted file mode 100644
index cfc411f..0000000
--- a/cmds/statsd/src/stats_util.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#pragma once
-
-#include "HashableDimensionKey.h"
-
-#include <unordered_map>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const HashableDimensionKey DEFAULT_DIMENSION_KEY = HashableDimensionKey();
-const MetricDimensionKey DEFAULT_METRIC_DIMENSION_KEY = MetricDimensionKey();
-
-typedef std::map<int64_t, HashableDimensionKey> ConditionKey;
-
-typedef std::unordered_map<MetricDimensionKey, int64_t> DimToValMap;
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/statscompanion_util.cpp b/cmds/statsd/src/statscompanion_util.cpp
deleted file mode 100644
index ce07ec0..0000000
--- a/cmds/statsd/src/statscompanion_util.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "statscompanion_util.h"
-#include <android/binder_auto_utils.h>
-#include <android/binder_manager.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-shared_ptr<IStatsCompanionService> getStatsCompanionService() {
-    ::ndk::SpAIBinder binder(AServiceManager_getService("statscompanion"));
-    return IStatsCompanionService::fromBinder(binder);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/statscompanion_util.h b/cmds/statsd/src/statscompanion_util.h
deleted file mode 100644
index e20c40b..0000000
--- a/cmds/statsd/src/statscompanion_util.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include <aidl/android/os/IStatsCompanionService.h>
-
-using aidl::android::os::IStatsCompanionService;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/** Fetches and returns the StatsCompanionService. */
-shared_ptr<IStatsCompanionService> getStatsCompanionService();
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
deleted file mode 100644
index acdffd3..0000000
--- a/cmds/statsd/src/statsd_config.proto
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.internal.os";
-option java_outer_classname = "StatsdConfigProto";
-
-enum Position {
-  POSITION_UNKNOWN = 0;
-
-  FIRST = 1;
-
-  LAST = 2;
-
-  ANY = 3;
-
-  ALL = 4;
-}
-
-enum TimeUnit {
-  TIME_UNIT_UNSPECIFIED = 0;
-  ONE_MINUTE = 1;  // WILL BE GUARDRAILED TO 5 MINS UNLESS UID = SHELL OR ROOT
-  FIVE_MINUTES = 2;
-  TEN_MINUTES = 3;
-  THIRTY_MINUTES = 4;
-  ONE_HOUR = 5;
-  THREE_HOURS = 6;
-  SIX_HOURS = 7;
-  TWELVE_HOURS = 8;
-  ONE_DAY = 9;
-  ONE_WEEK = 10;
-  CTS = 1000;
-}
-
-message FieldMatcher {
-  optional int32 field = 1;
-
-  optional Position position = 2;
-
-  repeated FieldMatcher child = 3;
-}
-
-message FieldValueMatcher {
-  optional int32 field = 1;
-
-  optional Position position = 2;
-
-  oneof value_matcher {
-    bool eq_bool = 3;
-    string eq_string = 4;
-    int64 eq_int = 5;
-
-    int64 lt_int = 6;
-    int64 gt_int = 7;
-    float lt_float = 8;
-    float gt_float = 9;
-
-    int64 lte_int = 10;
-    int64 gte_int = 11;
-
-    MessageMatcher matches_tuple = 12;
-
-    StringListMatcher eq_any_string = 13;
-    StringListMatcher neq_any_string = 14;
-  }
-}
-
-message MessageMatcher {
-  repeated FieldValueMatcher field_value_matcher = 1;
-}
-
-message StringListMatcher {
-    repeated string str_value = 1;
-}
-
-enum LogicalOperation {
-  LOGICAL_OPERATION_UNSPECIFIED = 0;
-  AND = 1;
-  OR = 2;
-  NOT = 3;
-  NAND = 4;
-  NOR = 5;
-}
-
-message SimpleAtomMatcher {
-  optional int32 atom_id = 1;
-
-  repeated FieldValueMatcher field_value_matcher = 2;
-}
-
-message AtomMatcher {
-  optional int64 id = 1;
-
-  message Combination {
-    optional LogicalOperation operation = 1;
-
-    repeated int64 matcher = 2;
-  }
-  oneof contents {
-    SimpleAtomMatcher simple_atom_matcher = 2;
-    Combination combination = 3;
-  }
-}
-
-message SimplePredicate {
-  optional int64 start = 1;
-
-  optional int64 stop = 2;
-
-  optional bool count_nesting = 3 [default = true];
-
-  optional int64 stop_all = 4;
-
-  enum InitialValue {
-    UNKNOWN = 0;
-    FALSE = 1;
-  }
-  optional InitialValue initial_value = 5 [default = UNKNOWN];
-
-  optional FieldMatcher dimensions = 6;
-}
-
-message Predicate {
-  optional int64 id = 1;
-
-  message Combination {
-    optional LogicalOperation operation = 1;
-
-    repeated int64 predicate = 2;
-  }
-
-  oneof contents {
-    SimplePredicate simple_predicate = 2;
-    Combination combination = 3;
-  }
-}
-
-message StateMap {
-  message StateGroup {
-    optional int64 group_id = 1;
-
-    repeated int32 value = 2;
-  }
-
-  repeated StateGroup group = 1;
-}
-
-message State {
-  optional int64 id = 1;
-
-  optional int32 atom_id = 2;
-
-  optional StateMap map = 3;
-}
-
-message MetricConditionLink {
-  optional int64 condition = 1;
-
-  optional FieldMatcher fields_in_what = 2;
-
-  optional FieldMatcher fields_in_condition = 3;
-}
-
-message MetricStateLink {
-  optional int32 state_atom_id = 1;
-
-  optional FieldMatcher fields_in_what = 2;
-
-  optional FieldMatcher fields_in_state = 3;
-}
-
-message FieldFilter {
-  optional bool include_all = 1 [default = false];
-  optional FieldMatcher fields = 2;
-}
-
-message EventMetric {
-  optional int64 id = 1;
-
-  optional int64 what = 2;
-
-  optional int64 condition = 3;
-
-  repeated MetricConditionLink links = 4;
-
-  reserved 100;
-  reserved 101;
-}
-
-message CountMetric {
-  optional int64 id = 1;
-
-  optional int64 what = 2;
-
-  optional int64 condition = 3;
-
-  optional FieldMatcher dimensions_in_what = 4;
-
-  repeated int64 slice_by_state = 8;
-
-  optional TimeUnit bucket = 5;
-
-  repeated MetricConditionLink links = 6;
-
-  repeated MetricStateLink state_link = 9;
-
-  optional FieldMatcher dimensions_in_condition = 7 [deprecated = true];
-
-  reserved 100;
-  reserved 101;
-}
-
-message DurationMetric {
-  optional int64 id = 1;
-
-  optional int64 what = 2;
-
-  optional int64 condition = 3;
-
-  repeated int64 slice_by_state = 9;
-
-  repeated MetricConditionLink links = 4;
-
-  repeated MetricStateLink state_link = 10;
-
-  enum AggregationType {
-    SUM = 1;
-
-    MAX_SPARSE = 2;
-  }
-  optional AggregationType aggregation_type = 5 [default = SUM];
-
-  optional FieldMatcher dimensions_in_what = 6;
-
-  optional TimeUnit bucket = 7;
-
-  optional FieldMatcher dimensions_in_condition = 8 [deprecated = true];
-
-  reserved 100;
-  reserved 101;
-}
-
-message GaugeMetric {
-  optional int64 id = 1;
-
-  optional int64 what = 2;
-
-  optional int64 trigger_event = 12;
-
-  optional FieldFilter gauge_fields_filter = 3;
-
-  optional int64 condition = 4;
-
-  optional FieldMatcher dimensions_in_what = 5;
-
-  optional FieldMatcher dimensions_in_condition = 8 [deprecated = true];
-
-  optional TimeUnit bucket = 6;
-
-  repeated MetricConditionLink links = 7;
-
-  enum SamplingType {
-    RANDOM_ONE_SAMPLE = 1;
-    ALL_CONDITION_CHANGES = 2 [deprecated = true];
-    CONDITION_CHANGE_TO_TRUE = 3;
-    FIRST_N_SAMPLES = 4;
-  }
-  optional SamplingType sampling_type = 9 [default = RANDOM_ONE_SAMPLE] ;
-
-  optional int64 min_bucket_size_nanos = 10;
-
-  optional int64 max_num_gauge_atoms_per_bucket = 11 [default = 10];
-
-  optional int32 max_pull_delay_sec = 13 [default = 30];
-
-  optional bool split_bucket_for_app_upgrade = 14 [default = true];
-
-  reserved 100;
-  reserved 101;
-}
-
-message ValueMetric {
-  optional int64 id = 1;
-
-  optional int64 what = 2;
-
-  optional FieldMatcher value_field = 3;
-
-  optional int64 condition = 4;
-
-  optional FieldMatcher dimensions_in_what = 5;
-
-  repeated int64 slice_by_state = 18;
-
-  optional TimeUnit bucket = 6;
-
-  repeated MetricConditionLink links = 7;
-
-  repeated MetricStateLink state_link = 19;
-
-  enum AggregationType {
-    SUM = 1;
-    MIN = 2;
-    MAX = 3;
-    AVG = 4;
-  }
-  optional AggregationType aggregation_type = 8 [default = SUM];
-
-  optional int64 min_bucket_size_nanos = 10;
-
-  optional bool use_absolute_value_on_reset = 11 [default = false];
-
-  optional bool use_diff = 12;
-
-  optional bool use_zero_default_base = 15 [default = false];
-
-  enum ValueDirection {
-      UNKNOWN = 0;
-      INCREASING = 1;
-      DECREASING = 2;
-      ANY = 3;
-  }
-  optional ValueDirection value_direction = 13 [default = INCREASING];
-
-  optional bool skip_zero_diff_output = 14 [default = true];
-
-  optional int32 max_pull_delay_sec = 16 [default = 30];
-
-  optional bool split_bucket_for_app_upgrade = 17 [default = true];
-
-  optional FieldMatcher dimensions_in_condition = 9 [deprecated = true];
-
-  reserved 100;
-  reserved 101;
-}
-
-message Alert {
-  optional int64 id = 1;
-
-  optional int64 metric_id = 2;
-
-  optional int32 num_buckets = 3;
-
-  optional int32 refractory_period_secs = 4;
-
-  optional double trigger_if_sum_gt = 5;
-}
-
-message Alarm {
-  optional int64 id = 1;
-
-  optional int64 offset_millis = 2;
-
-  optional int64 period_millis = 3;
-}
-
-message IncidentdDetails {
-  repeated int32 section = 1;
-
-  enum Destination {
-    AUTOMATIC = 0;
-    EXPLICIT = 1;
-  }
-  optional Destination dest = 2;
-
-  // Package name of the incident report receiver.
-  optional string receiver_pkg = 3;
-
-  // Class name of the incident report receiver.
-  optional string receiver_cls = 4;
-
-  optional string alert_description = 5;
-}
-
-message PerfettoDetails {
-  // The |trace_config| field is a proto-encoded message of type
-  // perfetto.protos.TraceConfig defined in
-  // //external/perfetto/protos/perfetto/config/. On device,
-  // statsd doesn't need to deserialize the message as it's just
-  // passed binary-encoded to the perfetto cmdline client.
-  optional bytes trace_config = 1;
-}
-
-message BroadcastSubscriberDetails {
-  optional int64 subscriber_id = 1;
-  repeated string cookie = 2;
-}
-
-message Subscription {
-  optional int64 id = 1;
-
-  enum RuleType {
-    RULE_TYPE_UNSPECIFIED = 0;
-    ALARM = 1;
-    ALERT = 2;
-  }
-  optional RuleType rule_type = 2;
-
-  optional int64 rule_id = 3;
-
-  oneof subscriber_information {
-    IncidentdDetails incidentd_details = 4;
-    PerfettoDetails perfetto_details = 5;
-    BroadcastSubscriberDetails broadcast_subscriber_details = 6;
-  }
-
-  optional float probability_of_informing = 7 [default = 1.1];
-
-  // This was used for perfprofd historically.
-  reserved 8;
-}
-
-enum ActivationType {
-  ACTIVATION_TYPE_UNKNOWN = 0;
-  ACTIVATE_IMMEDIATELY = 1;
-  ACTIVATE_ON_BOOT = 2;
-}
-
-message EventActivation {
-  optional int64 atom_matcher_id = 1;
-  optional int64 ttl_seconds = 2;
-  optional int64 deactivation_atom_matcher_id = 3;
-  optional ActivationType activation_type = 4;
-}
-
-message MetricActivation {
-  optional int64 metric_id = 1;
-
-  optional ActivationType activation_type = 3 [deprecated = true];
-
-  repeated EventActivation event_activation = 2;
-}
-
-message PullAtomPackages {
-    optional int32 atom_id = 1;
-
-    repeated string packages = 2;
-}
-
-message StatsdConfig {
-  optional int64 id = 1;
-
-  repeated EventMetric event_metric = 2;
-
-  repeated CountMetric count_metric = 3;
-
-  repeated ValueMetric value_metric = 4;
-
-  repeated GaugeMetric gauge_metric = 5;
-
-  repeated DurationMetric duration_metric = 6;
-
-  repeated AtomMatcher atom_matcher = 7;
-
-  repeated Predicate predicate = 8;
-
-  repeated Alert alert = 9;
-
-  repeated Alarm alarm = 10;
-
-  repeated Subscription subscription = 11;
-
-  repeated string allowed_log_source = 12;
-
-  repeated int64 no_report_metric = 13;
-
-  message Annotation {
-    optional int64 field_int64 = 1;
-    optional int32 field_int32 = 2;
-  }
-  repeated Annotation annotation = 14;
-
-  optional int64 ttl_in_seconds = 15;
-
-  optional bool hash_strings_in_metric_report = 16 [default = true];
-
-  repeated MetricActivation metric_activation = 17;
-
-  optional bool version_strings_in_metric_report = 18;
-
-  optional bool installer_in_metric_report = 19;
-
-  optional bool persist_locally = 20 [default = false];
-
-  repeated State state = 21;
-
-  repeated string default_pull_packages = 22;
-
-  repeated PullAtomPackages pull_atom_packages = 23;
-
-  repeated int32 whitelisted_atom_ids = 24;
-
-  // Field number 1000 is reserved for later use.
-  reserved 1000;
-}
diff --git a/cmds/statsd/src/statsd_metadata.proto b/cmds/statsd/src/statsd_metadata.proto
deleted file mode 100644
index 200b392..0000000
--- a/cmds/statsd/src/statsd_metadata.proto
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-syntax = "proto2";
-
-package android.os.statsd.metadata;
-
-message ConfigKey {
-  optional int64 config_id = 1;
-  optional int32 uid = 2;
-}
-
-message Field {
-  optional int32 tag = 1;
-  optional int32 field = 2;
-}
-
-message FieldValue {
-  optional Field field = 1;
-  oneof value {
-    int32 value_int = 2;
-    int64 value_long = 3;
-    float value_float = 4;
-    double value_double = 5;
-    string value_str = 6;
-    bytes value_storage = 7;
-  }
-}
-
-message MetricDimensionKey {
-  repeated FieldValue dimension_key_in_what = 1;
-  repeated FieldValue state_values_key = 2;
-}
-
-message AlertDimensionKeyedData {
-  // The earliest time the alert can be fired again in wall clock time.
-  optional int32 last_refractory_ends_sec = 1;
-  optional MetricDimensionKey dimension_key = 2;
-}
-
-message AlertMetadata {
-  optional int64 alert_id = 1;
-  repeated AlertDimensionKeyedData alert_dim_keyed_data = 2;
-}
-
-// All metadata for a config in statsd
-message StatsMetadata {
-  optional ConfigKey config_key = 1;
-  repeated AlertMetadata alert_metadata = 2;
-}
-
-message StatsMetadataList {
-  repeated StatsMetadata stats_metadata = 1;
-}
\ No newline at end of file
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
deleted file mode 100644
index dcfdfe3..0000000
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ /dev/null
@@ -1,781 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "android-base/stringprintf.h"
-#include "guardrail/StatsdStats.h"
-#include "storage/StorageManager.h"
-#include "stats_log_util.h"
-
-#include <android-base/file.h>
-#include <private/android_filesystem_config.h>
-#include <fstream>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::FIELD_COUNT_REPEATED;
-using android::util::FIELD_TYPE_MESSAGE;
-using std::map;
-
-/**
- * NOTE: these directories are protected by SELinux, any changes here must also update
- * the SELinux policies.
- */
-#define STATS_DATA_DIR "/data/misc/stats-data"
-#define STATS_SERVICE_DIR "/data/misc/stats-service"
-#define TRAIN_INFO_DIR "/data/misc/train-info"
-#define TRAIN_INFO_PATH "/data/misc/train-info/train-info.bin"
-
-// Magic word at the start of the train info file, change this if changing the file format
-const uint32_t TRAIN_INFO_FILE_MAGIC = 0xfb7447bf;
-
-// for ConfigMetricsReportList
-const int FIELD_ID_REPORTS = 2;
-
-std::mutex StorageManager::sTrainInfoMutex;
-
-using android::base::StringPrintf;
-using std::unique_ptr;
-
-struct FileName {
-    int64_t mTimestampSec;
-    int mUid;
-    int64_t mConfigId;
-    bool mIsHistory;
-    string getFullFileName(const char* path) {
-        return StringPrintf("%s/%lld_%d_%lld%s", path, (long long)mTimestampSec, (int)mUid,
-                            (long long)mConfigId, (mIsHistory ? "_history" : ""));
-    };
-};
-
-string StorageManager::getDataFileName(long wallClockSec, int uid, int64_t id) {
-    return StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, wallClockSec, uid,
-                        (long long)id);
-}
-
-string StorageManager::getDataHistoryFileName(long wallClockSec, int uid, int64_t id) {
-    return StringPrintf("%s/%ld_%d_%lld_history", STATS_DATA_DIR, wallClockSec, uid,
-                        (long long)id);
-}
-
-static string findTrainInfoFileNameLocked(const string& trainName) {
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir);
-    if (dir == NULL) {
-        VLOG("Path %s does not exist", TRAIN_INFO_DIR);
-        return "";
-    }
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* fileName = de->d_name;
-        if (fileName[0] == '.') continue;
-
-        size_t fileNameLength = strlen(fileName);
-        if (fileNameLength >= trainName.length()) {
-            if (0 == strncmp(fileName + fileNameLength - trainName.length(), trainName.c_str(),
-                             trainName.length())) {
-              return string(fileName);
-            }
-        }
-    }
-
-    return "";
-}
-
-// Returns array of int64_t which contains timestamp in seconds, uid,
-// configID and whether the file is a local history file.
-static void parseFileName(char* name, FileName* output) {
-    int64_t result[3];
-    int index = 0;
-    char* substr = strtok(name, "_");
-    while (substr != nullptr && index < 3) {
-        result[index] = StrToInt64(substr);
-        index++;
-        substr = strtok(nullptr, "_");
-    }
-    // When index ends before hitting 3, file name is corrupted. We
-    // intentionally put -1 at index 0 to indicate the error to caller.
-    // TODO(b/110563137): consider removing files with unexpected name format.
-    if (index < 3) {
-        result[0] = -1;
-    }
-
-    output->mTimestampSec = result[0];
-    output->mUid = result[1];
-    output->mConfigId = result[2];
-    // check if the file is a local history.
-    output->mIsHistory = (substr != nullptr && strcmp("history", substr) == 0);
-}
-
-void StorageManager::writeFile(const char* file, const void* buffer, int numBytes) {
-    int fd = open(file, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
-    if (fd == -1) {
-        VLOG("Attempt to access %s but failed", file);
-        return;
-    }
-    trimToFit(STATS_SERVICE_DIR);
-    trimToFit(STATS_DATA_DIR);
-
-    if (android::base::WriteFully(fd, buffer, numBytes)) {
-        VLOG("Successfully wrote %s", file);
-    } else {
-        ALOGE("Failed to write %s", file);
-    }
-
-    int result = fchown(fd, AID_STATSD, AID_STATSD);
-    if (result) {
-        VLOG("Failed to chown %s to statsd", file);
-    }
-
-    close(fd);
-}
-
-bool StorageManager::writeTrainInfo(const InstallTrainInfo& trainInfo) {
-    std::lock_guard<std::mutex> lock(sTrainInfoMutex);
-
-    if (trainInfo.trainName.empty()) {
-      return false;
-    }
-    deleteSuffixedFiles(TRAIN_INFO_DIR, trainInfo.trainName.c_str());
-
-    std::string fileName =
-            StringPrintf("%s/%ld_%s", TRAIN_INFO_DIR, (long) getWallClockSec(),
-                         trainInfo.trainName.c_str());
-
-    int fd = open(fileName.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
-    if (fd == -1) {
-        VLOG("Attempt to access %s but failed", fileName.c_str());
-        return false;
-    }
-
-    size_t result;
-    // Write the magic word
-    result = write(fd, &TRAIN_INFO_FILE_MAGIC, sizeof(TRAIN_INFO_FILE_MAGIC));
-    if (result != sizeof(TRAIN_INFO_FILE_MAGIC)) {
-        VLOG("Failed to wrtie train info magic");
-        close(fd);
-        return false;
-    }
-
-    // Write the train version
-    const size_t trainVersionCodeByteCount = sizeof(trainInfo.trainVersionCode);
-    result = write(fd, &trainInfo.trainVersionCode, trainVersionCodeByteCount);
-    if (result != trainVersionCodeByteCount) {
-        VLOG("Failed to wrtie train version code");
-        close(fd);
-        return false;
-    }
-
-    // Write # of bytes in trainName to file
-    const size_t trainNameSize = trainInfo.trainName.size();
-    const size_t trainNameSizeByteCount = sizeof(trainNameSize);
-    result = write(fd, (uint8_t*)&trainNameSize, trainNameSizeByteCount);
-    if (result != trainNameSizeByteCount) {
-        VLOG("Failed to write train name size");
-        close(fd);
-        return false;
-    }
-
-    // Write trainName to file
-    result = write(fd, trainInfo.trainName.c_str(), trainNameSize);
-    if (result != trainNameSize) {
-        VLOG("Failed to write train name");
-        close(fd);
-        return false;
-    }
-
-    // Write status to file
-    const size_t statusByteCount = sizeof(trainInfo.status);
-    result = write(fd, (uint8_t*)&trainInfo.status, statusByteCount);
-    if (result != statusByteCount) {
-        VLOG("Failed to write status");
-        close(fd);
-        return false;
-    }
-
-    // Write experiment id count to file.
-    const size_t experimentIdsCount = trainInfo.experimentIds.size();
-    const size_t experimentIdsCountByteCount = sizeof(experimentIdsCount);
-    result = write(fd, (uint8_t*) &experimentIdsCount, experimentIdsCountByteCount);
-    if (result != experimentIdsCountByteCount) {
-        VLOG("Failed to write experiment id count");
-        close(fd);
-        return false;
-    }
-
-    // Write experimentIds to file
-    for (size_t i = 0; i < experimentIdsCount; i++) {
-        const int64_t experimentId = trainInfo.experimentIds[i];
-        const size_t experimentIdByteCount = sizeof(experimentId);
-        result = write(fd, &experimentId, experimentIdByteCount);
-        if (result == experimentIdByteCount) {
-            VLOG("Successfully wrote experiment IDs");
-        } else {
-            VLOG("Failed to write experiment ids");
-            close(fd);
-            return false;
-        }
-    }
-
-    // Write bools to file
-    const size_t boolByteCount = sizeof(trainInfo.requiresStaging);
-    result = write(fd, (uint8_t*)&trainInfo.requiresStaging, boolByteCount);
-    if (result != boolByteCount) {
-      VLOG("Failed to write requires staging");
-      close(fd);
-      return false;
-    }
-
-    result = write(fd, (uint8_t*)&trainInfo.rollbackEnabled, boolByteCount);
-    if (result != boolByteCount) {
-      VLOG("Failed to write rollback enabled");
-      close(fd);
-      return false;
-    }
-
-    result = write(fd, (uint8_t*)&trainInfo.requiresLowLatencyMonitor, boolByteCount);
-    if (result != boolByteCount) {
-      VLOG("Failed to write requires log latency monitor");
-      close(fd);
-      return false;
-    }
-
-    close(fd);
-    return true;
-}
-
-bool StorageManager::readTrainInfo(const std::string& trainName, InstallTrainInfo& trainInfo) {
-    std::lock_guard<std::mutex> lock(sTrainInfoMutex);
-    return readTrainInfoLocked(trainName, trainInfo);
-}
-
-bool StorageManager::readTrainInfoLocked(const std::string& trainName, InstallTrainInfo& trainInfo) {
-    trimToFit(TRAIN_INFO_DIR, /*parseTimestampOnly=*/ true);
-    string fileName = findTrainInfoFileNameLocked(trainName);
-    if (fileName.empty()) {
-        return false;
-    }
-    int fd = open(StringPrintf("%s/%s", TRAIN_INFO_DIR, fileName.c_str()).c_str(), O_RDONLY | O_CLOEXEC);
-    if (fd == -1) {
-        VLOG("Failed to open %s", fileName.c_str());
-        return false;
-    }
-
-    // Read the magic word
-    uint32_t magic;
-    size_t result = read(fd, &magic, sizeof(magic));
-    if (result != sizeof(magic)) {
-        VLOG("Failed to read train info magic");
-        close(fd);
-        return false;
-    }
-
-    if (magic != TRAIN_INFO_FILE_MAGIC) {
-        VLOG("Train info magic was 0x%08x, expected 0x%08x", magic, TRAIN_INFO_FILE_MAGIC);
-        close(fd);
-        return false;
-    }
-
-    // Read the train version code
-    const size_t trainVersionCodeByteCount(sizeof(trainInfo.trainVersionCode));
-    result = read(fd, &trainInfo.trainVersionCode, trainVersionCodeByteCount);
-    if (result != trainVersionCodeByteCount) {
-        VLOG("Failed to read train version code from train info file");
-        close(fd);
-        return false;
-    }
-
-    // Read # of bytes taken by trainName in the file.
-    size_t trainNameSize;
-    result = read(fd, &trainNameSize, sizeof(size_t));
-    if (result != sizeof(size_t)) {
-        VLOG("Failed to read train name size from train info file");
-        close(fd);
-        return false;
-    }
-
-    // Read trainName
-    trainInfo.trainName.resize(trainNameSize);
-    result = read(fd, trainInfo.trainName.data(), trainNameSize);
-    if (result != trainNameSize) {
-        VLOG("Failed to read train name from train info file");
-        close(fd);
-        return false;
-    }
-
-    // Read status
-    const size_t statusByteCount = sizeof(trainInfo.status);
-    result = read(fd, &trainInfo.status, statusByteCount);
-    if (result != statusByteCount) {
-        VLOG("Failed to read train status from train info file");
-        close(fd);
-        return false;
-    }
-
-    // Read experiment ids count.
-    size_t experimentIdsCount;
-    result = read(fd, &experimentIdsCount, sizeof(size_t));
-    if (result != sizeof(size_t)) {
-        VLOG("Failed to read train experiment id count from train info file");
-        close(fd);
-        return false;
-    }
-
-    // Read experimentIds
-    for (size_t i = 0; i < experimentIdsCount; i++) {
-        int64_t experimentId;
-        result = read(fd, &experimentId, sizeof(experimentId));
-        if (result != sizeof(experimentId)) {
-            VLOG("Failed to read train experiment id from train info file");
-            close(fd);
-            return false;
-        }
-        trainInfo.experimentIds.push_back(experimentId);
-    }
-
-    // Read bools
-    const size_t boolByteCount = sizeof(trainInfo.requiresStaging);
-    result = read(fd, &trainInfo.requiresStaging, boolByteCount);
-    if (result != boolByteCount) {
-        VLOG("Failed to read requires requires staging from train info file");
-        close(fd);
-        return false;
-    }
-
-    result = read(fd, &trainInfo.rollbackEnabled, boolByteCount);
-    if (result != boolByteCount) {
-        VLOG("Failed to read requires rollback enabled from train info file");
-        close(fd);
-        return false;
-    }
-
-    result = read(fd, &trainInfo.requiresLowLatencyMonitor, boolByteCount);
-    if (result != boolByteCount) {
-        VLOG("Failed to read requires requires low latency monitor from train info file");
-        close(fd);
-        return false;
-    }
-
-    // Expect to be at EOF.
-    char c;
-    result = read(fd, &c, 1);
-    if (result != 0) {
-        VLOG("Failed to read train info from file. Did not get expected EOF.");
-        close(fd);
-        return false;
-    }
-
-    VLOG("Read train info file successful");
-    close(fd);
-    return true;
-}
-
-vector<InstallTrainInfo> StorageManager::readAllTrainInfo() {
-    std::lock_guard<std::mutex> lock(sTrainInfoMutex);
-    vector<InstallTrainInfo> trainInfoList;
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir);
-    if (dir == NULL) {
-        VLOG("Directory does not exist: %s", TRAIN_INFO_DIR);
-        return trainInfoList;
-    }
-
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') {
-            continue;
-        }
-
-        InstallTrainInfo trainInfo;
-        bool readSuccess = StorageManager::readTrainInfoLocked(name, trainInfo);
-        if (!readSuccess) {
-            continue;
-        }
-        trainInfoList.push_back(trainInfo);
-    }
-    return trainInfoList;
-}
-
-void StorageManager::deleteFile(const char* file) {
-    if (remove(file) != 0) {
-        VLOG("Attempt to delete %s but is not found", file);
-    } else {
-        VLOG("Successfully deleted %s", file);
-    }
-}
-
-void StorageManager::deleteAllFiles(const char* path) {
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
-    if (dir == NULL) {
-        VLOG("Directory does not exist: %s", path);
-        return;
-    }
-
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') continue;
-        deleteFile(StringPrintf("%s/%s", path, name).c_str());
-    }
-}
-
-void StorageManager::deleteSuffixedFiles(const char* path, const char* suffix) {
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
-    if (dir == NULL) {
-        VLOG("Directory does not exist: %s", path);
-        return;
-    }
-
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') {
-            continue;
-        }
-        size_t nameLen = strlen(name);
-        size_t suffixLen = strlen(suffix);
-        if (suffixLen <= nameLen && strncmp(name + nameLen - suffixLen, suffix, suffixLen) == 0) {
-            deleteFile(StringPrintf("%s/%s", path, name).c_str());
-        }
-    }
-}
-
-void StorageManager::sendBroadcast(const char* path,
-                                   const std::function<void(const ConfigKey&)>& sendBroadcast) {
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
-    if (dir == NULL) {
-        VLOG("no stats-data directory on disk");
-        return;
-    }
-
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') continue;
-        VLOG("file %s", name);
-
-        FileName output;
-        parseFileName(name, &output);
-        if (output.mTimestampSec == -1 || output.mIsHistory) continue;
-        sendBroadcast(ConfigKey((int)output.mUid, output.mConfigId));
-    }
-}
-
-bool StorageManager::hasConfigMetricsReport(const ConfigKey& key) {
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_DATA_DIR), closedir);
-    if (dir == NULL) {
-        VLOG("Path %s does not exist", STATS_DATA_DIR);
-        return false;
-    }
-
-    string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
-
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') continue;
-
-        size_t nameLen = strlen(name);
-        size_t suffixLen = suffix.length();
-        if (suffixLen <= nameLen &&
-            strncmp(name + nameLen - suffixLen, suffix.c_str(), suffixLen) == 0) {
-            // Check again that the file name is parseable.
-            FileName output;
-            parseFileName(name, &output);
-            if (output.mTimestampSec == -1 || output.mIsHistory) continue;
-            return true;
-        }
-    }
-    return false;
-}
-
-void StorageManager::appendConfigMetricsReport(const ConfigKey& key, ProtoOutputStream* proto,
-                                               bool erase_data, bool isAdb) {
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_DATA_DIR), closedir);
-    if (dir == NULL) {
-        VLOG("Path %s does not exist", STATS_DATA_DIR);
-        return;
-    }
-
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        string fileName(name);
-        if (name[0] == '.') continue;
-        FileName output;
-        parseFileName(name, &output);
-
-        if (output.mTimestampSec == -1 || (output.mIsHistory && !isAdb) ||
-            output.mUid != key.GetUid() || output.mConfigId != key.GetId()) {
-            continue;
-        }
-
-        auto fullPathName = StringPrintf("%s/%s", STATS_DATA_DIR, fileName.c_str());
-        int fd = open(fullPathName.c_str(), O_RDONLY | O_CLOEXEC);
-        if (fd != -1) {
-            string content;
-            if (android::base::ReadFdToString(fd, &content)) {
-                proto->write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS,
-                             content.c_str(), content.size());
-            }
-            close(fd);
-        } else {
-            ALOGE("file cannot be opened");
-        }
-
-        if (erase_data) {
-            remove(fullPathName.c_str());
-        } else if (!output.mIsHistory && !isAdb) {
-            // This means a real data owner has called to get this data. But the config says it
-            // wants to keep a local history. So now this file must be renamed as a history file.
-            // So that next time, when owner calls getData() again, this data won't be uploaded
-            // again. rename returns 0 on success
-            if (rename(fullPathName.c_str(), (fullPathName + "_history").c_str())) {
-                ALOGE("Failed to rename file %s", fullPathName.c_str());
-            }
-        }
-    }
-}
-
-bool StorageManager::readFileToString(const char* file, string* content) {
-    int fd = open(file, O_RDONLY | O_CLOEXEC);
-    bool res = false;
-    if (fd != -1) {
-        if (android::base::ReadFdToString(fd, content)) {
-            res = true;
-        } else {
-            VLOG("Failed to read file %s\n", file);
-        }
-        close(fd);
-    }
-    return res;
-}
-
-void StorageManager::readConfigFromDisk(map<ConfigKey, StatsdConfig>& configsMap) {
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR), closedir);
-    if (dir == NULL) {
-        VLOG("no default config on disk");
-        return;
-    }
-    trimToFit(STATS_SERVICE_DIR);
-
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') continue;
-
-        FileName output;
-        parseFileName(name, &output);
-        if (output.mTimestampSec == -1) continue;
-        string file_name = output.getFullFileName(STATS_SERVICE_DIR);
-        int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
-        if (fd != -1) {
-            string content;
-            if (android::base::ReadFdToString(fd, &content)) {
-                StatsdConfig config;
-                if (config.ParseFromString(content)) {
-                    configsMap[ConfigKey(output.mUid, output.mConfigId)] = config;
-                    VLOG("map key uid=%lld|configID=%lld", (long long)output.mUid,
-                         (long long)output.mConfigId);
-                }
-            }
-            close(fd);
-        }
-    }
-}
-
-bool StorageManager::readConfigFromDisk(const ConfigKey& key, StatsdConfig* config) {
-    string content;
-    return config != nullptr &&
-        StorageManager::readConfigFromDisk(key, &content) && config->ParseFromString(content);
-}
-
-bool StorageManager::readConfigFromDisk(const ConfigKey& key, string* content) {
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR),
-                                             closedir);
-    if (dir == NULL) {
-        VLOG("Directory does not exist: %s", STATS_SERVICE_DIR);
-        return false;
-    }
-
-    string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') {
-            continue;
-        }
-        size_t nameLen = strlen(name);
-        size_t suffixLen = suffix.length();
-        // There can be at most one file that matches this suffix (config key).
-        if (suffixLen <= nameLen &&
-            strncmp(name + nameLen - suffixLen, suffix.c_str(), suffixLen) == 0) {
-            int fd = open(StringPrintf("%s/%s", STATS_SERVICE_DIR, name).c_str(),
-                                  O_RDONLY | O_CLOEXEC);
-            if (fd != -1) {
-                if (android::base::ReadFdToString(fd, content)) {
-                    return true;
-                }
-                close(fd);
-            }
-        }
-    }
-    return false;
-}
-
-bool StorageManager::hasIdenticalConfig(const ConfigKey& key,
-                                        const vector<uint8_t>& config) {
-    string content;
-    if (StorageManager::readConfigFromDisk(key, &content)) {
-        vector<uint8_t> vec(content.begin(), content.end());
-        if (vec == config) {
-            return true;
-        }
-    }
-    return false;
-}
-
-void StorageManager::sortFiles(vector<FileInfo>* fileNames) {
-    // Reverse sort to effectively remove from the back (oldest entries).
-    // This will sort files in reverse-chronological order. Local history files have lower
-    // priority than regular data files.
-    sort(fileNames->begin(), fileNames->end(), [](FileInfo& lhs, FileInfo& rhs) {
-        // first consider if the file is a local history
-        if (lhs.mIsHistory && !rhs.mIsHistory) {
-            return false;
-        } else if (rhs.mIsHistory && !lhs.mIsHistory) {
-            return true;
-        }
-
-        // then consider the age.
-        if (lhs.mFileAgeSec < rhs.mFileAgeSec) {
-            return true;
-        } else if (lhs.mFileAgeSec > rhs.mFileAgeSec) {
-            return false;
-        }
-
-        // then good luck.... use string::compare
-        return lhs.mFileName.compare(rhs.mFileName) > 0;
-    });
-}
-
-void StorageManager::trimToFit(const char* path, bool parseTimestampOnly) {
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
-    if (dir == NULL) {
-        VLOG("Path %s does not exist", path);
-        return;
-    }
-    dirent* de;
-    int totalFileSize = 0;
-    vector<FileInfo> fileNames;
-    auto nowSec = getWallClockSec();
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') continue;
-
-        FileName output;
-        string file_name;
-        if (parseTimestampOnly) {
-            file_name = StringPrintf("%s/%s", path, name);
-            output.mTimestampSec = StrToInt64(strtok(name, "_"));
-            output.mIsHistory = false;
-        } else {
-            parseFileName(name, &output);
-            file_name = output.getFullFileName(path);
-        }
-        if (output.mTimestampSec == -1) continue;
-
-        // Check for timestamp and delete if it's too old.
-        long fileAge = nowSec - output.mTimestampSec;
-        if (fileAge > StatsdStats::kMaxAgeSecond ||
-            (output.mIsHistory && fileAge > StatsdStats::kMaxLocalHistoryAgeSecond)) {
-            deleteFile(file_name.c_str());
-            continue;
-        }
-
-        ifstream file(file_name.c_str(), ifstream::in | ifstream::binary);
-        int fileSize = 0;
-        if (file.is_open()) {
-            file.seekg(0, ios::end);
-            fileSize = file.tellg();
-            file.close();
-            totalFileSize += fileSize;
-        }
-        fileNames.emplace_back(file_name, output.mIsHistory, fileSize, fileAge);
-    }
-
-    if (fileNames.size() > StatsdStats::kMaxFileNumber ||
-        totalFileSize > StatsdStats::kMaxFileSize) {
-        sortFiles(&fileNames);
-    }
-
-    // Start removing files from oldest to be under the limit.
-    while (fileNames.size() > 0 && (fileNames.size() > StatsdStats::kMaxFileNumber ||
-                                    totalFileSize > StatsdStats::kMaxFileSize)) {
-        totalFileSize -= fileNames.at(fileNames.size() - 1).mFileSizeBytes;
-        deleteFile(fileNames.at(fileNames.size() - 1).mFileName.c_str());
-        fileNames.pop_back();
-    }
-}
-
-void StorageManager::printStats(int outFd) {
-    printDirStats(outFd, STATS_SERVICE_DIR);
-    printDirStats(outFd, STATS_DATA_DIR);
-}
-
-void StorageManager::printDirStats(int outFd, const char* path) {
-    dprintf(outFd, "Printing stats of %s\n", path);
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
-    if (dir == NULL) {
-        VLOG("Path %s does not exist", path);
-        return;
-    }
-    dirent* de;
-    int fileCount = 0;
-    int totalFileSize = 0;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') {
-            continue;
-        }
-        FileName output;
-        parseFileName(name, &output);
-        if (output.mTimestampSec == -1) continue;
-        dprintf(outFd, "\t #%d, Last updated: %lld, UID: %d, Config ID: %lld, %s", fileCount + 1,
-                (long long)output.mTimestampSec, output.mUid, (long long)output.mConfigId,
-                (output.mIsHistory ? "local history" : ""));
-        string file_name = output.getFullFileName(path);
-        ifstream file(file_name.c_str(), ifstream::in | ifstream::binary);
-        if (file.is_open()) {
-            file.seekg(0, ios::end);
-            int fileSize = file.tellg();
-            file.close();
-            dprintf(outFd, ", File Size: %d bytes", fileSize);
-            totalFileSize += fileSize;
-        }
-        dprintf(outFd, "\n");
-        fileCount++;
-    }
-    dprintf(outFd, "\tTotal number of files: %d, Total size of files: %d bytes.\n", fileCount,
-            totalFileSize);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h
deleted file mode 100644
index d59046d..0000000
--- a/cmds/statsd/src/storage/StorageManager.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef STORAGE_MANAGER_H
-#define STORAGE_MANAGER_H
-
-#include <android/util/ProtoOutputStream.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-
-#include "packages/UidMap.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-
-class StorageManager : public virtual RefBase {
-public:
-    struct FileInfo {
-        FileInfo(std::string name, bool isHistory, int fileSize, long fileAge)
-            : mFileName(name),
-              mIsHistory(isHistory),
-              mFileSizeBytes(fileSize),
-              mFileAgeSec(fileAge) {
-        }
-        std::string mFileName;
-        bool mIsHistory;
-        int mFileSizeBytes;
-        long mFileAgeSec;
-    };
-
-    /**
-     * Writes a given byte array as a file to the specified file path.
-     */
-    static void writeFile(const char* file, const void* buffer, int numBytes);
-
-    /**
-     * Writes train info.
-     */
-    static bool writeTrainInfo(const InstallTrainInfo& trainInfo);
-
-    /**
-     * Reads train info.
-     */
-    static bool readTrainInfo(const std::string& trainName, InstallTrainInfo& trainInfo);
-
-    /**
-     * Reads train info assuming lock is obtained.
-     */
-    static bool readTrainInfoLocked(const std::string& trainName, InstallTrainInfo& trainInfo);
-
-    /**
-     * Reads all train info and returns a vector of train info.
-     */
-    static vector<InstallTrainInfo> readAllTrainInfo();
-
-    /**
-     * Reads the file content to the buffer.
-     */
-    static bool readFileToString(const char* file, string* content);
-
-    /**
-     * Deletes a single file given a file name.
-     */
-    static void deleteFile(const char* file);
-
-    /**
-     * Deletes all files in a given directory.
-     */
-    static void deleteAllFiles(const char* path);
-
-    /**
-     * Deletes all files whose name matches with a provided suffix.
-     */
-    static void deleteSuffixedFiles(const char* path, const char* suffix);
-
-    /**
-     * Send broadcasts to relevant receiver for each data stored on disk.
-     */
-    static void sendBroadcast(const char* path,
-                              const std::function<void(const ConfigKey&)>& sendBroadcast);
-
-    /**
-     * Returns true if there's at least one report on disk.
-     */
-    static bool hasConfigMetricsReport(const ConfigKey& key);
-
-    /**
-     * Appends the ConfigMetricsReport found on disk to the specifid proto
-     * and, if erase_data, deletes it from disk.
-     *
-     * [isAdb]: if the caller is adb dump. This includes local adb dump or dumpsys by
-     * bugreport or incidentd. When true, we will append any local history data too.
-     *
-     * When
-     * erase_data=true, isAdb=true:   append history data to output, remove all data after read
-     * erase_data=false, isAdb=true:  append history data to output, keep data after read
-     * erase_data=true, isAdb=false:  do not append history data, and remove data after read
-     * erase_data=false, isAdb=false: do not append history data and *rename* all data files to
-     *                                history files.
-     */
-    static void appendConfigMetricsReport(const ConfigKey& key, ProtoOutputStream* proto,
-                                          bool erase_data, bool isAdb);
-
-    /**
-     * Call to load the saved configs from disk.
-     */
-    static void readConfigFromDisk(std::map<ConfigKey, StatsdConfig>& configsMap);
-
-    /**
-     * Call to load the specified config from disk. Returns false if the config file does not
-     * exist or error occurs when reading the file.
-     */
-    static bool readConfigFromDisk(const ConfigKey& key, StatsdConfig* config);
-    static bool readConfigFromDisk(const ConfigKey& key, string* config);
-
-    /**
-     * Trims files in the provided directory to limit the total size, number of
-     * files, accumulation of outdated files.
-     */
-    static void trimToFit(const char* dir, bool parseTimestampOnly = false);
-
-    /**
-     * Returns true if there already exists identical configuration on device.
-     */
-    static bool hasIdenticalConfig(const ConfigKey& key,
-                                   const vector<uint8_t>& config);
-
-    /**
-     * Prints disk usage statistics related to statsd.
-     */
-    static void printStats(int out);
-
-    static string getDataFileName(long wallClockSec, int uid, int64_t id);
-
-    static string getDataHistoryFileName(long wallClockSec, int uid, int64_t id);
-
-    static void sortFiles(vector<FileInfo>* fileNames);
-
-private:
-    /**
-     * Prints disk usage statistics about a directory related to statsd.
-     */
-    static void printDirStats(int out, const char* path);
-
-    static std::mutex sTrainInfoMutex;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#endif  // STORAGE_MANAGER_H
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
deleted file mode 100644
index 1d77513..0000000
--- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-#define DEBUG false
-#include "Log.h"
-
-#include "FieldValue.h"
-#include "IncidentdReporter.h"
-#include "packages/UidMap.h"
-#include "stats_log_util.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include <incident/incident_report.h>
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-using std::vector;
-
-using util::FIELD_TYPE_INT32;
-using util::FIELD_TYPE_INT64;
-using util::FIELD_TYPE_MESSAGE;
-using util::FIELD_TYPE_STRING;
-
-// field ids in IncidentHeaderProto
-const int FIELD_ID_ALERT_ID = 1;
-const int FIELD_ID_REASON = 2;
-const int FIELD_ID_CONFIG_KEY = 3;
-const int FIELD_ID_CONFIG_KEY_UID = 1;
-const int FIELD_ID_CONFIG_KEY_ID = 2;
-
-const int FIELD_ID_TRIGGER_DETAILS = 4;
-const int FIELD_ID_TRIGGER_DETAILS_TRIGGER_METRIC = 1;
-const int FIELD_ID_METRIC_VALUE_METRIC_ID = 1;
-const int FIELD_ID_METRIC_VALUE_DIMENSION_IN_WHAT = 2;
-const int FIELD_ID_METRIC_VALUE_VALUE = 4;
-
-const int FIELD_ID_PACKAGE_INFO = 3;
-
-namespace {
-void getProtoData(const int64_t& rule_id, int64_t metricId, const MetricDimensionKey& dimensionKey,
-                  int64_t metricValue, const ConfigKey& configKey, const string& reason,
-                  vector<uint8_t>* protoData) {
-    ProtoOutputStream headerProto;
-    headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_ID, (long long)rule_id);
-    headerProto.write(FIELD_TYPE_STRING | FIELD_ID_REASON, reason);
-    uint64_t token =
-            headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
-    headerProto.write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_KEY_UID, configKey.GetUid());
-    headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_KEY_ID, (long long)configKey.GetId());
-    headerProto.end(token);
-
-    token = headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_TRIGGER_DETAILS);
-
-    // MetricValue trigger_metric = 1;
-    uint64_t metricToken =
-            headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_TRIGGER_DETAILS_TRIGGER_METRIC);
-    // message MetricValue {
-    // optional int64 metric_id = 1;
-    headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_VALUE_METRIC_ID, (long long)metricId);
-    // optional DimensionsValue dimension_in_what = 2;
-    uint64_t dimToken =
-            headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_METRIC_VALUE_DIMENSION_IN_WHAT);
-    writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), nullptr, &headerProto);
-    headerProto.end(dimToken);
-
-    // deprecated field
-    // optional DimensionsValue dimension_in_condition = 3;
-
-    // optional int64 value = 4;
-    headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_VALUE_VALUE, (long long)metricValue);
-
-    // }
-    headerProto.end(metricToken);
-
-    // write relevant uid package info
-    std::set<int32_t> uids;
-
-    for (const auto& dim : dimensionKey.getDimensionKeyInWhat().getValues()) {
-        int uid = getUidIfExists(dim);
-        // any uid <= 2000 are predefined AID_*
-        if (uid > 2000) {
-            uids.insert(uid);
-        }
-    }
-
-    if (!uids.empty()) {
-        uint64_t token = headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_PACKAGE_INFO);
-        UidMap::getInstance()->writeUidMapSnapshot(getElapsedRealtimeNs(), true, true, uids,
-                                                   nullptr /*string set*/, &headerProto);
-        headerProto.end(token);
-    }
-
-    headerProto.end(token);
-
-    protoData->resize(headerProto.size());
-    size_t pos = 0;
-    sp<android::util::ProtoReader> reader = headerProto.data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(&((*protoData)[pos]), reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-}
-}  // namespace
-
-bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int64_t metricId,
-                            const MetricDimensionKey& dimensionKey, int64_t metricValue,
-                            const ConfigKey& configKey) {
-    if (config.section_size() == 0) {
-        VLOG("The alert %lld contains zero section in config(%d,%lld)", (unsigned long long)rule_id,
-             configKey.GetUid(), (long long)configKey.GetId());
-        return false;
-    }
-
-    AIncidentReportArgs* args = AIncidentReportArgs_init();
-
-    vector<uint8_t> protoData;
-    getProtoData(rule_id, metricId, dimensionKey, metricValue, configKey,
-                 config.alert_description(), &protoData);
-    AIncidentReportArgs_addHeader(args, protoData.data(), protoData.size());
-
-    for (int i = 0; i < config.section_size(); i++) {
-        AIncidentReportArgs_addSection(args, config.section(i));
-    }
-
-    uint8_t dest;
-    switch (config.dest()) {
-        case IncidentdDetails_Destination_AUTOMATIC:
-            dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC;
-            break;
-        case IncidentdDetails_Destination_EXPLICIT:
-            dest = INCIDENT_REPORT_PRIVACY_POLICY_EXPLICIT;
-            break;
-        default:
-            dest = INCIDENT_REPORT_PRIVACY_POLICY_AUTOMATIC;
-    }
-    AIncidentReportArgs_setPrivacyPolicy(args, dest);
-
-    AIncidentReportArgs_setReceiverPackage(args, config.receiver_pkg().c_str());
-
-    AIncidentReportArgs_setReceiverClass(args, config.receiver_cls().c_str());
-
-    int err = AIncidentReportArgs_takeReport(args);
-    AIncidentReportArgs_delete(args);
-
-    return err == NO_ERROR;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.h b/cmds/statsd/src/subscriber/IncidentdReporter.h
deleted file mode 100644
index e78a4d9..0000000
--- a/cmds/statsd/src/subscriber/IncidentdReporter.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include "HashableDimensionKey.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alert, IncidentdDetails
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Calls incidentd to trigger an incident report and put in dropbox for uploading.
- */
-bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int64_t metricId,
-                            const MetricDimensionKey& dimensionKey, int64_t metricValue,
-                            const ConfigKey& configKey);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.cpp b/cmds/statsd/src/subscriber/SubscriberReporter.cpp
deleted file mode 100644
index c915ef3..0000000
--- a/cmds/statsd/src/subscriber/SubscriberReporter.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#define DEBUG false  // STOPSHIP if true
-#include "Log.h"
-
-#include "SubscriberReporter.h"
-
-using std::lock_guard;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-struct BroadcastSubscriberDeathCookie {
-    BroadcastSubscriberDeathCookie(const ConfigKey& configKey, int64_t subscriberId,
-                                   const shared_ptr<IPendingIntentRef>& pir):
-        mConfigKey(configKey),
-        mSubscriberId(subscriberId),
-        mPir(pir) {}
-
-    ConfigKey mConfigKey;
-    int64_t mSubscriberId;
-    shared_ptr<IPendingIntentRef> mPir;
-};
-
-void SubscriberReporter::broadcastSubscriberDied(void* cookie) {
-    auto cookie_ = static_cast<BroadcastSubscriberDeathCookie*>(cookie);
-    ConfigKey& configKey = cookie_->mConfigKey;
-    int64_t subscriberId = cookie_->mSubscriberId;
-    shared_ptr<IPendingIntentRef>& pir = cookie_->mPir;
-
-    SubscriberReporter& thiz = getInstance();
-
-    // Erase the mapping from a (config_key, subscriberId) to a pir if the
-    // mapping exists.
-    lock_guard<mutex> lock(thiz.mLock);
-    auto subscriberMapIt = thiz.mIntentMap.find(configKey);
-    if (subscriberMapIt != thiz.mIntentMap.end()) {
-        auto subscriberMap = subscriberMapIt->second;
-        auto pirIt = subscriberMap.find(subscriberId);
-        if (pirIt != subscriberMap.end() && pirIt->second == pir) {
-            subscriberMap.erase(subscriberId);
-            if (subscriberMap.empty()) {
-                thiz.mIntentMap.erase(configKey);
-            }
-        }
-    }
-
-    // The death recipient corresponding to this specific pir can never be
-    // triggered again, so free up resources.
-    delete cookie_;
-}
-
-SubscriberReporter::SubscriberReporter() :
-    mBroadcastSubscriberDeathRecipient(AIBinder_DeathRecipient_new(broadcastSubscriberDied)) {
-}
-
-void SubscriberReporter::setBroadcastSubscriber(const ConfigKey& configKey,
-                                                int64_t subscriberId,
-                                                const shared_ptr<IPendingIntentRef>& pir) {
-    VLOG("SubscriberReporter::setBroadcastSubscriber called.");
-    {
-        lock_guard<mutex> lock(mLock);
-        mIntentMap[configKey][subscriberId] = pir;
-    }
-    AIBinder_linkToDeath(pir->asBinder().get(), mBroadcastSubscriberDeathRecipient.get(),
-                         new BroadcastSubscriberDeathCookie(configKey, subscriberId, pir));
-}
-
-void SubscriberReporter::unsetBroadcastSubscriber(const ConfigKey& configKey,
-                                                  int64_t subscriberId) {
-    VLOG("SubscriberReporter::unsetBroadcastSubscriber called.");
-    lock_guard<mutex> lock(mLock);
-    auto subscriberMapIt = mIntentMap.find(configKey);
-    if (subscriberMapIt != mIntentMap.end()) {
-        subscriberMapIt->second.erase(subscriberId);
-        if (subscriberMapIt->second.empty()) {
-            mIntentMap.erase(configKey);
-        }
-    }
-}
-
-void SubscriberReporter::alertBroadcastSubscriber(const ConfigKey& configKey,
-                                                  const Subscription& subscription,
-                                                  const MetricDimensionKey& dimKey) const {
-    // Reminder about ids:
-    //  subscription id - name of the Subscription (that ties the Alert to the broadcast)
-    //  subscription rule_id - the name of the Alert (that triggers the broadcast)
-    //  subscriber_id - name of the PendingIntent to use to send the broadcast
-    //  config uid - the uid that uploaded the config (and therefore gave the PendingIntent,
-    //                 although the intent may be to broadcast to a different uid)
-    //  config id - the name of this config (for this particular uid)
-
-    VLOG("SubscriberReporter::alertBroadcastSubscriber called.");
-    lock_guard<mutex> lock(mLock);
-
-    if (!subscription.has_broadcast_subscriber_details()
-            || !subscription.broadcast_subscriber_details().has_subscriber_id()) {
-        ALOGE("Broadcast subscriber does not have an id.");
-        return;
-    }
-    int64_t subscriberId = subscription.broadcast_subscriber_details().subscriber_id();
-
-    vector<string> cookies;
-    cookies.reserve(subscription.broadcast_subscriber_details().cookie_size());
-    for (auto& cookie : subscription.broadcast_subscriber_details().cookie()) {
-        cookies.push_back(cookie);
-    }
-
-    auto it1 = mIntentMap.find(configKey);
-    if (it1 == mIntentMap.end()) {
-        ALOGW("Cannot inform subscriber for missing config key %s ", configKey.ToString().c_str());
-        return;
-    }
-    auto it2 = it1->second.find(subscriberId);
-    if (it2 == it1->second.end()) {
-        ALOGW("Cannot inform subscriber of config %s for missing subscriberId %lld ",
-                configKey.ToString().c_str(), (long long)subscriberId);
-        return;
-    }
-    sendBroadcastLocked(it2->second, configKey, subscription, cookies, dimKey);
-}
-
-void SubscriberReporter::sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir,
-                                             const ConfigKey& configKey,
-                                             const Subscription& subscription,
-                                             const vector<string>& cookies,
-                                             const MetricDimensionKey& dimKey) const {
-    VLOG("SubscriberReporter::sendBroadcastLocked called.");
-    pir->sendSubscriberBroadcast(
-            configKey.GetUid(),
-            configKey.GetId(),
-            subscription.id(),
-            subscription.rule_id(),
-            cookies,
-            dimKey.getDimensionKeyInWhat().toStatsDimensionsValueParcel());
-}
-
-shared_ptr<IPendingIntentRef> SubscriberReporter::getBroadcastSubscriber(const ConfigKey& configKey,
-                                                                         int64_t subscriberId) {
-    lock_guard<mutex> lock(mLock);
-    auto subscriberMapIt = mIntentMap.find(configKey);
-    if (subscriberMapIt == mIntentMap.end()) {
-        return nullptr;
-    }
-    auto pirMapIt = subscriberMapIt->second.find(subscriberId);
-    if (pirMapIt == subscriberMapIt->second.end()) {
-        return nullptr;
-    }
-    return pirMapIt->second;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/subscriber/SubscriberReporter.h b/cmds/statsd/src/subscriber/SubscriberReporter.h
deleted file mode 100644
index 4fe4281..0000000
--- a/cmds/statsd/src/subscriber/SubscriberReporter.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-#include <aidl/android/os/IPendingIntentRef.h>
-#include <utils/RefBase.h>
-#include <utils/String16.h>
-
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // subscription
-#include "HashableDimensionKey.h"
-
-#include <mutex>
-#include <unordered_map>
-#include <vector>
-
-using aidl::android::os::IPendingIntentRef;
-using std::mutex;
-using std::shared_ptr;
-using std::string;
-using std::unordered_map;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// Reports information to subscribers.
-// Single instance shared across the process. All methods are thread safe.
-class SubscriberReporter {
-public:
-    /** Get (singleton) instance of SubscriberReporter. */
-    static SubscriberReporter& getInstance() {
-        static SubscriberReporter subscriberReporter;
-        return subscriberReporter;
-    }
-
-    ~SubscriberReporter(){};
-    SubscriberReporter(SubscriberReporter const&) = delete;
-    void operator=(SubscriberReporter const&) = delete;
-
-    /**
-     * Stores the given intentSender, associating it with the given (configKey, subscriberId) pair.
-     */
-    void setBroadcastSubscriber(const ConfigKey& configKey,
-                                int64_t subscriberId,
-                                const shared_ptr<IPendingIntentRef>& pir);
-
-    /**
-     * Erases any intentSender information from the given (configKey, subscriberId) pair.
-     */
-    void unsetBroadcastSubscriber(const ConfigKey& configKey, int64_t subscriberId);
-
-    /**
-     * Sends a broadcast via the intentSender previously stored for the
-     * given (configKey, subscriberId) pair by setBroadcastSubscriber.
-     * Information about the subscriber, as well as information extracted from the dimKey, is sent.
-     */
-    void alertBroadcastSubscriber(const ConfigKey& configKey,
-                                  const Subscription& subscription,
-                                  const MetricDimensionKey& dimKey) const;
-
-    shared_ptr<IPendingIntentRef> getBroadcastSubscriber(const ConfigKey& configKey,
-                                                         int64_t subscriberId);
-
-private:
-    SubscriberReporter();
-
-    mutable mutex mLock;
-
-    /** Maps <ConfigKey, SubscriberId> -> IPendingIntentRef (which represents a PendingIntent). */
-    unordered_map<ConfigKey, unordered_map<int64_t, shared_ptr<IPendingIntentRef>>> mIntentMap;
-
-    /**
-     * Sends a broadcast via the given intentSender (using mStatsCompanionService), along
-     * with the information in the other parameters.
-     */
-    void sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir,
-                             const ConfigKey& configKey,
-                             const Subscription& subscription,
-                             const vector<string>& cookies,
-                             const MetricDimensionKey& dimKey) const;
-
-    ::ndk::ScopedAIBinder_DeathRecipient mBroadcastSubscriberDeathRecipient;
-
-    /**
-     * Death recipient callback that is called when a broadcast subscriber dies.
-     * The cookie is a pointer to a BroadcastSubscriberDeathCookie.
-     */
-    static void broadcastSubscriberDied(void* cookie);
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/uid_data.proto b/cmds/statsd/src/uid_data.proto
deleted file mode 100644
index a6fa26c..0000000
--- a/cmds/statsd/src/uid_data.proto
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-syntax = "proto2";
-
-package android.os.statsd;
-
-option java_package = "com.android.internal.os";
-option java_outer_classname = "UidDataProto";
-
-message ApplicationInfo {
-  optional int32 uid = 1;
-  optional int64 version = 2;
-  optional string version_string = 3;
-  optional string package_name = 4;
-  optional string installer = 5;
-}
-
-// StatsServiceCompanion uses the proto to supply statsd with uid-package
-// mapping updates.
-message UidData {
-  repeated ApplicationInfo app_info = 1;
-}
diff --git a/cmds/statsd/src/utils/MultiConditionTrigger.cpp b/cmds/statsd/src/utils/MultiConditionTrigger.cpp
deleted file mode 100644
index 43a6933..0000000
--- a/cmds/statsd/src/utils/MultiConditionTrigger.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-#define DEBUG false  // STOPSHIP if true
-
-#include "MultiConditionTrigger.h"
-
-#include <thread>
-
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-MultiConditionTrigger::MultiConditionTrigger(const set<string>& conditionNames,
-                                             function<void()> trigger)
-    : mRemainingConditionNames(conditionNames),
-      mTrigger(trigger),
-      mCompleted(mRemainingConditionNames.empty()) {
-    if (mCompleted) {
-        thread executorThread([this] { mTrigger(); });
-        executorThread.detach();
-    }
-}
-
-void MultiConditionTrigger::markComplete(const string& conditionName) {
-    bool doTrigger = false;
-    {
-        lock_guard<mutex> lg(mMutex);
-        if (mCompleted) {
-            return;
-        }
-        mRemainingConditionNames.erase(conditionName);
-        mCompleted = mRemainingConditionNames.empty();
-        doTrigger = mCompleted;
-    }
-    if (doTrigger) {
-        std::thread executorThread([this] { mTrigger(); });
-        executorThread.detach();
-    }
-}
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/utils/MultiConditionTrigger.h b/cmds/statsd/src/utils/MultiConditionTrigger.h
deleted file mode 100644
index 51f6029..0000000
--- a/cmds/statsd/src/utils/MultiConditionTrigger.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-#pragma once
-
-#include <gtest/gtest_prod.h>
-
-#include <mutex>
-#include <set>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * This class provides a utility to wait for a set of named conditions to occur.
- *
- * It will execute the trigger runnable in a detached thread once all conditions have been marked
- * true.
- */
-class MultiConditionTrigger {
-public:
-    explicit MultiConditionTrigger(const std::set<std::string>& conditionNames,
-                                   std::function<void()> trigger);
-
-    MultiConditionTrigger(const MultiConditionTrigger&) = delete;
-    MultiConditionTrigger& operator=(const MultiConditionTrigger&) = delete;
-
-    // Mark a specific condition as true. If this condition has called markComplete already or if
-    // the event was not specified in the constructor, the function is a no-op.
-    void markComplete(const std::string& eventName);
-
-private:
-    mutable std::mutex mMutex;
-    std::set<std::string> mRemainingConditionNames;
-    std::function<void()> mTrigger;
-    bool mCompleted;
-
-    FRIEND_TEST(MultiConditionTriggerTest, TestCountDownCalledBySameEventName);
-};
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/statsd_test.xml b/cmds/statsd/statsd_test.xml
deleted file mode 100644
index 8f9bb1c..0000000
--- a/cmds/statsd/statsd_test.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Runs statsd_test.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-native" />
-    <option name="test-suite-tag" value="mts" />
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-       <option name="cleanup" value="true" />
-       <option name="push" value="statsd_test->/data/local/tmp/statsd_test" />
-       <option name="append-bitness" value="true" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="statsd_test" />
-    </test>
-
-    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
-        <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
-    </object>
-</configuration>
diff --git a/cmds/statsd/tests/AlarmMonitor_test.cpp b/cmds/statsd/tests/AlarmMonitor_test.cpp
deleted file mode 100644
index 1dc9795..0000000
--- a/cmds/statsd/tests/AlarmMonitor_test.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (C) 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.
-
-#include "anomaly/AlarmMonitor.h"
-
-#include <gtest/gtest.h>
-
-using namespace android::os::statsd;
-using std::shared_ptr;
-
-#ifdef __ANDROID__
-TEST(AlarmMonitor, popSoonerThan) {
-    std::string emptyMetricId;
-    std::string emptyDimensionId;
-    unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> set;
-    AlarmMonitor am(2,
-                    [](const shared_ptr<IStatsCompanionService>&, int64_t){},
-                    [](const shared_ptr<IStatsCompanionService>&){});
-
-    set = am.popSoonerThan(5);
-    EXPECT_TRUE(set.empty());
-
-    sp<const InternalAlarm> a = new InternalAlarm{10};
-    sp<const InternalAlarm> b = new InternalAlarm{20};
-    sp<const InternalAlarm> c = new InternalAlarm{20};
-    sp<const InternalAlarm> d = new InternalAlarm{30};
-    sp<const InternalAlarm> e = new InternalAlarm{40};
-    sp<const InternalAlarm> f = new InternalAlarm{50};
-
-    am.add(a);
-    am.add(b);
-    am.add(c);
-    am.add(d);
-    am.add(e);
-    am.add(f);
-
-    set = am.popSoonerThan(5);
-    EXPECT_TRUE(set.empty());
-
-    set = am.popSoonerThan(30);
-    ASSERT_EQ(4u, set.size());
-    EXPECT_EQ(1u, set.count(a));
-    EXPECT_EQ(1u, set.count(b));
-    EXPECT_EQ(1u, set.count(c));
-    EXPECT_EQ(1u, set.count(d));
-
-    set = am.popSoonerThan(60);
-    ASSERT_EQ(2u, set.size());
-    EXPECT_EQ(1u, set.count(e));
-    EXPECT_EQ(1u, set.count(f));
-
-    set = am.popSoonerThan(80);
-    ASSERT_EQ(0u, set.size());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/ConfigManager_test.cpp b/cmds/statsd/tests/ConfigManager_test.cpp
deleted file mode 100644
index 24c8f2b..0000000
--- a/cmds/statsd/tests/ConfigManager_test.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/config/ConfigManager.h"
-#include "src/metrics/MetricsManager.h"
-#include "statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-#include <iostream>
-
-using namespace android;
-using namespace android::os::statsd;
-using namespace testing;
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static ostream& operator<<(ostream& os, const StatsdConfig& config) {
-    return os << "StatsdConfig{id=" << config.id() << "}";
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-/**
- * Mock ConfigListener
- */
-class MockListener : public ConfigListener {
-public:
-    MOCK_METHOD3(OnConfigUpdated,
-                 void(const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config));
-    MOCK_METHOD1(OnConfigRemoved, void(const ConfigKey& key));
-};
-
-/**
- * Validate that the ConfigKey is the one we wanted.
- */
-MATCHER_P2(ConfigKeyEq, uid, id, "") {
-    return arg.GetUid() == uid && (long long)arg.GetId() == (long long)id;
-}
-
-/**
- * Validate that the StatsdConfig is the one we wanted.
- */
-MATCHER_P(StatsdConfigEq, id, 0) {
-    return (long long)arg.id() == (long long)id;
-}
-
-const int64_t testConfigId = 12345;
-
-/**
- * Test the addOrUpdate and remove methods
- */
-TEST(ConfigManagerTest, TestAddUpdateRemove) {
-    sp<MockListener> listener = new StrictMock<MockListener>();
-
-    sp<ConfigManager> manager = new ConfigManager();
-    manager->AddListener(listener);
-
-    StatsdConfig config91;
-    config91.set_id(91);
-    StatsdConfig config92;
-    config92.set_id(92);
-    StatsdConfig config93;
-    config93.set_id(93);
-    StatsdConfig config94;
-    config94.set_id(94);
-
-    {
-        InSequence s;
-
-        manager->StartupForTest();
-
-        // Add another one
-        EXPECT_CALL(*(listener.get()),
-                    OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")), StatsdConfigEq(91)))
-                .RetiresOnSaturation();
-        manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config91);
-
-        // Update It
-        EXPECT_CALL(*(listener.get()),
-                    OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")), StatsdConfigEq(92)))
-                .RetiresOnSaturation();
-        manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config92);
-
-        // Add one with the same uid but a different name
-        EXPECT_CALL(*(listener.get()),
-                    OnConfigUpdated(_, ConfigKeyEq(1, StringToId("yyy")), StatsdConfigEq(93)))
-                .RetiresOnSaturation();
-        manager->UpdateConfig(ConfigKey(1, StringToId("yyy")), config93);
-
-        // Add one with the same name but a different uid
-        EXPECT_CALL(*(listener.get()),
-                    OnConfigUpdated(_, ConfigKeyEq(2, StringToId("zzz")), StatsdConfigEq(94)))
-                .RetiresOnSaturation();
-        manager->UpdateConfig(ConfigKey(2, StringToId("zzz")), config94);
-
-        // Remove (1,yyy)
-        EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(1, StringToId("yyy"))))
-                .RetiresOnSaturation();
-        manager->RemoveConfig(ConfigKey(1, StringToId("yyy")));
-
-        // Remove (2,zzz)
-        EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("zzz"))))
-                .RetiresOnSaturation();
-        manager->RemoveConfig(ConfigKey(2, StringToId("zzz")));
-
-        // Remove (1,zzz)
-        EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(1, StringToId("zzz"))))
-                .RetiresOnSaturation();
-        manager->RemoveConfig(ConfigKey(1, StringToId("zzz")));
-
-        // Remove (2,zzz) again and we shouldn't get the callback
-        manager->RemoveConfig(ConfigKey(2, StringToId("zzz")));
-    }
-}
-
-/**
- * Test removing all of the configs for a uid.
- */
-TEST(ConfigManagerTest, TestRemoveUid) {
-    sp<MockListener> listener = new StrictMock<MockListener>();
-
-    sp<ConfigManager> manager = new ConfigManager();
-    manager->AddListener(listener);
-
-    StatsdConfig config;
-
-    EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _, _)).Times(5);
-    EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("xxx"))));
-    EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("yyy"))));
-    EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("zzz"))));
-
-    manager->StartupForTest();
-    manager->UpdateConfig(ConfigKey(1, StringToId("aaa")), config);
-    manager->UpdateConfig(ConfigKey(2, StringToId("xxx")), config);
-    manager->UpdateConfig(ConfigKey(2, StringToId("yyy")), config);
-    manager->UpdateConfig(ConfigKey(2, StringToId("zzz")), config);
-    manager->UpdateConfig(ConfigKey(3, StringToId("bbb")), config);
-
-    manager->RemoveConfigs(2);
-}
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
deleted file mode 100644
index a21eb9b..0000000
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/matcher_util.h"
-#include "src/logd/LogEvent.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "subscriber/SubscriberReporter.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-using android::util::ProtoReader;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// These constants must be kept in sync with those in StatsDimensionsValue.java.
-const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
-const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3;
-const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6;
-const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7;
-
-namespace {
-void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
-                  const vector<int>& attributionUids, const vector<string>& attributionTags,
-                  const string& name) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_writeString(statsEvent, name.c_str());
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
-                  const vector<int>& attributionUids, const vector<string>& attributionTags,
-                  const int32_t value) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_writeInt32(statsEvent, value);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-}  // anonymous namespace
-
-TEST(AtomMatcherTest, TestFieldTranslation) {
-    FieldMatcher matcher1;
-    matcher1.set_field(10);
-    FieldMatcher* child = matcher1.add_child();
-    child->set_field(1);
-    child->set_position(Position::ANY);
-
-    child = child->add_child();
-    child->set_field(1);
-
-    vector<Matcher> output;
-    translateFieldMatcher(matcher1, &output);
-
-    ASSERT_EQ((size_t)1, output.size());
-
-    const auto& matcher12 = output[0];
-    EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
-    EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
-    EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
-}
-
-TEST(AtomMatcherTest, TestFieldTranslation_ALL) {
-    FieldMatcher matcher1;
-    matcher1.set_field(10);
-    FieldMatcher* child = matcher1.add_child();
-    child->set_field(1);
-    child->set_position(Position::ALL);
-
-    child = child->add_child();
-    child->set_field(1);
-
-    vector<Matcher> output;
-    translateFieldMatcher(matcher1, &output);
-
-    ASSERT_EQ((size_t)1, output.size());
-
-    const auto& matcher12 = output[0];
-    EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
-    EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
-    EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask);
-}
-
-TEST(AtomMatcherTest, TestFilter_ALL) {
-    FieldMatcher matcher1;
-    matcher1.set_field(10);
-    FieldMatcher* child = matcher1.add_child();
-    child->set_field(1);
-    child->set_position(Position::ALL);
-
-    child->add_child()->set_field(1);
-    child->add_child()->set_field(2);
-
-    child = matcher1.add_child();
-    child->set_field(2);
-
-    vector<Matcher> matchers;
-    translateFieldMatcher(matcher1, &matchers);
-
-    std::vector<int> attributionUids = {1111, 2222, 3333};
-    std::vector<string> attributionTags = {"location1", "location2", "location3"};
-
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event, 10 /*atomId*/, 1012345, attributionUids, attributionTags, "some value");
-    HashableDimensionKey output;
-
-    filterValues(matchers, event.getValues(), &output);
-
-    ASSERT_EQ((size_t)7, output.getValues().size());
-    EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
-    EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
-    EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
-    EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
-
-    EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
-    EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
-    EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
-    EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
-
-    EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
-    EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
-    EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
-    EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
-
-    EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
-    EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
-}
-
-TEST(AtomMatcherTest, TestSubDimension) {
-    HashableDimensionKey dim;
-
-    int pos1[] = {1, 1, 1};
-    int pos2[] = {1, 1, 2};
-    int pos3[] = {1, 1, 3};
-    int pos4[] = {2, 0, 0};
-    Field field1(10, pos1, 2);
-    Field field2(10, pos2, 2);
-
-    Field field3(10, pos3, 2);
-    Field field4(10, pos4, 0);
-
-    Value value1((int32_t)10025);
-    Value value2("tag");
-
-    Value value11((int32_t)10026);
-    Value value22("tag2");
-
-    dim.addValue(FieldValue(field1, value1));
-    dim.addValue(FieldValue(field2, value2));
-
-    HashableDimensionKey subDim1;
-    subDim1.addValue(FieldValue(field1, value1));
-
-    HashableDimensionKey subDim2;
-    subDim1.addValue(FieldValue(field2, value2));
-
-    EXPECT_TRUE(dim.contains(dim));
-    EXPECT_TRUE(dim.contains(subDim1));
-    EXPECT_TRUE(dim.contains(subDim2));
-
-    HashableDimensionKey subDim3;
-    subDim3.addValue(FieldValue(field1, value11));
-    EXPECT_FALSE(dim.contains(subDim3));
-
-    HashableDimensionKey subDim4;
-    // Empty dimension is always a sub dimension of other dimensions
-    EXPECT_TRUE(dim.contains(subDim4));
-}
-
-TEST(AtomMatcherTest, TestMetric2ConditionLink) {
-    std::vector<int> attributionUids = {1111, 2222, 3333};
-    std::vector<string> attributionTags = {"location1", "location2", "location3"};
-
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event, 10 /*atomId*/, 12345, attributionUids, attributionTags, "some value");
-
-    FieldMatcher whatMatcher;
-    whatMatcher.set_field(10);
-    FieldMatcher* child11 = whatMatcher.add_child();
-    child11->set_field(1);
-    child11->set_position(Position::ANY);
-    child11 = child11->add_child();
-    child11->set_field(1);
-
-    FieldMatcher conditionMatcher;
-    conditionMatcher.set_field(27);
-    FieldMatcher* child2 = conditionMatcher.add_child();
-    child2->set_field(2);
-    child2->set_position(Position::LAST);
-
-    child2 = child2->add_child();
-    child2->set_field(2);
-
-    Metric2Condition link;
-
-    translateFieldMatcher(whatMatcher, &link.metricFields);
-    translateFieldMatcher(conditionMatcher, &link.conditionFields);
-
-    ASSERT_EQ((size_t)1, link.metricFields.size());
-    EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
-    EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
-    EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
-
-    ASSERT_EQ((size_t)1, link.conditionFields.size());
-    EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
-    EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
-    EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
-}
-
-TEST(AtomMatcherTest, TestWriteDimensionPath) {
-    for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) {
-        FieldMatcher matcher1;
-        matcher1.set_field(10);
-        FieldMatcher* child = matcher1.add_child();
-        child->set_field(2);
-        child->set_position(position);
-        child->add_child()->set_field(1);
-        child->add_child()->set_field(3);
-
-        child = matcher1.add_child();
-        child->set_field(4);
-
-        child = matcher1.add_child();
-        child->set_field(6);
-        child->add_child()->set_field(2);
-
-        vector<Matcher> matchers;
-        translateFieldMatcher(matcher1, &matchers);
-
-        android::util::ProtoOutputStream protoOut;
-        writeDimensionPathToProto(matchers, &protoOut);
-
-        vector<uint8_t> outData;
-        outData.resize(protoOut.size());
-        size_t pos = 0;
-        sp<ProtoReader> reader = protoOut.data();
-        while (reader->readBuffer() != NULL) {
-            size_t toRead = reader->currentToRead();
-            std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
-            pos += toRead;
-            reader->move(toRead);
-        }
-
-        DimensionsValue result;
-        ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
-
-        EXPECT_EQ(10, result.field());
-        EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
-        ASSERT_EQ(3, result.value_tuple().dimensions_value_size());
-
-        const auto& dim1 = result.value_tuple().dimensions_value(0);
-        EXPECT_EQ(2, dim1.field());
-        ASSERT_EQ(2, dim1.value_tuple().dimensions_value_size());
-
-        const auto& dim11 = dim1.value_tuple().dimensions_value(0);
-        EXPECT_EQ(1, dim11.field());
-
-        const auto& dim12 = dim1.value_tuple().dimensions_value(1);
-        EXPECT_EQ(3, dim12.field());
-
-        const auto& dim2 = result.value_tuple().dimensions_value(1);
-        EXPECT_EQ(4, dim2.field());
-
-        const auto& dim3 = result.value_tuple().dimensions_value(2);
-        EXPECT_EQ(6, dim3.field());
-        ASSERT_EQ(1, dim3.value_tuple().dimensions_value_size());
-        const auto& dim31 = dim3.value_tuple().dimensions_value(0);
-        EXPECT_EQ(2, dim31.field());
-    }
-}
-
-void checkAttributionNodeInDimensionsValueParcel(StatsDimensionsValueParcel& attributionNodeParcel,
-                                                 int32_t nodeDepthInAttributionChain,
-                                                 int32_t uid, string tag) {
-    EXPECT_EQ(attributionNodeParcel.field, nodeDepthInAttributionChain /*position at depth 1*/);
-    ASSERT_EQ(attributionNodeParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
-    ASSERT_EQ(attributionNodeParcel.tupleValue.size(), 2);
-
-    StatsDimensionsValueParcel uidParcel = attributionNodeParcel.tupleValue[0];
-    EXPECT_EQ(uidParcel.field, 1 /*position at depth 2*/);
-    EXPECT_EQ(uidParcel.valueType, STATS_DIMENSIONS_VALUE_INT_TYPE);
-    EXPECT_EQ(uidParcel.intValue, uid);
-
-    StatsDimensionsValueParcel tagParcel = attributionNodeParcel.tupleValue[1];
-    EXPECT_EQ(tagParcel.field, 2 /*position at depth 2*/);
-    EXPECT_EQ(tagParcel.valueType, STATS_DIMENSIONS_VALUE_STRING_TYPE);
-    EXPECT_EQ(tagParcel.stringValue, tag);
-}
-
-// Test conversion of a HashableDimensionKey into a StatsDimensionValueParcel
-TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
-    int atomId = 10;
-    // First four fields form an attribution chain
-    int pos1[] = {1, 1, 1};
-    int pos2[] = {1, 1, 2};
-    int pos3[] = {1, 2, 1};
-    int pos4[] = {1, 2, 2};
-    int pos5[] = {2, 1, 1};
-
-    Field field1(atomId, pos1, /*depth=*/2);
-    Field field2(atomId, pos2, /*depth=*/2);
-    Field field3(atomId, pos3, /*depth=*/2);
-    Field field4(atomId, pos4, /*depth=*/2);
-    Field field5(atomId, pos5, /*depth=*/0);
-
-    Value value1((int32_t)1);
-    Value value2("string2");
-    Value value3((int32_t)3);
-    Value value4("string4");
-    Value value5((float)5.0);
-
-    HashableDimensionKey dimensionKey;
-    dimensionKey.addValue(FieldValue(field1, value1));
-    dimensionKey.addValue(FieldValue(field2, value2));
-    dimensionKey.addValue(FieldValue(field3, value3));
-    dimensionKey.addValue(FieldValue(field4, value4));
-    dimensionKey.addValue(FieldValue(field5, value5));
-
-    StatsDimensionsValueParcel rootParcel = dimensionKey.toStatsDimensionsValueParcel();
-    EXPECT_EQ(rootParcel.field, atomId);
-    ASSERT_EQ(rootParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
-    ASSERT_EQ(rootParcel.tupleValue.size(), 2);
-
-    // Check that attribution chain is populated correctly
-    StatsDimensionsValueParcel attributionChainParcel = rootParcel.tupleValue[0];
-    EXPECT_EQ(attributionChainParcel.field, 1 /*position at depth 0*/);
-    ASSERT_EQ(attributionChainParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
-    ASSERT_EQ(attributionChainParcel.tupleValue.size(), 2);
-    checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[0],
-                                                /*nodeDepthInAttributionChain=*/1,
-                                                value1.int_value, value2.str_value);
-    checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[1],
-                                                /*nodeDepthInAttributionChain=*/2,
-                                                value3.int_value, value4.str_value);
-
-    // Check that the float is populated correctly
-    StatsDimensionsValueParcel floatParcel = rootParcel.tupleValue[1];
-    EXPECT_EQ(floatParcel.field, 2 /*position at depth 0*/);
-    EXPECT_EQ(floatParcel.valueType, STATS_DIMENSIONS_VALUE_FLOAT_TYPE);
-    EXPECT_EQ(floatParcel.floatValue, value5.float_value);
-}
-
-TEST(AtomMatcherTest, TestWriteDimensionToProto) {
-    HashableDimensionKey dim;
-    int pos1[] = {1, 1, 1};
-    int pos2[] = {1, 1, 2};
-    int pos3[] = {1, 1, 3};
-    int pos4[] = {2, 0, 0};
-    Field field1(10, pos1, 2);
-    Field field2(10, pos2, 2);
-    Field field3(10, pos3, 2);
-    Field field4(10, pos4, 0);
-
-    Value value1((int32_t)10025);
-    Value value2("tag");
-    Value value3((int32_t)987654);
-    Value value4((int32_t)99999);
-
-    dim.addValue(FieldValue(field1, value1));
-    dim.addValue(FieldValue(field2, value2));
-    dim.addValue(FieldValue(field3, value3));
-    dim.addValue(FieldValue(field4, value4));
-
-    android::util::ProtoOutputStream protoOut;
-    writeDimensionToProto(dim, nullptr /* include strings */, &protoOut);
-
-    vector<uint8_t> outData;
-    outData.resize(protoOut.size());
-    size_t pos = 0;
-    sp<ProtoReader> reader = protoOut.data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-
-    DimensionsValue result;
-    ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
-    EXPECT_EQ(10, result.field());
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
-    ASSERT_EQ(2, result.value_tuple().dimensions_value_size());
-
-    const auto& dim1 = result.value_tuple().dimensions_value(0);
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
-    ASSERT_EQ(3, dim1.value_tuple().dimensions_value_size());
-
-    const auto& dim11 = dim1.value_tuple().dimensions_value(0);
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
-    EXPECT_EQ(10025, dim11.value_int());
-
-    const auto& dim12 = dim1.value_tuple().dimensions_value(1);
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
-    EXPECT_EQ("tag", dim12.value_str());
-
-    const auto& dim13 = dim1.value_tuple().dimensions_value(2);
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
-    EXPECT_EQ(987654, dim13.value_int());
-
-    const auto& dim2 = result.value_tuple().dimensions_value(1);
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
-    EXPECT_EQ(99999, dim2.value_int());
-}
-
-TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) {
-    HashableDimensionKey dim;
-    int pos1[] = {1, 1, 1};
-    int pos2[] = {1, 1, 2};
-    int pos3[] = {1, 1, 3};
-    int pos4[] = {2, 0, 0};
-    Field field1(10, pos1, 2);
-    Field field2(10, pos2, 2);
-    Field field3(10, pos3, 2);
-    Field field4(10, pos4, 0);
-
-    Value value1((int32_t)10025);
-    Value value2("tag");
-    Value value3((int32_t)987654);
-    Value value4((int64_t)99999);
-
-    dim.addValue(FieldValue(field1, value1));
-    dim.addValue(FieldValue(field2, value2));
-    dim.addValue(FieldValue(field3, value3));
-    dim.addValue(FieldValue(field4, value4));
-
-    android::util::ProtoOutputStream protoOut;
-    writeDimensionLeafNodesToProto(dim, 1, nullptr /* include strings */, &protoOut);
-
-    vector<uint8_t> outData;
-    outData.resize(protoOut.size());
-    size_t pos = 0;
-    sp<ProtoReader> reader = protoOut.data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-
-    DimensionsValueTuple result;
-    ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
-    ASSERT_EQ(4, result.dimensions_value_size());
-
-    const auto& dim1 = result.dimensions_value(0);
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim1.value_case());
-    EXPECT_EQ(10025, dim1.value_int());
-
-    const auto& dim2 = result.dimensions_value(1);
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim2.value_case());
-    EXPECT_EQ("tag", dim2.value_str());
-
-    const auto& dim3 = result.dimensions_value(2);
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim3.value_case());
-    EXPECT_EQ(987654, dim3.value_int());
-
-    const auto& dim4 = result.dimensions_value(3);
-    EXPECT_EQ(DimensionsValue::ValueCase::kValueLong, dim4.value_case());
-    EXPECT_EQ(99999, dim4.value_long());
-}
-
-TEST(AtomMatcherTest, TestWriteAtomToProto) {
-    std::vector<int> attributionUids = {1111, 2222};
-    std::vector<string> attributionTags = {"location1", "location2"};
-
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event, 4 /*atomId*/, 12345, attributionUids, attributionTags, 999);
-
-    android::util::ProtoOutputStream protoOutput;
-    writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
-
-    vector<uint8_t> outData;
-    outData.resize(protoOutput.size());
-    size_t pos = 0;
-    sp<ProtoReader> reader = protoOutput.data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-
-    Atom result;
-    ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
-    EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
-    const auto& atom = result.ble_scan_result_received();
-    ASSERT_EQ(2, atom.attribution_node_size());
-    EXPECT_EQ(1111, atom.attribution_node(0).uid());
-    EXPECT_EQ("location1", atom.attribution_node(0).tag());
-    EXPECT_EQ(2222, atom.attribution_node(1).uid());
-    EXPECT_EQ("location2", atom.attribution_node(1).tag());
-    EXPECT_EQ(999, atom.num_results());
-}
-
-/*
- * Test two Matchers is not a subset of one Matcher.
- * Test one Matcher is subset of two Matchers.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions1) {
-    // Initialize first set of matchers
-    FieldMatcher matcher1;
-    matcher1.set_field(10);
-
-    FieldMatcher* child = matcher1.add_child();
-    child->set_field(1);
-    child->set_position(Position::ALL);
-    child->add_child()->set_field(1);
-    child->add_child()->set_field(2);
-
-    vector<Matcher> matchers1;
-    translateFieldMatcher(matcher1, &matchers1);
-    ASSERT_EQ(2, matchers1.size());
-
-    // Initialize second set of matchers
-    FieldMatcher matcher2;
-    matcher2.set_field(10);
-
-    child = matcher2.add_child();
-    child->set_field(1);
-    child->set_position(Position::ALL);
-    child->add_child()->set_field(1);
-
-    vector<Matcher> matchers2;
-    translateFieldMatcher(matcher2, &matchers2);
-    ASSERT_EQ(1, matchers2.size());
-
-    EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
-    EXPECT_TRUE(subsetDimensions(matchers2, matchers1));
-}
-/*
- * Test not a subset with one matching Matcher, one non-matching Matcher.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions2) {
-    // Initialize first set of matchers
-    FieldMatcher matcher1;
-    matcher1.set_field(10);
-
-    FieldMatcher* child = matcher1.add_child();
-    child->set_field(1);
-
-    child = matcher1.add_child();
-    child->set_field(2);
-
-    vector<Matcher> matchers1;
-    translateFieldMatcher(matcher1, &matchers1);
-
-    // Initialize second set of matchers
-    FieldMatcher matcher2;
-    matcher2.set_field(10);
-
-    child = matcher2.add_child();
-    child->set_field(1);
-
-    child = matcher2.add_child();
-    child->set_field(3);
-
-    vector<Matcher> matchers2;
-    translateFieldMatcher(matcher2, &matchers2);
-
-    EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
-}
-
-/*
- * Test not a subset if parent field is not equal.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions3) {
-    // Initialize first set of matchers
-    FieldMatcher matcher1;
-    matcher1.set_field(10);
-
-    FieldMatcher* child = matcher1.add_child();
-    child->set_field(1);
-
-    vector<Matcher> matchers1;
-    translateFieldMatcher(matcher1, &matchers1);
-
-    // Initialize second set of matchers
-    FieldMatcher matcher2;
-    matcher2.set_field(5);
-
-    child = matcher2.add_child();
-    child->set_field(1);
-
-    vector<Matcher> matchers2;
-    translateFieldMatcher(matcher2, &matchers2);
-
-    EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
-}
-
-/*
- * Test is subset with two matching Matchers.
- */
-TEST(AtomMatcherTest, TestSubsetDimensions4) {
-    // Initialize first set of matchers
-    FieldMatcher matcher1;
-    matcher1.set_field(10);
-
-    FieldMatcher* child = matcher1.add_child();
-    child->set_field(1);
-
-    child = matcher1.add_child();
-    child->set_field(2);
-
-    vector<Matcher> matchers1;
-    translateFieldMatcher(matcher1, &matchers1);
-
-    // Initialize second set of matchers
-    FieldMatcher matcher2;
-    matcher2.set_field(10);
-
-    child = matcher2.add_child();
-    child->set_field(1);
-
-    child = matcher2.add_child();
-    child->set_field(2);
-
-    child = matcher2.add_child();
-    child->set_field(3);
-
-    vector<Matcher> matchers2;
-    translateFieldMatcher(matcher2, &matchers2);
-
-    EXPECT_TRUE(subsetDimensions(matchers1, matchers2));
-    EXPECT_FALSE(subsetDimensions(matchers2, matchers1));
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/HashableDimensionKey_test.cpp b/cmds/statsd/tests/HashableDimensionKey_test.cpp
deleted file mode 100644
index 29adcd0..0000000
--- a/cmds/statsd/tests/HashableDimensionKey_test.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-#include "src/HashableDimensionKey.h"
-
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-using android::util::ProtoReader;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Test that #containsLinkedStateValues returns false when the whatKey is
- * smaller than the primaryKey.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_WhatKeyTooSmall) {
-    std::vector<Metric2State> mMetric2StateLinks;
-
-    int32_t uid1 = 1000;
-    HashableDimensionKey whatKey = DEFAULT_DIMENSION_KEY;
-    HashableDimensionKey primaryKey;
-    getUidProcessKey(uid1, &primaryKey);
-
-    EXPECT_FALSE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks,
-                                           UID_PROCESS_STATE_ATOM_ID));
-}
-
-/**
- * Test that #containsLinkedStateValues returns false when the linked values
- * are not equal.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_UnequalLinkedValues) {
-    int stateAtomId = UID_PROCESS_STATE_ATOM_ID;
-
-    FieldMatcher whatMatcher;
-    whatMatcher.set_field(util::OVERLAY_STATE_CHANGED);
-    FieldMatcher* child11 = whatMatcher.add_child();
-    child11->set_field(1);
-
-    FieldMatcher stateMatcher;
-    stateMatcher.set_field(stateAtomId);
-    FieldMatcher* child21 = stateMatcher.add_child();
-    child21->set_field(1);
-
-    std::vector<Metric2State> mMetric2StateLinks;
-    Metric2State ms;
-    ms.stateAtomId = stateAtomId;
-    translateFieldMatcher(whatMatcher, &ms.metricFields);
-    translateFieldMatcher(stateMatcher, &ms.stateFields);
-    mMetric2StateLinks.push_back(ms);
-
-    int32_t uid1 = 1000;
-    int32_t uid2 = 1001;
-    HashableDimensionKey whatKey;
-    getOverlayKey(uid2, "package", &whatKey);
-    HashableDimensionKey primaryKey;
-    getUidProcessKey(uid1, &primaryKey);
-
-    EXPECT_FALSE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks, stateAtomId));
-}
-
-/**
- * Test that #containsLinkedStateValues returns false when there is no link
- * between the key values.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_MissingMetric2StateLinks) {
-    int stateAtomId = UID_PROCESS_STATE_ATOM_ID;
-
-    std::vector<Metric2State> mMetric2StateLinks;
-
-    int32_t uid1 = 1000;
-    HashableDimensionKey whatKey;
-    getOverlayKey(uid1, "package", &whatKey);
-    HashableDimensionKey primaryKey;
-    getUidProcessKey(uid1, &primaryKey);
-
-    EXPECT_FALSE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks, stateAtomId));
-}
-
-/**
- * Test that #containsLinkedStateValues returns true when the key values are
- * linked and equal.
- */
-TEST(HashableDimensionKeyTest, TestContainsLinkedStateValues_AllConditionsMet) {
-    int stateAtomId = UID_PROCESS_STATE_ATOM_ID;
-
-    FieldMatcher whatMatcher;
-    whatMatcher.set_field(util::OVERLAY_STATE_CHANGED);
-    FieldMatcher* child11 = whatMatcher.add_child();
-    child11->set_field(1);
-
-    FieldMatcher stateMatcher;
-    stateMatcher.set_field(stateAtomId);
-    FieldMatcher* child21 = stateMatcher.add_child();
-    child21->set_field(1);
-
-    std::vector<Metric2State> mMetric2StateLinks;
-    Metric2State ms;
-    ms.stateAtomId = stateAtomId;
-    translateFieldMatcher(whatMatcher, &ms.metricFields);
-    translateFieldMatcher(stateMatcher, &ms.stateFields);
-    mMetric2StateLinks.push_back(ms);
-
-    int32_t uid1 = 1000;
-    HashableDimensionKey whatKey;
-    getOverlayKey(uid1, "package", &whatKey);
-    HashableDimensionKey primaryKey;
-    getUidProcessKey(uid1, &primaryKey);
-
-    EXPECT_TRUE(containsLinkedStateValues(whatKey, primaryKey, mMetric2StateLinks, stateAtomId));
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
deleted file mode 100644
index 92cd04f..0000000
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ /dev/null
@@ -1,809 +0,0 @@
-// Copyright (C) 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.
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include "annotations.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/matcher_util.h"
-#include "stats_event.h"
-#include "stats_log_util.h"
-#include "stats_util.h"
-#include "statsd_test_util.h"
-
-using namespace android::os::statsd;
-using std::unordered_map;
-using std::vector;
-
-const int32_t TAG_ID = 123;
-const int32_t TAG_ID_2 = 28;  // hardcoded tag of atom with uid field
-const int FIELD_ID_1 = 1;
-const int FIELD_ID_2 = 2;
-const int FIELD_ID_3 = 2;
-
-const int ATTRIBUTION_UID_FIELD_ID = 1;
-const int ATTRIBUTION_TAG_FIELD_ID = 2;
-
-
-#ifdef __ANDROID__
-
-namespace {
-
-void makeIntLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
-                     const int32_t value) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-    AStatsEvent_writeInt32(statsEvent, value);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeFloatLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
-                       const float floatValue) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-    AStatsEvent_writeFloat(statsEvent, floatValue);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
-                        const string& name) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-    AStatsEvent_writeString(statsEvent, name.c_str());
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeIntWithBoolAnnotationLogEvent(LogEvent* logEvent, const int32_t atomId,
-                                       const int32_t field, const uint8_t annotationId,
-                                       const bool annotationValue) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_writeInt32(statsEvent, field);
-    AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeAttributionLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
-                             const vector<int>& attributionUids,
-                             const vector<string>& attributionTags, const string& name) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_writeString(statsEvent, name.c_str());
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeBoolLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
-                      const bool bool1, const bool bool2) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
-    AStatsEvent_writeBool(statsEvent, bool1);
-    AStatsEvent_writeBool(statsEvent, bool2);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-}  // anonymous namespace
-
-TEST(AtomMatcherTest, TestSimpleMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-
-    // Set up the matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeIntLogEvent(&event, TAG_ID, 0, 11);
-
-    // Test
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Wrong tag id.
-    simpleMatcher->set_atom_id(TAG_ID + 1);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestAttributionMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    std::vector<int> attributionUids = {1111, 2222, 3333};
-    std::vector<string> attributionTags = {"location1", "location2", "location3"};
-
-    // Set up the log event.
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
-
-    // Set up the matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    // Match first node.
-    auto attributionMatcher = simpleMatcher->add_field_value_matcher();
-    attributionMatcher->set_field(FIELD_ID_1);
-    attributionMatcher->set_position(Position::FIRST);
-    attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
-            ATTRIBUTION_TAG_FIELD_ID);
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "tag");
-
-    auto fieldMatcher = simpleMatcher->add_field_value_matcher();
-    fieldMatcher->set_field(FIELD_ID_2);
-    fieldMatcher->set_eq_string("some value");
-
-    // Tag not matched.
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "location3");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "location1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match last node.
-    attributionMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "location3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match any node.
-    attributionMatcher->set_position(Position::ANY);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "location1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "location2");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "location3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "location4");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Attribution match but primitive field not match.
-    attributionMatcher->set_position(Position::ANY);
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "location2");
-    fieldMatcher->set_eq_string("wrong value");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldMatcher->set_eq_string("some value");
-
-    // Uid match.
-    attributionMatcher->set_position(Position::ANY);
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_field(
-            ATTRIBUTION_UID_FIELD_ID);
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg0");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    uidMap->updateMap(
-            1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
-            {android::String16("v1"), android::String16("v1"), android::String16("v2"),
-             android::String16("v1"), android::String16("v2")},
-            {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
-             android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
-            {android::String16(""), android::String16(""), android::String16(""),
-             android::String16(""), android::String16("")});
-
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg2");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg0");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    attributionMatcher->set_position(Position::FIRST);
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg0");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg3");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg2");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    attributionMatcher->set_position(Position::LAST);
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg0");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg2");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg1");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Uid + tag.
-    attributionMatcher->set_position(Position::ANY);
-    attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
-            ATTRIBUTION_TAG_FIELD_ID);
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg0");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg1");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg1");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location2");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg2");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg3");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg3");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location1");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    attributionMatcher->set_position(Position::FIRST);
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg0");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg1");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg1");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location2");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg2");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location3");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg3");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location3");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg3");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location1");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    attributionMatcher->set_position(Position::LAST);
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg0");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location1");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg1");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location1");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg1");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location2");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg2");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg3");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg3");
-    attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string(
-            "location1");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestUidFieldMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    uidMap->updateMap(
-            1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
-            {android::String16("v1"), android::String16("v1"), android::String16("v2"),
-             android::String16("v1"), android::String16("v2")},
-            {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
-             android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
-            {android::String16(""), android::String16(""), android::String16(""),
-             android::String16(""), android::String16("")});
-
-    // Set up matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-    simpleMatcher->add_field_value_matcher()->set_field(1);
-    simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("pkg0");
-
-    // Make event without is_uid annotation.
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeIntLogEvent(&event1, TAG_ID, 0, 1111);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
-    // Make event with is_uid annotation.
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeIntWithBoolAnnotationLogEvent(&event2, TAG_ID_2, 1111, ANNOTATION_ID_IS_UID, true);
-
-    // Event has is_uid annotation, so mapping from uid to package name occurs.
-    simpleMatcher->set_atom_id(TAG_ID_2);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
-
-    // Event has is_uid annotation, but uid maps to different package name.
-    simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("Pkg2");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2));
-}
-
-TEST(AtomMatcherTest, TestNeqAnyStringMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    uidMap->updateMap(
-            1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
-            {android::String16("v1"), android::String16("v1"), android::String16("v2"),
-             android::String16("v1"), android::String16("v2")},
-            {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
-             android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
-            {android::String16(""), android::String16(""), android::String16(""),
-             android::String16(""), android::String16("")});
-
-    std::vector<int> attributionUids = {1111, 2222, 3333, 1066};
-    std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"};
-
-    // Set up the event
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
-
-    // Set up the matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    // Match first node.
-    auto attributionMatcher = simpleMatcher->add_field_value_matcher();
-    attributionMatcher->set_field(FIELD_ID_1);
-    attributionMatcher->set_position(Position::FIRST);
-    attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
-            ATTRIBUTION_UID_FIELD_ID);
-    auto neqStringList = attributionMatcher->mutable_matches_tuple()
-                                 ->mutable_field_value_matcher(0)
-                                 ->mutable_neq_any_string();
-    neqStringList->add_str_value("pkg2");
-    neqStringList->add_str_value("pkg3");
-
-    auto fieldMatcher = simpleMatcher->add_field_value_matcher();
-    fieldMatcher->set_field(FIELD_ID_2);
-    fieldMatcher->set_eq_string("some value");
-
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    neqStringList->Clear();
-    neqStringList->add_str_value("pkg1");
-    neqStringList->add_str_value("pkg3");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    attributionMatcher->set_position(Position::ANY);
-    neqStringList->Clear();
-    neqStringList->add_str_value("maps.com");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    neqStringList->Clear();
-    neqStringList->add_str_value("PkG3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    attributionMatcher->set_position(Position::LAST);
-    neqStringList->Clear();
-    neqStringList->add_str_value("AID_STATSD");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestEqAnyStringMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    uidMap->updateMap(
-            1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
-            {android::String16("v1"), android::String16("v1"), android::String16("v2"),
-             android::String16("v1"), android::String16("v2")},
-            {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
-             android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
-            {android::String16(""), android::String16(""), android::String16(""),
-             android::String16(""), android::String16("")});
-
-    std::vector<int> attributionUids = {1067, 2222, 3333, 1066};
-    std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"};
-
-    // Set up the event
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value");
-
-    // Set up the matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    // Match first node.
-    auto attributionMatcher = simpleMatcher->add_field_value_matcher();
-    attributionMatcher->set_field(FIELD_ID_1);
-    attributionMatcher->set_position(Position::FIRST);
-    attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field(
-            ATTRIBUTION_UID_FIELD_ID);
-    auto eqStringList = attributionMatcher->mutable_matches_tuple()
-                                ->mutable_field_value_matcher(0)
-                                ->mutable_eq_any_string();
-    eqStringList->add_str_value("AID_ROOT");
-    eqStringList->add_str_value("AID_INCIDENTD");
-
-    auto fieldMatcher = simpleMatcher->add_field_value_matcher();
-    fieldMatcher->set_field(FIELD_ID_2);
-    fieldMatcher->set_eq_string("some value");
-
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    attributionMatcher->set_position(Position::ANY);
-    eqStringList->Clear();
-    eqStringList->add_str_value("AID_STATSD");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    eqStringList->Clear();
-    eqStringList->add_str_value("pkg1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    auto normalStringField = fieldMatcher->mutable_eq_any_string();
-    normalStringField->add_str_value("some value123");
-    normalStringField->add_str_value("some value");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    normalStringField->Clear();
-    normalStringField->add_str_value("AID_STATSD");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    eqStringList->Clear();
-    eqStringList->add_str_value("maps.com");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestBoolMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    // Set up the matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-    auto keyValue1 = simpleMatcher->add_field_value_matcher();
-    keyValue1->set_field(FIELD_ID_1);
-    auto keyValue2 = simpleMatcher->add_field_value_matcher();
-    keyValue2->set_field(FIELD_ID_2);
-
-    // Set up the event
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeBoolLogEvent(&event, TAG_ID, 0, true, false);
-
-    // Test
-    keyValue1->set_eq_bool(true);
-    keyValue2->set_eq_bool(false);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    keyValue1->set_eq_bool(false);
-    keyValue2->set_eq_bool(false);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    keyValue1->set_eq_bool(false);
-    keyValue2->set_eq_bool(true);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    keyValue1->set_eq_bool(true);
-    keyValue2->set_eq_bool(true);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestStringMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    // Set up the matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-    auto keyValue = simpleMatcher->add_field_value_matcher();
-    keyValue->set_field(FIELD_ID_1);
-    keyValue->set_eq_string("some value");
-
-    // Set up the event
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeStringLogEvent(&event, TAG_ID, 0, "some value");
-
-    // Test
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestMultiFieldsMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    // Set up the matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-    auto keyValue1 = simpleMatcher->add_field_value_matcher();
-    keyValue1->set_field(FIELD_ID_1);
-    auto keyValue2 = simpleMatcher->add_field_value_matcher();
-    keyValue2->set_field(FIELD_ID_2);
-
-    // Set up the event
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    CreateTwoValueLogEvent(&event, TAG_ID, 0, 2, 3);
-
-    // Test
-    keyValue1->set_eq_int(2);
-    keyValue2->set_eq_int(3);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    keyValue1->set_eq_int(2);
-    keyValue2->set_eq_int(4);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    keyValue1->set_eq_int(4);
-    keyValue2->set_eq_int(3);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestIntComparisonMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    // Set up the matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-
-    simpleMatcher->set_atom_id(TAG_ID);
-    auto keyValue = simpleMatcher->add_field_value_matcher();
-    keyValue->set_field(FIELD_ID_1);
-
-    // Set up the event
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeIntLogEvent(&event, TAG_ID, 0, 11);
-
-    // Test
-
-    // eq_int
-    keyValue->set_eq_int(10);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_eq_int(11);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_eq_int(12);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // lt_int
-    keyValue->set_lt_int(10);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_lt_int(11);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_lt_int(12);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // lte_int
-    keyValue->set_lte_int(10);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_lte_int(11);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_lte_int(12);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // gt_int
-    keyValue->set_gt_int(10);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_gt_int(11);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_gt_int(12);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // gte_int
-    keyValue->set_gte_int(10);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_gte_int(11);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    keyValue->set_gte_int(12);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestFloatComparisonMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    // Set up the matcher
-    AtomMatcher matcher;
-    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    auto keyValue = simpleMatcher->add_field_value_matcher();
-    keyValue->set_field(FIELD_ID_1);
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeFloatLogEvent(&event1, TAG_ID, 0, 10.1f);
-    keyValue->set_lt_float(10.0);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeFloatLogEvent(&event2, TAG_ID, 0, 9.9f);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
-
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    makeFloatLogEvent(&event3, TAG_ID, 0, 10.1f);
-    keyValue->set_gt_float(10.0);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event3));
-
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    makeFloatLogEvent(&event4, TAG_ID, 0, 9.9f);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event4));
-}
-
-// Helper for the composite matchers.
-void addSimpleMatcher(SimpleAtomMatcher* simpleMatcher, int tag, int key, int val) {
-    simpleMatcher->set_atom_id(tag);
-    auto keyValue = simpleMatcher->add_field_value_matcher();
-    keyValue->set_field(key);
-    keyValue->set_eq_int(val);
-}
-
-TEST(AtomMatcherTest, TestAndMatcher) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::AND;
-
-    vector<int> children;
-    children.push_back(0);
-    children.push_back(1);
-    children.push_back(2);
-
-    vector<MatchingState> matcherResults;
-    matcherResults.push_back(MatchingState::kMatched);
-    matcherResults.push_back(MatchingState::kNotMatched);
-    matcherResults.push_back(MatchingState::kMatched);
-
-    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-
-    matcherResults.clear();
-    matcherResults.push_back(MatchingState::kMatched);
-    matcherResults.push_back(MatchingState::kMatched);
-    matcherResults.push_back(MatchingState::kMatched);
-
-    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestOrMatcher) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::OR;
-
-    vector<int> children;
-    children.push_back(0);
-    children.push_back(1);
-    children.push_back(2);
-
-    vector<MatchingState> matcherResults;
-    matcherResults.push_back(MatchingState::kMatched);
-    matcherResults.push_back(MatchingState::kNotMatched);
-    matcherResults.push_back(MatchingState::kMatched);
-
-    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
-    matcherResults.clear();
-    matcherResults.push_back(MatchingState::kNotMatched);
-    matcherResults.push_back(MatchingState::kNotMatched);
-    matcherResults.push_back(MatchingState::kNotMatched);
-
-    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestNotMatcher) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::NOT;
-
-    vector<int> children;
-    children.push_back(0);
-
-    vector<MatchingState> matcherResults;
-    matcherResults.push_back(MatchingState::kMatched);
-
-    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-
-    matcherResults.clear();
-    matcherResults.push_back(MatchingState::kNotMatched);
-    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestNandMatcher) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::NAND;
-
-    vector<int> children;
-    children.push_back(0);
-    children.push_back(1);
-
-    vector<MatchingState> matcherResults;
-    matcherResults.push_back(MatchingState::kMatched);
-    matcherResults.push_back(MatchingState::kNotMatched);
-
-    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
-    matcherResults.clear();
-    matcherResults.push_back(MatchingState::kNotMatched);
-    matcherResults.push_back(MatchingState::kNotMatched);
-    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
-    matcherResults.clear();
-    matcherResults.push_back(MatchingState::kMatched);
-    matcherResults.push_back(MatchingState::kMatched);
-    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-}
-
-TEST(AtomMatcherTest, TestNorMatcher) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::NOR;
-
-    vector<int> children;
-    children.push_back(0);
-    children.push_back(1);
-
-    vector<MatchingState> matcherResults;
-    matcherResults.push_back(MatchingState::kMatched);
-    matcherResults.push_back(MatchingState::kNotMatched);
-
-    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-
-    matcherResults.clear();
-    matcherResults.push_back(MatchingState::kNotMatched);
-    matcherResults.push_back(MatchingState::kNotMatched);
-    EXPECT_TRUE(combinationMatch(children, operation, matcherResults));
-
-    matcherResults.clear();
-    matcherResults.push_back(MatchingState::kMatched);
-    matcherResults.push_back(MatchingState::kMatched);
-    EXPECT_FALSE(combinationMatch(children, operation, matcherResults));
-}
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
deleted file mode 100644
index bde59f4..0000000
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/logd/LogEvent.h"
-
-#include <gtest/gtest.h>
-
-#include "frameworks/proto_logging/stats/atoms.pb.h"
-#include "frameworks/proto_logging/stats/enums/stats/launcher/launcher.pb.h"
-#include "log/log_event_list.h"
-#include "stats_event.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::string;
-using std::vector;
-using util::ProtoOutputStream;
-using util::ProtoReader;
-
-namespace {
-
-Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth, const vector<bool>& last) {
-    Field f(tag, (int32_t*)pos.data(), depth);
-
-    // For loop starts at 1 because the last field at depth 0 is not decorated.
-    for (int i = 1; i < depth; i++) {
-        if (last[i]) f.decorateLastPos(i);
-    }
-
-    return f;
-}
-
-void createIntWithBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId,
-                                         bool annotationValue) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
-    AStatsEvent_writeInt32(statsEvent, 10);
-    AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue);
-    AStatsEvent_build(statsEvent);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    EXPECT_TRUE(logEvent->parseBuffer(buf, size));
-
-    AStatsEvent_release(statsEvent);
-}
-
-void createIntWithIntAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId,
-                                        int annotationValue) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
-    AStatsEvent_writeInt32(statsEvent, 10);
-    AStatsEvent_addInt32Annotation(statsEvent, annotationId, annotationValue);
-    AStatsEvent_build(statsEvent);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    EXPECT_TRUE(logEvent->parseBuffer(buf, size));
-
-    AStatsEvent_release(statsEvent);
-}
-
-}  // anonymous namespace
-
-TEST(LogEventTest, TestPrimitiveParsing) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeInt32(event, 10);
-    AStatsEvent_writeInt64(event, 0x123456789);
-    AStatsEvent_writeFloat(event, 2.0);
-    AStatsEvent_writeBool(event, true);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
-    EXPECT_EQ(100, logEvent.GetTagId());
-    EXPECT_EQ(1000, logEvent.GetUid());
-    EXPECT_EQ(1001, logEvent.GetPid());
-    EXPECT_FALSE(logEvent.hasAttributionChain());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(4, values.size());
-
-    const FieldValue& int32Item = values[0];
-    Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
-    EXPECT_EQ(expectedField, int32Item.mField);
-    EXPECT_EQ(Type::INT, int32Item.mValue.getType());
-    EXPECT_EQ(10, int32Item.mValue.int_value);
-
-    const FieldValue& int64Item = values[1];
-    expectedField = getField(100, {2, 1, 1}, 0, {false, false, false});
-    EXPECT_EQ(expectedField, int64Item.mField);
-    EXPECT_EQ(Type::LONG, int64Item.mValue.getType());
-    EXPECT_EQ(0x123456789, int64Item.mValue.long_value);
-
-    const FieldValue& floatItem = values[2];
-    expectedField = getField(100, {3, 1, 1}, 0, {false, false, false});
-    EXPECT_EQ(expectedField, floatItem.mField);
-    EXPECT_EQ(Type::FLOAT, floatItem.mValue.getType());
-    EXPECT_EQ(2.0, floatItem.mValue.float_value);
-
-    const FieldValue& boolItem = values[3];
-    expectedField = getField(100, {4, 1, 1}, 0, {true, false, false});
-    EXPECT_EQ(expectedField, boolItem.mField);
-    EXPECT_EQ(Type::INT, boolItem.mValue.getType());  // FieldValue does not support boolean type
-    EXPECT_EQ(1, boolItem.mValue.int_value);
-
-    AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestStringAndByteArrayParsing) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    string str = "test";
-    AStatsEvent_writeString(event, str.c_str());
-    AStatsEvent_writeByteArray(event, (uint8_t*)str.c_str(), str.length());
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
-    EXPECT_EQ(100, logEvent.GetTagId());
-    EXPECT_EQ(1000, logEvent.GetUid());
-    EXPECT_EQ(1001, logEvent.GetPid());
-    EXPECT_FALSE(logEvent.hasAttributionChain());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(2, values.size());
-
-    const FieldValue& stringItem = values[0];
-    Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
-    EXPECT_EQ(expectedField, stringItem.mField);
-    EXPECT_EQ(Type::STRING, stringItem.mValue.getType());
-    EXPECT_EQ(str, stringItem.mValue.str_value);
-
-    const FieldValue& storageItem = values[1];
-    expectedField = getField(100, {2, 1, 1}, 0, {true, false, false});
-    EXPECT_EQ(expectedField, storageItem.mField);
-    EXPECT_EQ(Type::STORAGE, storageItem.mValue.getType());
-    vector<uint8_t> expectedValue = {'t', 'e', 's', 't'};
-    EXPECT_EQ(expectedValue, storageItem.mValue.storage_value);
-
-    AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestEmptyString) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    string empty = "";
-    AStatsEvent_writeString(event, empty.c_str());
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
-    EXPECT_EQ(100, logEvent.GetTagId());
-    EXPECT_EQ(1000, logEvent.GetUid());
-    EXPECT_EQ(1001, logEvent.GetPid());
-    EXPECT_FALSE(logEvent.hasAttributionChain());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(1, values.size());
-
-    const FieldValue& item = values[0];
-    Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
-    EXPECT_EQ(expectedField, item.mField);
-    EXPECT_EQ(Type::STRING, item.mValue.getType());
-    EXPECT_EQ(empty, item.mValue.str_value);
-
-    AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestByteArrayWithNullCharacter) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    uint8_t message[] = {'\t', 'e', '\0', 's', 't'};
-    AStatsEvent_writeByteArray(event, message, 5);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
-    EXPECT_EQ(100, logEvent.GetTagId());
-    EXPECT_EQ(1000, logEvent.GetUid());
-    EXPECT_EQ(1001, logEvent.GetPid());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(1, values.size());
-
-    const FieldValue& item = values[0];
-    Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
-    EXPECT_EQ(expectedField, item.mField);
-    EXPECT_EQ(Type::STORAGE, item.mValue.getType());
-    vector<uint8_t> expectedValue(message, message + 5);
-    EXPECT_EQ(expectedValue, item.mValue.storage_value);
-
-    AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestAttributionChain) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-
-    string tag1 = "tag1";
-    string tag2 = "tag2";
-
-    uint32_t uids[] = {1001, 1002};
-    const char* tags[] = {tag1.c_str(), tag2.c_str()};
-
-    AStatsEvent_writeAttributionChain(event, uids, tags, 2);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
-    EXPECT_EQ(100, logEvent.GetTagId());
-    EXPECT_EQ(1000, logEvent.GetUid());
-    EXPECT_EQ(1001, logEvent.GetPid());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(4, values.size());  // 2 per attribution node
-
-    std::pair<int, int> attrIndexRange;
-    EXPECT_TRUE(logEvent.hasAttributionChain(&attrIndexRange));
-    EXPECT_EQ(0, attrIndexRange.first);
-    EXPECT_EQ(3, attrIndexRange.second);
-
-    // Check first attribution node
-    const FieldValue& uid1Item = values[0];
-    Field expectedField = getField(100, {1, 1, 1}, 2, {true, false, false});
-    EXPECT_EQ(expectedField, uid1Item.mField);
-    EXPECT_EQ(Type::INT, uid1Item.mValue.getType());
-    EXPECT_EQ(1001, uid1Item.mValue.int_value);
-
-    const FieldValue& tag1Item = values[1];
-    expectedField = getField(100, {1, 1, 2}, 2, {true, false, true});
-    EXPECT_EQ(expectedField, tag1Item.mField);
-    EXPECT_EQ(Type::STRING, tag1Item.mValue.getType());
-    EXPECT_EQ(tag1, tag1Item.mValue.str_value);
-
-    // Check second attribution nodes
-    const FieldValue& uid2Item = values[2];
-    expectedField = getField(100, {1, 2, 1}, 2, {true, true, false});
-    EXPECT_EQ(expectedField, uid2Item.mField);
-    EXPECT_EQ(Type::INT, uid2Item.mValue.getType());
-    EXPECT_EQ(1002, uid2Item.mValue.int_value);
-
-    const FieldValue& tag2Item = values[3];
-    expectedField = getField(100, {1, 2, 2}, 2, {true, true, true});
-    EXPECT_EQ(expectedField, tag2Item.mField);
-    EXPECT_EQ(Type::STRING, tag2Item.mValue.getType());
-    EXPECT_EQ(tag2, tag2Item.mValue.str_value);
-
-    AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestAnnotationIdIsUid) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_IS_UID, true);
-
-    const vector<FieldValue>& values = event.getValues();
-    ASSERT_EQ(values.size(), 1);
-    EXPECT_EQ(event.getUidFieldIndex(), 0);
-}
-
-TEST(LogEventTest, TestAnnotationIdStateNested) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_STATE_NESTED, true);
-
-    const vector<FieldValue>& values = event.getValues();
-    ASSERT_EQ(values.size(), 1);
-    EXPECT_TRUE(values[0].mAnnotations.isNested());
-}
-
-TEST(LogEventTest, TestPrimaryFieldAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_PRIMARY_FIELD, true);
-
-    const vector<FieldValue>& values = event.getValues();
-    ASSERT_EQ(values.size(), 1);
-    EXPECT_TRUE(values[0].mAnnotations.isPrimaryField());
-}
-
-TEST(LogEventTest, TestExclusiveStateAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_EXCLUSIVE_STATE, true);
-
-    const vector<FieldValue>& values = event.getValues();
-    ASSERT_EQ(values.size(), 1);
-    EXPECT_TRUE(values[0].mAnnotations.isExclusiveState());
-}
-
-TEST(LogEventTest, TestPrimaryFieldFirstUidAnnotation) {
-    // Event has 10 ints and then an attribution chain
-    int numInts = 10;
-    int firstUidInChainIndex = numInts;
-    string tag1 = "tag1";
-    string tag2 = "tag2";
-    uint32_t uids[] = {1001, 1002};
-    const char* tags[] = {tag1.c_str(), tag2.c_str()};
-
-    // Construct AStatsEvent
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, 100);
-    for (int i = 0; i < numInts; i++) {
-        AStatsEvent_writeInt32(statsEvent, 10);
-    }
-    AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2);
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
-    AStatsEvent_build(statsEvent);
-
-    // Construct LogEvent
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    LogEvent logEvent(/*uid=*/0, /*pid=*/0);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-    AStatsEvent_release(statsEvent);
-
-    // Check annotation
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(values.size(), numInts + 4);
-    EXPECT_TRUE(values[firstUidInChainIndex].mAnnotations.isPrimaryField());
-}
-
-TEST(LogEventTest, TestResetStateAnnotation) {
-    int32_t resetState = 10;
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_TRIGGER_STATE_RESET, resetState);
-
-    const vector<FieldValue>& values = event.getValues();
-    ASSERT_EQ(values.size(), 1);
-    EXPECT_EQ(event.getResetState(), resetState);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/LogReader_test.cpp b/cmds/statsd/tests/LogReader_test.cpp
deleted file mode 100644
index 7ce1d6a..0000000
--- a/cmds/statsd/tests/LogReader_test.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 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.
-
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-
-TEST(LogReaderTest, TestNothingAtAll) {
-    printf("yay!");
-}
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
deleted file mode 100644
index f05ec49..0000000
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright (C) 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.
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-#include <stdio.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "metrics/metrics_test_helper.h"
-#include "src/condition/ConditionTracker.h"
-#include "src/matchers/AtomMatchingTracker.h"
-#include "src/metrics/CountMetricProducer.h"
-#include "src/metrics/GaugeMetricProducer.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/metrics/ValueMetricProducer.h"
-#include "src/metrics/parsing_utils/metrics_manager_util.h"
-#include "src/state/StateManager.h"
-#include "statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using android::os::statsd::Predicate;
-using std::map;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-const ConfigKey kConfigKey(0, 12345);
-
-const long timeBaseSec = 1000;
-
-StatsdConfig buildGoodConfig() {
-    StatsdConfig config;
-    config.set_id(12345);
-
-    AtomMatcher* eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
-    SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
-    simpleAtomMatcher->add_field_value_matcher()->set_field(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
-            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
-    eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
-
-    simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
-    simpleAtomMatcher->add_field_value_matcher()->set_field(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
-
-    eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
-    AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_matcher(StringToId("SCREEN_IS_ON"));
-    combination->add_matcher(StringToId("SCREEN_IS_OFF"));
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(3);
-    metric->set_what(StringToId("SCREEN_IS_ON"));
-    metric->set_bucket(ONE_MINUTE);
-    metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
-    metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-    return config;
-}
-
-set<int32_t> unionSet(const vector<set<int32_t>> sets) {
-    set<int32_t> toRet;
-    for (const set<int32_t>& s : sets) {
-        toRet.insert(s.begin(), s.end());
-    }
-    return toRet;
-}
-}  // anonymous namespace
-
-TEST(MetricsManagerTest, TestLogSources) {
-    string app1 = "app1";
-    set<int32_t> app1Uids = {1111, 11111};
-    string app2 = "app2";
-    set<int32_t> app2Uids = {2222};
-    string app3 = "app3";
-    set<int32_t> app3Uids = {3333, 1111};
-
-    map<string, set<int32_t>> pkgToUids;
-    pkgToUids[app1] = app1Uids;
-    pkgToUids[app2] = app2Uids;
-    pkgToUids[app3] = app3Uids;
-
-    int32_t atom1 = 10, atom2 = 20, atom3 = 30;
-    sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
-    EXPECT_CALL(*uidMap, getAppUid(_))
-            .Times(4)
-            .WillRepeatedly(Invoke([&pkgToUids](const string& pkg) {
-                const auto& it = pkgToUids.find(pkg);
-                if (it != pkgToUids.end()) {
-                    return it->second;
-                }
-                return set<int32_t>();
-            }));
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterPullUidProvider(kConfigKey, _)).Times(1);
-    EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey, _)).Times(1);
-
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_SYSTEM");
-    config.add_allowed_log_source(app1);
-    config.add_default_pull_packages("AID_SYSTEM");
-    config.add_default_pull_packages("AID_ROOT");
-
-    const set<int32_t> defaultPullUids = {AID_SYSTEM, AID_ROOT};
-
-    PullAtomPackages* pullAtomPackages = config.add_pull_atom_packages();
-    pullAtomPackages->set_atom_id(atom1);
-    pullAtomPackages->add_packages(app1);
-    pullAtomPackages->add_packages(app3);
-
-    pullAtomPackages = config.add_pull_atom_packages();
-    pullAtomPackages->set_atom_id(atom2);
-    pullAtomPackages->add_packages(app2);
-    pullAtomPackages->add_packages("AID_STATSD");
-
-    MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
-                                  pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-    EXPECT_TRUE(metricsManager.isConfigValid());
-
-    EXPECT_THAT(metricsManager.mAllowedUid, ElementsAre(AID_SYSTEM));
-    EXPECT_THAT(metricsManager.mAllowedPkg, ElementsAre(app1));
-    EXPECT_THAT(metricsManager.mAllowedLogSources,
-                ContainerEq(unionSet(vector<set<int32_t>>({app1Uids, {AID_SYSTEM}}))));
-    EXPECT_THAT(metricsManager.mDefaultPullUids, ContainerEq(defaultPullUids));
-
-    vector<int32_t> atom1Uids = metricsManager.getPullAtomUids(atom1);
-    EXPECT_THAT(atom1Uids,
-                UnorderedElementsAreArray(unionSet({defaultPullUids, app1Uids, app3Uids})));
-
-    vector<int32_t> atom2Uids = metricsManager.getPullAtomUids(atom2);
-    EXPECT_THAT(atom2Uids,
-                UnorderedElementsAreArray(unionSet({defaultPullUids, app2Uids, {AID_STATSD}})));
-
-    vector<int32_t> atom3Uids = metricsManager.getPullAtomUids(atom3);
-    EXPECT_THAT(atom3Uids, UnorderedElementsAreArray(defaultPullUids));
-}
-
-TEST(MetricsManagerTest, TestLogSourcesOnConfigUpdate) {
-    string app1 = "app1";
-    set<int32_t> app1Uids = {1111, 11111};
-    string app2 = "app2";
-    set<int32_t> app2Uids = {2222};
-    string app3 = "app3";
-    set<int32_t> app3Uids = {3333, 1111};
-
-    map<string, set<int32_t>> pkgToUids;
-    pkgToUids[app1] = app1Uids;
-    pkgToUids[app2] = app2Uids;
-    pkgToUids[app3] = app3Uids;
-
-    int32_t atom1 = 10, atom2 = 20, atom3 = 30;
-    sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
-    EXPECT_CALL(*uidMap, getAppUid(_))
-            .Times(8)
-            .WillRepeatedly(Invoke([&pkgToUids](const string& pkg) {
-                const auto& it = pkgToUids.find(pkg);
-                if (it != pkgToUids.end()) {
-                    return it->second;
-                }
-                return set<int32_t>();
-            }));
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterPullUidProvider(kConfigKey, _)).Times(1);
-    EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey, _)).Times(1);
-
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_SYSTEM");
-    config.add_allowed_log_source(app1);
-    config.add_default_pull_packages("AID_SYSTEM");
-    config.add_default_pull_packages("AID_ROOT");
-
-    PullAtomPackages* pullAtomPackages = config.add_pull_atom_packages();
-    pullAtomPackages->set_atom_id(atom1);
-    pullAtomPackages->add_packages(app1);
-    pullAtomPackages->add_packages(app3);
-
-    pullAtomPackages = config.add_pull_atom_packages();
-    pullAtomPackages->set_atom_id(atom2);
-    pullAtomPackages->add_packages(app2);
-    pullAtomPackages->add_packages("AID_STATSD");
-
-    MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
-                                  pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-    EXPECT_TRUE(metricsManager.isConfigValid());
-
-    // Update with new allowed log sources.
-    StatsdConfig newConfig;
-    newConfig.add_allowed_log_source("AID_ROOT");
-    newConfig.add_allowed_log_source(app2);
-    newConfig.add_default_pull_packages("AID_SYSTEM");
-    newConfig.add_default_pull_packages("AID_STATSD");
-
-    pullAtomPackages = newConfig.add_pull_atom_packages();
-    pullAtomPackages->set_atom_id(atom2);
-    pullAtomPackages->add_packages(app1);
-    pullAtomPackages->add_packages(app3);
-
-    pullAtomPackages = newConfig.add_pull_atom_packages();
-    pullAtomPackages->set_atom_id(atom3);
-    pullAtomPackages->add_packages(app2);
-    pullAtomPackages->add_packages("AID_ADB");
-
-    metricsManager.updateConfig(newConfig, timeBaseSec, timeBaseSec, anomalyAlarmMonitor,
-                                periodicAlarmMonitor);
-    EXPECT_TRUE(metricsManager.isConfigValid());
-
-    EXPECT_THAT(metricsManager.mAllowedUid, ElementsAre(AID_ROOT));
-    EXPECT_THAT(metricsManager.mAllowedPkg, ElementsAre(app2));
-    EXPECT_THAT(metricsManager.mAllowedLogSources,
-                ContainerEq(unionSet(vector<set<int32_t>>({app2Uids, {AID_ROOT}}))));
-    const set<int32_t> defaultPullUids = {AID_SYSTEM, AID_STATSD};
-    EXPECT_THAT(metricsManager.mDefaultPullUids, ContainerEq(defaultPullUids));
-
-    vector<int32_t> atom1Uids = metricsManager.getPullAtomUids(atom1);
-    EXPECT_THAT(atom1Uids, UnorderedElementsAreArray(defaultPullUids));
-
-    vector<int32_t> atom2Uids = metricsManager.getPullAtomUids(atom2);
-    EXPECT_THAT(atom2Uids,
-                UnorderedElementsAreArray(unionSet({defaultPullUids, app1Uids, app3Uids})));
-
-    vector<int32_t> atom3Uids = metricsManager.getPullAtomUids(atom3);
-    EXPECT_THAT(atom3Uids,
-                UnorderedElementsAreArray(unionSet({defaultPullUids, app2Uids, {AID_ADB}})));
-}
-
-TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) {
-    sp<UidMap> uidMap;
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-
-    StatsdConfig config;
-    config.add_whitelisted_atom_ids(3);
-    config.add_whitelisted_atom_ids(4);
-
-    MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
-                                  pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
-    LogEvent event(0 /* uid */, 0 /* pid */);
-    CreateNoValuesLogEvent(&event, 10 /* atom id */, 0 /* timestamp */);
-    EXPECT_FALSE(metricsManager.checkLogCredentials(event));
-
-    CreateNoValuesLogEvent(&event, 3 /* atom id */, 0 /* timestamp */);
-    EXPECT_TRUE(metricsManager.checkLogCredentials(event));
-
-    CreateNoValuesLogEvent(&event, 4 /* atom id */, 0 /* timestamp */);
-    EXPECT_TRUE(metricsManager.checkLogCredentials(event));
-}
-
-TEST(MetricsManagerTest, TestWhitelistedAtomStateTracker) {
-    sp<UidMap> uidMap;
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-
-    StatsdConfig config = buildGoodConfig();
-    config.add_allowed_log_source("AID_SYSTEM");
-    config.add_whitelisted_atom_ids(3);
-    config.add_whitelisted_atom_ids(4);
-
-    State state;
-    state.set_id(1);
-    state.set_atom_id(3);
-
-    *config.add_state() = state;
-
-    config.mutable_count_metric(0)->add_slice_by_state(state.id());
-
-    StateManager::getInstance().clear();
-
-    MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
-                                  pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
-    EXPECT_EQ(0, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_FALSE(metricsManager.isConfigValid());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
deleted file mode 100644
index 1409b62..0000000
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ /dev/null
@@ -1,1886 +0,0 @@
-// Copyright (C) 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.
-
-#include "StatsLogProcessor.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include "StatsService.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "packages/UidMap.h"
-#include "statslog_statsdtest.h"
-#include "storage/StorageManager.h"
-#include "tests/statsd_test_util.h"
-
-using namespace android;
-using namespace testing;
-using ::ndk::SharedRefBase;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-
-#ifdef __ANDROID__
-
-/**
- * Mock MetricsManager (ByteSize() is called).
- */
-class MockMetricsManager : public MetricsManager {
-public:
-    MockMetricsManager()
-        : MetricsManager(ConfigKey(1, 12345), StatsdConfig(), 1000, 1000, new UidMap(),
-                         new StatsPullerManager(),
-                         new AlarmMonitor(10,
-                                          [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
-                                          [](const shared_ptr<IStatsCompanionService>&) {}),
-                         new AlarmMonitor(10,
-                                          [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
-                                          [](const shared_ptr<IStatsCompanionService>&) {})) {
-    }
-
-    MOCK_METHOD0(byteSize, size_t());
-
-    MOCK_METHOD1(dropData, void(const int64_t dropTimeNs));
-};
-
-TEST(StatsLogProcessorTest, TestRateLimitByteSize) {
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    // Construct the processor with a no-op sendBroadcast function that does nothing.
-    StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, 0,
-                        [](const ConfigKey& key) { return true; },
-                        [](const int&, const vector<int64_t>&) {return true;});
-
-    MockMetricsManager mockMetricsManager;
-
-    ConfigKey key(100, 12345);
-    // Expect only the first flush to trigger a check for byte size since the last two are
-    // rate-limited.
-    EXPECT_CALL(mockMetricsManager, byteSize()).Times(1);
-    p.flushIfNecessaryLocked(key, mockMetricsManager);
-    p.flushIfNecessaryLocked(key, mockMetricsManager);
-    p.flushIfNecessaryLocked(key, mockMetricsManager);
-}
-
-TEST(StatsLogProcessorTest, TestRateLimitBroadcast) {
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    int broadcastCount = 0;
-    StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
-                        [&broadcastCount](const ConfigKey& key) {
-                            broadcastCount++;
-                            return true;
-                        },
-                        [](const int&, const vector<int64_t>&) {return true;});
-
-    MockMetricsManager mockMetricsManager;
-
-    ConfigKey key(100, 12345);
-    EXPECT_CALL(mockMetricsManager, byteSize())
-            .Times(1)
-            .WillRepeatedly(::testing::Return(int(
-                    StatsdStats::kMaxMetricsBytesPerConfig * .95)));
-
-    // Expect only one broadcast despite always returning a size that should trigger broadcast.
-    p.flushIfNecessaryLocked(key, mockMetricsManager);
-    EXPECT_EQ(1, broadcastCount);
-
-    // b/73089712
-    // This next call to flush should not trigger a broadcast.
-    // p.mLastByteSizeTimes.clear();  // Force another check for byte size.
-    // p.flushIfNecessaryLocked(2, key, mockMetricsManager);
-    // EXPECT_EQ(1, broadcastCount);
-}
-
-TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) {
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    int broadcastCount = 0;
-    StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
-                        [&broadcastCount](const ConfigKey& key) {
-                            broadcastCount++;
-                            return true;
-                        },
-                        [](const int&, const vector<int64_t>&) {return true;});
-
-    MockMetricsManager mockMetricsManager;
-
-    ConfigKey key(100, 12345);
-    EXPECT_CALL(mockMetricsManager, byteSize())
-            .Times(1)
-            .WillRepeatedly(::testing::Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2)));
-
-    EXPECT_CALL(mockMetricsManager, dropData(_)).Times(1);
-
-    // Expect to call the onDumpReport and skip the broadcast.
-    p.flushIfNecessaryLocked(key, mockMetricsManager);
-    EXPECT_EQ(0, broadcastCount);
-}
-
-StatsdConfig MakeConfig(bool includeMetric) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    if (includeMetric) {
-        auto appCrashMatcher = CreateProcessCrashAtomMatcher();
-        *config.add_atom_matcher() = appCrashMatcher;
-        auto countMetric = config.add_count_metric();
-        countMetric->set_id(StringToId("AppCrashes"));
-        countMetric->set_what(appCrashMatcher.id());
-        countMetric->set_bucket(FIVE_MINUTES);
-    }
-    return config;
-}
-
-TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) {
-    // Setup simple config key corresponding to empty config.
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")},
-                 {String16("p1"), String16("p2")}, {String16(""), String16("")});
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    int broadcastCount = 0;
-    StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
-                        [&broadcastCount](const ConfigKey& key) {
-                            broadcastCount++;
-                            return true;
-                        },
-                        [](const int&, const vector<int64_t>&) {return true;});
-    ConfigKey key(3, 4);
-    StatsdConfig config = MakeConfig(true);
-    p.OnConfigUpdated(0, key, config);
-
-    // Expect to get no metrics, but snapshot specified above in uidmap.
-    vector<uint8_t> bytes;
-    p.onDumpReport(key, 1, false, true, ADB_DUMP, FAST, &bytes);
-
-    ConfigMetricsReportList output;
-    output.ParseFromArray(bytes.data(), bytes.size());
-    EXPECT_TRUE(output.reports_size() > 0);
-    auto uidmap = output.reports(0).uid_map();
-    EXPECT_TRUE(uidmap.snapshots_size() > 0);
-    ASSERT_EQ(2, uidmap.snapshots(0).package_info_size());
-}
-
-TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) {
-    // Setup simple config key corresponding to empty config.
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")},
-                 {String16("p1"), String16("p2")}, {String16(""), String16("")});
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    int broadcastCount = 0;
-    StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
-                        [&broadcastCount](const ConfigKey& key) {
-                            broadcastCount++;
-                            return true;
-                        },
-                        [](const int&, const vector<int64_t>&) {return true;});
-    ConfigKey key(3, 4);
-    StatsdConfig config = MakeConfig(false);
-    p.OnConfigUpdated(0, key, config);
-
-    // Expect to get no metrics, but snapshot specified above in uidmap.
-    vector<uint8_t> bytes;
-    p.onDumpReport(key, 1, false, true, ADB_DUMP, FAST, &bytes);
-
-    ConfigMetricsReportList output;
-    output.ParseFromArray(bytes.data(), bytes.size());
-    EXPECT_TRUE(output.reports_size() > 0);
-    EXPECT_FALSE(output.reports(0).has_uid_map());
-}
-
-TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) {
-    // Setup simple config key corresponding to empty config.
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    int broadcastCount = 0;
-    StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
-                        [&broadcastCount](const ConfigKey& key) {
-                            broadcastCount++;
-                            return true;
-                        },
-                        [](const int&, const vector<int64_t>&) {return true;});
-    ConfigKey key(3, 4);
-    StatsdConfig config;
-    auto annotation = config.add_annotation();
-    annotation->set_field_int64(1);
-    annotation->set_field_int32(2);
-    config.add_allowed_log_source("AID_ROOT");
-    p.OnConfigUpdated(1, key, config);
-
-    // Expect to get no metrics, but snapshot specified above in uidmap.
-    vector<uint8_t> bytes;
-    p.onDumpReport(key, 1, false, true, ADB_DUMP, FAST, &bytes);
-
-    ConfigMetricsReportList output;
-    output.ParseFromArray(bytes.data(), bytes.size());
-    EXPECT_TRUE(output.reports_size() > 0);
-    auto report = output.reports(0);
-    ASSERT_EQ(1, report.annotation_size());
-    EXPECT_EQ(1, report.annotation(0).field_int64());
-    EXPECT_EQ(2, report.annotation(0).field_int32());
-}
-
-TEST(StatsLogProcessorTest, TestOnDumpReportEraseData) {
-    // Setup a simple config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = wakelockAcquireMatcher;
-
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(123456);
-    countMetric->set_what(wakelockAcquireMatcher.id());
-    countMetric->set_bucket(FIVE_MINUTES);
-
-    ConfigKey cfgKey;
-    sp<StatsLogProcessor> processor = CreateStatsLogProcessor(1, 1, config, cfgKey);
-
-    std::vector<int> attributionUids = {111};
-    std::vector<string> attributionTags = {"App1"};
-    std::unique_ptr<LogEvent> event =
-            CreateAcquireWakelockEvent(2 /*timestamp*/, attributionUids, attributionTags, "wl1");
-    processor->OnLogEvent(event.get());
-
-    vector<uint8_t> bytes;
-    ConfigMetricsReportList output;
-
-    // Dump report WITHOUT erasing data.
-    processor->onDumpReport(cfgKey, 3, true, false /* Do NOT erase data. */, ADB_DUMP, FAST,
-                            &bytes);
-    output.ParseFromArray(bytes.data(), bytes.size());
-    ASSERT_EQ(output.reports_size(), 1);
-    ASSERT_EQ(output.reports(0).metrics_size(), 1);
-    ASSERT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
-
-    // Dump report WITH erasing data. There should be data since we didn't previously erase it.
-    processor->onDumpReport(cfgKey, 4, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes);
-    output.ParseFromArray(bytes.data(), bytes.size());
-    ASSERT_EQ(output.reports_size(), 1);
-    ASSERT_EQ(output.reports(0).metrics_size(), 1);
-    ASSERT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
-
-    // Dump report again. There should be no data since we erased it.
-    processor->onDumpReport(cfgKey, 5, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes);
-    output.ParseFromArray(bytes.data(), bytes.size());
-    // We don't care whether statsd has a report, as long as it has no count metrics in it.
-    bool noData = output.reports_size() == 0 || output.reports(0).metrics_size() == 0 ||
-                  output.reports(0).metrics(0).count_metrics().data_size() == 0;
-    EXPECT_TRUE(noData);
-}
-
-TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate) {
-    // Setup simple config key corresponding to empty config.
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    StatsLogProcessor p(
-            m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
-            [](const ConfigKey& key) { return true; },
-            [](const int&, const vector<int64_t>&) { return true; });
-    ConfigKey key(3, 4);
-    StatsdConfig config = MakeConfig(false);
-    p.OnConfigUpdated(0, key, config);
-    EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
-
-    config.add_default_pull_packages("AID_STATSD");
-    p.OnConfigUpdated(5, key, config);
-    EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
-
-    p.OnConfigRemoved(key);
-    EXPECT_EQ(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
-}
-
-TEST(StatsLogProcessorTest, InvalidConfigRemoved) {
-    // Setup simple config key corresponding to empty config.
-    StatsdStats::getInstance().reset();
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    m->updateMap(1, {1, 2}, {1, 2}, {String16("v1"), String16("v2")},
-                 {String16("p1"), String16("p2")}, {String16(""), String16("")});
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
-                        [](const ConfigKey& key) { return true; },
-                        [](const int&, const vector<int64_t>&) {return true;});
-    ConfigKey key(3, 4);
-    StatsdConfig config = MakeConfig(true);
-    p.OnConfigUpdated(0, key, config);
-    EXPECT_EQ(1, p.mMetricsManagers.size());
-    EXPECT_NE(p.mMetricsManagers.find(key), p.mMetricsManagers.end());
-    // Cannot assert the size of mConfigStats since it is static and does not get cleared on reset.
-    EXPECT_NE(StatsdStats::getInstance().mConfigStats.end(),
-              StatsdStats::getInstance().mConfigStats.find(key));
-    EXPECT_EQ(0, StatsdStats::getInstance().mIceBox.size());
-
-    StatsdConfig invalidConfig = MakeConfig(true);
-    invalidConfig.clear_allowed_log_source();
-    p.OnConfigUpdated(0, key, invalidConfig);
-    EXPECT_EQ(0, p.mMetricsManagers.size());
-    // The current configs should not contain the invalid config.
-    EXPECT_EQ(StatsdStats::getInstance().mConfigStats.end(),
-              StatsdStats::getInstance().mConfigStats.find(key));
-    // Both "config" and "invalidConfig" should be in the icebox.
-    EXPECT_EQ(2, StatsdStats::getInstance().mIceBox.size());
-
-}
-
-
-TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) {
-    int uid = 1111;
-
-    // Setup a simple config, no activation
-    StatsdConfig config1;
-    int64_t cfgId1 = 12341;
-    config1.set_id(cfgId1);
-    config1.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-    *config1.add_atom_matcher() = wakelockAcquireMatcher;
-
-    long metricId1 = 1234561;
-    long metricId2 = 1234562;
-    auto countMetric1 = config1.add_count_metric();
-    countMetric1->set_id(metricId1);
-    countMetric1->set_what(wakelockAcquireMatcher.id());
-    countMetric1->set_bucket(FIVE_MINUTES);
-
-    auto countMetric2 = config1.add_count_metric();
-    countMetric2->set_id(metricId2);
-    countMetric2->set_what(wakelockAcquireMatcher.id());
-    countMetric2->set_bucket(FIVE_MINUTES);
-
-    ConfigKey cfgKey1(uid, cfgId1);
-
-    // Add another config, with two metrics, one with activation
-    StatsdConfig config2;
-    int64_t cfgId2 = 12342;
-    config2.set_id(cfgId2);
-    config2.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    *config2.add_atom_matcher() = wakelockAcquireMatcher;
-
-    long metricId3 = 1234561;
-    long metricId4 = 1234562;
-
-    auto countMetric3 = config2.add_count_metric();
-    countMetric3->set_id(metricId3);
-    countMetric3->set_what(wakelockAcquireMatcher.id());
-    countMetric3->set_bucket(FIVE_MINUTES);
-
-    auto countMetric4 = config2.add_count_metric();
-    countMetric4->set_id(metricId4);
-    countMetric4->set_what(wakelockAcquireMatcher.id());
-    countMetric4->set_bucket(FIVE_MINUTES);
-
-    auto metric3Activation = config2.add_metric_activation();
-    metric3Activation->set_metric_id(metricId3);
-    metric3Activation->set_activation_type(ACTIVATE_IMMEDIATELY);
-    auto metric3ActivationTrigger = metric3Activation->add_event_activation();
-    metric3ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
-    metric3ActivationTrigger->set_ttl_seconds(100);
-
-    ConfigKey cfgKey2(uid, cfgId2);
-
-    // Add another config, with two metrics, both with activations
-    StatsdConfig config3;
-    int64_t cfgId3 = 12343;
-    config3.set_id(cfgId3);
-    config3.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    *config3.add_atom_matcher() = wakelockAcquireMatcher;
-
-    long metricId5 = 1234565;
-    long metricId6 = 1234566;
-    auto countMetric5 = config3.add_count_metric();
-    countMetric5->set_id(metricId5);
-    countMetric5->set_what(wakelockAcquireMatcher.id());
-    countMetric5->set_bucket(FIVE_MINUTES);
-
-    auto countMetric6 = config3.add_count_metric();
-    countMetric6->set_id(metricId6);
-    countMetric6->set_what(wakelockAcquireMatcher.id());
-    countMetric6->set_bucket(FIVE_MINUTES);
-
-    auto metric5Activation = config3.add_metric_activation();
-    metric5Activation->set_metric_id(metricId5);
-    metric5Activation->set_activation_type(ACTIVATE_IMMEDIATELY);
-    auto metric5ActivationTrigger = metric5Activation->add_event_activation();
-    metric5ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
-    metric5ActivationTrigger->set_ttl_seconds(100);
-
-    auto metric6Activation = config3.add_metric_activation();
-    metric6Activation->set_metric_id(metricId6);
-    metric6Activation->set_activation_type(ACTIVATE_IMMEDIATELY);
-    auto metric6ActivationTrigger = metric6Activation->add_event_activation();
-    metric6ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
-    metric6ActivationTrigger->set_ttl_seconds(200);
-
-    ConfigKey cfgKey3(uid, cfgId3);
-
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    vector<int64_t> activeConfigsBroadcast;
-
-    long timeBase1 = 1;
-    int broadcastCount = 0;
-    StatsLogProcessor processor(
-            m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, timeBase1,
-            [](const ConfigKey& key) { return true; },
-            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
-                                                             const vector<int64_t>& activeConfigs) {
-                broadcastCount++;
-                EXPECT_EQ(broadcastUid, uid);
-                activeConfigsBroadcast.clear();
-                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
-                                              activeConfigs.end());
-                return true;
-            });
-
-    processor.OnConfigUpdated(1, cfgKey1, config1);
-    processor.OnConfigUpdated(2, cfgKey2, config2);
-    processor.OnConfigUpdated(3, cfgKey3, config3);
-
-    ASSERT_EQ(3, processor.mMetricsManagers.size());
-
-    // Expect the first config and both metrics in it to be active.
-    auto it = processor.mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor.mMetricsManagers.end());
-    auto& metricsManager1 = it->second;
-    EXPECT_TRUE(metricsManager1->isActive());
-
-    auto metricIt = metricsManager1->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId1) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
-    auto& metricProducer1 = *metricIt;
-    EXPECT_TRUE(metricProducer1->isActive());
-
-    metricIt = metricsManager1->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId2) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
-    auto& metricProducer2 = *metricIt;
-    EXPECT_TRUE(metricProducer2->isActive());
-
-    // Expect config 2 to be active. Metric 3 shouldn't be active, metric 4 should be active.
-    it = processor.mMetricsManagers.find(cfgKey2);
-    EXPECT_TRUE(it != processor.mMetricsManagers.end());
-    auto& metricsManager2 = it->second;
-    EXPECT_TRUE(metricsManager2->isActive());
-
-    metricIt = metricsManager2->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId3) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
-    auto& metricProducer3 = *metricIt;
-    EXPECT_FALSE(metricProducer3->isActive());
-
-    metricIt = metricsManager2->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId4) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
-    auto& metricProducer4 = *metricIt;
-    EXPECT_TRUE(metricProducer4->isActive());
-
-    // Expect the third config and both metrics in it to be inactive.
-    it = processor.mMetricsManagers.find(cfgKey3);
-    EXPECT_TRUE(it != processor.mMetricsManagers.end());
-    auto& metricsManager3 = it->second;
-    EXPECT_FALSE(metricsManager3->isActive());
-
-    metricIt = metricsManager3->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId5) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
-    auto& metricProducer5 = *metricIt;
-    EXPECT_FALSE(metricProducer5->isActive());
-
-    metricIt = metricsManager3->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager3->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId6) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
-    auto& metricProducer6 = *metricIt;
-    EXPECT_FALSE(metricProducer6->isActive());
-
-    // No broadcast for active configs should have happened yet.
-    EXPECT_EQ(broadcastCount, 0);
-
-    // Activate all 3 metrics that were not active.
-    std::vector<int> attributionUids = {111};
-    std::vector<string> attributionTags = {"App1"};
-    std::unique_ptr<LogEvent> event =
-            CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
-    processor.OnLogEvent(event.get());
-
-    // Assert that all 3 configs are active.
-    EXPECT_TRUE(metricsManager1->isActive());
-    EXPECT_TRUE(metricsManager2->isActive());
-    EXPECT_TRUE(metricsManager3->isActive());
-
-    // A broadcast should have happened, and all 3 configs should be active in the broadcast.
-    EXPECT_EQ(broadcastCount, 1);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 3);
-    EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId1) !=
-                activeConfigsBroadcast.end());
-    EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId2) !=
-                activeConfigsBroadcast.end());
-    EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId3) !=
-                activeConfigsBroadcast.end());
-
-    // When we shut down, metrics 3 & 5 have 100ns remaining, metric 6 has 100s + 100ns.
-    int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
-    processor.SaveActiveConfigsToDisk(shutDownTime);
-    const int64_t ttl3 = event->GetElapsedTimestampNs() +
-                         metric3ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime;
-    const int64_t ttl5 = event->GetElapsedTimestampNs() +
-                         metric5ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime;
-    const int64_t ttl6 = event->GetElapsedTimestampNs() +
-                         metric6ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime;
-
-    // Create a second StatsLogProcessor and push the same 3 configs.
-    long timeBase2 = 1000;
-    sp<StatsLogProcessor> processor2 =
-            CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-    processor2->OnConfigUpdated(timeBase2, cfgKey2, config2);
-    processor2->OnConfigUpdated(timeBase2, cfgKey3, config3);
-
-    ASSERT_EQ(3, processor2->mMetricsManagers.size());
-
-    // First config and both metrics are active.
-    it = processor2->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor2->mMetricsManagers.end());
-    auto& metricsManager1001 = it->second;
-    EXPECT_TRUE(metricsManager1001->isActive());
-
-    metricIt = metricsManager1001->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId1) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
-    auto& metricProducer1001 = *metricIt;
-    EXPECT_TRUE(metricProducer1001->isActive());
-
-    metricIt = metricsManager1001->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId2) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
-    auto& metricProducer1002 = *metricIt;
-    EXPECT_TRUE(metricProducer1002->isActive());
-
-    // Second config is active. Metric 3 is inactive, metric 4 is active.
-    it = processor2->mMetricsManagers.find(cfgKey2);
-    EXPECT_TRUE(it != processor2->mMetricsManagers.end());
-    auto& metricsManager1002 = it->second;
-    EXPECT_TRUE(metricsManager1002->isActive());
-
-    metricIt = metricsManager1002->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId3) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
-    auto& metricProducer1003 = *metricIt;
-    EXPECT_FALSE(metricProducer1003->isActive());
-
-    metricIt = metricsManager1002->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId4) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
-    auto& metricProducer1004 = *metricIt;
-    EXPECT_TRUE(metricProducer1004->isActive());
-
-    // Config 3 is inactive. both metrics are inactive.
-    it = processor2->mMetricsManagers.find(cfgKey3);
-    EXPECT_TRUE(it != processor2->mMetricsManagers.end());
-    auto& metricsManager1003 = it->second;
-    EXPECT_FALSE(metricsManager1003->isActive());
-    ASSERT_EQ(2, metricsManager1003->mAllMetricProducers.size());
-
-    metricIt = metricsManager1003->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId5) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
-    auto& metricProducer1005 = *metricIt;
-    EXPECT_FALSE(metricProducer1005->isActive());
-
-    metricIt = metricsManager1003->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1003->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId6) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
-    auto& metricProducer1006 = *metricIt;
-    EXPECT_FALSE(metricProducer1006->isActive());
-
-    // Assert that all 3 metrics with activation are inactive and that the ttls were properly set.
-    EXPECT_FALSE(metricProducer1003->isActive());
-    const auto& activation1003 = metricProducer1003->mEventActivationMap.begin()->second;
-    EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns);
-    EXPECT_EQ(0, activation1003->start_ns);
-    EXPECT_FALSE(metricProducer1005->isActive());
-    const auto& activation1005 = metricProducer1005->mEventActivationMap.begin()->second;
-    EXPECT_EQ(100 * NS_PER_SEC, activation1005->ttl_ns);
-    EXPECT_EQ(0, activation1005->start_ns);
-    EXPECT_FALSE(metricProducer1006->isActive());
-    const auto& activation1006 = metricProducer1006->mEventActivationMap.begin()->second;
-    EXPECT_EQ(200 * NS_PER_SEC, activation1006->ttl_ns);
-    EXPECT_EQ(0, activation1006->start_ns);
-
-    processor2->LoadActiveConfigsFromDisk();
-
-    // After loading activations from disk, assert that all 3 metrics are active.
-    EXPECT_TRUE(metricProducer1003->isActive());
-    EXPECT_EQ(timeBase2 + ttl3 - activation1003->ttl_ns, activation1003->start_ns);
-    EXPECT_TRUE(metricProducer1005->isActive());
-    EXPECT_EQ(timeBase2 + ttl5 - activation1005->ttl_ns, activation1005->start_ns);
-    EXPECT_TRUE(metricProducer1006->isActive());
-    EXPECT_EQ(timeBase2 + ttl6 - activation1006->ttl_ns, activation1003->start_ns);
-
-    // Make sure no more broadcasts have happened.
-    EXPECT_EQ(broadcastCount, 1);
-}
-
-TEST(StatsLogProcessorTest, TestActivationOnBoot) {
-    int uid = 1111;
-
-    StatsdConfig config1;
-    config1.set_id(12341);
-    config1.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-    *config1.add_atom_matcher() = wakelockAcquireMatcher;
-
-    long metricId1 = 1234561;
-    long metricId2 = 1234562;
-    auto countMetric1 = config1.add_count_metric();
-    countMetric1->set_id(metricId1);
-    countMetric1->set_what(wakelockAcquireMatcher.id());
-    countMetric1->set_bucket(FIVE_MINUTES);
-
-    auto countMetric2 = config1.add_count_metric();
-    countMetric2->set_id(metricId2);
-    countMetric2->set_what(wakelockAcquireMatcher.id());
-    countMetric2->set_bucket(FIVE_MINUTES);
-
-    auto metric1Activation = config1.add_metric_activation();
-    metric1Activation->set_metric_id(metricId1);
-    metric1Activation->set_activation_type(ACTIVATE_ON_BOOT);
-    auto metric1ActivationTrigger = metric1Activation->add_event_activation();
-    metric1ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
-    metric1ActivationTrigger->set_ttl_seconds(100);
-
-    ConfigKey cfgKey1(uid, 12341);
-    long timeBase1 = 1;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
-
-    ASSERT_EQ(1, processor->mMetricsManagers.size());
-    auto it = processor->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor->mMetricsManagers.end());
-    auto& metricsManager1 = it->second;
-    EXPECT_TRUE(metricsManager1->isActive());
-
-    auto metricIt = metricsManager1->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId1) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
-    auto& metricProducer1 = *metricIt;
-    EXPECT_FALSE(metricProducer1->isActive());
-
-    metricIt = metricsManager1->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId2) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
-    auto& metricProducer2 = *metricIt;
-    EXPECT_TRUE(metricProducer2->isActive());
-
-    const auto& activation1 = metricProducer1->mEventActivationMap.begin()->second;
-    EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
-    EXPECT_EQ(0, activation1->start_ns);
-    EXPECT_EQ(kNotActive, activation1->state);
-
-    std::vector<int> attributionUids = {111};
-    std::vector<string> attributionTags = {"App1"};
-    std::unique_ptr<LogEvent> event =
-            CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
-    processor->OnLogEvent(event.get());
-
-    EXPECT_FALSE(metricProducer1->isActive());
-    EXPECT_EQ(0, activation1->start_ns);
-    EXPECT_EQ(kActiveOnBoot, activation1->state);
-
-    int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
-    processor->SaveActiveConfigsToDisk(shutDownTime);
-    EXPECT_FALSE(metricProducer1->isActive());
-    const int64_t ttl1 = metric1ActivationTrigger->ttl_seconds() * NS_PER_SEC;
-
-    long timeBase2 = 1000;
-    sp<StatsLogProcessor> processor2 =
-            CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-
-    ASSERT_EQ(1, processor2->mMetricsManagers.size());
-    it = processor2->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor2->mMetricsManagers.end());
-    auto& metricsManager1001 = it->second;
-    EXPECT_TRUE(metricsManager1001->isActive());
-
-    metricIt = metricsManager1001->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId1) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
-    auto& metricProducer1001 = *metricIt;
-    EXPECT_FALSE(metricProducer1001->isActive());
-
-    metricIt = metricsManager1001->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId2) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
-    auto& metricProducer1002 = *metricIt;
-    EXPECT_TRUE(metricProducer1002->isActive());
-
-    const auto& activation1001 = metricProducer1001->mEventActivationMap.begin()->second;
-    EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns);
-    EXPECT_EQ(0, activation1001->start_ns);
-    EXPECT_EQ(kNotActive, activation1001->state);
-
-    processor2->LoadActiveConfigsFromDisk();
-
-    EXPECT_TRUE(metricProducer1001->isActive());
-    EXPECT_EQ(timeBase2 + ttl1 - activation1001->ttl_ns, activation1001->start_ns);
-    EXPECT_EQ(kActive, activation1001->state);
-}
-
-TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations) {
-    int uid = 1111;
-
-    // Create config with 2 metrics:
-    // Metric 1: Activate on boot with 2 activations
-    // Metric 2: Always active
-    StatsdConfig config1;
-    config1.set_id(12341);
-    config1.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config1.add_atom_matcher() = wakelockAcquireMatcher;
-    *config1.add_atom_matcher() = screenOnMatcher;
-
-    long metricId1 = 1234561;
-    long metricId2 = 1234562;
-
-    auto countMetric1 = config1.add_count_metric();
-    countMetric1->set_id(metricId1);
-    countMetric1->set_what(wakelockAcquireMatcher.id());
-    countMetric1->set_bucket(FIVE_MINUTES);
-
-    auto countMetric2 = config1.add_count_metric();
-    countMetric2->set_id(metricId2);
-    countMetric2->set_what(wakelockAcquireMatcher.id());
-    countMetric2->set_bucket(FIVE_MINUTES);
-
-    auto metric1Activation = config1.add_metric_activation();
-    metric1Activation->set_metric_id(metricId1);
-    metric1Activation->set_activation_type(ACTIVATE_ON_BOOT);
-    auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
-    metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
-    metric1ActivationTrigger1->set_ttl_seconds(100);
-    auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
-    metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
-    metric1ActivationTrigger2->set_ttl_seconds(200);
-
-    ConfigKey cfgKey1(uid, 12341);
-    long timeBase1 = 1;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
-
-    // Metric 1 is not active.
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    ASSERT_EQ(1, processor->mMetricsManagers.size());
-    auto it = processor->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor->mMetricsManagers.end());
-    auto& metricsManager1 = it->second;
-    EXPECT_TRUE(metricsManager1->isActive());
-
-    auto metricIt = metricsManager1->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId1) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
-    auto& metricProducer1 = *metricIt;
-    EXPECT_FALSE(metricProducer1->isActive());
-
-    metricIt = metricsManager1->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId2) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
-    auto& metricProducer2 = *metricIt;
-    EXPECT_TRUE(metricProducer2->isActive());
-
-    int i = 0;
-    for (; i < metricsManager1->mAllAtomMatchingTrackers.size(); i++) {
-        if (metricsManager1->mAllAtomMatchingTrackers[i]->getId() ==
-            metric1ActivationTrigger1->atom_matcher_id()) {
-            break;
-        }
-    }
-    const auto& activation1 = metricProducer1->mEventActivationMap.at(i);
-    EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
-    EXPECT_EQ(0, activation1->start_ns);
-    EXPECT_EQ(kNotActive, activation1->state);
-
-    i = 0;
-    for (; i < metricsManager1->mAllAtomMatchingTrackers.size(); i++) {
-        if (metricsManager1->mAllAtomMatchingTrackers[i]->getId() ==
-            metric1ActivationTrigger2->atom_matcher_id()) {
-            break;
-        }
-    }
-    const auto& activation2 = metricProducer1->mEventActivationMap.at(i);
-    EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns);
-    EXPECT_EQ(0, activation2->start_ns);
-    EXPECT_EQ(kNotActive, activation2->state);
-    // }}}------------------------------------------------------------------------------
-
-    // Trigger Activation 1 for Metric 1
-    std::vector<int> attributionUids = {111};
-    std::vector<string> attributionTags = {"App1"};
-    std::unique_ptr<LogEvent> event =
-            CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
-    processor->OnLogEvent(event.get());
-
-    // Metric 1 is not active; Activation 1 set to kActiveOnBoot
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_FALSE(metricProducer1->isActive());
-    EXPECT_EQ(0, activation1->start_ns);
-    EXPECT_EQ(kActiveOnBoot, activation1->state);
-    EXPECT_EQ(0, activation2->start_ns);
-    EXPECT_EQ(kNotActive, activation2->state);
-
-    EXPECT_TRUE(metricProducer2->isActive());
-    // }}}-----------------------------------------------------------------------------
-
-    // Simulate shutdown by saving state to disk
-    int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
-    processor->SaveActiveConfigsToDisk(shutDownTime);
-    EXPECT_FALSE(metricProducer1->isActive());
-    int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
-
-    // Simulate device restarted state by creating new instance of StatsLogProcessor with the
-    // same config.
-    long timeBase2 = 1000;
-    sp<StatsLogProcessor> processor2 =
-            CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-
-    // Metric 1 is not active.
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    ASSERT_EQ(1, processor2->mMetricsManagers.size());
-    it = processor2->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor2->mMetricsManagers.end());
-    auto& metricsManager1001 = it->second;
-    EXPECT_TRUE(metricsManager1001->isActive());
-
-    metricIt = metricsManager1001->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId1) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
-    auto& metricProducer1001 = *metricIt;
-    EXPECT_FALSE(metricProducer1001->isActive());
-
-    metricIt = metricsManager1001->mAllMetricProducers.begin();
-    for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId2) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
-    auto& metricProducer1002 = *metricIt;
-    EXPECT_TRUE(metricProducer1002->isActive());
-
-    i = 0;
-    for (; i < metricsManager1001->mAllAtomMatchingTrackers.size(); i++) {
-        if (metricsManager1001->mAllAtomMatchingTrackers[i]->getId() ==
-            metric1ActivationTrigger1->atom_matcher_id()) {
-            break;
-        }
-    }
-    const auto& activation1001_1 = metricProducer1001->mEventActivationMap.at(i);
-    EXPECT_EQ(100 * NS_PER_SEC, activation1001_1->ttl_ns);
-    EXPECT_EQ(0, activation1001_1->start_ns);
-    EXPECT_EQ(kNotActive, activation1001_1->state);
-
-    i = 0;
-    for (; i < metricsManager1001->mAllAtomMatchingTrackers.size(); i++) {
-        if (metricsManager1001->mAllAtomMatchingTrackers[i]->getId() ==
-            metric1ActivationTrigger2->atom_matcher_id()) {
-            break;
-        }
-    }
-
-    const auto& activation1001_2 = metricProducer1001->mEventActivationMap.at(i);
-    EXPECT_EQ(200 * NS_PER_SEC, activation1001_2->ttl_ns);
-    EXPECT_EQ(0, activation1001_2->start_ns);
-    EXPECT_EQ(kNotActive, activation1001_2->state);
-    // }}}-----------------------------------------------------------------------------------
-
-    // Load saved state from disk.
-    processor2->LoadActiveConfigsFromDisk();
-
-    // Metric 1 active; Activation 1 is active, Activation 2 is not active
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_TRUE(metricProducer1001->isActive());
-    EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
-    EXPECT_EQ(kActive, activation1001_1->state);
-    EXPECT_EQ(0, activation1001_2->start_ns);
-    EXPECT_EQ(kNotActive, activation1001_2->state);
-
-    EXPECT_TRUE(metricProducer1002->isActive());
-    // }}}--------------------------------------------------------------------------------
-
-    // Trigger Activation 2 for Metric 1.
-    auto screenOnEvent =
-            CreateScreenStateChangedEvent(timeBase2 + 200, android::view::DISPLAY_STATE_ON);
-    processor2->OnLogEvent(screenOnEvent.get());
-
-    // Metric 1 active; Activation 1 is active, Activation 2 is set to kActiveOnBoot
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_TRUE(metricProducer1001->isActive());
-    EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
-    EXPECT_EQ(kActive, activation1001_1->state);
-    EXPECT_EQ(0, activation1001_2->start_ns);
-    EXPECT_EQ(kActiveOnBoot, activation1001_2->state);
-
-    EXPECT_TRUE(metricProducer1002->isActive());
-    // }}}---------------------------------------------------------------------------
-
-    // Simulate shutdown by saving state to disk
-    shutDownTime = timeBase2 + 50 * NS_PER_SEC;
-    processor2->SaveActiveConfigsToDisk(shutDownTime);
-    EXPECT_TRUE(metricProducer1001->isActive());
-    EXPECT_TRUE(metricProducer1002->isActive());
-    ttl1 = timeBase2 + metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC - shutDownTime;
-    int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC;
-
-    // Simulate device restarted state by creating new instance of StatsLogProcessor with the
-    // same config.
-    long timeBase3 = timeBase2 + 120 * NS_PER_SEC;
-    sp<StatsLogProcessor> processor3 =
-            CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1);
-
-    // Metric 1 is not active.
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    ASSERT_EQ(1, processor3->mMetricsManagers.size());
-    it = processor3->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor3->mMetricsManagers.end());
-    auto& metricsManagerTimeBase3 = it->second;
-    EXPECT_TRUE(metricsManagerTimeBase3->isActive());
-
-    metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
-    for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId1) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
-    auto& metricProducerTimeBase3_1 = *metricIt;
-    EXPECT_FALSE(metricProducerTimeBase3_1->isActive());
-
-    metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
-    for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId2) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
-    auto& metricProducerTimeBase3_2 = *metricIt;
-    EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
-
-    i = 0;
-    for (; i < metricsManagerTimeBase3->mAllAtomMatchingTrackers.size(); i++) {
-        if (metricsManagerTimeBase3->mAllAtomMatchingTrackers[i]->getId() ==
-            metric1ActivationTrigger1->atom_matcher_id()) {
-            break;
-        }
-    }
-    const auto& activationTimeBase3_1 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
-    EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase3_1->ttl_ns);
-    EXPECT_EQ(0, activationTimeBase3_1->start_ns);
-    EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
-
-    i = 0;
-    for (; i < metricsManagerTimeBase3->mAllAtomMatchingTrackers.size(); i++) {
-        if (metricsManagerTimeBase3->mAllAtomMatchingTrackers[i]->getId() ==
-            metric1ActivationTrigger2->atom_matcher_id()) {
-            break;
-        }
-    }
-
-    const auto& activationTimeBase3_2 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
-    EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase3_2->ttl_ns);
-    EXPECT_EQ(0, activationTimeBase3_2->start_ns);
-    EXPECT_EQ(kNotActive, activationTimeBase3_2->state);
-
-    EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
-    // }}}----------------------------------------------------------------------------------
-
-    // Load saved state from disk.
-    processor3->LoadActiveConfigsFromDisk();
-
-    // Metric 1 active: Activation 1 is active, Activation 2 is active
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
-    EXPECT_EQ(timeBase3 + ttl1 - activationTimeBase3_1->ttl_ns, activationTimeBase3_1->start_ns);
-    EXPECT_EQ(kActive, activationTimeBase3_1->state);
-    EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns);
-    EXPECT_EQ(kActive, activationTimeBase3_2->state);
-
-    EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
-    // }}}-------------------------------------------------------------------------------
-
-    // Trigger Activation 2 for Metric 1 again.
-    screenOnEvent = CreateScreenStateChangedEvent(timeBase3 + 100 * NS_PER_SEC,
-                                                  android::view::DISPLAY_STATE_ON);
-    processor3->OnLogEvent(screenOnEvent.get());
-
-    // Metric 1 active; Activation 1 is not active, Activation 2 is set to active
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
-    EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
-    EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns);
-    EXPECT_EQ(kActive, activationTimeBase3_2->state);
-
-    EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
-    // }}}---------------------------------------------------------------------------
-
-    // Simulate shutdown by saving state to disk.
-    shutDownTime = timeBase3 + 500 * NS_PER_SEC;
-    processor3->SaveActiveConfigsToDisk(shutDownTime);
-    EXPECT_TRUE(metricProducer1001->isActive());
-    EXPECT_TRUE(metricProducer1002->isActive());
-    ttl1 = timeBase3 + ttl1 - shutDownTime;
-    ttl2 = timeBase3 + metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC - shutDownTime;
-
-    // Simulate device restarted state by creating new instance of StatsLogProcessor with the
-    // same config.
-    long timeBase4 = timeBase3 + 600 * NS_PER_SEC;
-    sp<StatsLogProcessor> processor4 =
-            CreateStatsLogProcessor(timeBase4, timeBase4, config1, cfgKey1);
-
-    // Metric 1 is not active.
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    ASSERT_EQ(1, processor4->mMetricsManagers.size());
-    it = processor4->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor4->mMetricsManagers.end());
-    auto& metricsManagerTimeBase4 = it->second;
-    EXPECT_TRUE(metricsManagerTimeBase4->isActive());
-
-    metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin();
-    for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId1) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end());
-    auto& metricProducerTimeBase4_1 = *metricIt;
-    EXPECT_FALSE(metricProducerTimeBase4_1->isActive());
-
-    metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin();
-    for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) {
-        if ((*metricIt)->getMetricId() == metricId2) {
-            break;
-        }
-    }
-    EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end());
-    auto& metricProducerTimeBase4_2 = *metricIt;
-    EXPECT_TRUE(metricProducerTimeBase4_2->isActive());
-
-    i = 0;
-    for (; i < metricsManagerTimeBase4->mAllAtomMatchingTrackers.size(); i++) {
-        if (metricsManagerTimeBase4->mAllAtomMatchingTrackers[i]->getId() ==
-            metric1ActivationTrigger1->atom_matcher_id()) {
-            break;
-        }
-    }
-    const auto& activationTimeBase4_1 = metricProducerTimeBase4_1->mEventActivationMap.at(i);
-    EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase4_1->ttl_ns);
-    EXPECT_EQ(0, activationTimeBase4_1->start_ns);
-    EXPECT_EQ(kNotActive, activationTimeBase4_1->state);
-
-    i = 0;
-    for (; i < metricsManagerTimeBase4->mAllAtomMatchingTrackers.size(); i++) {
-        if (metricsManagerTimeBase4->mAllAtomMatchingTrackers[i]->getId() ==
-            metric1ActivationTrigger2->atom_matcher_id()) {
-            break;
-        }
-    }
-
-    const auto& activationTimeBase4_2 = metricProducerTimeBase4_1->mEventActivationMap.at(i);
-    EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase4_2->ttl_ns);
-    EXPECT_EQ(0, activationTimeBase4_2->start_ns);
-    EXPECT_EQ(kNotActive, activationTimeBase4_2->state);
-
-    EXPECT_TRUE(metricProducerTimeBase4_2->isActive());
-    // }}}----------------------------------------------------------------------------------
-
-    // Load saved state from disk.
-    processor4->LoadActiveConfigsFromDisk();
-
-    // Metric 1 active: Activation 1 is not active, Activation 2 is not active
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_FALSE(metricProducerTimeBase4_1->isActive());
-    EXPECT_EQ(kNotActive, activationTimeBase4_1->state);
-    EXPECT_EQ(kNotActive, activationTimeBase4_2->state);
-
-    EXPECT_TRUE(metricProducerTimeBase4_2->isActive());
-    // }}}-------------------------------------------------------------------------------
-}
-
-TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActivationTypes) {
-    int uid = 1111;
-
-    // Create config with 2 metrics:
-    // Metric 1: Activate on boot with 2 activations
-    // Metric 2: Always active
-    StatsdConfig config1;
-    config1.set_id(12341);
-    config1.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config1.add_atom_matcher() = wakelockAcquireMatcher;
-    *config1.add_atom_matcher() = screenOnMatcher;
-
-    long metricId1 = 1234561;
-    long metricId2 = 1234562;
-
-    auto countMetric1 = config1.add_count_metric();
-    countMetric1->set_id(metricId1);
-    countMetric1->set_what(wakelockAcquireMatcher.id());
-    countMetric1->set_bucket(FIVE_MINUTES);
-
-    auto countMetric2 = config1.add_count_metric();
-    countMetric2->set_id(metricId2);
-    countMetric2->set_what(wakelockAcquireMatcher.id());
-    countMetric2->set_bucket(FIVE_MINUTES);
-
-    auto metric1Activation = config1.add_metric_activation();
-    metric1Activation->set_metric_id(metricId1);
-    metric1Activation->set_activation_type(ACTIVATE_ON_BOOT);
-    auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
-    metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
-    metric1ActivationTrigger1->set_ttl_seconds(100);
-    auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
-    metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
-    metric1ActivationTrigger2->set_ttl_seconds(200);
-    metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
-
-    ConfigKey cfgKey1(uid, 12341);
-    long timeBase1 = 1;
-    sp<StatsLogProcessor> processor1 =
-            CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
-
-    // Metric 1 is not active.
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    ASSERT_EQ(1, processor1->mMetricsManagers.size());
-    auto it = processor1->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor1->mMetricsManagers.end());
-    auto& metricsManager1 = it->second;
-    EXPECT_TRUE(metricsManager1->isActive());
-
-    ASSERT_EQ(metricsManager1->mAllMetricProducers.size(), 2);
-    // We assume that the index of a MetricProducer within the mAllMetricProducers
-    // array follows the order in which metrics are added to the config.
-    auto& metricProducer1_1 = metricsManager1->mAllMetricProducers[0];
-    EXPECT_EQ(metricProducer1_1->getMetricId(), metricId1);
-    EXPECT_FALSE(metricProducer1_1->isActive());  // inactive due to associated MetricActivation
-
-    auto& metricProducer1_2 = metricsManager1->mAllMetricProducers[1];
-    EXPECT_EQ(metricProducer1_2->getMetricId(), metricId2);
-    EXPECT_TRUE(metricProducer1_2->isActive());
-
-    ASSERT_EQ(metricProducer1_1->mEventActivationMap.size(), 2);
-    // The key in mEventActivationMap is the index of the associated atom matcher. We assume
-    // that matchers are indexed in the order that they are added to the config.
-    const auto& activation1_1_1 = metricProducer1_1->mEventActivationMap.at(0);
-    EXPECT_EQ(100 * NS_PER_SEC, activation1_1_1->ttl_ns);
-    EXPECT_EQ(0, activation1_1_1->start_ns);
-    EXPECT_EQ(kNotActive, activation1_1_1->state);
-    EXPECT_EQ(ACTIVATE_ON_BOOT, activation1_1_1->activationType);
-
-    const auto& activation1_1_2 = metricProducer1_1->mEventActivationMap.at(1);
-    EXPECT_EQ(200 * NS_PER_SEC, activation1_1_2->ttl_ns);
-    EXPECT_EQ(0, activation1_1_2->start_ns);
-    EXPECT_EQ(kNotActive, activation1_1_2->state);
-    EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1_1_2->activationType);
-    // }}}------------------------------------------------------------------------------
-
-    // Trigger Activation 1 for Metric 1
-    std::vector<int> attributionUids = {111};
-    std::vector<string> attributionTags = {"App1"};
-    std::unique_ptr<LogEvent> event =
-            CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1");
-    processor1->OnLogEvent(event.get());
-
-    // Metric 1 is not active; Activation 1 set to kActiveOnBoot
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_FALSE(metricProducer1_1->isActive());
-    EXPECT_EQ(0, activation1_1_1->start_ns);
-    EXPECT_EQ(kActiveOnBoot, activation1_1_1->state);
-    EXPECT_EQ(0, activation1_1_2->start_ns);
-    EXPECT_EQ(kNotActive, activation1_1_2->state);
-
-    EXPECT_TRUE(metricProducer1_2->isActive());
-    // }}}-----------------------------------------------------------------------------
-
-    // Simulate shutdown by saving state to disk
-    int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
-    processor1->SaveActiveConfigsToDisk(shutDownTime);
-    EXPECT_FALSE(metricProducer1_1->isActive());
-
-    // Simulate device restarted state by creating new instance of StatsLogProcessor with the
-    // same config.
-    long timeBase2 = 1000;
-    sp<StatsLogProcessor> processor2 =
-            CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
-
-    // Metric 1 is not active.
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    ASSERT_EQ(1, processor2->mMetricsManagers.size());
-    it = processor2->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor2->mMetricsManagers.end());
-    auto& metricsManager2 = it->second;
-    EXPECT_TRUE(metricsManager2->isActive());
-
-    ASSERT_EQ(metricsManager2->mAllMetricProducers.size(), 2);
-    // We assume that the index of a MetricProducer within the mAllMetricProducers
-    // array follows the order in which metrics are added to the config.
-    auto& metricProducer2_1 = metricsManager2->mAllMetricProducers[0];
-    EXPECT_EQ(metricProducer2_1->getMetricId(), metricId1);
-    EXPECT_FALSE(metricProducer2_1->isActive());
-
-    auto& metricProducer2_2 = metricsManager2->mAllMetricProducers[1];
-    EXPECT_EQ(metricProducer2_2->getMetricId(), metricId2);
-    EXPECT_TRUE(metricProducer2_2->isActive());
-
-    ASSERT_EQ(metricProducer2_1->mEventActivationMap.size(), 2);
-    // The key in mEventActivationMap is the index of the associated atom matcher. We assume
-    // that matchers are indexed in the order that they are added to the config.
-    const auto& activation2_1_1 = metricProducer2_1->mEventActivationMap.at(0);
-    EXPECT_EQ(100 * NS_PER_SEC, activation2_1_1->ttl_ns);
-    EXPECT_EQ(0, activation2_1_1->start_ns);
-    EXPECT_EQ(kNotActive, activation2_1_1->state);
-    EXPECT_EQ(ACTIVATE_ON_BOOT, activation2_1_1->activationType);
-
-    const auto& activation2_1_2 = metricProducer2_1->mEventActivationMap.at(1);
-    EXPECT_EQ(200 * NS_PER_SEC, activation2_1_2->ttl_ns);
-    EXPECT_EQ(0, activation2_1_2->start_ns);
-    EXPECT_EQ(kNotActive, activation2_1_2->state);
-    EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2_1_2->activationType);
-    // }}}-----------------------------------------------------------------------------------
-
-    // Load saved state from disk.
-    processor2->LoadActiveConfigsFromDisk();
-
-    // Metric 1 active; Activation 1 is active, Activation 2 is not active
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_TRUE(metricProducer2_1->isActive());
-    int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
-    EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
-    EXPECT_EQ(kActive, activation2_1_1->state);
-    EXPECT_EQ(0, activation2_1_2->start_ns);
-    EXPECT_EQ(kNotActive, activation2_1_2->state);
-
-    EXPECT_TRUE(metricProducer2_2->isActive());
-    // }}}--------------------------------------------------------------------------------
-
-    // Trigger Activation 2 for Metric 1.
-    auto screenOnEvent =
-            CreateScreenStateChangedEvent(timeBase2 + 200, android::view::DISPLAY_STATE_ON);
-    processor2->OnLogEvent(screenOnEvent.get());
-
-    // Metric 1 active; Activation 1 is active, Activation 2 is active
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_TRUE(metricProducer2_1->isActive());
-    EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
-    EXPECT_EQ(kActive, activation2_1_1->state);
-    EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation2_1_2->start_ns);
-    EXPECT_EQ(kActive, activation2_1_2->state);
-
-    EXPECT_TRUE(metricProducer2_2->isActive());
-    // }}}---------------------------------------------------------------------------
-
-    // Simulate shutdown by saving state to disk
-    shutDownTime = timeBase2 + 50 * NS_PER_SEC;
-    processor2->SaveActiveConfigsToDisk(shutDownTime);
-    EXPECT_TRUE(metricProducer2_1->isActive());
-    EXPECT_TRUE(metricProducer2_2->isActive());
-    ttl1 -= shutDownTime - timeBase2;
-    int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC -
-                   (shutDownTime - screenOnEvent->GetElapsedTimestampNs());
-
-    // Simulate device restarted state by creating new instance of StatsLogProcessor with the
-    // same config.
-    long timeBase3 = timeBase2 + 120 * NS_PER_SEC;
-    sp<StatsLogProcessor> processor3 =
-            CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1);
-
-    // Metric 1 is not active.
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    ASSERT_EQ(1, processor3->mMetricsManagers.size());
-    it = processor3->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor3->mMetricsManagers.end());
-    auto& metricsManager3 = it->second;
-    EXPECT_TRUE(metricsManager3->isActive());
-
-    ASSERT_EQ(metricsManager3->mAllMetricProducers.size(), 2);
-    // We assume that the index of a MetricProducer within the mAllMetricProducers
-    // array follows the order in which metrics are added to the config.
-    auto& metricProducer3_1 = metricsManager3->mAllMetricProducers[0];
-    EXPECT_EQ(metricProducer3_1->getMetricId(), metricId1);
-    EXPECT_FALSE(metricProducer3_1->isActive());
-
-    auto& metricProducer3_2 = metricsManager3->mAllMetricProducers[1];
-    EXPECT_EQ(metricProducer3_2->getMetricId(), metricId2);
-    EXPECT_TRUE(metricProducer3_2->isActive());
-
-    ASSERT_EQ(metricProducer3_1->mEventActivationMap.size(), 2);
-    // The key in mEventActivationMap is the index of the associated atom matcher. We assume
-    // that matchers are indexed in the order that they are added to the config.
-    const auto& activation3_1_1 = metricProducer3_1->mEventActivationMap.at(0);
-    EXPECT_EQ(100 * NS_PER_SEC, activation3_1_1->ttl_ns);
-    EXPECT_EQ(0, activation3_1_1->start_ns);
-    EXPECT_EQ(kNotActive, activation3_1_1->state);
-    EXPECT_EQ(ACTIVATE_ON_BOOT, activation3_1_1->activationType);
-
-    const auto& activation3_1_2 = metricProducer3_1->mEventActivationMap.at(1);
-    EXPECT_EQ(200 * NS_PER_SEC, activation3_1_2->ttl_ns);
-    EXPECT_EQ(0, activation3_1_2->start_ns);
-    EXPECT_EQ(kNotActive, activation3_1_2->state);
-    EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation3_1_2->activationType);
-    // }}}----------------------------------------------------------------------------------
-
-    // Load saved state from disk.
-    processor3->LoadActiveConfigsFromDisk();
-
-    // Metric 1 active: Activation 1 is active, Activation 2 is active
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_TRUE(metricProducer3_1->isActive());
-    EXPECT_EQ(timeBase3 + ttl1 - activation3_1_1->ttl_ns, activation3_1_1->start_ns);
-    EXPECT_EQ(kActive, activation3_1_1->state);
-    EXPECT_EQ(timeBase3 + ttl2 - activation3_1_2->ttl_ns, activation3_1_2->start_ns);
-    EXPECT_EQ(kActive, activation3_1_2->state);
-
-    EXPECT_TRUE(metricProducer3_2->isActive());
-    // }}}-------------------------------------------------------------------------------
-
-    // Trigger Activation 2 for Metric 1 again.
-    screenOnEvent = CreateScreenStateChangedEvent(timeBase3 + 100 * NS_PER_SEC,
-                                                  android::view::DISPLAY_STATE_ON);
-    processor3->OnLogEvent(screenOnEvent.get());
-
-    // Metric 1 active; Activation 1 is inactive (above screenOnEvent causes ttl1 to expire),
-    //                  Activation 2 is set to active
-    // Metric 2 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_TRUE(metricProducer3_1->isActive());
-    EXPECT_EQ(kNotActive, activation3_1_1->state);
-    EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation3_1_2->start_ns);
-    EXPECT_EQ(kActive, activation3_1_2->state);
-
-    EXPECT_TRUE(metricProducer3_2->isActive());
-    // }}}---------------------------------------------------------------------------
-}
-
-TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart) {
-    int uid = 9876;
-    long configId = 12341;
-
-    // Create config with 3 metrics:
-    // Metric 1: Activate on 2 activations, 1 on boot, 1 immediate.
-    // Metric 2: Activate on 2 activations, 1 on boot, 1 immediate.
-    // Metric 3: Always active
-    StatsdConfig config1;
-    config1.set_id(configId);
-    config1.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    auto jobStartMatcher = CreateStartScheduledJobAtomMatcher();
-    auto jobFinishMatcher = CreateFinishScheduledJobAtomMatcher();
-    *config1.add_atom_matcher() = wakelockAcquireMatcher;
-    *config1.add_atom_matcher() = screenOnMatcher;
-    *config1.add_atom_matcher() = jobStartMatcher;
-    *config1.add_atom_matcher() = jobFinishMatcher;
-
-    long metricId1 = 1234561;
-    long metricId2 = 1234562;
-    long metricId3 = 1234563;
-
-    auto countMetric1 = config1.add_count_metric();
-    countMetric1->set_id(metricId1);
-    countMetric1->set_what(wakelockAcquireMatcher.id());
-    countMetric1->set_bucket(FIVE_MINUTES);
-
-    auto countMetric2 = config1.add_count_metric();
-    countMetric2->set_id(metricId2);
-    countMetric2->set_what(wakelockAcquireMatcher.id());
-    countMetric2->set_bucket(FIVE_MINUTES);
-
-    auto countMetric3 = config1.add_count_metric();
-    countMetric3->set_id(metricId3);
-    countMetric3->set_what(wakelockAcquireMatcher.id());
-    countMetric3->set_bucket(FIVE_MINUTES);
-
-    // Metric 1 activates on boot for wakelock acquire, immediately for screen on.
-    auto metric1Activation = config1.add_metric_activation();
-    metric1Activation->set_metric_id(metricId1);
-    auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
-    metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
-    metric1ActivationTrigger1->set_ttl_seconds(100);
-    metric1ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT);
-    auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
-    metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
-    metric1ActivationTrigger2->set_ttl_seconds(200);
-    metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
-
-    // Metric 2 activates on boot for scheduled job start, immediately for scheduled job finish.
-    auto metric2Activation = config1.add_metric_activation();
-    metric2Activation->set_metric_id(metricId2);
-    auto metric2ActivationTrigger1 = metric2Activation->add_event_activation();
-    metric2ActivationTrigger1->set_atom_matcher_id(jobStartMatcher.id());
-    metric2ActivationTrigger1->set_ttl_seconds(100);
-    metric2ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT);
-    auto metric2ActivationTrigger2 = metric2Activation->add_event_activation();
-    metric2ActivationTrigger2->set_atom_matcher_id(jobFinishMatcher.id());
-    metric2ActivationTrigger2->set_ttl_seconds(200);
-    metric2ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
-
-    // Send the config.
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    string serialized = config1.SerializeAsString();
-    service->addConfigurationChecked(uid, configId, {serialized.begin(), serialized.end()});
-
-    // Make sure the config is stored on disk. Otherwise, we will not reset on system server death.
-    StatsdConfig tmpConfig;
-    ConfigKey cfgKey1(uid, configId);
-    EXPECT_TRUE(StorageManager::readConfigFromDisk(cfgKey1, &tmpConfig));
-
-    // Metric 1 is not active.
-    // Metric 2 is not active.
-    // Metric 3 is active.
-    // {{{---------------------------------------------------------------------------
-    sp<StatsLogProcessor> processor = service->mProcessor;
-    ASSERT_EQ(1, processor->mMetricsManagers.size());
-    auto it = processor->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor->mMetricsManagers.end());
-    auto& metricsManager1 = it->second;
-    EXPECT_TRUE(metricsManager1->isActive());
-    ASSERT_EQ(3, metricsManager1->mAllMetricProducers.size());
-
-    auto& metricProducer1 = metricsManager1->mAllMetricProducers[0];
-    EXPECT_EQ(metricId1, metricProducer1->getMetricId());
-    EXPECT_FALSE(metricProducer1->isActive());
-
-    auto& metricProducer2 = metricsManager1->mAllMetricProducers[1];
-    EXPECT_EQ(metricId2, metricProducer2->getMetricId());
-    EXPECT_FALSE(metricProducer2->isActive());
-
-    auto& metricProducer3 = metricsManager1->mAllMetricProducers[2];
-    EXPECT_EQ(metricId3, metricProducer3->getMetricId());
-    EXPECT_TRUE(metricProducer3->isActive());
-
-    // Check event activations.
-    ASSERT_EQ(metricsManager1->mAllAtomMatchingTrackers.size(), 4);
-    EXPECT_EQ(metricsManager1->mAllAtomMatchingTrackers[0]->getId(),
-              metric1ActivationTrigger1->atom_matcher_id());
-    const auto& activation1 = metricProducer1->mEventActivationMap.at(0);
-    EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
-    EXPECT_EQ(0, activation1->start_ns);
-    EXPECT_EQ(kNotActive, activation1->state);
-    EXPECT_EQ(ACTIVATE_ON_BOOT, activation1->activationType);
-
-    EXPECT_EQ(metricsManager1->mAllAtomMatchingTrackers[1]->getId(),
-              metric1ActivationTrigger2->atom_matcher_id());
-    const auto& activation2 = metricProducer1->mEventActivationMap.at(1);
-    EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns);
-    EXPECT_EQ(0, activation2->start_ns);
-    EXPECT_EQ(kNotActive, activation2->state);
-    EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2->activationType);
-
-    EXPECT_EQ(metricsManager1->mAllAtomMatchingTrackers[2]->getId(),
-              metric2ActivationTrigger1->atom_matcher_id());
-    const auto& activation3 = metricProducer2->mEventActivationMap.at(2);
-    EXPECT_EQ(100 * NS_PER_SEC, activation3->ttl_ns);
-    EXPECT_EQ(0, activation3->start_ns);
-    EXPECT_EQ(kNotActive, activation3->state);
-    EXPECT_EQ(ACTIVATE_ON_BOOT, activation3->activationType);
-
-    EXPECT_EQ(metricsManager1->mAllAtomMatchingTrackers[3]->getId(),
-              metric2ActivationTrigger2->atom_matcher_id());
-    const auto& activation4 = metricProducer2->mEventActivationMap.at(3);
-    EXPECT_EQ(200 * NS_PER_SEC, activation4->ttl_ns);
-    EXPECT_EQ(0, activation4->start_ns);
-    EXPECT_EQ(kNotActive, activation4->state);
-    EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation4->activationType);
-    // }}}------------------------------------------------------------------------------
-
-    // Trigger Activation 1 for Metric 1. Should activate on boot.
-    // Trigger Activation 4 for Metric 2. Should activate immediately.
-    int64_t configAddedTimeNs = metricsManager1->mLastReportTimeNs;
-    std::vector<int> attributionUids = {111};
-    std::vector<string> attributionTags = {"App1"};
-    std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(
-            1 + configAddedTimeNs, attributionUids, attributionTags, "wl1");
-    processor->OnLogEvent(event1.get());
-
-    std::unique_ptr<LogEvent> event2 = CreateFinishScheduledJobEvent(
-            2 + configAddedTimeNs, attributionUids, attributionTags, "finish1");
-    processor->OnLogEvent(event2.get());
-
-    // Metric 1 is not active; Activation 1 set to kActiveOnBoot
-    // Metric 2 is active. Activation 4 set to kActive
-    // Metric 3 is active.
-    // {{{---------------------------------------------------------------------------
-    EXPECT_FALSE(metricProducer1->isActive());
-    EXPECT_EQ(0, activation1->start_ns);
-    EXPECT_EQ(kActiveOnBoot, activation1->state);
-    EXPECT_EQ(0, activation2->start_ns);
-    EXPECT_EQ(kNotActive, activation2->state);
-
-    EXPECT_TRUE(metricProducer2->isActive());
-    EXPECT_EQ(0, activation3->start_ns);
-    EXPECT_EQ(kNotActive, activation3->state);
-    EXPECT_EQ(2 + configAddedTimeNs, activation4->start_ns);
-    EXPECT_EQ(kActive, activation4->state);
-
-    EXPECT_TRUE(metricProducer3->isActive());
-    // }}}-----------------------------------------------------------------------------
-
-    // Can't fake time with StatsService.
-    // Lets get a time close to the system server death time and make sure it's sane.
-    int64_t approximateSystemServerDeath = getElapsedRealtimeNs();
-    EXPECT_TRUE(approximateSystemServerDeath > 2 + configAddedTimeNs);
-    EXPECT_TRUE(approximateSystemServerDeath < NS_PER_SEC + configAddedTimeNs);
-
-    // System server dies.
-    service->statsCompanionServiceDiedImpl();
-
-    // We should have a new metrics manager. Lets get it and ensure activation status is restored.
-    // {{{---------------------------------------------------------------------------
-    ASSERT_EQ(1, processor->mMetricsManagers.size());
-    it = processor->mMetricsManagers.find(cfgKey1);
-    EXPECT_TRUE(it != processor->mMetricsManagers.end());
-    auto& metricsManager2 = it->second;
-    EXPECT_TRUE(metricsManager2->isActive());
-    ASSERT_EQ(3, metricsManager2->mAllMetricProducers.size());
-
-    auto& metricProducer1001 = metricsManager2->mAllMetricProducers[0];
-    EXPECT_EQ(metricId1, metricProducer1001->getMetricId());
-    EXPECT_FALSE(metricProducer1001->isActive());
-
-    auto& metricProducer1002 = metricsManager2->mAllMetricProducers[1];
-    EXPECT_EQ(metricId2, metricProducer1002->getMetricId());
-    EXPECT_TRUE(metricProducer1002->isActive());
-
-    auto& metricProducer1003 = metricsManager2->mAllMetricProducers[2];
-    EXPECT_EQ(metricId3, metricProducer1003->getMetricId());
-    EXPECT_TRUE(metricProducer1003->isActive());
-
-    // Check event activations.
-    // Activation 1 is kActiveOnBoot.
-    // Activation 2 and 3 are not active.
-    // Activation 4 is active.
-    ASSERT_EQ(metricsManager2->mAllAtomMatchingTrackers.size(), 4);
-    EXPECT_EQ(metricsManager2->mAllAtomMatchingTrackers[0]->getId(),
-              metric1ActivationTrigger1->atom_matcher_id());
-    const auto& activation1001 = metricProducer1001->mEventActivationMap.at(0);
-    EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns);
-    EXPECT_EQ(0, activation1001->start_ns);
-    EXPECT_EQ(kActiveOnBoot, activation1001->state);
-    EXPECT_EQ(ACTIVATE_ON_BOOT, activation1001->activationType);
-
-    EXPECT_EQ(metricsManager2->mAllAtomMatchingTrackers[1]->getId(),
-              metric1ActivationTrigger2->atom_matcher_id());
-    const auto& activation1002 = metricProducer1001->mEventActivationMap.at(1);
-    EXPECT_EQ(200 * NS_PER_SEC, activation1002->ttl_ns);
-    EXPECT_EQ(0, activation1002->start_ns);
-    EXPECT_EQ(kNotActive, activation1002->state);
-    EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1002->activationType);
-
-    EXPECT_EQ(metricsManager2->mAllAtomMatchingTrackers[2]->getId(),
-              metric2ActivationTrigger1->atom_matcher_id());
-    const auto& activation1003 = metricProducer1002->mEventActivationMap.at(2);
-    EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns);
-    EXPECT_EQ(0, activation1003->start_ns);
-    EXPECT_EQ(kNotActive, activation1003->state);
-    EXPECT_EQ(ACTIVATE_ON_BOOT, activation1003->activationType);
-
-    EXPECT_EQ(metricsManager2->mAllAtomMatchingTrackers[3]->getId(),
-              metric2ActivationTrigger2->atom_matcher_id());
-    const auto& activation1004 = metricProducer1002->mEventActivationMap.at(3);
-    EXPECT_EQ(200 * NS_PER_SEC, activation1004->ttl_ns);
-    EXPECT_EQ(2 + configAddedTimeNs, activation1004->start_ns);
-    EXPECT_EQ(kActive, activation1004->state);
-    EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1004->activationType);
-    // }}}------------------------------------------------------------------------------
-
-    // Clear the data stored on disk as a result of the system server death.
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey1, configAddedTimeNs + NS_PER_SEC, false, true, ADB_DUMP, FAST,
-                            &buffer);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogHostUid) {
-    int hostUid = 20;
-    int isolatedUid = 30;
-    uint64_t eventTimeNs = 12355;
-    int atomId = 89;
-    int field1 = 90;
-    int field2 = 28;
-    sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
-    ConfigKey cfgKey;
-    StatsdConfig config = MakeConfig(false);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
-    shared_ptr<LogEvent> logEvent = makeUidLogEvent(atomId, eventTimeNs, hostUid, field1, field2);
-
-    processor->OnLogEvent(logEvent.get());
-
-    const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogIsolatedUid) {
-    int hostUid = 20;
-    int isolatedUid = 30;
-    uint64_t eventTimeNs = 12355;
-    int atomId = 89;
-    int field1 = 90;
-    int field2 = 28;
-    sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
-    ConfigKey cfgKey;
-    StatsdConfig config = MakeConfig(false);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
-    shared_ptr<LogEvent> logEvent =
-            makeUidLogEvent(atomId, eventTimeNs, isolatedUid, field1, field2);
-
-    processor->OnLogEvent(logEvent.get());
-
-    const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogHostUidAttributionChain) {
-    int hostUid = 20;
-    int isolatedUid = 30;
-    uint64_t eventTimeNs = 12355;
-    int atomId = 89;
-    int field1 = 90;
-    int field2 = 28;
-    sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
-    ConfigKey cfgKey;
-    StatsdConfig config = MakeConfig(false);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
-    shared_ptr<LogEvent> logEvent = makeAttributionLogEvent(atomId, eventTimeNs, {hostUid, 200},
-                                                            {"tag1", "tag2"}, field1, field2);
-
-    processor->OnLogEvent(logEvent.get());
-
-    const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(field1, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(field2, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogIsolatedUidAttributionChain) {
-    int hostUid = 20;
-    int isolatedUid = 30;
-    uint64_t eventTimeNs = 12355;
-    int atomId = 89;
-    int field1 = 90;
-    int field2 = 28;
-    sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
-    ConfigKey cfgKey;
-    StatsdConfig config = MakeConfig(false);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
-    shared_ptr<LogEvent> logEvent = makeAttributionLogEvent(atomId, eventTimeNs, {isolatedUid, 200},
-                                                            {"tag1", "tag2"}, field1, field2);
-
-    processor->OnLogEvent(logEvent.get());
-
-    const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(field1, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(field2, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(StatsLogProcessorTest, TestDumpReportWithoutErasingDataDoesNotUpdateTimestamp) {
-    int hostUid = 20;
-    int isolatedUid = 30;
-    sp<MockUidMap> mockUidMap = makeMockUidMapForOneHost(hostUid, {isolatedUid});
-    ConfigKey key(3, 4);
-
-    // TODO: All tests should not persist state on disk. This removes any reports that were present.
-    ProtoOutputStream proto;
-    StorageManager::appendConfigMetricsReport(key, &proto, /*erase data=*/true, /*isAdb=*/false);
-
-    StatsdConfig config = MakeConfig(false);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(1, 1, config, key, nullptr, 0, mockUidMap);
-    vector<uint8_t> bytes;
-
-    int64_t dumpTime1Ns = 1 * NS_PER_SEC;
-    processor->onDumpReport(key, dumpTime1Ns, false /* include_current_bucket */,
-            true /* erase_data */, ADB_DUMP, FAST, &bytes);
-
-    ConfigMetricsReportList output;
-    output.ParseFromArray(bytes.data(), bytes.size());
-    EXPECT_EQ(output.reports_size(), 1);
-    EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime1Ns);
-
-    int64_t dumpTime2Ns = 5 * NS_PER_SEC;
-    processor->onDumpReport(key, dumpTime2Ns, false /* include_current_bucket */,
-            false /* erase_data */, ADB_DUMP, FAST, &bytes);
-
-    // Check that the dump report without clearing data is successful.
-    output.ParseFromArray(bytes.data(), bytes.size());
-    EXPECT_EQ(output.reports_size(), 1);
-    EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime2Ns);
-    EXPECT_EQ(output.reports(0).last_report_elapsed_nanos(), dumpTime1Ns);
-
-    int64_t dumpTime3Ns = 10 * NS_PER_SEC;
-    processor->onDumpReport(key, dumpTime3Ns, false /* include_current_bucket */,
-            true /* erase_data */, ADB_DUMP, FAST, &bytes);
-
-    // Check that the previous dump report that didn't clear data did not overwrite the first dump's
-    // timestamps.
-    output.ParseFromArray(bytes.data(), bytes.size());
-    EXPECT_EQ(output.reports_size(), 1);
-    EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime3Ns);
-    EXPECT_EQ(output.reports(0).last_report_elapsed_nanos(), dumpTime1Ns);
-
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/StatsService_test.cpp b/cmds/statsd/tests/StatsService_test.cpp
deleted file mode 100644
index cc38c4a..0000000
--- a/cmds/statsd/tests/StatsService_test.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (C) 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.
-
-#include "StatsService.h"
-#include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <android/binder_interface_utils.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-
-using namespace android;
-using namespace testing;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-using ::ndk::SharedRefBase;
-
-#ifdef __ANDROID__
-
-TEST(StatsServiceTest, TestAddConfig_simple) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    StatsdConfig config;
-    config.set_id(12345);
-    string serialized = config.SerializeAsString();
-
-    EXPECT_TRUE(
-            service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
-}
-
-TEST(StatsServiceTest, TestAddConfig_empty) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    string serialized = "";
-
-    EXPECT_TRUE(
-            service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
-}
-
-TEST(StatsServiceTest, TestAddConfig_invalid) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    string serialized = "Invalid config!";
-
-    EXPECT_FALSE(
-            service->addConfigurationChecked(123, 12345, {serialized.begin(), serialized.end()}));
-}
-
-TEST(StatsServiceTest, TestGetUidFromArgs) {
-    Vector<String8> args;
-    args.push(String8("-1"));
-    args.push(String8("0"));
-    args.push(String8("1"));
-    args.push(String8("a1"));
-    args.push(String8(""));
-
-    int32_t uid;
-
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    service->mEngBuild = true;
-
-    // "-1"
-    EXPECT_FALSE(service->getUidFromArgs(args, 0, uid));
-
-    // "0"
-    EXPECT_TRUE(service->getUidFromArgs(args, 1, uid));
-    EXPECT_EQ(0, uid);
-
-    // "1"
-    EXPECT_TRUE(service->getUidFromArgs(args, 2, uid));
-    EXPECT_EQ(1, uid);
-
-    // "a1"
-    EXPECT_FALSE(service->getUidFromArgs(args, 3, uid));
-
-    // ""
-    EXPECT_FALSE(service->getUidFromArgs(args, 4, uid));
-
-    // For a non-userdebug, uid "1" cannot be impersonated.
-    service->mEngBuild = false;
-    EXPECT_FALSE(service->getUidFromArgs(args, 2, uid));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
deleted file mode 100644
index 33bdc64..0000000
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright (C) 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.
-
-#include "packages/UidMap.h"
-#include "StatsLogProcessor.h"
-#include "config/ConfigKey.h"
-#include "guardrail/StatsdStats.h"
-#include "logd/LogEvent.h"
-#include "hash.h"
-#include "statslog_statsdtest.h"
-#include "statsd_test_util.h"
-
-#include <android/util/ProtoOutputStream.h>
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-
-using namespace android;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using android::util::ProtoOutputStream;
-using android::util::ProtoReader;
-
-#ifdef __ANDROID__
-const string kApp1 = "app1.sharing.1";
-const string kApp2 = "app2.sharing.1";
-
-TEST(UidMapTest, TestIsolatedUID) {
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    // Construct the processor with a no-op sendBroadcast function that does nothing.
-    StatsLogProcessor p(
-            m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
-            [](const ConfigKey& key) { return true; },
-            [](const int&, const vector<int64_t>&) { return true; });
-
-    std::unique_ptr<LogEvent> addEvent = CreateIsolatedUidChangedEvent(
-            1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 1 /*is_create*/);
-    EXPECT_EQ(101, m->getHostUidOrSelf(101));
-    p.OnLogEvent(addEvent.get());
-    EXPECT_EQ(100, m->getHostUidOrSelf(101));
-
-    std::unique_ptr<LogEvent> removeEvent = CreateIsolatedUidChangedEvent(
-            1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 0 /*is_create*/);
-    p.OnLogEvent(removeEvent.get());
-    EXPECT_EQ(101, m->getHostUidOrSelf(101));
-}
-
-TEST(UidMapTest, TestMatching) {
-    UidMap m;
-    vector<int32_t> uids;
-    vector<int64_t> versions;
-    vector<String16> apps;
-    vector<String16> versionStrings;
-    vector<String16> installers;
-
-    uids.push_back(1000);
-    uids.push_back(1000);
-    versionStrings.push_back(String16("v1"));
-    versionStrings.push_back(String16("v1"));
-    installers.push_back(String16(""));
-    installers.push_back(String16(""));
-    apps.push_back(String16(kApp1.c_str()));
-    apps.push_back(String16(kApp2.c_str()));
-    versions.push_back(4);
-    versions.push_back(5);
-    m.updateMap(1, uids, versions, versionStrings, apps, installers);
-    EXPECT_TRUE(m.hasApp(1000, kApp1));
-    EXPECT_TRUE(m.hasApp(1000, kApp2));
-    EXPECT_FALSE(m.hasApp(1000, "not.app"));
-
-    std::set<string> name_set = m.getAppNamesFromUid(1000u, true /* returnNormalized */);
-    ASSERT_EQ(name_set.size(), 2u);
-    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
-    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
-    name_set = m.getAppNamesFromUid(12345, true /* returnNormalized */);
-    EXPECT_TRUE(name_set.empty());
-}
-
-TEST(UidMapTest, TestAddAndRemove) {
-    UidMap m;
-    vector<int32_t> uids;
-    vector<int64_t> versions;
-    vector<String16> apps;
-    vector<String16> versionStrings;
-    vector<String16> installers;
-
-    uids.push_back(1000);
-    uids.push_back(1000);
-    versionStrings.push_back(String16("v1"));
-    versionStrings.push_back(String16("v1"));
-    installers.push_back(String16(""));
-    installers.push_back(String16(""));
-    apps.push_back(String16(kApp1.c_str()));
-    apps.push_back(String16(kApp2.c_str()));
-    versions.push_back(4);
-    versions.push_back(5);
-    m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
-    std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    ASSERT_EQ(name_set.size(), 2u);
-    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
-    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
-    // Update the app1 version.
-    m.updateApp(2, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
-    EXPECT_EQ(40, m.getAppVersion(1000, kApp1));
-
-    name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    ASSERT_EQ(name_set.size(), 2u);
-    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
-    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
-    m.removeApp(3, String16(kApp1.c_str()), 1000);
-    EXPECT_FALSE(m.hasApp(1000, kApp1));
-    EXPECT_TRUE(m.hasApp(1000, kApp2));
-    name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    ASSERT_EQ(name_set.size(), 1u);
-    EXPECT_TRUE(name_set.find(kApp1) == name_set.end());
-    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
-    // Remove app2.
-    m.removeApp(4, String16(kApp2.c_str()), 1000);
-    EXPECT_FALSE(m.hasApp(1000, kApp1));
-    EXPECT_FALSE(m.hasApp(1000, kApp2));
-    name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_TRUE(name_set.empty());
-}
-
-TEST(UidMapTest, TestUpdateApp) {
-    UidMap m;
-    m.updateMap(1, {1000, 1000}, {4, 5}, {String16("v4"), String16("v5")},
-                {String16(kApp1.c_str()), String16(kApp2.c_str())}, {String16(""), String16("")});
-    std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    ASSERT_EQ(name_set.size(), 2u);
-    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
-    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-
-    // Adds a new name for uid 1000.
-    m.updateApp(2, String16("NeW_aPP1_NAmE"), 1000, 40, String16("v40"), String16(""));
-    name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    ASSERT_EQ(name_set.size(), 3u);
-    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
-    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
-    EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
-    EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
-
-    // This name is also reused by another uid 2000.
-    m.updateApp(3, String16("NeW_aPP1_NAmE"), 2000, 1, String16("v1"), String16(""));
-    name_set = m.getAppNamesFromUid(2000, true /* returnNormalized */);
-    ASSERT_EQ(name_set.size(), 1u);
-    EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
-    EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
-}
-
-static void protoOutputStreamToUidMapping(ProtoOutputStream* proto, UidMapping* results) {
-    vector<uint8_t> bytes;
-    bytes.resize(proto->size());
-    size_t pos = 0;
-    sp<ProtoReader> reader = proto->data();
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-    results->ParseFromArray(bytes.data(), bytes.size());
-}
-
-// Test that uid map returns at least one snapshot even if we already obtained
-// this snapshot from a previous call to getData.
-TEST(UidMapTest, TestOutputIncludesAtLeastOneSnapshot) {
-    UidMap m;
-    // Initialize single config key.
-    ConfigKey config1(1, StringToId("config1"));
-    m.OnConfigUpdated(config1);
-    vector<int32_t> uids;
-    vector<int64_t> versions;
-    vector<String16> apps;
-    vector<String16> versionStrings;
-    vector<String16> installers;
-    uids.push_back(1000);
-    apps.push_back(String16(kApp2.c_str()));
-    versionStrings.push_back(String16("v1"));
-    installers.push_back(String16(""));
-    versions.push_back(5);
-    m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
-    // Set the last timestamp for this config key to be newer.
-    m.mLastUpdatePerConfigKey[config1] = 2;
-
-    ProtoOutputStream proto;
-    m.appendUidMap(3, config1, nullptr, true, true, &proto);
-
-    // Check there's still a uidmap attached this one.
-    UidMapping results;
-    protoOutputStreamToUidMapping(&proto, &results);
-    ASSERT_EQ(1, results.snapshots_size());
-    EXPECT_EQ("v1", results.snapshots(0).package_info(0).version_string());
-}
-
-TEST(UidMapTest, TestRemovedAppRetained) {
-    UidMap m;
-    // Initialize single config key.
-    ConfigKey config1(1, StringToId("config1"));
-    m.OnConfigUpdated(config1);
-    vector<int32_t> uids;
-    vector<int64_t> versions;
-    vector<String16> versionStrings;
-    vector<String16> installers;
-    vector<String16> apps;
-    uids.push_back(1000);
-    apps.push_back(String16(kApp2.c_str()));
-    versions.push_back(5);
-    versionStrings.push_back(String16("v5"));
-    installers.push_back(String16(""));
-    m.updateMap(1, uids, versions, versionStrings, apps, installers);
-    m.removeApp(2, String16(kApp2.c_str()), 1000);
-
-    ProtoOutputStream proto;
-    m.appendUidMap(3, config1, nullptr, true, true, &proto);
-
-    // Snapshot should still contain this item as deleted.
-    UidMapping results;
-    protoOutputStreamToUidMapping(&proto, &results);
-    ASSERT_EQ(1, results.snapshots(0).package_info_size());
-    EXPECT_EQ(true, results.snapshots(0).package_info(0).deleted());
-}
-
-TEST(UidMapTest, TestRemovedAppOverGuardrail) {
-    UidMap m;
-    // Initialize single config key.
-    ConfigKey config1(1, StringToId("config1"));
-    m.OnConfigUpdated(config1);
-    vector<int32_t> uids;
-    vector<int64_t> versions;
-    vector<String16> versionStrings;
-    vector<String16> installers;
-    vector<String16> apps;
-    const int maxDeletedApps = StatsdStats::kMaxDeletedAppsInUidMap;
-    for (int j = 0; j < maxDeletedApps + 10; j++) {
-        uids.push_back(j);
-        apps.push_back(String16(kApp1.c_str()));
-        versions.push_back(j);
-        versionStrings.push_back(String16("v"));
-        installers.push_back(String16(""));
-    }
-    m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
-    // First, verify that we have the expected number of items.
-    UidMapping results;
-    ProtoOutputStream proto;
-    m.appendUidMap(3, config1, nullptr, true, true, &proto);
-    protoOutputStreamToUidMapping(&proto, &results);
-    ASSERT_EQ(maxDeletedApps + 10, results.snapshots(0).package_info_size());
-
-    // Now remove all the apps.
-    m.updateMap(1, uids, versions, versionStrings, apps, installers);
-    for (int j = 0; j < maxDeletedApps + 10; j++) {
-        m.removeApp(4, String16(kApp1.c_str()), j);
-    }
-
-    proto.clear();
-    m.appendUidMap(5, config1, nullptr, true, true, &proto);
-    // Snapshot drops the first nine items.
-    protoOutputStreamToUidMapping(&proto, &results);
-    ASSERT_EQ(maxDeletedApps, results.snapshots(0).package_info_size());
-}
-
-TEST(UidMapTest, TestClearingOutput) {
-    UidMap m;
-
-    ConfigKey config1(1, StringToId("config1"));
-    ConfigKey config2(1, StringToId("config2"));
-
-    m.OnConfigUpdated(config1);
-
-    vector<int32_t> uids;
-    vector<int64_t> versions;
-    vector<String16> versionStrings;
-    vector<String16> installers;
-    vector<String16> apps;
-    uids.push_back(1000);
-    uids.push_back(1000);
-    apps.push_back(String16(kApp1.c_str()));
-    apps.push_back(String16(kApp2.c_str()));
-    versions.push_back(4);
-    versions.push_back(5);
-    versionStrings.push_back(String16("v4"));
-    versionStrings.push_back(String16("v5"));
-    installers.push_back(String16(""));
-    installers.push_back(String16(""));
-    m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
-    ProtoOutputStream proto;
-    m.appendUidMap(2, config1, nullptr, true, true, &proto);
-    UidMapping results;
-    protoOutputStreamToUidMapping(&proto, &results);
-    ASSERT_EQ(1, results.snapshots_size());
-
-    // We have to keep at least one snapshot in memory at all times.
-    proto.clear();
-    m.appendUidMap(2, config1, nullptr, true, true, &proto);
-    protoOutputStreamToUidMapping(&proto, &results);
-    ASSERT_EQ(1, results.snapshots_size());
-
-    // Now add another configuration.
-    m.OnConfigUpdated(config2);
-    m.updateApp(5, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
-    ASSERT_EQ(1U, m.mChanges.size());
-    proto.clear();
-    m.appendUidMap(6, config1, nullptr, true, true, &proto);
-    protoOutputStreamToUidMapping(&proto, &results);
-    ASSERT_EQ(1, results.snapshots_size());
-    ASSERT_EQ(1, results.changes_size());
-    ASSERT_EQ(1U, m.mChanges.size());
-
-    // Add another delta update.
-    m.updateApp(7, String16(kApp2.c_str()), 1001, 41, String16("v41"), String16(""));
-    ASSERT_EQ(2U, m.mChanges.size());
-
-    // We still can't remove anything.
-    proto.clear();
-    m.appendUidMap(8, config1, nullptr, true, true, &proto);
-    protoOutputStreamToUidMapping(&proto, &results);
-    ASSERT_EQ(1, results.snapshots_size());
-    ASSERT_EQ(1, results.changes_size());
-    ASSERT_EQ(2U, m.mChanges.size());
-
-    proto.clear();
-    m.appendUidMap(9, config2, nullptr, true, true, &proto);
-    protoOutputStreamToUidMapping(&proto, &results);
-    ASSERT_EQ(1, results.snapshots_size());
-    ASSERT_EQ(2, results.changes_size());
-    // At this point both should be cleared.
-    ASSERT_EQ(0U, m.mChanges.size());
-}
-
-TEST(UidMapTest, TestMemoryComputed) {
-    UidMap m;
-
-    ConfigKey config1(1, StringToId("config1"));
-    m.OnConfigUpdated(config1);
-
-    size_t startBytes = m.mBytesUsed;
-    vector<int32_t> uids;
-    vector<int64_t> versions;
-    vector<String16> apps;
-    vector<String16> versionStrings;
-    vector<String16> installers;
-    uids.push_back(1000);
-    apps.push_back(String16(kApp1.c_str()));
-    versions.push_back(1);
-    versionStrings.push_back(String16("v1"));
-    installers.push_back(String16(""));
-    m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
-    m.updateApp(3, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
-
-    ProtoOutputStream proto;
-    vector<uint8_t> bytes;
-    m.appendUidMap(2, config1, nullptr, true, true, &proto);
-    size_t prevBytes = m.mBytesUsed;
-
-    m.appendUidMap(4, config1, nullptr, true, true, &proto);
-    EXPECT_TRUE(m.mBytesUsed < prevBytes);
-}
-
-TEST(UidMapTest, TestMemoryGuardrail) {
-    UidMap m;
-    string buf;
-
-    ConfigKey config1(1, StringToId("config1"));
-    m.OnConfigUpdated(config1);
-
-    size_t startBytes = m.mBytesUsed;
-    vector<int32_t> uids;
-    vector<int64_t> versions;
-    vector<String16> versionStrings;
-    vector<String16> installers;
-    vector<String16> apps;
-    for (int i = 0; i < 100; i++) {
-        uids.push_back(1);
-        buf = "EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY." + to_string(i);
-        apps.push_back(String16(buf.c_str()));
-        versions.push_back(1);
-        versionStrings.push_back(String16("v1"));
-        installers.push_back(String16(""));
-    }
-    m.updateMap(1, uids, versions, versionStrings, apps, installers);
-
-    m.updateApp(3, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 2,
-                String16("v2"), String16(""));
-    ASSERT_EQ(1U, m.mChanges.size());
-
-    // Now force deletion by limiting the memory to hold one delta change.
-    m.maxBytesOverride = 120; // Since the app string alone requires >45 characters.
-    m.updateApp(5, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 4,
-                String16("v4"), String16(""));
-    ASSERT_EQ(1U, m.mChanges.size());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
deleted file mode 100644
index 64ea219..0000000
--- a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (C) 2018 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.
-
-#include "src/anomaly/AlarmTracker.h"
-
-#include <gtest/gtest.h>
-#include <log/log_time.h>
-#include <stdio.h>
-#include <vector>
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::shared_ptr;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-TEST(AlarmTrackerTest, TestTriggerTimestamp) {
-    sp<AlarmMonitor> subscriberAlarmMonitor =
-        new AlarmMonitor(100,
-                         [](const shared_ptr<IStatsCompanionService>&, int64_t){},
-                         [](const shared_ptr<IStatsCompanionService>&){});
-    Alarm alarm;
-    alarm.set_offset_millis(15 * MS_PER_SEC);
-    alarm.set_period_millis(60 * 60 * MS_PER_SEC);  // 1hr
-    int64_t startMillis = 100000000 * MS_PER_SEC;
-    int64_t nextAlarmTime = startMillis / MS_PER_SEC + 15;
-    AlarmTracker tracker(startMillis, startMillis, alarm, kConfigKey, subscriberAlarmMonitor);
-
-    EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
-
-    uint64_t currentTimeSec = startMillis / MS_PER_SEC + 10;
-    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarmSet =
-        subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
-    EXPECT_TRUE(firedAlarmSet.empty());
-    tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
-    EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
-    EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-
-    currentTimeSec = startMillis / MS_PER_SEC + 7000;
-    nextAlarmTime = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60;
-    firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
-    ASSERT_EQ(firedAlarmSet.size(), 1u);
-    tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
-    EXPECT_TRUE(firedAlarmSet.empty());
-    EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
-    EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-
-    // Alarm fires exactly on time.
-    currentTimeSec = startMillis / MS_PER_SEC + 15 + 2 * 60 * 60;
-    nextAlarmTime = startMillis / MS_PER_SEC + 15 + 3 * 60 * 60;
-    firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
-    ASSERT_EQ(firedAlarmSet.size(), 1u);
-    tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
-    EXPECT_TRUE(firedAlarmSet.empty());
-    EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
-    EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-
-    // Alarm fires exactly 1 period late.
-    currentTimeSec = startMillis / MS_PER_SEC + 15 + 4 * 60 * 60;
-    nextAlarmTime = startMillis / MS_PER_SEC + 15 + 5 * 60 * 60;
-    firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
-    ASSERT_EQ(firedAlarmSet.size(), 1u);
-    tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
-    EXPECT_TRUE(firedAlarmSet.empty());
-    EXPECT_EQ(tracker.mAlarmSec, nextAlarmTime);
-    EXPECT_EQ(tracker.getAlarmTimestampSec(), nextAlarmTime);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
deleted file mode 100644
index 0cc8af1..0000000
--- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/anomaly/AnomalyTracker.h"
-
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-MetricDimensionKey getMockMetricDimensionKey(int key, string value) {
-    int pos[] = {key, 0, 0};
-    HashableDimensionKey dim;
-    dim.addValue(FieldValue(Field(1, pos, 0), Value(value)));
-    return MetricDimensionKey(dim, DEFAULT_DIMENSION_KEY);
-}
-
-void AddValueToBucket(const std::vector<std::pair<MetricDimensionKey, long>>& key_value_pair_list,
-                      std::shared_ptr<DimToValMap> bucket) {
-    for (auto itr = key_value_pair_list.begin(); itr != key_value_pair_list.end(); itr++) {
-        (*bucket)[itr->first] += itr->second;
-    }
-}
-
-std::shared_ptr<DimToValMap> MockBucket(
-        const std::vector<std::pair<MetricDimensionKey, long>>& key_value_pair_list) {
-    std::shared_ptr<DimToValMap> bucket = std::make_shared<DimToValMap>();
-    AddValueToBucket(key_value_pair_list, bucket);
-    return bucket;
-}
-
-// Returns the value, for the given key, in that bucket, or 0 if not present.
-int64_t getBucketValue(const std::shared_ptr<DimToValMap>& bucket,
-                       const MetricDimensionKey& key) {
-    const auto& itr = bucket->find(key);
-    if (itr != bucket->end()) {
-        return itr->second;
-    }
-    return 0;
-}
-
-// Returns true if keys in trueList are detected as anomalies and keys in falseList are not.
-bool detectAnomaliesPass(AnomalyTracker& tracker,
-                         const int64_t& bucketNum,
-                         const std::shared_ptr<DimToValMap>& currentBucket,
-                         const std::set<const MetricDimensionKey>& trueList,
-                         const std::set<const MetricDimensionKey>& falseList) {
-    for (const MetricDimensionKey& key : trueList) {
-        if (!tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
-            return false;
-        }
-    }
-    for (const MetricDimensionKey& key : falseList) {
-        if (tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
-            return false;
-        }
-    }
-    return true;
-}
-
-// Calls tracker.detectAndDeclareAnomaly on each key in the bucket.
-void detectAndDeclareAnomalies(AnomalyTracker& tracker,
-                               const int64_t& bucketNum,
-                               const std::shared_ptr<DimToValMap>& bucket,
-                               const int64_t& eventTimestamp) {
-    for (const auto& kv : *bucket) {
-        tracker.detectAndDeclareAnomaly(eventTimestamp, bucketNum, 0 /*metric_id*/, kv.first,
-                                        kv.second);
-    }
-}
-
-// Asserts that the refractory time for each key in timestamps is the corresponding
-// timestamp (in ns) + refractoryPeriodSec.
-// If a timestamp value is negative, instead asserts that the refractory period is inapplicable
-// (either non-existant or already past).
-void checkRefractoryTimes(AnomalyTracker& tracker,
-                          const int64_t& currTimestampNs,
-                          const int32_t& refractoryPeriodSec,
-                          const std::unordered_map<MetricDimensionKey, int64_t>& timestamps) {
-    for (const auto& kv : timestamps) {
-        if (kv.second < 0) {
-            // Make sure that, if there is a refractory period, it is already past.
-            EXPECT_LT(tracker.getRefractoryPeriodEndsSec(kv.first) * NS_PER_SEC,
-                    (uint64_t)currTimestampNs)
-                    << "Failure was at currTimestampNs " << currTimestampNs;
-        } else {
-            EXPECT_EQ(tracker.getRefractoryPeriodEndsSec(kv.first),
-                      std::ceil(1.0 * kv.second / NS_PER_SEC) + refractoryPeriodSec)
-                      << "Failure was at currTimestampNs " << currTimestampNs;
-        }
-    }
-}
-
-TEST(AnomalyTrackerTest, TestConsecutiveBuckets) {
-    const int64_t bucketSizeNs = 30 * NS_PER_SEC;
-    const int32_t refractoryPeriodSec = 2 * bucketSizeNs / NS_PER_SEC;
-    Alert alert;
-    alert.set_num_buckets(3);
-    alert.set_refractory_period_secs(refractoryPeriodSec);
-    alert.set_trigger_if_sum_gt(2);
-
-    AnomalyTracker anomalyTracker(alert, kConfigKey);
-    MetricDimensionKey keyA = getMockMetricDimensionKey(1, "a");
-    MetricDimensionKey keyB = getMockMetricDimensionKey(1, "b");
-    MetricDimensionKey keyC = getMockMetricDimensionKey(1, "c");
-
-    int64_t eventTimestamp0 = 10 * NS_PER_SEC;
-    int64_t eventTimestamp1 = bucketSizeNs + 11 * NS_PER_SEC;
-    int64_t eventTimestamp2 = 2 * bucketSizeNs + 12 * NS_PER_SEC;
-    int64_t eventTimestamp3 = 3 * bucketSizeNs + 13 * NS_PER_SEC;
-    int64_t eventTimestamp4 = 4 * bucketSizeNs + 14 * NS_PER_SEC;
-    int64_t eventTimestamp5 = 5 * bucketSizeNs + 5 * NS_PER_SEC;
-    int64_t eventTimestamp6 = 6 * bucketSizeNs + 16 * NS_PER_SEC;
-
-    std::shared_ptr<DimToValMap> bucket0 = MockBucket({{keyA, 1}, {keyB, 2}, {keyC, 1}});
-    std::shared_ptr<DimToValMap> bucket1 = MockBucket({{keyA, 1}});
-    std::shared_ptr<DimToValMap> bucket2 = MockBucket({{keyB, 1}});
-    std::shared_ptr<DimToValMap> bucket3 = MockBucket({{keyA, 2}});
-    std::shared_ptr<DimToValMap> bucket4 = MockBucket({{keyB, 5}});
-    std::shared_ptr<DimToValMap> bucket5 = MockBucket({{keyA, 2}});
-    std::shared_ptr<DimToValMap> bucket6 = MockBucket({{keyA, 2}});
-
-    // Start time with no events.
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0u);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, -1LL);
-
-    // Event from bucket #0 occurs.
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 0, bucket0, {}, {keyA, keyB, keyC}));
-    detectAndDeclareAnomalies(anomalyTracker, 0, bucket0, eventTimestamp1);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp0, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, -1}, {keyC, -1}});
-
-    // Adds past bucket #0
-    anomalyTracker.addPastBucket(bucket0, 0);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 0LL);
-
-    // Event from bucket #1 occurs.
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 1, bucket1, {}, {keyA, keyB, keyC}));
-    detectAndDeclareAnomalies(anomalyTracker, 1, bucket1, eventTimestamp1);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, -1}, {keyC, -1}});
-
-    // Adds past bucket #0 again. The sum does not change.
-    anomalyTracker.addPastBucket(bucket0, 0);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 0LL);
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 1, bucket1, {}, {keyA, keyB, keyC}));
-    detectAndDeclareAnomalies(anomalyTracker, 1, bucket1, eventTimestamp1 + 1);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, -1}, {keyC, -1}});
-
-    // Adds past bucket #1.
-    anomalyTracker.addPastBucket(bucket1, 1);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 1L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-
-    // Event from bucket #2 occurs. New anomaly on keyB.
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 2, bucket2, {keyB}, {keyA, keyC}));
-    detectAndDeclareAnomalies(anomalyTracker, 2, bucket2, eventTimestamp2);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}});
-
-    // Adds past bucket #1 again. Nothing changes.
-    anomalyTracker.addPastBucket(bucket1, 1);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 1L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-    // Event from bucket #2 occurs (again).
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 2, bucket2, {keyB}, {keyA, keyC}));
-    detectAndDeclareAnomalies(anomalyTracker, 2, bucket2, eventTimestamp2 + 1);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}});
-
-    // Adds past bucket #2.
-    anomalyTracker.addPastBucket(bucket2, 2);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 2L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-
-    // Event from bucket #3 occurs. New anomaly on keyA.
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 3, bucket3, {keyA}, {keyB, keyC}));
-    detectAndDeclareAnomalies(anomalyTracker, 3, bucket3, eventTimestamp3);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp3, refractoryPeriodSec,
-            {{keyA, eventTimestamp3}, {keyB, eventTimestamp2}, {keyC, -1}});
-
-    // Adds bucket #3.
-    anomalyTracker.addPastBucket(bucket3, 3L);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 3L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-
-    // Event from bucket #4 occurs. New anomaly on keyB.
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 4, bucket4, {keyB}, {keyA, keyC}));
-    detectAndDeclareAnomalies(anomalyTracker, 4, bucket4, eventTimestamp4);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp4, refractoryPeriodSec,
-            {{keyA, eventTimestamp3}, {keyB, eventTimestamp4}, {keyC, -1}});
-
-    // Adds bucket #4.
-    anomalyTracker.addPastBucket(bucket4, 4);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 4L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 5LL);
-
-    // Event from bucket #5 occurs. New anomaly on keyA, which is still in refractory.
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 5, bucket5, {keyA, keyB}, {keyC}));
-    detectAndDeclareAnomalies(anomalyTracker, 5, bucket5, eventTimestamp5);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp5, refractoryPeriodSec,
-            {{keyA, eventTimestamp3}, {keyB, eventTimestamp4}, {keyC, -1}});
-
-    // Adds bucket #5.
-    anomalyTracker.addPastBucket(bucket5, 5);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 5L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 5LL);
-
-    // Event from bucket #6 occurs. New anomaly on keyA, which is now out of refractory.
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 6, bucket6, {keyA, keyB}, {keyC}));
-    detectAndDeclareAnomalies(anomalyTracker, 6, bucket6, eventTimestamp6);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
-            {{keyA, eventTimestamp6}, {keyB, eventTimestamp4}, {keyC, -1}});
-}
-
-TEST(AnomalyTrackerTest, TestSparseBuckets) {
-    const int64_t bucketSizeNs = 30 * NS_PER_SEC;
-    const int32_t refractoryPeriodSec = 2 * bucketSizeNs / NS_PER_SEC;
-    Alert alert;
-    alert.set_num_buckets(3);
-    alert.set_refractory_period_secs(refractoryPeriodSec);
-    alert.set_trigger_if_sum_gt(2);
-
-    AnomalyTracker anomalyTracker(alert, kConfigKey);
-    MetricDimensionKey keyA = getMockMetricDimensionKey(1, "a");
-    MetricDimensionKey keyB = getMockMetricDimensionKey(1, "b");
-    MetricDimensionKey keyC = getMockMetricDimensionKey(1, "c");
-    MetricDimensionKey keyD = getMockMetricDimensionKey(1, "d");
-    MetricDimensionKey keyE = getMockMetricDimensionKey(1, "e");
-
-    std::shared_ptr<DimToValMap> bucket9 = MockBucket({{keyA, 1}, {keyB, 2}, {keyC, 1}});
-    std::shared_ptr<DimToValMap> bucket16 = MockBucket({{keyB, 4}});
-    std::shared_ptr<DimToValMap> bucket18 = MockBucket({{keyB, 1}, {keyC, 1}});
-    std::shared_ptr<DimToValMap> bucket20 = MockBucket({{keyB, 3}, {keyC, 1}});
-    std::shared_ptr<DimToValMap> bucket25 = MockBucket({{keyD, 1}});
-    std::shared_ptr<DimToValMap> bucket28 = MockBucket({{keyE, 2}});
-
-    int64_t eventTimestamp1 = bucketSizeNs * 8 + 1;
-    int64_t eventTimestamp2 = bucketSizeNs * 15 + 11;
-    int64_t eventTimestamp3 = bucketSizeNs * 17 + 1;
-    int64_t eventTimestamp4 = bucketSizeNs * 19 + 2;
-    int64_t eventTimestamp5 = bucketSizeNs * 24 + 3;
-    int64_t eventTimestamp6 = bucketSizeNs * 27 + 3;
-
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, -1LL);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 9, bucket9, {}, {keyA, keyB, keyC, keyD}));
-    detectAndDeclareAnomalies(anomalyTracker, 9, bucket9, eventTimestamp1);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
-    // Add past bucket #9
-    anomalyTracker.addPastBucket(bucket9, 9);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 9L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 16, bucket16, {keyB}, {keyA, keyC, keyD}));
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
-    detectAndDeclareAnomalies(anomalyTracker, 16, bucket16, eventTimestamp2);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
-    // Add past bucket #16
-    anomalyTracker.addPastBucket(bucket16, 16);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 16L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 18, bucket18, {keyB}, {keyA, keyC, keyD}));
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
-    // Within refractory period.
-    detectAndDeclareAnomalies(anomalyTracker, 18, bucket18, eventTimestamp3);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp3, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
-
-    // Add past bucket #18
-    anomalyTracker.addPastBucket(bucket18, 18);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 18L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 20, bucket20, {keyB}, {keyA, keyC, keyD}));
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 19L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-    detectAndDeclareAnomalies(anomalyTracker, 20, bucket20, eventTimestamp4);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp4, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
-    // Add bucket #18 again. Nothing changes.
-    anomalyTracker.addPastBucket(bucket18, 18);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 19L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 20, bucket20, {keyB}, {keyA, keyC, keyD}));
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-    detectAndDeclareAnomalies(anomalyTracker, 20, bucket20, eventTimestamp4 + 1);
-    // Within refractory period.
-    checkRefractoryTimes(anomalyTracker, eventTimestamp4 + 1, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
-    // Add past bucket #20
-    anomalyTracker.addPastBucket(bucket20, 20);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 20L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 3LL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 25, bucket25, {}, {keyA, keyB, keyC, keyD}));
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 24L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
-    detectAndDeclareAnomalies(anomalyTracker, 25, bucket25, eventTimestamp5);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp5, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
-    // Add past bucket #25
-    anomalyTracker.addPastBucket(bucket25, 25);
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 25L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
-    EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyD), 1LL);
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {},
-            {keyA, keyB, keyC, keyD, keyE}));
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
-    detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-
-    // Updates current bucket #28.
-    (*bucket28)[keyE] = 5;
-    EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {keyE},
-            {keyA, keyB, keyC, keyD}));
-    EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
-    detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6 + 7);
-    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
-    checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
-            {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, eventTimestamp6 + 7}});
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp b/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
deleted file mode 100644
index 1d501fd..0000000
--- a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (C) 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.
-
-#include "condition/condition_util.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-
-#include <gtest/gtest.h>
-
-#include <stdio.h>
-#include <vector>
-
-using namespace android::os::statsd;
-using std::vector;
-
-#ifdef __ANDROID__
-
-TEST(ConditionTrackerTest, TestUnknownCondition) {
-    LogicalOperation operation = LogicalOperation::AND;
-
-    vector<int> children;
-    children.push_back(0);
-    children.push_back(1);
-    children.push_back(2);
-
-    vector<ConditionState> conditionResults;
-    conditionResults.push_back(ConditionState::kUnknown);
-    conditionResults.push_back(ConditionState::kFalse);
-    conditionResults.push_back(ConditionState::kTrue);
-
-    EXPECT_EQ(evaluateCombinationCondition(children, operation, conditionResults),
-              ConditionState::kUnknown);
-}
-
-TEST(ConditionTrackerTest, TestAndCondition) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::AND;
-
-    vector<int> children;
-    children.push_back(0);
-    children.push_back(1);
-    children.push_back(2);
-
-    vector<ConditionState> conditionResults;
-    conditionResults.push_back(ConditionState::kTrue);
-    conditionResults.push_back(ConditionState::kFalse);
-    conditionResults.push_back(ConditionState::kTrue);
-
-    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-
-    conditionResults.clear();
-    conditionResults.push_back(ConditionState::kTrue);
-    conditionResults.push_back(ConditionState::kTrue);
-    conditionResults.push_back(ConditionState::kTrue);
-
-    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-TEST(ConditionTrackerTest, TestOrCondition) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::OR;
-
-    vector<int> children;
-    children.push_back(0);
-    children.push_back(1);
-    children.push_back(2);
-
-    vector<ConditionState> conditionResults;
-    conditionResults.push_back(ConditionState::kTrue);
-    conditionResults.push_back(ConditionState::kFalse);
-    conditionResults.push_back(ConditionState::kTrue);
-
-    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
-    conditionResults.clear();
-    conditionResults.push_back(ConditionState::kFalse);
-    conditionResults.push_back(ConditionState::kFalse);
-    conditionResults.push_back(ConditionState::kFalse);
-
-    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-TEST(ConditionTrackerTest, TestNotCondition) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::NOT;
-
-    vector<int> children;
-    children.push_back(0);
-
-    vector<ConditionState> conditionResults;
-    conditionResults.push_back(ConditionState::kTrue);
-
-    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-
-    conditionResults.clear();
-    conditionResults.push_back(ConditionState::kFalse);
-    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
-    children.clear();
-    conditionResults.clear();
-    EXPECT_EQ(evaluateCombinationCondition(children, operation, conditionResults),
-              ConditionState::kUnknown);
-}
-
-TEST(ConditionTrackerTest, TestNandCondition) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::NAND;
-
-    vector<int> children;
-    children.push_back(0);
-    children.push_back(1);
-
-    vector<ConditionState> conditionResults;
-    conditionResults.push_back(ConditionState::kTrue);
-    conditionResults.push_back(ConditionState::kFalse);
-
-    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
-    conditionResults.clear();
-    conditionResults.push_back(ConditionState::kFalse);
-    conditionResults.push_back(ConditionState::kFalse);
-    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
-    conditionResults.clear();
-    conditionResults.push_back(ConditionState::kTrue);
-    conditionResults.push_back(ConditionState::kTrue);
-    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-TEST(ConditionTrackerTest, TestNorCondition) {
-    // Set up the matcher
-    LogicalOperation operation = LogicalOperation::NOR;
-
-    vector<int> children;
-    children.push_back(0);
-    children.push_back(1);
-
-    vector<ConditionState> conditionResults;
-    conditionResults.push_back(ConditionState::kTrue);
-    conditionResults.push_back(ConditionState::kFalse);
-
-    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-
-    conditionResults.clear();
-    conditionResults.push_back(ConditionState::kFalse);
-    conditionResults.push_back(ConditionState::kFalse);
-    EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
-
-    conditionResults.clear();
-    conditionResults.push_back(ConditionState::kTrue);
-    conditionResults.push_back(ConditionState::kTrue);
-    EXPECT_FALSE(evaluateCombinationCondition(children, operation, conditionResults));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/condition/ConditionTimer_test.cpp b/cmds/statsd/tests/condition/ConditionTimer_test.cpp
deleted file mode 100644
index 46dc9a9..0000000
--- a/cmds/statsd/tests/condition/ConditionTimer_test.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (C) 2019 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.
-
-#include "src/condition/ConditionTimer.h"
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-static int64_t time_base = 10;
-static int64_t ct_start_time = 200;
-
-TEST(ConditionTimerTest, TestTimer_Inital_False) {
-    ConditionTimer timer(false, time_base);
-    EXPECT_EQ(false, timer.mCondition);
-    EXPECT_EQ(0, timer.mTimerNs);
-
-    EXPECT_EQ(0, timer.newBucketStart(ct_start_time));
-    EXPECT_EQ(0, timer.mTimerNs);
-
-    timer.onConditionChanged(true, ct_start_time + 5);
-    EXPECT_EQ(ct_start_time + 5, timer.mLastConditionChangeTimestampNs);
-    EXPECT_EQ(true, timer.mCondition);
-
-    EXPECT_EQ(95, timer.newBucketStart(ct_start_time + 100));
-    EXPECT_EQ(ct_start_time + 100, timer.mLastConditionChangeTimestampNs);
-    EXPECT_EQ(true, timer.mCondition);
-}
-
-TEST(ConditionTimerTest, TestTimer_Inital_True) {
-    ConditionTimer timer(true, time_base);
-    EXPECT_EQ(true, timer.mCondition);
-    EXPECT_EQ(0, timer.mTimerNs);
-
-    EXPECT_EQ(ct_start_time - time_base, timer.newBucketStart(ct_start_time));
-    EXPECT_EQ(true, timer.mCondition);
-    EXPECT_EQ(0, timer.mTimerNs);
-    EXPECT_EQ(ct_start_time, timer.mLastConditionChangeTimestampNs);
-
-    timer.onConditionChanged(false, ct_start_time + 5);
-    EXPECT_EQ(5, timer.mTimerNs);
-
-    EXPECT_EQ(5, timer.newBucketStart(ct_start_time + 100));
-    EXPECT_EQ(0, timer.mTimerNs);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
deleted file mode 100644
index 8998b5f..0000000
--- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
+++ /dev/null
@@ -1,741 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/condition/SimpleConditionTracker.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <vector>
-#include <numeric>
-
-using std::map;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-
-const int ATTRIBUTION_NODE_FIELD_ID = 1;
-const int ATTRIBUTION_UID_FIELD_ID = 1;
-const int TAG_ID = 1;
-const uint64_t protoHash = 0x123456789;
-
-SimplePredicate getWakeLockHeldCondition(bool countNesting, bool defaultFalse,
-                                         bool outputSlicedUid, Position position) {
-    SimplePredicate simplePredicate;
-    simplePredicate.set_start(StringToId("WAKE_LOCK_ACQUIRE"));
-    simplePredicate.set_stop(StringToId("WAKE_LOCK_RELEASE"));
-    simplePredicate.set_stop_all(StringToId("RELEASE_ALL"));
-    if (outputSlicedUid) {
-        simplePredicate.mutable_dimensions()->set_field(TAG_ID);
-        simplePredicate.mutable_dimensions()->add_child()->set_field(ATTRIBUTION_NODE_FIELD_ID);
-        simplePredicate.mutable_dimensions()->mutable_child(0)->set_position(position);
-        simplePredicate.mutable_dimensions()->mutable_child(0)->add_child()->set_field(
-            ATTRIBUTION_UID_FIELD_ID);
-    }
-
-    simplePredicate.set_count_nesting(countNesting);
-    simplePredicate.set_initial_value(defaultFalse ? SimplePredicate_InitialValue_FALSE
-                                                       : SimplePredicate_InitialValue_UNKNOWN);
-    return simplePredicate;
-}
-
-void makeWakeLockEvent(LogEvent* logEvent, uint32_t atomId, uint64_t timestamp,
-                       const vector<int>& uids, const string& wl, int acquire) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
-
-    vector<std::string> tags(uids.size()); // vector of empty strings
-    writeAttribution(statsEvent, uids, tags);
-
-    AStatsEvent_writeString(statsEvent, wl.c_str());
-    AStatsEvent_writeInt32(statsEvent, acquire);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-} // anonymous namespace
-
-
-std::map<int64_t, HashableDimensionKey> getWakeLockQueryKey(
-    const Position position,
-    const std::vector<int> &uids, const string& conditionName) {
-    std::map<int64_t, HashableDimensionKey> outputKeyMap;
-    std::vector<int> uid_indexes;
-    int pos[] = {1, 1, 1};
-    int depth = 2;
-    Field field(1, pos, depth);
-    switch(position) {
-        case Position::FIRST:
-            uid_indexes.push_back(0);
-            break;
-        case Position::LAST:
-            uid_indexes.push_back(uids.size() - 1);
-            field.setField(0x02018001);
-            break;
-        case Position::ANY:
-            uid_indexes.resize(uids.size());
-            std::iota(uid_indexes.begin(), uid_indexes.end(), 0);
-            field.setField(0x02010001);
-            break;
-        default:
-            break;
-    }
-
-    for (const int idx : uid_indexes) {
-        Value value((int32_t)uids[idx]);
-        HashableDimensionKey dim;
-        dim.addValue(FieldValue(field, value));
-        outputKeyMap[StringToId(conditionName)] = dim;
-    }
-    return outputKeyMap;
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedInitialValueFalse) {
-    SimplePredicate simplePredicate;
-    simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
-    simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
-    simplePredicate.set_count_nesting(false);
-    simplePredicate.set_initial_value(SimplePredicate_InitialValue_FALSE);
-
-    unordered_map<int64_t, int> trackerNameIndexMap;
-    trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
-    trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
-    SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), protoHash,
-                                            0 /*tracker index*/, simplePredicate,
-                                            trackerNameIndexMap);
-
-    ConditionKey queryKey;
-    vector<sp<ConditionTracker>> allPredicates;
-    vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-
-    // Check that initial condition is false.
-    conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-
-    vector<MatchingState> matcherState;
-    vector<bool> changedCache(1, false);
-
-    // Matched stop event.
-    // Check that condition is still false.
-    unique_ptr<LogEvent> screenOffEvent =
-            CreateScreenStateChangedEvent(/*timestamp=*/50, android::view::DISPLAY_STATE_OFF);
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kNotMatched);  // On matcher not matched
-    matcherState.push_back(MatchingState::kMatched);     // Off matcher matched
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    conditionTracker.evaluateCondition(*screenOffEvent, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-    EXPECT_FALSE(changedCache[0]);
-
-    // Matched start event.
-    // Check that condition has changed to true.
-    unique_ptr<LogEvent> screenOnEvent =
-            CreateScreenStateChangedEvent(/*timestamp=*/100, android::view::DISPLAY_STATE_ON);
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kMatched);     // On matcher matched
-    matcherState.push_back(MatchingState::kNotMatched);  // Off matcher not matched
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-    conditionTracker.evaluateCondition(*screenOnEvent, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-    EXPECT_TRUE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedInitialValueUnknown) {
-    SimplePredicate simplePredicate;
-    simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
-    simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
-    simplePredicate.set_count_nesting(false);
-    simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN);
-
-    unordered_map<int64_t, int> trackerNameIndexMap;
-    trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
-    trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
-    SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), protoHash,
-                                            0 /*tracker index*/, simplePredicate,
-                                            trackerNameIndexMap);
-
-    ConditionKey queryKey;
-    vector<sp<ConditionTracker>> allPredicates;
-    vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-
-    // Check that initial condition is unknown.
-    conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-    EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
-
-    vector<MatchingState> matcherState;
-    vector<bool> changedCache(1, false);
-
-    // Matched stop event.
-    // Check that condition is changed to false.
-    unique_ptr<LogEvent> screenOffEvent =
-            CreateScreenStateChangedEvent(/*timestamp=*/50, android::view::DISPLAY_STATE_OFF);
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kNotMatched);  // On matcher not matched
-    matcherState.push_back(MatchingState::kMatched);     // Off matcher matched
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    conditionTracker.evaluateCondition(*screenOffEvent, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-    EXPECT_TRUE(changedCache[0]);
-
-    // Matched start event.
-    // Check that condition has changed to true.
-    unique_ptr<LogEvent> screenOnEvent =
-            CreateScreenStateChangedEvent(/*timestamp=*/100, android::view::DISPLAY_STATE_ON);
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kMatched);     // On matcher matched
-    matcherState.push_back(MatchingState::kNotMatched);  // Off matcher not matched
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-    conditionTracker.evaluateCondition(*screenOnEvent, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-    EXPECT_TRUE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedCondition) {
-    SimplePredicate simplePredicate;
-    simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
-    simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
-    simplePredicate.set_count_nesting(false);
-    simplePredicate.set_initial_value(SimplePredicate_InitialValue_UNKNOWN);
-
-    unordered_map<int64_t, int> trackerNameIndexMap;
-    trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
-    trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
-    SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), protoHash,
-                                            0 /*tracker index*/, simplePredicate,
-                                            trackerNameIndexMap);
-    EXPECT_FALSE(conditionTracker.isSliced());
-
-    // This event is not accessed in this test besides dimensions which is why this is okay.
-    // This is technically an invalid LogEvent because we do not call parseBuffer.
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-
-    vector<MatchingState> matcherState;
-    matcherState.push_back(MatchingState::kNotMatched);
-    matcherState.push_back(MatchingState::kNotMatched);
-
-    vector<sp<ConditionTracker>> allPredicates;
-    vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-    vector<bool> changedCache(1, false);
-
-    conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    // not matched start or stop. condition doesn't change
-    EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
-    EXPECT_FALSE(changedCache[0]);
-
-    // prepare a case for match start.
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kMatched);
-    matcherState.push_back(MatchingState::kNotMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-
-    conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    // now condition should change to true.
-    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-    EXPECT_TRUE(changedCache[0]);
-
-    // match nothing.
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kNotMatched);
-    matcherState.push_back(MatchingState::kNotMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-
-    conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-    EXPECT_FALSE(changedCache[0]);
-
-    // the case for match stop.
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kNotMatched);
-    matcherState.push_back(MatchingState::kMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-
-    conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-
-    // condition changes to false.
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-    EXPECT_TRUE(changedCache[0]);
-
-    // match stop again.
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kNotMatched);
-    matcherState.push_back(MatchingState::kMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-
-    conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    // condition should still be false. not changed.
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-    EXPECT_FALSE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestNonSlicedConditionNestCounting) {
-    std::vector<sp<ConditionTracker>> allConditions;
-    SimplePredicate simplePredicate;
-    simplePredicate.set_start(StringToId("SCREEN_TURNED_ON"));
-    simplePredicate.set_stop(StringToId("SCREEN_TURNED_OFF"));
-    simplePredicate.set_count_nesting(true);
-
-    unordered_map<int64_t, int> trackerNameIndexMap;
-    trackerNameIndexMap[StringToId("SCREEN_TURNED_ON")] = 0;
-    trackerNameIndexMap[StringToId("SCREEN_TURNED_OFF")] = 1;
-
-    SimpleConditionTracker conditionTracker(kConfigKey, StringToId("SCREEN_IS_ON"), protoHash,
-                                            0 /*condition tracker index*/, simplePredicate,
-                                            trackerNameIndexMap);
-    EXPECT_FALSE(conditionTracker.isSliced());
-
-    // This event is not accessed in this test besides dimensions which is why this is okay.
-    // This is technically an invalid LogEvent because we do not call parseBuffer.
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-
-    // one matched start
-    vector<MatchingState> matcherState;
-    matcherState.push_back(MatchingState::kMatched);
-    matcherState.push_back(MatchingState::kNotMatched);
-    vector<sp<ConditionTracker>> allPredicates;
-    vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-    vector<bool> changedCache(1, false);
-
-    conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-
-    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-    EXPECT_TRUE(changedCache[0]);
-
-    // prepare for another matched start.
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kMatched);
-    matcherState.push_back(MatchingState::kNotMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-
-    conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-
-    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-    EXPECT_FALSE(changedCache[0]);
-
-    // ONE MATCHED STOP
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kNotMatched);
-    matcherState.push_back(MatchingState::kMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-
-    conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    // result should still be true
-    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-    EXPECT_FALSE(changedCache[0]);
-
-    // ANOTHER MATCHED STOP
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kNotMatched);
-    matcherState.push_back(MatchingState::kMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-
-    conditionTracker.evaluateCondition(event, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-    EXPECT_TRUE(changedCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestSlicedCondition) {
-    std::vector<sp<ConditionTracker>> allConditions;
-    for (Position position : {Position::FIRST, Position::LAST}) {
-        SimplePredicate simplePredicate = getWakeLockHeldCondition(
-                true /*nesting*/, true /*default to false*/, true /*output slice by uid*/,
-                position);
-        string conditionName = "WL_HELD_BY_UID2";
-
-        unordered_map<int64_t, int> trackerNameIndexMap;
-        trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
-        trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
-        trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
-
-        SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName), protoHash,
-                                                0 /*condition tracker index*/, simplePredicate,
-                                                trackerNameIndexMap);
-
-        std::vector<int> uids = {111, 222, 333};
-
-        LogEvent event1(/*uid=*/0, /*pid=*/0);
-        makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/1);
-
-        // one matched start
-        vector<MatchingState> matcherState;
-        matcherState.push_back(MatchingState::kMatched);
-        matcherState.push_back(MatchingState::kNotMatched);
-        matcherState.push_back(MatchingState::kNotMatched);
-        vector<sp<ConditionTracker>> allPredicates;
-        vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-        vector<bool> changedCache(1, false);
-
-        conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
-                                           changedCache);
-
-        if (position == Position::FIRST || position == Position::LAST) {
-            ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
-        } else {
-            ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
-        }
-        EXPECT_TRUE(changedCache[0]);
-        if (position == Position::FIRST || position == Position::LAST) {
-            ASSERT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), 1u);
-            EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-        } else {
-            EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(),
-                      uids.size());
-        }
-
-        // Now test query
-        const auto queryKey = getWakeLockQueryKey(position, uids, conditionName);
-        conditionCache[0] = ConditionState::kNotEvaluated;
-
-        conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-        EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
-        // another wake lock acquired by this uid
-        LogEvent event2(/*uid=*/0, /*pid=*/0);
-        makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/1);
-        matcherState.clear();
-        matcherState.push_back(MatchingState::kMatched);
-        matcherState.push_back(MatchingState::kNotMatched);
-        conditionCache[0] = ConditionState::kNotEvaluated;
-        changedCache[0] = false;
-        conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
-                                           changedCache);
-        EXPECT_FALSE(changedCache[0]);
-        if (position == Position::FIRST || position == Position::LAST) {
-            ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
-        } else {
-            ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
-        }
-        EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
-        EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-
-
-        // wake lock 1 release
-        LogEvent event3(/*uid=*/0, /*pid=*/0);
-        makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids, "wl1", /*acquire=*/0);
-        matcherState.clear();
-        matcherState.push_back(MatchingState::kNotMatched);
-        matcherState.push_back(MatchingState::kMatched);
-        conditionCache[0] = ConditionState::kNotEvaluated;
-        changedCache[0] = false;
-        conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
-                                           changedCache);
-        // nothing changes, because wake lock 2 is still held for this uid
-        EXPECT_FALSE(changedCache[0]);
-        if (position == Position::FIRST || position == Position::LAST) {
-            ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
-        } else {
-            ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
-        }
-        EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
-        EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-
-        LogEvent event4(/*uid=*/0, /*pid=*/0);
-        makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids, "wl2", /*acquire=*/0);
-        matcherState.clear();
-        matcherState.push_back(MatchingState::kNotMatched);
-        matcherState.push_back(MatchingState::kMatched);
-        conditionCache[0] = ConditionState::kNotEvaluated;
-        changedCache[0] = false;
-        conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
-                                           changedCache);
-        ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
-        EXPECT_TRUE(changedCache[0]);
-        if (position == Position::FIRST || position == Position::LAST) {
-            ASSERT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), 1u);
-            EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
-        } else {
-            EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(),
-                      uids.size());
-        }
-
-        // query again
-        conditionCache[0] = ConditionState::kNotEvaluated;
-        conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-        EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-    }
-
-}
-
-TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim) {
-    std::vector<sp<ConditionTracker>> allConditions;
-
-    SimplePredicate simplePredicate =
-            getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
-                                     false /*slice output by uid*/, Position::ANY /* position */);
-    string conditionName = "WL_HELD";
-
-    unordered_map<int64_t, int> trackerNameIndexMap;
-    trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
-    trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
-    trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
-
-    SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName), protoHash,
-                                            0 /*condition tracker index*/, simplePredicate,
-                                            trackerNameIndexMap);
-
-    EXPECT_FALSE(conditionTracker.isSliced());
-
-    std::vector<int> uids1 = {111, 1111, 11111};
-    string uid1_wl1 = "wl1_1";
-    std::vector<int> uids2 = {222, 2222, 22222};
-    string uid2_wl1 = "wl2_1";
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1, /*acquire=*/1);
-
-    // one matched start for uid1
-    vector<MatchingState> matcherState;
-    matcherState.push_back(MatchingState::kMatched);
-    matcherState.push_back(MatchingState::kNotMatched);
-    matcherState.push_back(MatchingState::kNotMatched);
-    vector<sp<ConditionTracker>> allPredicates;
-    vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-    vector<bool> changedCache(1, false);
-
-    conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-
-    ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
-    EXPECT_TRUE(changedCache[0]);
-
-    // Now test query
-    ConditionKey queryKey;
-    conditionCache[0] = ConditionState::kNotEvaluated;
-
-    conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
-    EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
-    // another wake lock acquired by this uid
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1, /*acquire=*/1);
-
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kMatched);
-    matcherState.push_back(MatchingState::kNotMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-    conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    EXPECT_FALSE(changedCache[0]);
-
-    // uid1 wake lock 1 release
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids1, uid1_wl1,
-                      /*release=*/0);  // now release it.
-
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kNotMatched);
-    matcherState.push_back(MatchingState::kMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-    conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    // nothing changes, because uid2 is still holding wl.
-    EXPECT_FALSE(changedCache[0]);
-
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    makeWakeLockEvent(&event4, /*atomId=*/1, /*timestamp=*/0, uids2, uid2_wl1,
-                      /*acquire=*/0);  // now release it.
-    matcherState.clear();
-    matcherState.push_back(MatchingState::kNotMatched);
-    matcherState.push_back(MatchingState::kMatched);
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    changedCache[0] = false;
-    conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
-                                       changedCache);
-    ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
-    EXPECT_TRUE(changedCache[0]);
-
-    // query again
-    conditionCache[0] = ConditionState::kNotEvaluated;
-    conditionTracker.isConditionMet(queryKey, allPredicates, true, conditionCache);
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-}
-
-TEST(SimpleConditionTrackerTest, TestStopAll) {
-    std::vector<sp<ConditionTracker>> allConditions;
-    for (Position position : {Position::FIRST, Position::LAST}) {
-        SimplePredicate simplePredicate =
-                getWakeLockHeldCondition(true /*nesting*/, true /*default to false*/,
-                                         true /*output slice by uid*/, position);
-        string conditionName = "WL_HELD_BY_UID3";
-
-        unordered_map<int64_t, int> trackerNameIndexMap;
-        trackerNameIndexMap[StringToId("WAKE_LOCK_ACQUIRE")] = 0;
-        trackerNameIndexMap[StringToId("WAKE_LOCK_RELEASE")] = 1;
-        trackerNameIndexMap[StringToId("RELEASE_ALL")] = 2;
-
-        SimpleConditionTracker conditionTracker(kConfigKey, StringToId(conditionName), protoHash,
-                                                0 /*condition tracker index*/, simplePredicate,
-                                                trackerNameIndexMap);
-
-        std::vector<int> uids1 = {111, 1111, 11111};
-        std::vector<int> uids2 = {222, 2222, 22222};
-
-        LogEvent event1(/*uid=*/0, /*pid=*/0);
-        makeWakeLockEvent(&event1, /*atomId=*/1, /*timestamp=*/0, uids1, "wl1", /*acquire=*/1);
-
-        // one matched start
-        vector<MatchingState> matcherState;
-        matcherState.push_back(MatchingState::kMatched);
-        matcherState.push_back(MatchingState::kNotMatched);
-        matcherState.push_back(MatchingState::kNotMatched);
-        vector<sp<ConditionTracker>> allPredicates;
-        vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated);
-        vector<bool> changedCache(1, false);
-
-        conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
-                                           changedCache);
-        if (position == Position::FIRST || position == Position::LAST) {
-            ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
-        } else {
-            ASSERT_EQ(uids1.size(), conditionTracker.mSlicedConditionState.size());
-        }
-        EXPECT_TRUE(changedCache[0]);
-        {
-            if (position == Position::FIRST || position == Position::LAST) {
-                ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
-                EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-            } else {
-                EXPECT_EQ(uids1.size(),
-                          conditionTracker.getChangedToTrueDimensions(allConditions)->size());
-                EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-            }
-        }
-
-        // Now test query
-        const auto queryKey = getWakeLockQueryKey(position, uids1, conditionName);
-        conditionCache[0] = ConditionState::kNotEvaluated;
-
-        conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-        EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
-        // another wake lock acquired by uid2
-        LogEvent event2(/*uid=*/0, /*pid=*/0);
-        makeWakeLockEvent(&event2, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
-
-        matcherState.clear();
-        matcherState.push_back(MatchingState::kMatched);
-        matcherState.push_back(MatchingState::kNotMatched);
-        matcherState.push_back(MatchingState::kNotMatched);
-        conditionCache[0] = ConditionState::kNotEvaluated;
-        changedCache[0] = false;
-        conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
-                                           changedCache);
-        if (position == Position::FIRST || position == Position::LAST) {
-            ASSERT_EQ(2UL, conditionTracker.mSlicedConditionState.size());
-        } else {
-            ASSERT_EQ(uids1.size() + uids2.size(), conditionTracker.mSlicedConditionState.size());
-        }
-        EXPECT_TRUE(changedCache[0]);
-        {
-            if (position == Position::FIRST || position == Position::LAST) {
-                ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
-                EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-            } else {
-                EXPECT_EQ(uids2.size(),
-                          conditionTracker.getChangedToTrueDimensions(allConditions)->size());
-                EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
-            }
-        }
-
-        // TEST QUERY
-        const auto queryKey2 = getWakeLockQueryKey(position, uids2, conditionName);
-        conditionCache[0] = ConditionState::kNotEvaluated;
-        conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-
-        EXPECT_EQ(ConditionState::kTrue, conditionCache[0]);
-
-        // stop all event
-        LogEvent event3(/*uid=*/0, /*pid=*/0);
-        makeWakeLockEvent(&event3, /*atomId=*/1, /*timestamp=*/0, uids2, "wl2", /*acquire=*/1);
-
-        matcherState.clear();
-        matcherState.push_back(MatchingState::kNotMatched);
-        matcherState.push_back(MatchingState::kNotMatched);
-        matcherState.push_back(MatchingState::kMatched);
-
-        conditionCache[0] = ConditionState::kNotEvaluated;
-        changedCache[0] = false;
-        conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
-                                           changedCache);
-        EXPECT_TRUE(changedCache[0]);
-        ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
-        {
-            if (position == Position::FIRST || position == Position::LAST) {
-                ASSERT_EQ(2UL, conditionTracker.getChangedToFalseDimensions(allConditions)->size());
-                EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
-            } else {
-                EXPECT_EQ(uids1.size() + uids2.size(),
-                          conditionTracker.getChangedToFalseDimensions(allConditions)->size());
-                EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
-            }
-        }
-
-        // TEST QUERY
-        const auto queryKey3 = getWakeLockQueryKey(position, uids1, conditionName);
-        conditionCache[0] = ConditionState::kNotEvaluated;
-        conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-        EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-
-        // TEST QUERY
-        const auto queryKey4 = getWakeLockQueryKey(position, uids2, conditionName);
-        conditionCache[0] = ConditionState::kNotEvaluated;
-        conditionTracker.isConditionMet(queryKey, allPredicates, false, conditionCache);
-        EXPECT_EQ(ConditionState::kFalse, conditionCache[0]);
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp b/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
deleted file mode 100644
index 93b2783..0000000
--- a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (C) 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.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
-    auto alarm = config.add_alarm();
-    alarm->set_id(123456);
-    alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(TEN_MINUTES));
-    alarm->set_period_millis(TimeUnitToBucketSizeInMillis(ONE_HOUR));
-
-    alarm = config.add_alarm();
-    alarm->set_id(654321);
-    alarm->set_offset_millis(TimeUnitToBucketSizeInMillis(FIVE_MINUTES));
-    alarm->set_period_millis(TimeUnitToBucketSizeInMillis(THIRTY_MINUTES));
-    return config;
-}
-
-}  // namespace
-
-TEST(AlarmE2eTest, TestMultipleAlarms) {
-    auto config = CreateStatsdConfig();
-    int64_t bucketStartTimeNs = 10000000000;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    ASSERT_EQ(2u, processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers.size());
-
-    auto alarmTracker1 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[0];
-    auto alarmTracker2 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[1];
-
-    int64_t alarmTimestampSec0 = bucketStartTimeNs / NS_PER_SEC + 10 * 60;
-    int64_t alarmTimestampSec1 = bucketStartTimeNs / NS_PER_SEC + 5 * 60;
-    EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec());
-    EXPECT_EQ(alarmTimestampSec1, alarmTracker2->getAlarmTimestampSec());
-
-    // Alarm fired.
-    const int64_t alarmFiredTimestampSec0 = alarmTimestampSec1 + 5;
-    auto alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
-            static_cast<uint32_t>(alarmFiredTimestampSec0));
-    ASSERT_EQ(1u, alarmSet.size());
-    processor->onPeriodicAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
-    EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec());
-    EXPECT_EQ(alarmTimestampSec1 + 30 * 60, alarmTracker2->getAlarmTimestampSec());
-
-    // Alarms fired very late.
-    const int64_t alarmFiredTimestampSec1 = alarmTimestampSec0 + 2 * 60 * 60 + 125;
-    alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
-            static_cast<uint32_t>(alarmFiredTimestampSec1));
-    ASSERT_EQ(2u, alarmSet.size());
-    processor->onPeriodicAlarmFired(alarmFiredTimestampSec1 * NS_PER_SEC, alarmSet);
-    EXPECT_EQ(alarmTimestampSec0 + 60 * 60 * 3, alarmTracker1->getAlarmTimestampSec());
-    EXPECT_EQ(alarmTimestampSec1 + 30 * 60 * 5, alarmTracker2->getAlarmTimestampSec());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
deleted file mode 100644
index af9436b..0000000
--- a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright (C) 2018 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.
-
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(int num_buckets, int threshold, int refractory_period_sec) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-
-    *config.add_atom_matcher() = wakelockAcquireMatcher;
-
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(123456);
-    countMetric->set_what(wakelockAcquireMatcher.id());
-    *countMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
-            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    countMetric->set_bucket(FIVE_MINUTES);
-
-    auto alert = config.add_alert();
-    alert->set_id(StringToId("alert"));
-    alert->set_metric_id(123456);
-    alert->set_num_buckets(num_buckets);
-    alert->set_refractory_period_secs(refractory_period_sec);
-    alert->set_trigger_if_sum_gt(threshold);
-    return config;
-}
-
-}  // namespace
-
-TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket) {
-    const int num_buckets = 1;
-    const int threshold = 3;
-    const int refractory_period_sec = 10;
-    auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
-    const uint64_t alert_id = config.alert(0).id();
-
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
-    sp<AnomalyTracker> anomalyTracker =
-            processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
-    std::vector<int> attributionUids1 = {111};
-    std::vector<string> attributionTags1 = {"App1"};
-    std::vector<int> attributionUids2 = {111, 222};
-    std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-    std::vector<int> attributionUids3 = {111, 333};
-    std::vector<string> attributionTags3 = {"App1", "App3"};
-    std::vector<int> attributionUids4 = {222, 333};
-    std::vector<string> attributionTags4 = {"GMSCoreModule1", "App3"};
-    std::vector<int> attributionUids5 = {222};
-    std::vector<string> attributionTags5 = {"GMSCoreModule1"};
-
-    FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
-                           Value((int32_t)111));
-    HashableDimensionKey whatKey1({fieldValue1});
-    MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
-    FieldValue fieldValue2(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
-                           Value((int32_t)222));
-    HashableDimensionKey whatKey2({fieldValue2});
-    MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
-
-    auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
-                                            attributionTags1, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids4, attributionTags4,
-                                       "wl2");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids2, attributionTags2,
-                                       "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids5, attributionTags5,
-                                       "wl2");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids3, attributionTags3,
-                                       "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids5, attributionTags5,
-                                       "wl2");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
-    // Fired alarm and refractory period end timestamp updated.
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 5, attributionUids1, attributionTags1,
-                                       "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 100, attributionUids1, attributionTags1,
-                                       "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + bucketStartTimeNs / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1, attributionUids1,
-                                       attributionTags1, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids1,
-                                       attributionTags1, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs - 1) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids4,
-                                       attributionTags4, "wl2");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids5,
-                                       attributionTags5, "wl2");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 3, attributionUids5,
-                                       attributionTags5, "wl2");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 4, attributionUids5,
-                                       attributionTags5, "wl2");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 4) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-}
-
-TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets) {
-    const int num_buckets = 3;
-    const int threshold = 3;
-    const int refractory_period_sec = 10;
-    auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
-    const uint64_t alert_id = config.alert(0).id();
-
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
-    sp<AnomalyTracker> anomalyTracker =
-            processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
-    std::vector<int> attributionUids1 = {111};
-    std::vector<string> attributionTags1 = {"App1"};
-    std::vector<int> attributionUids2 = {111, 222};
-    std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-
-    FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
-                           Value((int32_t)111));
-    HashableDimensionKey whatKey1({fieldValue1});
-    MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
-    auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
-                                            attributionTags1, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3, attributionUids2, attributionTags2,
-                                       "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Fired alarm and refractory period end timestamp updated.
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 4, attributionUids1, attributionTags1,
-                                       "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 1, attributionUids1,
-                                       attributionTags1, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids2,
-                                       attributionTags2, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1, attributionUids2,
-                                       attributionTags2, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + 1) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 2, attributionUids2,
-                                       attributionTags2, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 3 * bucketSizeNs + 2) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-}
-
-TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written) {
-    const int num_buckets = 1;
-    const int threshold = 0;
-    const int refractory_period_sec = 86400 * 365; // 1 year
-    auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
-    const int64_t alert_id = config.alert(0).id();
-
-    int64_t bucketStartTimeNs = 10000000000;
-
-    int configUid = 2000;
-    int64_t configId = 1000;
-    ConfigKey cfgKey(configUid, configId);
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
-    metadata::StatsMetadataList result;
-    int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
-    int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
-    processor->WriteMetadataToProto(mockWallClockNs, mockElapsedTimeNs, &result);
-
-    ASSERT_EQ(result.stats_metadata_size(), 0);
-}
-
-TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk) {
-    const int num_buckets = 1;
-    const int threshold = 0;
-    const int refractory_period_sec = 86400 * 365; // 1 year
-    auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
-    const int64_t alert_id = config.alert(0).id();
-
-    int64_t bucketStartTimeNs = 10000000000;
-
-    int configUid = 2000;
-    int64_t configId = 1000;
-    ConfigKey cfgKey(configUid, configId);
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
-    sp<AnomalyTracker> anomalyTracker =
-            processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
-    std::vector<int> attributionUids1 = {111};
-    std::vector<string> attributionTags1 = {"App1"};
-    std::vector<int> attributionUids2 = {111, 222};
-    std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-
-    FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
-                           Value((int32_t)111));
-    HashableDimensionKey whatKey1({fieldValue1});
-    MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
-    auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
-                                            attributionTags1, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 2) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    metadata::StatsMetadataList result;
-    int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
-    int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
-    processor->WriteMetadataToProto(mockWallClockNs, mockElapsedTimeNs, &result);
-
-    metadata::StatsMetadata statsMetadata = result.stats_metadata(0);
-    ASSERT_EQ(result.stats_metadata_size(), 1);
-    EXPECT_EQ(statsMetadata.config_key().config_id(), configId);
-    EXPECT_EQ(statsMetadata.config_key().uid(), configUid);
-
-    metadata::AlertMetadata alertMetadata = statsMetadata.alert_metadata(0);
-    ASSERT_EQ(statsMetadata.alert_metadata_size(), 1);
-    EXPECT_EQ(alertMetadata.alert_id(), alert_id);
-    metadata::AlertDimensionKeyedData keyedData = alertMetadata.alert_dim_keyed_data(0);
-    ASSERT_EQ(alertMetadata.alert_dim_keyed_data_size(), 1);
-    EXPECT_EQ(keyedData.last_refractory_ends_sec(),
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1) -
-              mockElapsedTimeNs / NS_PER_SEC +
-              mockWallClockNs / NS_PER_SEC);
-
-    metadata::MetricDimensionKey metadataDimKey = keyedData.dimension_key();
-    metadata::FieldValue dimKeyInWhat = metadataDimKey.dimension_key_in_what(0);
-    EXPECT_EQ(dimKeyInWhat.field().tag(), fieldValue1.mField.getTag());
-    EXPECT_EQ(dimKeyInWhat.field().field(), fieldValue1.mField.getField());
-    EXPECT_EQ(dimKeyInWhat.value_int(), fieldValue1.mValue.int_value);
-}
-
-TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk) {
-    const int num_buckets = 1;
-    const int threshold = 0;
-    const int refractory_period_sec = 86400 * 365; // 1 year
-    auto config = CreateStatsdConfig(num_buckets, threshold, refractory_period_sec);
-    const int64_t alert_id = config.alert(0).id();
-
-    int64_t bucketStartTimeNs = 10000000000;
-
-    int configUid = 2000;
-    int64_t configId = 1000;
-    ConfigKey cfgKey(configUid, configId);
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
-    sp<AnomalyTracker> anomalyTracker =
-            processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
-    std::vector<int> attributionUids1 = {111};
-    std::vector<string> attributionTags1 = {"App1"};
-    std::vector<int> attributionUids2 = {111, 222};
-    std::vector<string> attributionTags2 = {"App1", "GMSCoreModule1"};
-
-    FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
-                           Value((int32_t)111));
-    HashableDimensionKey whatKey1({fieldValue1});
-    MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
-    auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
-                                            attributionTags1, "wl1");
-    processor->OnLogEvent(event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + 2) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
-    int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
-    processor->SaveMetadataToDisk(mockWallClockNs, mockElapsedTimeNs);
-
-    auto processor2 = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    int64_t mockElapsedTimeSinceBoot = 10 * NS_PER_SEC;
-    processor2->LoadMetadataFromDisk(mockWallClockNs, mockElapsedTimeSinceBoot);
-
-    sp<AnomalyTracker> anomalyTracker2 =
-                processor2->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-    EXPECT_EQ(anomalyTracker2->getRefractoryPeriodEndsSec(dimensionKey1) -
-              mockElapsedTimeSinceBoot / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1) -
-              mockElapsedTimeNs / NS_PER_SEC);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
deleted file mode 100644
index 70e7365..0000000
--- a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright (C) 2018 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.
-
-#include <android/binder_ibinder.h>
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/StatsService.h"
-#include "src/anomaly/DurationAnomalyTracker.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-const int kConfigKey = 789130124;
-const int kCallingUid = 0;
-
-StatsdConfig CreateStatsdConfig(int num_buckets,
-                                uint64_t threshold_ns,
-                                DurationMetric::AggregationType aggregationType,
-                                bool nesting) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
-    auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-    *config.add_predicate() = screenIsOffPredicate;
-
-    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    FieldMatcher dimensions = CreateAttributionUidDimensions(
-            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    dimensions.add_child()->set_field(3);  // The wakelock tag is set in field 3 of the wakelock.
-    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
-    holdingWakelockPredicate.mutable_simple_predicate()->set_count_nesting(nesting);
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("WakelockDuration"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->set_condition(screenIsOffPredicate.id());
-    durationMetric->set_aggregation_type(aggregationType);
-    *durationMetric->mutable_dimensions_in_what() =
-        CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    auto alert = config.add_alert();
-    alert->set_id(StringToId("alert"));
-    alert->set_metric_id(StringToId("WakelockDuration"));
-    alert->set_num_buckets(num_buckets);
-    alert->set_refractory_period_secs(2);
-    alert->set_trigger_if_sum_gt(threshold_ns);
-    return config;
-}
-
-std::vector<int> attributionUids1 = {111, 222};
-std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1"};
-
-std::vector<int> attributionUids2 = {111, 222};
-std::vector<string> attributionTags2 = {"App2", "GMSCoreModule1"};
-
-std::vector<int> attributionUids3 = {222};
-std::vector<string> attributionTags3 = {"GMSCoreModule1"};
-
-MetricDimensionKey dimensionKey1(
-        HashableDimensionKey({FieldValue(Field(util::WAKELOCK_STATE_CHANGED,
-                                               (int32_t)0x02010101),
-                                         Value((int32_t)111))}),
-        DEFAULT_DIMENSION_KEY);
-
-MetricDimensionKey dimensionKey2(
-    HashableDimensionKey({FieldValue(Field(util::WAKELOCK_STATE_CHANGED,
-                                           (int32_t)0x02010101), Value((int32_t)222))}),
-    DEFAULT_DIMENSION_KEY);
-
-void sendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) {
-    string str;
-    config.SerializeToString(&str);
-    std::vector<uint8_t> configAsVec(str.begin(), str.end());
-    service->addConfiguration(kConfigKey, configAsVec, kCallingUid);
-}
-
-}  // namespace
-
-TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket) {
-    const int num_buckets = 1;
-    const uint64_t threshold_ns = NS_PER_SEC;
-    auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
-    const uint64_t alert_id = config.alert(0).id();
-    const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
-
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    sendConfig(service, config);
-
-    auto processor = service->mProcessor;
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
-    int64_t bucketStartTimeNs = processor->mTimeBaseNs;
-    int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
-
-    sp<AnomalyTracker> anomalyTracker =
-            processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
-    auto screen_on_event = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    auto screen_off_event = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 10, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screen_on_event.get());
-    processor->OnLogEvent(screen_off_event.get());
-
-    // Acquire wakelock wl1.
-    auto acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 11, attributionUids1,
-                                                    attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((bucketStartTimeNs + 11 + threshold_ns) / NS_PER_SEC + 1,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Release wakelock wl1. No anomaly detected. Alarm cancelled at the "release" event.
-    auto release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + 101, attributionUids1,
-                                                    attributionTags1, "wl1");
-    processor->OnLogEvent(release_event.get());
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Acquire wakelock wl1 within bucket #0.
-    acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 110, attributionUids2,
-                                               attributionTags2, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((bucketStartTimeNs + 110 + threshold_ns - 90) / NS_PER_SEC + 1,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Release wakelock wl1. One anomaly detected.
-    release_event = CreateReleaseWakelockEvent(bucketStartTimeNs + NS_PER_SEC + 109,
-                                               attributionUids2, attributionTags2, "wl1");
-    processor->OnLogEvent(release_event.get());
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Acquire wakelock wl1.
-    acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + NS_PER_SEC + 112,
-                                               attributionUids1, attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    // Wakelock has been hold longer than the threshold in bucket #0. The alarm is set at the
-    // end of the refractory period.
-    const int64_t alarmFiredTimestampSec0 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + NS_PER_SEC + 109) / NS_PER_SEC + 1,
-              (uint32_t)alarmFiredTimestampSec0);
-    EXPECT_EQ(alarmFiredTimestampSec0,
-              processor->getAnomalyAlarmMonitor()->getRegisteredAlarmTimeSec());
-
-    // Anomaly alarm fired.
-    auto alarmTriggerEvent = CreateBatterySaverOnEvent(alarmFiredTimestampSec0 * NS_PER_SEC);
-    processor->OnLogEvent(alarmTriggerEvent.get(), alarmFiredTimestampSec0 * NS_PER_SEC);
-
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Release wakelock wl1.
-    release_event =
-            CreateReleaseWakelockEvent(alarmFiredTimestampSec0 * NS_PER_SEC + NS_PER_SEC + 1,
-                                       attributionUids1, attributionTags1, "wl1");
-    processor->OnLogEvent(release_event.get());
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    // Within refractory period. No more anomaly detected.
-    EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Acquire wakelock wl1.
-    acquire_event = CreateAcquireWakelockEvent(
-            roundedBucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC - 11, attributionUids2,
-            attributionTags2, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    const int64_t alarmFiredTimestampSec1 = anomalyTracker->getAlarmTimestampSec(dimensionKey1);
-    EXPECT_EQ((bucketStartTimeNs + bucketSizeNs - 5 * NS_PER_SEC) / NS_PER_SEC,
-              (uint64_t)alarmFiredTimestampSec1);
-
-    // Release wakelock wl1.
-    int64_t release_event_time = roundedBucketStartTimeNs + bucketSizeNs - 4 * NS_PER_SEC - 10;
-    release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
-                                               attributionTags2, "wl1");
-    processor->OnLogEvent(release_event.get(), release_event_time);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
-            static_cast<uint32_t>(alarmFiredTimestampSec1));
-    ASSERT_EQ(0u, alarmSet.size());
-
-    // Acquire wakelock wl1 near the end of bucket #0.
-    acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - 2,
-                                               attributionUids1, attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((bucketStartTimeNs + bucketSizeNs) / NS_PER_SEC,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
-    // Release the event at early bucket #1.
-    release_event_time = roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC - 1;
-    release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
-                                               attributionTags1, "wl1");
-    processor->OnLogEvent(release_event.get(), release_event_time);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    // Anomaly detected when stopping the alarm. The refractory period does not change.
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Condition changes to false.
-    screen_on_event =
-            CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 20,
-                                          android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screen_on_event.get());
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
-    acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 30,
-                                               attributionUids2, attributionTags2, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    // The condition is false. Do not start the alarm.
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(refractory_period_sec + (bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Condition turns true.
-    screen_off_event =
-            CreateScreenStateChangedEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC,
-                                          android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screen_off_event.get());
-    EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + threshold_ns) / NS_PER_SEC,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
-    // Condition turns to false.
-    int64_t condition_false_time = bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1;
-    screen_on_event = CreateScreenStateChangedEvent(
-            condition_false_time, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screen_on_event.get(), condition_false_time);
-    // Condition turns to false. Cancelled the alarm.
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    //  Detected one anomaly.
-    EXPECT_EQ(refractory_period_sec +
-                      (bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 1) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Condition turns to true again.
-    screen_off_event =
-            CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 2 * NS_PER_SEC + 2,
-                                          android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screen_off_event.get());
-    EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 2 + 2 + 1,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
-    release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 5 * NS_PER_SEC;
-    release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
-                                               attributionTags2, "wl1");
-    processor->OnLogEvent(release_event.get());
-    EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-}
-
-TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets) {
-    const int num_buckets = 3;
-    const uint64_t threshold_ns = NS_PER_SEC;
-    auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, true);
-    const uint64_t alert_id = config.alert(0).id();
-    const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
-
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    sendConfig(service, config);
-
-    auto processor = service->mProcessor;
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
-    int64_t bucketStartTimeNs = processor->mTimeBaseNs;
-    int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
-
-    sp<AnomalyTracker> anomalyTracker =
-            processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
-    auto screen_off_event = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screen_off_event.get());
-
-    // Acquire wakelock "wc1" in bucket #0.
-    auto acquire_event =
-            CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - NS_PER_SEC / 2 - 1,
-                                       attributionUids1, attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 1,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Release wakelock "wc1" in bucket #0.
-    int64_t release_event_time = roundedBucketStartTimeNs + bucketSizeNs - 1;
-    auto release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
-                                                    attributionTags1, "wl1");
-    processor->OnLogEvent(release_event.get(), release_event_time);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Acquire wakelock "wc1" in bucket #1.
-    acquire_event =
-            CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC + 1,
-                                       attributionUids2, attributionTags2, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((bucketStartTimeNs + bucketSizeNs + NS_PER_SEC) / NS_PER_SEC + 1,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    release_event_time = roundedBucketStartTimeNs + bucketSizeNs + NS_PER_SEC + 100;
-    release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
-                                               attributionTags2, "wl1");
-    processor->OnLogEvent(release_event.get(), release_event_time);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Acquire wakelock "wc2" in bucket #2.
-    acquire_event =
-            CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + NS_PER_SEC + 1,
-                                       attributionUids3, attributionTags3, "wl2");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((bucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 3,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey2));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
-    // Release wakelock "wc2" in bucket #2.
-    release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC;
-    release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids3,
-                                               attributionTags3, "wl2");
-    processor->OnLogEvent(release_event.get(), release_event_time);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
-    EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey2));
-
-    // Acquire wakelock "wc1" in bucket #2.
-    acquire_event =
-            CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs + 3 * NS_PER_SEC,
-                                       attributionUids2, attributionTags2, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((roundedBucketStartTimeNs + 2 * bucketSizeNs) / NS_PER_SEC + 3 + 1,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Release wakelock "wc1" in bucket #2.
-    release_event_time = roundedBucketStartTimeNs + 2 * bucketSizeNs + 3.5 * NS_PER_SEC;
-    release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids2,
-                                               attributionTags2, "wl1");
-    processor->OnLogEvent(release_event.get(), release_event_time);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(refractory_period_sec + (release_event_time) / NS_PER_SEC + 1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 6 * bucketSizeNs + 4,
-                                               attributionUids3, attributionTags3, "wl2");
-    processor->OnLogEvent(acquire_event.get());
-    acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 6 * bucketSizeNs + 5,
-                                               attributionUids1, attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((roundedBucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 2,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ((roundedBucketStartTimeNs + 6 * bucketSizeNs) / NS_PER_SEC + 2,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey2));
-
-    release_event_time = roundedBucketStartTimeNs + 6 * bucketSizeNs + NS_PER_SEC + 2;
-    release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids3,
-                                               attributionTags3, "wl2");
-    processor->OnLogEvent(release_event.get(), release_event_time);
-    release_event = CreateReleaseWakelockEvent(release_event_time + 4, attributionUids1,
-                                               attributionTags1, "wl1");
-    processor->OnLogEvent(release_event.get(), release_event_time + 4);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey2));
-    // The buckets are not messed up across dimensions. Only one dimension has anomaly triggered.
-    EXPECT_EQ(refractory_period_sec +
-                      (int64_t)(roundedBucketStartTimeNs + 6 * bucketSizeNs + NS_PER_SEC) /
-                              NS_PER_SEC +
-                      1,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-}
-
-TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period) {
-    const int num_buckets = 2;
-    const uint64_t threshold_ns = 3 * NS_PER_SEC;
-    auto config = CreateStatsdConfig(num_buckets, threshold_ns, DurationMetric::SUM, false);
-    const uint64_t alert_id = config.alert(0).id();
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1e6;
-    const uint32_t refractory_period_sec = 3 * bucketSizeNs / NS_PER_SEC;
-    config.mutable_alert(0)->set_refractory_period_secs(refractory_period_sec);
-
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    sendConfig(service, config);
-
-    auto processor = service->mProcessor;
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
-
-    int64_t bucketStartTimeNs = processor->mTimeBaseNs;
-    int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
-
-    sp<AnomalyTracker> anomalyTracker =
-            processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
-
-    auto screen_off_event = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screen_off_event.get());
-
-    // Acquire wakelock "wc1" in bucket #0.
-    auto acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs - 100,
-                                                    attributionUids1, attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Acquire the wakelock "wc1" again.
-    acquire_event =
-            CreateAcquireWakelockEvent(roundedBucketStartTimeNs + bucketSizeNs + 2 * NS_PER_SEC + 1,
-                                       attributionUids1, attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    // The alarm does not change.
-    EXPECT_EQ((roundedBucketStartTimeNs + bucketSizeNs) / NS_PER_SEC + 3,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(0u, anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // Anomaly alarm fired late.
-    const int64_t firedAlarmTimestampNs = roundedBucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
-    auto alarmTriggerEvent = CreateBatterySaverOnEvent(firedAlarmTimestampNs);
-    processor->OnLogEvent(alarmTriggerEvent.get(), firedAlarmTimestampNs);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    acquire_event = CreateAcquireWakelockEvent(roundedBucketStartTimeNs + 2 * bucketSizeNs - 100,
-                                               attributionUids1, attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    int64_t release_event_time = bucketStartTimeNs + 2 * bucketSizeNs + 1;
-    auto release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
-                                                    attributionTags1, "wl1");
-    processor->OnLogEvent(release_event.get(), release_event_time);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-    // Within the refractory period. No anomaly.
-    EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    // A new wakelock, but still within refractory period.
-    acquire_event = CreateAcquireWakelockEvent(
-            roundedBucketStartTimeNs + 2 * bucketSizeNs + 10 * NS_PER_SEC, attributionUids1,
-            attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
-    release_event =
-            CreateReleaseWakelockEvent(roundedBucketStartTimeNs + 3 * bucketSizeNs - NS_PER_SEC,
-                                       attributionUids1, attributionTags1, "wl1");
-    // Still in the refractory period. No anomaly.
-    processor->OnLogEvent(release_event.get());
-    EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1));
-
-    acquire_event = CreateAcquireWakelockEvent(
-            roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 5, attributionUids1,
-            attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((roundedBucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC + 1,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
-    release_event_time = roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 4;
-    release_event = CreateReleaseWakelockEvent(release_event_time, attributionUids1,
-                                               attributionTags1, "wl1");
-    processor->OnLogEvent(release_event.get(), release_event_time);
-    EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-
-    acquire_event = CreateAcquireWakelockEvent(
-            roundedBucketStartTimeNs + 5 * bucketSizeNs - 2 * NS_PER_SEC - 3, attributionUids1,
-            attributionTags1, "wl1");
-    processor->OnLogEvent(acquire_event.get());
-    EXPECT_EQ((roundedBucketStartTimeNs + 5 * bucketSizeNs) / NS_PER_SEC + 1,
-              anomalyTracker->getAlarmTimestampSec(dimensionKey1));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
deleted file mode 100644
index 4c2caa9..0000000
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright (C) 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.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <iostream>
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(const Position position) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-    auto attributionNodeMatcher =
-        wakelockAcquireMatcher.mutable_simple_atom_matcher()->add_field_value_matcher();
-    attributionNodeMatcher->set_field(1);
-    attributionNodeMatcher->set_position(Position::ANY);
-    auto uidMatcher = attributionNodeMatcher->mutable_matches_tuple()->add_field_value_matcher();
-    uidMatcher->set_field(1);  // uid field.
-    uidMatcher->set_eq_string("com.android.gmscore");
-
-    *config.add_atom_matcher() = wakelockAcquireMatcher;
-
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(123456);
-    countMetric->set_what(wakelockAcquireMatcher.id());
-    *countMetric->mutable_dimensions_in_what() =
-        CreateAttributionUidAndTagDimensions(
-            util::WAKELOCK_STATE_CHANGED, {position});
-    countMetric->set_bucket(FIVE_MINUTES);
-    return config;
-}
-
-// GMS core node is in the middle.
-std::vector<int> attributionUids1 = {111, 222, 333};
-std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1", "App3"};
-
-// GMS core node is the last one.
-std::vector<int> attributionUids2 = {111, 333, 222};
-std::vector<string> attributionTags2 = {"App1", "App3", "GMSCoreModule1"};
-
-// GMS core node is the first one.
-std::vector<int> attributionUids3 = {222, 333};
-std::vector<string> attributionTags3 = {"GMSCoreModule1", "App3"};
-
-// Single GMS core node.
-std::vector<int> attributionUids4 = {222};
-std::vector<string> attributionTags4 = {"GMSCoreModule1"};
-
-// GMS core has another uid.
-std::vector<int> attributionUids5 = {111, 444, 333};
-std::vector<string> attributionTags5 = {"App1", "GMSCoreModule2", "App3"};
-
-// Multiple GMS core nodes.
-std::vector<int> attributionUids6 = {444, 222};
-std::vector<string> attributionTags6 = {"GMSCoreModule2", "GMSCoreModule1"};
-
-// No GMS core nodes
-std::vector<int> attributionUids7 = {111, 333};
-std::vector<string> attributionTags7 = {"App1", "App3"};
-
-std::vector<int> attributionUids8 = {111};
-std::vector<string> attributionTags8 = {"App1"};
-
-// GMS core node with isolated uid.
-const int isolatedUid = 666;
-std::vector<int> attributionUids9 = {isolatedUid};
-std::vector<string> attributionTags9 = {"GMSCoreModule3"};
-
-std::vector<int> attributionUids10 = {isolatedUid};
-std::vector<string> attributionTags10 = {"GMSCoreModule1"};
-
-}  // namespace
-
-TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid) {
-    auto config = CreateStatsdConfig(Position::FIRST);
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
-    // Here it assumes that GMS core has two uids.
-    processor->getUidMap()->updateMap(
-            1, {222, 444, 111, 333}, {1, 1, 2, 2},
-            {String16("v1"), String16("v1"), String16("v2"), String16("v2")},
-            {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
-             String16("APP3")},
-            {String16(""), String16(""), String16(""), String16("")});
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    // Events 1~4 are in the 1st bucket.
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
-                                                attributionTags1, "wl1"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 200, attributionUids2,
-                                                attributionTags2, "wl1"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
-                                                attributionUids3, attributionTags3, "wl1"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs, attributionUids4,
-                                                attributionTags4, "wl1"));
-
-    // Events 5~8 are in the 3rd bucket.
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
-                                                attributionUids5, attributionTags5, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
-                                                attributionUids6, attributionTags6, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - 2,
-                                                attributionUids7, attributionTags7, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs,
-                                                attributionUids8, attributionTags8, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1,
-                                                attributionUids9, attributionTags9, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 100,
-                                                attributionUids9, attributionTags9, "wl2"));
-    events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs - 1, 222,
-                                                   isolatedUid, true /*is_create*/));
-    events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs + 10, 222,
-                                                   isolatedUid, false /*is_create*/));
-
-    sortLogEventsByTimestamp(&events);
-
-    for (const auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(countMetrics.data_size(), 4);
-
-    auto data = countMetrics.data(0);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          util::WAKELOCK_STATE_CHANGED, 111, "App1");
-    ASSERT_EQ(data.bucket_info_size(), 2);
-    EXPECT_EQ(data.bucket_info(0).count(), 2);
-    EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
-    EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-    EXPECT_EQ(data.bucket_info(1).count(), 1);
-    EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(),
-              bucketStartTimeNs + 2 * bucketSizeNs);
-    EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
-
-    data = countMetrics.data(1);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          util::WAKELOCK_STATE_CHANGED, 222,
-                                          "GMSCoreModule1");
-    ASSERT_EQ(data.bucket_info_size(), 2);
-    EXPECT_EQ(data.bucket_info(0).count(), 1);
-    EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
-    EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-    EXPECT_EQ(data.bucket_info(1).count(), 1);
-    EXPECT_EQ(data.bucket_info(1).start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-    EXPECT_EQ(data.bucket_info(1).end_bucket_elapsed_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
-
-    data = countMetrics.data(2);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          util::WAKELOCK_STATE_CHANGED, 222,
-                                          "GMSCoreModule3");
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    EXPECT_EQ(data.bucket_info(0).count(), 1);
-    EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
-              bucketStartTimeNs + 3 * bucketSizeNs);
-    EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 4 * bucketSizeNs);
-
-    data = countMetrics.data(3);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          util::WAKELOCK_STATE_CHANGED, 444,
-                                          "GMSCoreModule2");
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    EXPECT_EQ(data.bucket_info(0).count(), 1);
-    EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
-              bucketStartTimeNs + 2 * bucketSizeNs);
-    EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
-}
-
-TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain) {
-    auto config = CreateStatsdConfig(Position::ALL);
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
-    // Here it assumes that GMS core has two uids.
-    processor->getUidMap()->updateMap(
-            1, {222, 444, 111, 333}, {1, 1, 2, 2},
-            {String16("v1"), String16("v1"), String16("v2"), String16("v2")},
-            {String16("com.android.gmscore"), String16("com.android.gmscore"), String16("app1"),
-             String16("APP3")},
-            {String16(""), String16(""), String16(""), String16("")});
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    // Events 1~4 are in the 1st bucket.
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
-                                                attributionTags1, "wl1"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 200, attributionUids2,
-                                                attributionTags2, "wl1"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 1,
-                                                attributionUids3, attributionTags3, "wl1"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs, attributionUids4,
-                                                attributionTags4, "wl1"));
-
-    // Events 5~8 are in the 3rd bucket.
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 1,
-                                                attributionUids5, attributionTags5, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
-                                                attributionUids6, attributionTags6, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs - 2,
-                                                attributionUids7, attributionTags7, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs,
-                                                attributionUids8, attributionTags8, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 1,
-                                                attributionUids10, attributionTags10, "wl2"));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 3 * bucketSizeNs + 100,
-                                                attributionUids10, attributionTags10, "wl2"));
-    events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs - 1, 222,
-                                                   isolatedUid, true /*is_create*/));
-    events.push_back(CreateIsolatedUidChangedEvent(bucketStartTimeNs + 3 * bucketSizeNs + 10, 222,
-                                                   isolatedUid, false /*is_create*/));
-
-    sortLogEventsByTimestamp(&events);
-
-    for (const auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(countMetrics.data_size(), 6);
-
-    auto data = countMetrics.data(0);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
-                                          util::WAKELOCK_STATE_CHANGED, 222,
-                                          "GMSCoreModule1");
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(1).count());
-    EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
-              data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(1);
-    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 222);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          util::WAKELOCK_STATE_CHANGED, 222,
-                                          "GMSCoreModule1");
-    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 333);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          util::WAKELOCK_STATE_CHANGED, 333, "App3");
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    EXPECT_EQ(data.bucket_info(0).count(), 1);
-    EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
-    EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
-
-    data = countMetrics.data(2);
-    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 444);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          util::WAKELOCK_STATE_CHANGED, 444,
-                                          "GMSCoreModule2");
-    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 222);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          util::WAKELOCK_STATE_CHANGED, 222,
-                                          "GMSCoreModule1");
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    EXPECT_EQ(data.bucket_info(0).count(), 1);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(3);
-    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          util::WAKELOCK_STATE_CHANGED, 111, "App1");
-    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 222);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          util::WAKELOCK_STATE_CHANGED, 222,
-                                          "GMSCoreModule1");
-    ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
-                                          util::WAKELOCK_STATE_CHANGED, 333, "App3");
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    EXPECT_EQ(data.bucket_info(0).count(), 1);
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(4);
-    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          util::WAKELOCK_STATE_CHANGED, 111, "App1");
-    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 333);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          util::WAKELOCK_STATE_CHANGED, 333, "App3");
-    ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 222);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
-                                          util::WAKELOCK_STATE_CHANGED, 222,
-                                          "GMSCoreModule1");
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    EXPECT_EQ(data.bucket_info(0).count(), 1);
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(5);
-    ValidateUidDimension(data.dimensions_in_what(), 0, util::WAKELOCK_STATE_CHANGED, 111);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 0,
-                                          util::WAKELOCK_STATE_CHANGED, 111, "App1");
-    ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 444);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
-                                          util::WAKELOCK_STATE_CHANGED, 444,
-                                          "GMSCoreModule2");
-    ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
-    ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
-                                          util::WAKELOCK_STATE_CHANGED, 333, "App3");
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    EXPECT_EQ(data.bucket_info(0).count(), 1);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp b/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
deleted file mode 100644
index 0bce0ba..0000000
--- a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (C) 2018 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.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(int num_buckets, int threshold) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
-
-    *config.add_atom_matcher() = wakelockAcquireMatcher;
-
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(123456);
-    countMetric->set_what(wakelockAcquireMatcher.id());
-    *countMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
-            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    countMetric->set_bucket(FIVE_MINUTES);
-
-    auto alert = config.add_alert();
-    alert->set_id(StringToId("alert"));
-    alert->set_metric_id(123456);
-    alert->set_num_buckets(num_buckets);
-    alert->set_refractory_period_secs(10);
-    alert->set_trigger_if_sum_gt(threshold);
-
-    // Two hours
-    config.set_ttl_in_seconds(2 * 3600);
-    return config;
-}
-
-}  // namespace
-
-TEST(ConfigTtlE2eTest, TestCountMetric) {
-    const int num_buckets = 1;
-    const int threshold = 3;
-    auto config = CreateStatsdConfig(num_buckets, threshold);
-    const uint64_t alert_id = config.alert(0).id();
-    const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
-
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
-    std::vector<int> attributionUids1 = {111};
-    std::vector<string> attributionTags1 = {"App1"};
-
-    FieldValue fieldValue1(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
-                           Value((int32_t)111));
-    HashableDimensionKey whatKey1({fieldValue1});
-    MetricDimensionKey dimensionKey1(whatKey1, DEFAULT_DIMENSION_KEY);
-
-    FieldValue fieldValue2(Field(util::WAKELOCK_STATE_CHANGED, (int32_t)0x02010101),
-                           Value((int32_t)222));
-    HashableDimensionKey whatKey2({fieldValue2});
-    MetricDimensionKey dimensionKey2(whatKey2, DEFAULT_DIMENSION_KEY);
-
-    auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
-                                            attributionTags1, "wl1");
-    processor->OnLogEvent(event.get());
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2, attributionUids1,
-                                       attributionTags1, "wl2");
-    processor->OnLogEvent(event.get());
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * bucketSizeNs + 2, attributionUids1,
-                                       attributionTags1, "wl1");
-    processor->OnLogEvent(event.get());
-
-    EXPECT_EQ((int64_t)(bucketStartTimeNs + 25 * bucketSizeNs + 2 + 2 * 3600 * NS_PER_SEC),
-              processor->mMetricsManagers.begin()->second->getTtlEndNs());
-
-    // Clear the data stored on disk as a result of the ttl.
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 25 * bucketSizeNs + 3, false, true,
-                            ADB_DUMP, FAST, &buffer);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/ConfigUpdate_e2e_ab_test.cpp b/cmds/statsd/tests/e2e/ConfigUpdate_e2e_ab_test.cpp
deleted file mode 100644
index 098f284..0000000
--- a/cmds/statsd/tests/e2e/ConfigUpdate_e2e_ab_test.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-// Copyright (C) 2020 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.
-
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <gtest/gtest.h>
-
-#include "flags/flags.h"
-#include "src/StatsLogProcessor.h"
-#include "src/storage/StorageManager.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-#define STATS_DATA_DIR "/data/misc/stats-data"
-
-using android::base::SetProperty;
-using android::base::StringPrintf;
-using namespace std;
-
-namespace {
-
-StatsdConfig CreateSimpleConfig() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_STATSD");
-    config.set_hash_strings_in_metric_report(false);
-
-    *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-    // Simple count metric so the config isn't empty.
-    CountMetric* countMetric1 = config.add_count_metric();
-    countMetric1->set_id(StringToId("Count1"));
-    countMetric1->set_what(config.atom_matcher(0).id());
-    countMetric1->set_bucket(FIVE_MINUTES);
-    return config;
-}
-}  // namespace
-
-// Setup for parameterized tests.
-class ConfigUpdateE2eAbTest : public TestWithParam<bool> {
-private:
-    string originalFlagValue;
-
-public:
-    void SetUp() override {
-        originalFlagValue = getFlagBool(PARTIAL_CONFIG_UPDATE_FLAG, "");
-        string rawFlagName =
-                StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_NAMESPACE.c_str(),
-                             PARTIAL_CONFIG_UPDATE_FLAG.c_str());
-        SetProperty(rawFlagName, GetParam() ? "true" : "false");
-    }
-
-    void TearDown() override {
-        string rawFlagName =
-                StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_NAMESPACE.c_str(),
-                             PARTIAL_CONFIG_UPDATE_FLAG.c_str());
-        SetProperty(rawFlagName, originalFlagValue);
-    }
-};
-
-INSTANTIATE_TEST_SUITE_P(ConfigUpdateE2eAbTest, ConfigUpdateE2eAbTest, testing::Bool());
-
-TEST_P(ConfigUpdateE2eAbTest, TestUidMapVersionStringInstaller) {
-    sp<UidMap> uidMap = new UidMap();
-    vector<int32_t> uids({1000});
-    vector<int64_t> versions({1});
-    vector<String16> apps({String16("app1")});
-    vector<String16> versionStrings({String16("v1")});
-    vector<String16> installers({String16("installer1")});
-    uidMap->updateMap(1, uids, versions, versionStrings, apps, installers);
-
-    StatsdConfig config = CreateSimpleConfig();
-    config.set_version_strings_in_metric_report(true);
-    config.set_installer_in_metric_report(false);
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-
-    ConfigKey cfgKey(0, 12345);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey, nullptr, 0, uidMap);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-
-    // Now update.
-    config.set_version_strings_in_metric_report(false);
-    config.set_installer_in_metric_report(true);
-    processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_EQ(metricsManager == processor->mMetricsManagers.begin()->second, GetParam());
-    EXPECT_TRUE(metricsManager->isConfigValid());
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    // First report is written to disk when the update happens.
-    ASSERT_EQ(reports.reports_size(), 2);
-    UidMapping uidMapping = reports.reports(1).uid_map();
-    ASSERT_EQ(uidMapping.snapshots_size(), 1);
-    ASSERT_EQ(uidMapping.snapshots(0).package_info_size(), 1);
-    EXPECT_FALSE(uidMapping.snapshots(0).package_info(0).has_version_string());
-    EXPECT_EQ(uidMapping.snapshots(0).package_info(0).installer(), "installer1");
-}
-
-TEST_P(ConfigUpdateE2eAbTest, TestHashStrings) {
-    sp<UidMap> uidMap = new UidMap();
-    vector<int32_t> uids({1000});
-    vector<int64_t> versions({1});
-    vector<String16> apps({String16("app1")});
-    vector<String16> versionStrings({String16("v1")});
-    vector<String16> installers({String16("installer1")});
-    uidMap->updateMap(1, uids, versions, versionStrings, apps, installers);
-
-    StatsdConfig config = CreateSimpleConfig();
-    config.set_version_strings_in_metric_report(true);
-    config.set_hash_strings_in_metric_report(true);
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-
-    ConfigKey cfgKey(0, 12345);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey, nullptr, 0, uidMap);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-
-    // Now update.
-    config.set_hash_strings_in_metric_report(false);
-    processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_EQ(metricsManager == processor->mMetricsManagers.begin()->second, GetParam());
-    EXPECT_TRUE(metricsManager->isConfigValid());
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    // First report is written to disk when the update happens.
-    ASSERT_EQ(reports.reports_size(), 2);
-    UidMapping uidMapping = reports.reports(1).uid_map();
-    ASSERT_EQ(uidMapping.snapshots_size(), 1);
-    ASSERT_EQ(uidMapping.snapshots(0).package_info_size(), 1);
-    EXPECT_TRUE(uidMapping.snapshots(0).package_info(0).has_version_string());
-    EXPECT_FALSE(uidMapping.snapshots(0).package_info(0).has_version_string_hash());
-}
-
-TEST_P(ConfigUpdateE2eAbTest, TestAnnotations) {
-    StatsdConfig config = CreateSimpleConfig();
-    StatsdConfig_Annotation* annotation = config.add_annotation();
-    annotation->set_field_int64(11);
-    annotation->set_field_int32(1);
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    ConfigKey cfgKey(0, 12345);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
-
-    // Now update
-    config.clear_annotation();
-    annotation = config.add_annotation();
-    annotation->set_field_int64(22);
-    annotation->set_field_int32(2);
-    processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    // First report is written to disk when the update happens.
-    ASSERT_EQ(reports.reports_size(), 2);
-    ConfigMetricsReport report = reports.reports(1);
-    EXPECT_EQ(report.annotation_size(), 1);
-    EXPECT_EQ(report.annotation(0).field_int64(), 22);
-    EXPECT_EQ(report.annotation(0).field_int32(), 2);
-}
-
-TEST_P(ConfigUpdateE2eAbTest, TestPersistLocally) {
-    StatsdConfig config = CreateSimpleConfig();
-    config.set_persist_locally(false);
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    ConfigKey cfgKey(0, 12345);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    ASSERT_EQ(reports.reports_size(), 1);
-    // Number of reports should still be 1 since persist_locally is false.
-    reports.Clear();
-    buffer.clear();
-    processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    ASSERT_EQ(reports.reports_size(), 1);
-
-    // Now update.
-    config.set_persist_locally(true);
-    processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config);
-
-    // Should get 2: 1 in memory + 1 on disk. Both should be saved on disk.
-    reports.Clear();
-    buffer.clear();
-    processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    ASSERT_EQ(reports.reports_size(), 2);
-    // Should get 3, 2 on disk + 1 in memory.
-    reports.Clear();
-    buffer.clear();
-    processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    ASSERT_EQ(reports.reports_size(), 3);
-    string suffix = StringPrintf("%d_%lld", cfgKey.GetUid(), (long long)cfgKey.GetId());
-    StorageManager::deleteSuffixedFiles(STATS_DATA_DIR, suffix.c_str());
-    string historySuffix =
-            StringPrintf("%d_%lld_history", cfgKey.GetUid(), (long long)cfgKey.GetId());
-    StorageManager::deleteSuffixedFiles(STATS_DATA_DIR, historySuffix.c_str());
-}
-
-TEST_P(ConfigUpdateE2eAbTest, TestNoReportMetrics) {
-    StatsdConfig config = CreateSimpleConfig();
-    // Second simple count metric.
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(StringToId("Count2"));
-    countMetric->set_what(config.atom_matcher(0).id());
-    countMetric->set_bucket(FIVE_MINUTES);
-    config.add_no_report_metric(config.count_metric(0).id());
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    ConfigKey cfgKey(0, 12345);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
-
-    // Now update.
-    config.clear_no_report_metric();
-    config.add_no_report_metric(config.count_metric(1).id());
-    processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, baseTimeNs + 1001, false, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    // First report is written to disk when the update happens.
-    ASSERT_EQ(reports.reports_size(), 2);
-    // First report (before update) has the first count metric.
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).metric_id(), config.count_metric(1).id());
-    // Second report (after update) has the first count metric.
-    ASSERT_EQ(reports.reports(1).metrics_size(), 1);
-    EXPECT_EQ(reports.reports(1).metrics(0).metric_id(), config.count_metric(0).id());
-}
-
-TEST_P(ConfigUpdateE2eAbTest, TestAtomsAllowedFromAnyUid) {
-    StatsdConfig config = CreateSimpleConfig();
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    ConfigKey cfgKey(0, 12345);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
-    // Uses AID_ROOT, which isn't in allowed log sources.
-    unique_ptr<LogEvent> event = CreateBatteryStateChangedEvent(
-            baseTimeNs + 2, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
-    processor->OnLogEvent(event.get());
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, baseTimeNs + 1001, true, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    ASSERT_EQ(reports.reports_size(), 1);
-    // Check the metric and make sure it has 0 count.
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_FALSE(reports.reports(0).metrics(0).has_count_metrics());
-
-    // Now update. Allow plugged state to be logged from any uid, so the atom will be counted.
-    config.add_whitelisted_atom_ids(util::PLUGGED_STATE_CHANGED);
-    processor->OnConfigUpdated(baseTimeNs + 1000, cfgKey, config);
-    unique_ptr<LogEvent> event2 = CreateBatteryStateChangedEvent(
-            baseTimeNs + 2000, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
-    processor->OnLogEvent(event.get());
-    reports.Clear();
-    buffer.clear();
-    processor->onDumpReport(cfgKey, baseTimeNs + 3000, true, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    ASSERT_EQ(reports.reports_size(), 2);
-    // Check the metric and make sure it has 0 count.
-    ASSERT_EQ(reports.reports(1).metrics_size(), 1);
-    EXPECT_TRUE(reports.reports(1).metrics(0).has_count_metrics());
-    ASSERT_EQ(reports.reports(1).metrics(0).count_metrics().data_size(), 1);
-    ASSERT_EQ(reports.reports(1).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
-    EXPECT_EQ(reports.reports(1).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
-}
-
-TEST_P(ConfigUpdateE2eAbTest, TestConfigTtl) {
-    StatsdConfig config = CreateSimpleConfig();
-    config.set_ttl_in_seconds(1);
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    ConfigKey cfgKey(0, 12345);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(baseTimeNs, baseTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_EQ(metricsManager->getTtlEndNs(), baseTimeNs + NS_PER_SEC);
-
-    config.set_ttl_in_seconds(5);
-    processor->OnConfigUpdated(baseTimeNs + 2 * NS_PER_SEC, cfgKey, config);
-    metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_EQ(metricsManager->getTtlEndNs(), baseTimeNs + 7 * NS_PER_SEC);
-
-    // Clear the data stored on disk as a result of the update.
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, baseTimeNs + 3 * NS_PER_SEC, false, true, ADB_DUMP, FAST,
-                            &buffer);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp b/cmds/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp
deleted file mode 100644
index 94b778c..0000000
--- a/cmds/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright (C) 2020 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.
-
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <gtest/gtest.h>
-
-#include "flags/flags.h"
-#include "src/StatsLogProcessor.h"
-#include "src/storage/StorageManager.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-using android::base::SetProperty;
-using android::base::StringPrintf;
-using namespace std;
-
-// Tests that only run with the partial config update feature turned on.
-namespace {
-// Setup for test fixture.
-class ConfigUpdateE2eTest : public ::testing::Test {
-private:
-    string originalFlagValue;
-public:
-    void SetUp() override {
-        originalFlagValue = getFlagBool(PARTIAL_CONFIG_UPDATE_FLAG, "");
-        string rawFlagName =
-                StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_NAMESPACE.c_str(),
-                             PARTIAL_CONFIG_UPDATE_FLAG.c_str());
-        SetProperty(rawFlagName, "true");
-    }
-
-    void TearDown() override {
-        string rawFlagName =
-                StringPrintf("persist.device_config.%s.%s", STATSD_NATIVE_NAMESPACE.c_str(),
-                             PARTIAL_CONFIG_UPDATE_FLAG.c_str());
-        SetProperty(rawFlagName, originalFlagValue);
-    }
-};
-}  // Anonymous namespace.
-
-TEST_F(ConfigUpdateE2eTest, TestNewDurationExistingWhat) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
-    Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    ConfigKey key(123, 987);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(FIVE_MINUTES) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
-
-    int app1Uid = 123;
-    vector<int> attributionUids1 = {app1Uid};
-    vector<string> attributionTags1 = {"App1"};
-    // Create a wakelock acquire, causing the condition to be true.
-    unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC,
-                                                            attributionUids1, attributionTags1,
-                                                            "wl1");  // 0:10
-    processor->OnLogEvent(event.get());
-
-    // Add metric.
-    DurationMetric* durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("WakelockDuration"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    uint64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;  // 1:00
-    processor->OnConfigUpdated(updateTimeNs, key, config);
-
-    event = CreateReleaseWakelockEvent(bucketStartTimeNs + 80 * NS_PER_SEC, attributionUids1,
-                                       attributionTags1,
-                                       "wl1");  // 1:20
-    processor->OnLogEvent(event.get());
-    uint64_t dumpTimeNs = bucketStartTimeNs + 90 * NS_PER_SEC;  // 1:30
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
-    StatsLogReport::DurationMetricDataWrapper metricData;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metricData);
-    ASSERT_EQ(metricData.data_size(), 1);
-    DurationMetricData data = metricData.data(0);
-    ASSERT_EQ(data.bucket_info_size(), 1);
-
-    DurationBucketInfo bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(bucketInfo.start_bucket_elapsed_nanos(), updateTimeNs);
-    EXPECT_EQ(bucketInfo.end_bucket_elapsed_nanos(), dumpTimeNs);
-    EXPECT_EQ(bucketInfo.duration_nanos(), 20 * NS_PER_SEC);
-}
-
-TEST_F(ConfigUpdateE2eTest, TestNewDurationExistingWhatSlicedCondition) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
-    Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    // The predicate is dimensioning by first attribution node by uid.
-    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    Predicate isInBackgroundPredicate = CreateIsInBackgroundPredicate();
-    *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
-            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /*uid*/});
-    *config.add_predicate() = isInBackgroundPredicate;
-
-    ConfigKey key(123, 987);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(FIVE_MINUTES) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
-
-    int app1Uid = 123, app2Uid = 456;
-    vector<int> attributionUids1 = {app1Uid};
-    vector<string> attributionTags1 = {"App1"};
-    vector<int> attributionUids2 = {app2Uid};
-    vector<string> attributionTags2 = {"App2"};
-    unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC,
-                                                            attributionUids1, attributionTags1,
-                                                            "wl1");  // 0:10
-    processor->OnLogEvent(event.get());
-    event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, app1Uid);  // 0:22
-    processor->OnLogEvent(event.get());
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 35 * NS_PER_SEC, attributionUids2,
-                                       attributionTags2,
-                                       "wl1");  // 0:35
-    processor->OnLogEvent(event.get());
-
-    // Add metric.
-    DurationMetric* durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("WakelockDuration"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->set_condition(isInBackgroundPredicate.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    // The metric is dimensioning by first attribution node and only by uid.
-    *durationMetric->mutable_dimensions_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    durationMetric->set_bucket(FIVE_MINUTES);
-    // Links between wakelock state atom and condition of app is in background.
-    auto links = durationMetric->add_links();
-    links->set_condition(isInBackgroundPredicate.id());
-    *links->mutable_fields_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    *links->mutable_fields_in_condition() =
-            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /*uid*/});
-
-    uint64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;  // 1:00
-    processor->OnConfigUpdated(updateTimeNs, key, config);
-
-    event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 73 * NS_PER_SEC, app2Uid);  // 1:13
-    processor->OnLogEvent(event.get());
-    event = CreateReleaseWakelockEvent(bucketStartTimeNs + 84 * NS_PER_SEC, attributionUids1,
-                                       attributionTags1, "wl1");  // 1:24
-    processor->OnLogEvent(event.get());
-
-    uint64_t dumpTimeNs = bucketStartTimeNs + 90 * NS_PER_SEC;  //  1:30
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
-    StatsLogReport::DurationMetricDataWrapper metricData;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metricData);
-    ASSERT_EQ(metricData.data_size(), 2);
-
-    DurationMetricData data = metricData.data(0);
-    ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
-                                    app1Uid);
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    DurationBucketInfo bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(bucketInfo.duration_nanos(), 24 * NS_PER_SEC);
-
-    data = metricData.data(1);
-    ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
-                                    app2Uid);
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(bucketInfo.duration_nanos(), 17 * NS_PER_SEC);
-}
-
-TEST_F(ConfigUpdateE2eTest, TestNewDurationExistingWhatSlicedState) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
-    Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    // The predicate is dimensioning by first attribution node by uid.
-    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    auto uidProcessState = CreateUidProcessState();
-    *config.add_state() = uidProcessState;
-
-    // Count metric. We don't care about this one. Only use it so the StateTracker gets persisted.
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(StringToId("Tmp"));
-    countMetric->set_what(config.atom_matcher(0).id());
-    countMetric->add_slice_by_state(uidProcessState.id());
-    // The metric is dimensioning by first attribution node and only by uid.
-    *countMetric->mutable_dimensions_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    countMetric->set_bucket(FIVE_MINUTES);
-    auto stateLink = countMetric->add_state_link();
-    stateLink->set_state_atom_id(util::UID_PROCESS_STATE_CHANGED);
-    *stateLink->mutable_fields_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    *stateLink->mutable_fields_in_state() =
-            CreateDimensions(util::UID_PROCESS_STATE_CHANGED, {1 /*uid*/});
-    config.add_no_report_metric(countMetric->id());
-
-    ConfigKey key(123, 987);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(FIVE_MINUTES) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
-
-    int app1Uid = 123, app2Uid = 456;
-    vector<int> attributionUids1 = {app1Uid};
-    vector<string> attributionTags1 = {"App1"};
-    vector<int> attributionUids2 = {app2Uid};
-    vector<string> attributionTags2 = {"App2"};
-    unique_ptr<LogEvent> event = CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 10 * NS_PER_SEC, app1Uid,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);  // 0:10
-    processor->OnLogEvent(event.get());
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 22 * NS_PER_SEC, attributionUids1,
-                                       attributionTags1,
-                                       "wl1");  // 0:22
-    processor->OnLogEvent(event.get());
-    event = CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 30 * NS_PER_SEC, app2Uid,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);  // 0:30
-    processor->OnLogEvent(event.get());
-
-    // Add metric.
-    DurationMetric* durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("WakelockDuration"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->add_slice_by_state(uidProcessState.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    // The metric is dimensioning by first attribution node and only by uid.
-    *durationMetric->mutable_dimensions_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    durationMetric->set_bucket(FIVE_MINUTES);
-    // Links between wakelock state atom and condition of app is in background.
-    stateLink = durationMetric->add_state_link();
-    stateLink->set_state_atom_id(util::UID_PROCESS_STATE_CHANGED);
-    *stateLink->mutable_fields_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    *stateLink->mutable_fields_in_state() =
-            CreateDimensions(util::UID_PROCESS_STATE_CHANGED, {1 /*uid*/});
-
-    uint64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;  // 1:00
-    processor->OnConfigUpdated(updateTimeNs, key, config);
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + 72 * NS_PER_SEC, attributionUids2,
-                                       attributionTags2,
-                                       "wl1");  // 1:13
-    processor->OnLogEvent(event.get());
-    event = CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 75 * NS_PER_SEC, app1Uid,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND);  // 1:15
-    processor->OnLogEvent(event.get());
-    event = CreateReleaseWakelockEvent(bucketStartTimeNs + 84 * NS_PER_SEC, attributionUids1,
-                                       attributionTags1, "wl1");  // 1:24
-    processor->OnLogEvent(event.get());
-
-    uint64_t dumpTimeNs = bucketStartTimeNs + 90 * NS_PER_SEC;  //  1:30
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
-    StatsLogReport::DurationMetricDataWrapper metricData;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metricData);
-    ASSERT_EQ(metricData.data_size(), 3);
-
-    DurationMetricData data = metricData.data(0);
-    ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
-                                    app1Uid);
-    ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
-                       android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    DurationBucketInfo bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(bucketInfo.duration_nanos(), 15 * NS_PER_SEC);
-
-    data = metricData.data(1);
-    ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
-                                    app1Uid);
-    ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
-                       android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND);
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(bucketInfo.duration_nanos(), 9 * NS_PER_SEC);
-
-    data = metricData.data(2);
-    ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
-                                    app2Uid);
-    ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
-                       android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);
-    ASSERT_EQ(data.bucket_info_size(), 1);
-    bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(bucketInfo.duration_nanos(), 18 * NS_PER_SEC);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
deleted file mode 100644
index 04eb400..0000000
--- a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * Copyright (C) 2019, 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.
- */
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/state/StateManager.h"
-#include "src/state/StateTracker.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-/**
- * Tests the initial condition and condition after the first log events for
- * count metrics with either a combination condition or simple condition.
- *
- * Metrics should be initialized with condition kUnknown (given that the
- * predicate is using the default InitialValue of UNKNOWN). The condition should
- * be updated to either kFalse or kTrue if a condition event is logged for all
- * children conditions.
- */
-TEST(CountMetricE2eTest, TestInitialConditionChanges) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");     // LogEvent defaults to UID of root.
-    config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
-
-    auto syncStartMatcher = CreateSyncStartAtomMatcher();
-    *config.add_atom_matcher() = syncStartMatcher;
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
-    *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-
-    auto screenOnPredicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = screenOnPredicate;
-
-    auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
-    *config.add_predicate() = deviceUnpluggedPredicate;
-
-    auto screenOnOnBatteryPredicate = config.add_predicate();
-    screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate"));
-    screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
-    addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate);
-    addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate);
-
-    // CountSyncStartWhileScreenOnOnBattery (CombinationCondition)
-    CountMetric* countMetric1 = config.add_count_metric();
-    countMetric1->set_id(StringToId("CountSyncStartWhileScreenOnOnBattery"));
-    countMetric1->set_what(syncStartMatcher.id());
-    countMetric1->set_condition(screenOnOnBatteryPredicate->id());
-    countMetric1->set_bucket(FIVE_MINUTES);
-
-    // CountSyncStartWhileOnBattery (SimpleCondition)
-    CountMetric* countMetric2 = config.add_count_metric();
-    countMetric2->set_id(StringToId("CountSyncStartWhileOnBatterySliceScreen"));
-    countMetric2->set_what(syncStartMatcher.id());
-    countMetric2->set_condition(deviceUnpluggedPredicate.id());
-    countMetric2->set_bucket(FIVE_MINUTES);
-
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(2, metricsManager->mAllMetricProducers.size());
-
-    sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0];
-    sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[1];
-
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
-    auto screenOnEvent =
-            CreateScreenStateChangedEvent(bucketStartTimeNs + 30, android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
-    auto pluggedUsbEvent = CreateBatteryStateChangedEvent(
-            bucketStartTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
-    processor->OnLogEvent(pluggedUsbEvent.get());
-    EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
-    EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition);
-
-    auto pluggedNoneEvent = CreateBatteryStateChangedEvent(
-            bucketStartTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
-    processor->OnLogEvent(pluggedNoneEvent.get());
-    EXPECT_EQ(ConditionState::kTrue, metricProducer1->mCondition);
-    EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition);
-}
-
-/**
-* Test a count metric that has one slice_by_state with no primary fields.
-*
-* Once the CountMetricProducer is initialized, it has one atom id in
-* mSlicedStateAtoms and no entries in mStateGroupMap.
-
-* One StateTracker tracks the state atom, and it has one listener which is the
-* CountMetricProducer that was initialized.
-*/
-TEST(CountMetricE2eTest, TestSlicedState) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto syncStartMatcher = CreateSyncStartAtomMatcher();
-    *config.add_atom_matcher() = syncStartMatcher;
-
-    auto state = CreateScreenState();
-    *config.add_state() = state;
-
-    // Create count metric that slices by screen state.
-    int64_t metricId = 123456;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(syncStartMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    countMetric->add_slice_by_state(state.id());
-
-    // Initialize StatsLogProcessor.
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // Check that CountMetricProducer was initialized correctly.
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
-    // Check that StateTrackers were initialized correctly.
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
-    /*
-               bucket #1                      bucket #2
-    |     1     2     3     4     5     6     7     8     9     10 (minutes)
-    |-----------------------------|-----------------------------|--
-            x                x         x    x        x      x       (syncStartEvents)
-          |                                       |                 (ScreenIsOnEvent)
-                   |     |                                          (ScreenIsOffEvent)
-                                                        |           (ScreenDozeEvent)
-    */
-    // Initialize log events - first bucket.
-    std::vector<int> attributionUids1 = {123};
-    std::vector<string> attributionTags1 = {"App1"};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 50 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 1:00
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 75 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 1:25
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 150 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 2:40
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 200 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 3:30
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 4:20
-
-    // Initialize log events - second bucket.
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 350 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 6:00
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 6:50
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 450 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 7:40
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 475 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 8:05
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 500 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN));  // 8:30
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 520 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 8:50
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(3, countMetrics.data_size());
-
-    // For each CountMetricData, check StateValue info is correct and buckets
-    // have correct counts.
-    auto data = countMetrics.data(0);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(2, data.bucket_info(1).count());
-
-    data = countMetrics.data(2);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(1, data.bucket_info(1).count());
-}
-
-/**
- * Test a count metric that has one slice_by_state with a mapping and no
- * primary fields.
- *
- * Once the CountMetricProducer is initialized, it has one atom id in
- * mSlicedStateAtoms and has one entry per state value in mStateGroupMap.
- *
- * One StateTracker tracks the state atom, and it has one listener which is the
- * CountMetricProducer that was initialized.
- */
-TEST(CountMetricE2eTest, TestSlicedStateWithMap) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto syncStartMatcher = CreateSyncStartAtomMatcher();
-    *config.add_atom_matcher() = syncStartMatcher;
-
-    int64_t screenOnId = 4444;
-    int64_t screenOffId = 9876;
-    auto state = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
-    *config.add_state() = state;
-
-    // Create count metric that slices by screen state with on/off map.
-    int64_t metricId = 123456;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(syncStartMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    countMetric->add_slice_by_state(state.id());
-
-    // Initialize StatsLogProcessor.
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // Check that StateTrackers were initialized correctly.
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
-    // Check that CountMetricProducer was initialized correctly.
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
-
-    StateMap map = state.map();
-    for (auto group : map.group()) {
-        for (auto value : group.value()) {
-            EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value),
-                      group.group_id());
-        }
-    }
-
-    /*
-               bucket #1                      bucket #2
-    |     1     2     3     4     5     6     7     8     9     10 (minutes)
-    |-----------------------------|-----------------------------|--
-      x   x     x       x    x   x      x         x         x       (syncStartEvents)
-     -----------------------------------------------------------SCREEN_OFF events
-             |                  |                                   (ScreenStateOffEvent = 1)
-       |                  |                                         (ScreenStateDozeEvent = 3)
-                                                |                   (ScreenStateDozeSuspendEvent =
-    4)
-     -----------------------------------------------------------SCREEN_ON events
-                   |                                       |        (ScreenStateOnEvent = 2)
-                      |                                             (ScreenStateVrEvent = 5)
-                                            |                       (ScreenStateOnSuspendEvent = 6)
-    */
-    // Initialize log events - first bucket.
-    std::vector<int> attributionUids1 = {123};
-    std::vector<string> attributionTags1 = {"App1"};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 20 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 0:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 30 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 0:40
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 1:10
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 90 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:40
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 120 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 2:10
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 150 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 2:40
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 180 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_VR));  // 3:10
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 200 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 3:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 210 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 3:40
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 4:20
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 280 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 4:50
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 285 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 4:55
-
-    // Initialize log events - second bucket.
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 360 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 6:10
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 390 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND));  // 6:40
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 430 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND));  // 7:20
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 440 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 7:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 540 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 9:10
-    events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 570 * NS_PER_SEC, attributionUids1,
-                                          attributionTags1, "sync_name"));  // 9:40
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(3, countMetrics.data_size());
-
-    // For each CountMetricData, check StateValue info is correct and buckets
-    // have correct counts.
-    auto data = countMetrics.data(0);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(1, data.bucket_info(1).count());
-
-    data = countMetrics.data(2);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(4, data.bucket_info(0).count());
-    EXPECT_EQ(2, data.bucket_info(1).count());
-}
-
-/**
-* Test a count metric that has one slice_by_state with a primary field.
-
-* Once the CountMetricProducer is initialized, it should have one
-* MetricStateLink stored. State querying using a non-empty primary key
-* should also work as intended.
-*/
-TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto appCrashMatcher =
-            CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
-    *config.add_atom_matcher() = appCrashMatcher;
-
-    auto state = CreateUidProcessState();
-    *config.add_state() = state;
-
-    // Create count metric that slices by uid process state.
-    int64_t metricId = 123456;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(appCrashMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    countMetric->add_slice_by_state(state.id());
-    MetricStateLink* stateLink = countMetric->add_state_link();
-    stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
-    auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
-    auto fieldsInState = stateLink->mutable_fields_in_state();
-    *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
-
-    // Initialize StatsLogProcessor.
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // Check that StateTrackers were initialized correctly.
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
-    // Check that CountMetricProducer was initialized correctly.
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
-    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-    ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
-
-    /*
-    NOTE: "1" or "2" represents the uid associated with the state/app crash event
-               bucket #1               bucket #2
-    |    1    2    3    4    5    6    7    8    9    10
-    |------------------------|-------------------------|--
-      1  1    1      1   1  2     1        1        2    (AppCrashEvents)
-     -----------------------------------------------------PROCESS STATE events
-           1               2                             (TopEvent = 1002)
-                       1             1                   (ForegroundServiceEvent = 1003)
-                                         2               (ImportantBackgroundEvent = 1006)
-       1          1                               1      (ImportantForegroundEvent = 1005)
-
-    Based on the diagram above, an AppCrashEvent querying for process state value would return:
-    - StateTracker::kStateUnknown
-    - Important foreground
-    - Top
-    - Important foreground
-    - Foreground service
-    - Top (both the app crash and state still have matching uid = 2)
-
-    - Foreground service
-    - Foreground service
-    - Important background
-    */
-    // Initialize log events - first bucket.
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/));  // 0:30
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 30 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 0:40
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/));  // 1:10
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_TOP));  // 1:40
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/));  // 2:10
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 2:40
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/));  // 3:30
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 210 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE));  // 3:40
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/));  // 4:20
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_TOP));  // 4:50
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/));  // 4:55
-
-    // Initialize log events - second bucket.
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/));  // 6:10
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 390 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE));  // 6:40
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 430 * NS_PER_SEC, 2 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));  // 7:20
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 440 * NS_PER_SEC, 1 /*uid*/));  // 7:30
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 9:10
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/));  // 9:40
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(5, countMetrics.data_size());
-
-    // For each CountMetricData, check StateValue info is correct and buckets
-    // have correct counts.
-    auto data = countMetrics.data(0);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(2, data.bucket_info(0).count());
-
-    data = countMetrics.data(2);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(2, data.bucket_info(1).count());
-
-    data = countMetrics.data(3);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(2, data.bucket_info(0).count());
-
-    data = countMetrics.data(4);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-}
-
-TEST(CountMetricE2eTest, TestMultipleSlicedStates) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto appCrashMatcher =
-            CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
-    *config.add_atom_matcher() = appCrashMatcher;
-
-    int64_t screenOnId = 4444;
-    int64_t screenOffId = 9876;
-    auto state1 = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
-    *config.add_state() = state1;
-    auto state2 = CreateUidProcessState();
-    *config.add_state() = state2;
-
-    // Create count metric that slices by screen state with on/off map and
-    // slices by uid process state.
-    int64_t metricId = 123456;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(appCrashMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    countMetric->add_slice_by_state(state1.id());
-    countMetric->add_slice_by_state(state2.id());
-    MetricStateLink* stateLink = countMetric->add_state_link();
-    stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
-    auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
-    auto fieldsInState = stateLink->mutable_fields_in_state();
-    *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
-
-    // Initialize StatsLogProcessor.
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // Check that StateTrackers were properly initialized.
-    EXPECT_EQ(2, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
-    // Check that CountMetricProducer was initialized correctly.
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 2);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(1), UID_PROCESS_STATE_ATOM_ID);
-    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
-    ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
-
-    StateMap map = state1.map();
-    for (auto group : map.group()) {
-        for (auto value : group.value()) {
-            EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value),
-                      group.group_id());
-        }
-    }
-
-    /*
-                 bucket #1                      bucket #2
-      |    1    2    3    4    5    6    7    8    9    10 (minutes)
-      |------------------------|------------------------|--
-        1  1    1     1    1  2     1        1         2   (AppCrashEvents)
-       ---------------------------------------------------SCREEN_OFF events
-             |                              |              (ScreenOffEvent = 1)
-         |              |                                  (ScreenDozeEvent = 3)
-       ---------------------------------------------------SCREEN_ON events
-                   |                              |        (ScreenOnEvent = 2)
-                                        |                  (ScreenOnSuspendEvent = 6)
-       ---------------------------------------------------PROCESS STATE events
-             1               2                             (TopEvent = 1002)
-                                      1                    (ForegroundServiceEvent = 1003)
-                                            2              (ImportantBackgroundEvent = 1006)
-       1          1                                   1    (ImportantForegroundEvent = 1005)
-
-       Based on the diagram above, Screen State / Process State pairs for each
-       AppCrashEvent are:
-       - StateTracker::kStateUnknown / important foreground
-       - off / important foreground
-       - off / Top
-       - on / important foreground
-       - off / important foreground
-       - off / top
-
-       - off / important foreground
-       - off / foreground service
-       - on / important background
-
-      */
-    // Initialize log events - first bucket.
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 5 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 0:15
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/));  // 0:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 30 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 0:40
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/));  // 1:10
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_TOP));  // 1:40
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 90 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:40
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/));  // 2:10
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 2:40
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 160 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 2:50
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/));  // 3:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 210 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 3:40
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/));  // 4:20
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_TOP));  // 4:50
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/));  // 4:55
-
-    // Initialize log events - second bucket.
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/));  // 6:10
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 380 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE));  // 6:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 390 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND));  // 6:40
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 420 * NS_PER_SEC, 2 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));  // 7:10
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 440 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 7:30
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 450 * NS_PER_SEC, 1 /*uid*/));  // 7:40
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 520 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 8:50
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 9:10
-    events.push_back(
-            CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/));  // 9:40
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(6, countMetrics.data_size());
-
-    // For each CountMetricData, check StateValue info is correct and buckets
-    // have correct counts.
-    auto data = countMetrics.data(0);
-    ASSERT_EQ(2, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1, data.slice_by_state(0).value());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
-    EXPECT_TRUE(data.slice_by_state(1).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(2, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
-    EXPECT_TRUE(data.slice_by_state(1).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-
-    data = countMetrics.data(2);
-    ASSERT_EQ(2, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
-    EXPECT_TRUE(data.slice_by_state(1).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(1).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-
-    data = countMetrics.data(3);
-    ASSERT_EQ(2, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
-    EXPECT_TRUE(data.slice_by_state(1).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(1).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(2, data.bucket_info(0).count());
-
-    data = countMetrics.data(4);
-    ASSERT_EQ(2, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
-    EXPECT_TRUE(data.slice_by_state(1).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(1).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-
-    data = countMetrics.data(5);
-    ASSERT_EQ(2, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
-    EXPECT_TRUE(data.slice_by_state(1).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(2, data.bucket_info(0).count());
-    EXPECT_EQ(1, data.bucket_info(1).count());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
deleted file mode 100644
index 2473c1c..0000000
--- a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
+++ /dev/null
@@ -1,1476 +0,0 @@
-// Copyright (C) 2019 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.
-
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/state/StateTracker.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-TEST(DurationMetricE2eTest, TestOneBucket) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = screenOnMatcher;
-    *config.add_atom_matcher() = screenOffMatcher;
-
-    auto durationPredicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = durationPredicate;
-
-    int64_t metricId = 123456;
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(metricId);
-    durationMetric->set_what(durationPredicate.id());
-    durationMetric->set_bucket(FIVE_MINUTES);
-    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
-    const int64_t baseTimeNs = 0;                                   // 0:00
-    const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC;  // 0:01
-    const int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
-
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-
-    std::unique_ptr<LogEvent> event;
-
-    // Screen is off at start of bucket.
-    event = CreateScreenStateChangedEvent(configAddedTimeNs,
-                                          android::view::DISPLAY_STATE_OFF);  // 0:01
-    processor->OnLogEvent(event.get());
-
-    // Turn screen on.
-    const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC;  // 0:11
-    event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(event.get());
-
-    // Turn off screen 30 seconds after turning on.
-    const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC;  // 0:41
-    event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(event.get());
-
-    event = CreateScreenBrightnessChangedEvent(durationEndNs + 1 * NS_PER_SEC, 64);  // 0:42
-    processor->OnLogEvent(event.get());
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
-                            ADB_DUMP, FAST, &buffer);  // 5:01
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(1, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(durationEndNs - durationStartNs, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestTwoBuckets) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = screenOnMatcher;
-    *config.add_atom_matcher() = screenOffMatcher;
-
-    auto durationPredicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = durationPredicate;
-
-    int64_t metricId = 123456;
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(metricId);
-    durationMetric->set_what(durationPredicate.id());
-    durationMetric->set_bucket(FIVE_MINUTES);
-    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
-    const int64_t baseTimeNs = 0;                                   // 0:00
-    const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC;  // 0:01
-    const int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
-
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-
-    std::unique_ptr<LogEvent> event;
-
-    // Screen is off at start of bucket.
-    event = CreateScreenStateChangedEvent(configAddedTimeNs,
-                                          android::view::DISPLAY_STATE_OFF);  // 0:01
-    processor->OnLogEvent(event.get());
-
-    // Turn screen on.
-    const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC;  // 0:11
-    event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(event.get());
-
-    // Turn off screen 30 seconds after turning on.
-    const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC;  // 0:41
-    event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(event.get());
-
-    event = CreateScreenBrightnessChangedEvent(durationEndNs + 1 * NS_PER_SEC, 64);  // 0:42
-    processor->OnLogEvent(event.get());
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, false,
-                            true, ADB_DUMP, FAST, &buffer);  // 10:01
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(1, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-
-    auto bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(0, bucketInfo.bucket_num());
-    EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
-    EXPECT_EQ(configAddedTimeNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithActivation) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
-    auto crashMatcher = CreateProcessCrashAtomMatcher();
-    *config.add_atom_matcher() = screenOnMatcher;
-    *config.add_atom_matcher() = screenOffMatcher;
-    *config.add_atom_matcher() = crashMatcher;
-
-    auto durationPredicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = durationPredicate;
-
-    int64_t metricId = 123456;
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(metricId);
-    durationMetric->set_what(durationPredicate.id());
-    durationMetric->set_bucket(FIVE_MINUTES);
-    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
-    auto metric_activation1 = config.add_metric_activation();
-    metric_activation1->set_metric_id(metricId);
-    auto event_activation1 = metric_activation1->add_event_activation();
-    event_activation1->set_atom_matcher_id(crashMatcher.id());
-    event_activation1->set_ttl_seconds(30);  // 30 secs.
-
-    const int64_t bucketStartTimeNs = 10000000000;
-    const int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    vector<int64_t> activeConfigsBroadcast;
-
-    int broadcastCount = 0;
-    StatsLogProcessor processor(
-            m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
-            [](const ConfigKey& key) { return true; },
-            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
-                                                             const vector<int64_t>& activeConfigs) {
-                broadcastCount++;
-                EXPECT_EQ(broadcastUid, uid);
-                activeConfigsBroadcast.clear();
-                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
-                                              activeConfigs.end());
-                return true;
-            });
-
-    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);  // 0:00
-
-    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    auto& eventActivationMap = metricProducer->mEventActivationMap;
-
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    ASSERT_EQ(eventActivationMap.size(), 1u);
-    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    std::unique_ptr<LogEvent> event;
-
-    // Turn screen off.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * NS_PER_SEC,
-                                          android::view::DISPLAY_STATE_OFF);  // 0:02
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 2 * NS_PER_SEC);
-
-    // Turn screen on.
-    const int64_t durationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC;  // 0:05
-    event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), durationStartNs);
-
-    // Activate metric.
-    const int64_t activationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC;  // 0:10
-    const int64_t activationEndNs =
-            activationStartNs + event_activation1->ttl_seconds() * NS_PER_SEC;  // 0:40
-    event = CreateAppCrashEvent(activationStartNs, 111);
-    processor.OnLogEvent(event.get(), activationStartNs);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 1);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    // Expire activation.
-    const int64_t expirationNs = activationEndNs + 7 * NS_PER_SEC;
-    event = CreateScreenBrightnessChangedEvent(expirationNs, 64);  // 0:47
-    processor.OnLogEvent(event.get(), expirationNs);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 2);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    ASSERT_EQ(eventActivationMap.size(), 1u);
-    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    // Turn off screen 10 seconds after activation expiration.
-    const int64_t durationEndNs = activationEndNs + 10 * NS_PER_SEC;  // 0:50
-    event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
-    processor.OnLogEvent(event.get(), durationEndNs);
-
-    // Turn screen on.
-    const int64_t duration2StartNs = durationEndNs + 5 * NS_PER_SEC;  // 0:55
-    event = CreateScreenStateChangedEvent(duration2StartNs, android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), duration2StartNs);
-
-    // Turn off screen.
-    const int64_t duration2EndNs = duration2StartNs + 10 * NS_PER_SEC;  // 1:05
-    event = CreateScreenStateChangedEvent(duration2EndNs, android::view::DISPLAY_STATE_OFF);
-    processor.OnLogEvent(event.get(), duration2EndNs);
-
-    // Activate metric.
-    const int64_t activation2StartNs = duration2EndNs + 5 * NS_PER_SEC;  // 1:10
-    const int64_t activation2EndNs =
-            activation2StartNs + event_activation1->ttl_seconds() * NS_PER_SEC;  // 1:40
-    event = CreateAppCrashEvent(activation2StartNs, 211);
-    processor.OnLogEvent(event.get(), activation2StartNs);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, activation2StartNs);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor.onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
-                           ADB_DUMP, FAST, &buffer);  // 5:01
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(1, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-
-    auto bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(0, bucketInfo.bucket_num());
-    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(expirationNs, bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_EQ(expirationNs - durationStartNs, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithCondition) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
-    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
-    *config.add_predicate() = isInBackgroundPredicate;
-
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("WakelockDuration"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->set_condition(isInBackgroundPredicate.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    ConfigKey cfgKey;
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    auto& eventActivationMap = metricProducer->mEventActivationMap;
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_TRUE(eventActivationMap.empty());
-
-    int appUid = 123;
-    vector<int> attributionUids1 = {appUid};
-    vector<string> attributionTags1 = {"App1"};
-
-    auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
-                                            attributionTags1,
-                                            "wl1");  // 0:10
-    processor->OnLogEvent(event.get());
-
-    event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid);  // 0:22
-    processor->OnLogEvent(event.get());
-
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
-                                        appUid);  // 3:15
-    processor->OnLogEvent(event.get());
-
-    event = CreateReleaseWakelockEvent(bucketStartTimeNs + 4 * 60 * NS_PER_SEC, attributionUids1,
-                                       attributionTags1,
-                                       "wl1");  // 4:00
-    processor->OnLogEvent(event.get());
-
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(1, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-
-    // Validate bucket info.
-    ASSERT_EQ(1, data.bucket_info_size());
-
-    auto bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_EQ((2 * 60 + 53) * NS_PER_SEC, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedCondition) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
-    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    // The predicate is dimensioning by first attribution node by uid.
-    FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
-                                                             {Position::FIRST});
-    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
-    *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
-            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
-    *config.add_predicate() = isInBackgroundPredicate;
-
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("WakelockDuration"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->set_condition(isInBackgroundPredicate.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    // The metric is dimensioning by first attribution node and only by uid.
-    *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
-            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    // Links between wakelock state atom and condition of app is in background.
-    auto links = durationMetric->add_links();
-    links->set_condition(isInBackgroundPredicate.id());
-    *links->mutable_fields_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    auto dimensionCondition = links->mutable_fields_in_condition();
-    dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
-    dimensionCondition->add_child()->set_field(1);  // uid field.
-
-    ConfigKey cfgKey;
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    auto& eventActivationMap = metricProducer->mEventActivationMap;
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_TRUE(eventActivationMap.empty());
-
-    int appUid = 123;
-    std::vector<int> attributionUids1 = {appUid};
-    std::vector<string> attributionTags1 = {"App1"};
-
-    auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
-                                            attributionTags1, "wl1");  // 0:10
-    processor->OnLogEvent(event.get());
-
-    event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid);  // 0:22
-    processor->OnLogEvent(event.get());
-
-    event = CreateReleaseWakelockEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1,
-                                       attributionTags1, "wl1");  // 1:00
-    processor->OnLogEvent(event.get());
-
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
-                                        appUid);  // 3:15
-    processor->OnLogEvent(event.get());
-
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(1, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    // Validate dimension value.
-    ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    util::WAKELOCK_STATE_CHANGED, appUid);
-    // Validate bucket info.
-    ASSERT_EQ(1, data.bucket_info_size());
-
-    auto bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_EQ(38 * NS_PER_SEC, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-    *config.add_atom_matcher() = screenOnMatcher;
-
-    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    // The predicate is dimensioning by first attribution node by uid.
-    FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
-                                                             {Position::FIRST});
-    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
-    *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
-            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
-    *config.add_predicate() = isInBackgroundPredicate;
-
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("WakelockDuration"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->set_condition(isInBackgroundPredicate.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    // The metric is dimensioning by first attribution node and only by uid.
-    *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
-            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    // Links between wakelock state atom and condition of app is in background.
-    auto links = durationMetric->add_links();
-    links->set_condition(isInBackgroundPredicate.id());
-    *links->mutable_fields_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    auto dimensionCondition = links->mutable_fields_in_condition();
-    dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
-    dimensionCondition->add_child()->set_field(1);  // uid field.
-
-    auto metric_activation1 = config.add_metric_activation();
-    metric_activation1->set_metric_id(durationMetric->id());
-    auto event_activation1 = metric_activation1->add_event_activation();
-    event_activation1->set_atom_matcher_id(screenOnMatcher.id());
-    event_activation1->set_ttl_seconds(60 * 2);  // 2 minutes.
-
-    ConfigKey cfgKey;
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    auto& eventActivationMap = metricProducer->mEventActivationMap;
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    ASSERT_EQ(eventActivationMap.size(), 1u);
-    EXPECT_TRUE(eventActivationMap.find(4) != eventActivationMap.end());
-    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    int appUid = 123;
-    std::vector<int> attributionUids1 = {appUid};
-    std::vector<string> attributionTags1 = {"App1"};
-
-    auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
-                                            attributionTags1, "wl1");  // 0:10
-    processor->OnLogEvent(event.get());
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid);  // 0:22
-    processor->OnLogEvent(event.get());
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    const int64_t durationStartNs = bucketStartTimeNs + 30 * NS_PER_SEC;  // 0:30
-    event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(event.get());
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
-    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    const int64_t durationEndNs =
-            durationStartNs + (event_activation1->ttl_seconds() + 30) * NS_PER_SEC;  // 3:00
-    event = CreateAppCrashEvent(durationEndNs, 333);
-    processor->OnLogEvent(event.get());
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
-    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
-                                        appUid);  // 3:15
-    processor->OnLogEvent(event.get());
-
-    event = CreateReleaseWakelockEvent(bucketStartTimeNs + (4 * 60 + 17) * NS_PER_SEC,
-                                       attributionUids1, attributionTags1, "wl1");  // 4:17
-    processor->OnLogEvent(event.get());
-
-    event = CreateMoveToBackgroundEvent(bucketStartTimeNs + (4 * 60 + 20) * NS_PER_SEC,
-                                        appUid);  // 4:20
-    processor->OnLogEvent(event.get());
-
-    event = CreateAcquireWakelockEvent(bucketStartTimeNs + (4 * 60 + 25) * NS_PER_SEC,
-                                       attributionUids1, attributionTags1, "wl1");  // 4:25
-    processor->OnLogEvent(event.get());
-
-    const int64_t duration2StartNs = bucketStartTimeNs + (4 * 60 + 30) * NS_PER_SEC;  // 4:30
-    event = CreateScreenStateChangedEvent(duration2StartNs, android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(event.get());
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[4]->start_ns, duration2StartNs);
-    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
-
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(1, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    // Validate dimension value.
-    ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    util::WAKELOCK_STATE_CHANGED, appUid);
-    // Validate bucket info.
-    ASSERT_EQ(2, data.bucket_info_size());
-
-    auto bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(durationEndNs, bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
-
-    bucketInfo = data.bucket_info(1);
-    EXPECT_EQ(durationEndNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - duration2StartNs, bucketInfo.duration_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedState) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
-    *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
-
-    auto batterySaverModePredicate = CreateBatterySaverModePredicate();
-    *config.add_predicate() = batterySaverModePredicate;
-
-    auto screenState = CreateScreenState();
-    *config.add_state() = screenState;
-
-    // Create duration metric that slices by screen state.
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("DurationBatterySaverModeSliceScreen"));
-    durationMetric->set_what(batterySaverModePredicate.id());
-    durationMetric->add_slice_by_state(screenState.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    // Initialize StatsLogProcessor.
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    EXPECT_TRUE(metricsManager->isActive());
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_TRUE(metricProducer->mIsActive);
-    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
-    // Check that StateTrackers were initialized correctly.
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
-    /*
-               bucket #1                      bucket #2
-    |     1     2     3     4     5     6     7     8     9     10 (minutes)
-    |-----------------------------|-----------------------------|--
-        ON              OFF     ON                                  (BatterySaverMode)
-      |          |                   |                              (ScreenIsOnEvent)
-           |                  |                                     (ScreenIsOffEvent)
-              |                                                     (ScreenDozeEvent)
-    */
-    // Initialize log events.
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 10 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));                       // 0:20
-    events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 20 * NS_PER_SEC));  // 0:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 50 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:00
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 80 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 1:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 120 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));                         // 2:10
-    events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 200 * NS_PER_SEC));  // 3:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 250 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));                       // 4:20
-    events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 280 * NS_PER_SEC));  // 4:50
-
-    // Bucket boundary.
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 310 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 5:20
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 360 * NS_PER_SEC,
-                            true /* include current partial bucket */, true, ADB_DUMP, FAST,
-                            &buffer);  // 6:10
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(3, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(1);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(110 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(2);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
-    *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
-    *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
-    *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-
-    auto batterySaverModePredicate = CreateBatterySaverModePredicate();
-    *config.add_predicate() = batterySaverModePredicate;
-
-    auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
-    *config.add_predicate() = deviceUnpluggedPredicate;
-
-    auto screenState = CreateScreenState();
-    *config.add_state() = screenState;
-
-    // Create duration metric that has a condition and slices by screen state.
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("DurationBatterySaverModeOnBatterySliceScreen"));
-    durationMetric->set_what(batterySaverModePredicate.id());
-    durationMetric->set_condition(deviceUnpluggedPredicate.id());
-    durationMetric->add_slice_by_state(screenState.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    // Initialize StatsLogProcessor.
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    EXPECT_TRUE(metricsManager->isActive());
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_TRUE(metricProducer->mIsActive);
-    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
-    // Check that StateTrackers were initialized correctly.
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
-    /*
-               bucket #1                      bucket #2
-    |       1       2       3       4       5     6     7     8  (minutes)
-    |---------------------------------------|------------------
-             ON                          OFF    ON             (BatterySaverMode)
-                  T            F    T                          (DeviceUnpluggedPredicate)
-         |              |              |                       (ScreenIsOnEvent)
-                |           |                       |          (ScreenIsOffEvent)
-                                |                              (ScreenDozeEvent)
-    */
-    // Initialize log events.
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 20 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));                       // 0:30
-    events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 60 * NS_PER_SEC));  // 1:10
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 80 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:30
-    events.push_back(
-            CreateBatteryStateChangedEvent(bucketStartTimeNs + 110 * NS_PER_SEC,
-                                           BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE));  // 2:00
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 145 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 2:35
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 170 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 3:00
-    events.push_back(
-            CreateBatteryStateChangedEvent(bucketStartTimeNs + 180 * NS_PER_SEC,
-                                           BatteryPluggedStateEnum::BATTERY_PLUGGED_USB));  // 3:10
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 200 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 3:30
-    events.push_back(
-            CreateBatteryStateChangedEvent(bucketStartTimeNs + 230 * NS_PER_SEC,
-                                           BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE));  // 4:00
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 260 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));                         // 4:30
-    events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 280 * NS_PER_SEC));  // 4:50
-
-    // Bucket boundary.
-    events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 320 * NS_PER_SEC));  // 5:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 380 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 6:30
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 410 * NS_PER_SEC,
-                            true /* include current partial bucket */, true, ADB_DUMP, FAST,
-                            &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(3, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(1);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(60 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(2);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedStateMapped) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
-    *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
-
-    auto batterySaverModePredicate = CreateBatterySaverModePredicate();
-    *config.add_predicate() = batterySaverModePredicate;
-
-    int64_t screenOnId = 4444;
-    int64_t screenOffId = 9876;
-    auto screenStateWithMap = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
-    *config.add_state() = screenStateWithMap;
-
-    // Create duration metric that slices by mapped screen state.
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("DurationBatterySaverModeSliceScreenMapped"));
-    durationMetric->set_what(batterySaverModePredicate.id());
-    durationMetric->add_slice_by_state(screenStateWithMap.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    // Initialize StatsLogProcessor.
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    EXPECT_TRUE(metricsManager->isActive());
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_TRUE(metricProducer->mIsActive);
-    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
-
-    // Check that StateTrackers were initialized correctly.
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
-    /*
-               bucket #1                      bucket #2
-    |     1     2     3     4     5     6     7     8     9     10 (minutes)
-    |-----------------------------|-----------------------------|--
-        ON              OFF     ON                                  (BatterySaverMode)
-     ---------------------------------------------------------SCREEN_OFF events
-           |                  |                                  (ScreenStateOffEvent = 1)
-              |                                                  (ScreenStateDozeEvent = 3)
-                                                |                (ScreenStateDozeSuspendEvent = 4)
-     ---------------------------------------------------------SCREEN_ON events
-      |          |                   |                           (ScreenStateOnEvent = 2)
-                      |                                          (ScreenStateVrEvent = 5)
-                                            |                    (ScreenStateOnSuspendEvent = 6)
-    */
-    // Initialize log events.
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 10 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));                       // 0:20
-    events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 20 * NS_PER_SEC));  // 0:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 70 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:20
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 100 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 1:50
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 120 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 2:10
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 170 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_VR));                         // 3:00
-    events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 200 * NS_PER_SEC));  // 3:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 250 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_OFF));                       // 4:20
-    events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 280 * NS_PER_SEC));  // 4:50
-
-    // Bucket boundary 5:10.
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 320 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 5:30
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 390 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND));  // 6:40
-    events.push_back(CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 430 * NS_PER_SEC,
-            android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND));  // 7:20
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 490 * NS_PER_SEC,
-                            true /* include current partial bucket */, true, ADB_DUMP, FAST,
-                            &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(2, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(130 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(110 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(1);
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(80 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-}
-
-TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
-    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    auto uidProcessState = CreateUidProcessState();
-    *config.add_state() = uidProcessState;
-
-    // Create duration metric that slices by uid process state.
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("DurationHoldingWakelockSliceUidProcessState"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->add_slice_by_state(uidProcessState.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    // The state has only one primary field (uid).
-    auto stateLink = durationMetric->add_state_link();
-    stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
-    auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    auto fieldsInState = stateLink->mutable_fields_in_state();
-    *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
-    // Initialize StatsLogProcessor.
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // This config is rejected because the dimension in what fields are not a superset of the sliced
-    // state primary fields.
-    ASSERT_EQ(processor->mMetricsManagers.size(), 0);
-}
-
-TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset) {
-    // Initialize config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
-    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    *(holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions()) =
-            CreateAttributionUidAndOtherDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST},
-                                                   {3 /* tag */});
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    auto uidProcessState = CreateUidProcessState();
-    *config.add_state() = uidProcessState;
-
-    // Create duration metric that slices by uid process state.
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("DurationPartialWakelockPerTagUidSliceProcessState"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->add_slice_by_state(uidProcessState.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    // The metric is dimensioning by first uid of attribution node and tag.
-    *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidAndOtherDimensions(
-            util::WAKELOCK_STATE_CHANGED, {Position::FIRST}, {3 /* tag */});
-    // The state has only one primary field (uid).
-    auto stateLink = durationMetric->add_state_link();
-    stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
-    auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    auto fieldsInState = stateLink->mutable_fields_in_state();
-    *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
-    // Initialize StatsLogProcessor.
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    EXPECT_TRUE(metricsManager->isActive());
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_TRUE(metricProducer->mIsActive);
-    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
-    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
-
-    // Check that StateTrackers were initialized correctly.
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
-    // Initialize log events.
-    int appUid1 = 1001;
-    int appUid2 = 1002;
-    std::vector<int> attributionUids1 = {appUid1};
-    std::vector<string> attributionTags1 = {"App1"};
-
-    std::vector<int> attributionUids2 = {appUid2};
-    std::vector<string> attributionTags2 = {"App2"};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 10 * NS_PER_SEC, appUid1,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 0:20
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 20 * NS_PER_SEC,
-                                                attributionUids1, attributionTags1,
-                                                "wakelock1"));  // 0:30
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * NS_PER_SEC,
-                                                attributionUids1, attributionTags1,
-                                                "wakelock2"));  // 0:35
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 30 * NS_PER_SEC,
-                                                attributionUids2, attributionTags2,
-                                                "wakelock1"));  // 0:40
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 35 * NS_PER_SEC,
-                                                attributionUids2, attributionTags2,
-                                                "wakelock2"));  // 0:45
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 50 * NS_PER_SEC, appUid2,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));  // 1:00
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 60 * NS_PER_SEC, appUid1,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));  // 1:10
-    events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 100 * NS_PER_SEC,
-                                                attributionUids2, attributionTags2,
-                                                "wakelock1"));  // 1:50
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 120 * NS_PER_SEC, appUid2,
-            android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE));  // 2:10
-    events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 200 * NS_PER_SEC,
-                                                attributionUids1, attributionTags1,
-                                                "wakelock2"));  // 3:30
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 320 * NS_PER_SEC,
-                            true /* include current partial bucket */, true, ADB_DUMP, FAST,
-                            &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(9, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
-                                                  "wakelock1");
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(1);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
-                                                  "wakelock1");
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(240 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(2);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
-                                                  "wakelock2");
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(35 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(3);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
-                                                  "wakelock2");
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(140 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(4);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
-                                                  "wakelock1");
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(5);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
-                                                  "wakelock1");
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(6);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
-                                                  "wakelock2");
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(15 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(7);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
-                                                  "wakelock2");
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(180 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
-
-    data = durationMetrics.data(8);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
-                                                  "wakelock2");
-    ASSERT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
deleted file mode 100644
index 1be2612..0000000
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ /dev/null
@@ -1,624 +0,0 @@
-// Copyright (C) 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.
-
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-const int64_t metricId = 123456;
-const int32_t ATOM_TAG = util::SUBSYSTEM_SLEEP_STATE;
-
-StatsdConfig CreateStatsdConfig(const GaugeMetric::SamplingType sampling_type,
-                                bool useCondition = true) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
-    auto atomMatcher = CreateSimpleAtomMatcher("TestMatcher", ATOM_TAG);
-    *config.add_atom_matcher() = atomMatcher;
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
-    auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-    *config.add_predicate() = screenIsOffPredicate;
-
-    auto gaugeMetric = config.add_gauge_metric();
-    gaugeMetric->set_id(metricId);
-    gaugeMetric->set_what(atomMatcher.id());
-    if (useCondition) {
-        gaugeMetric->set_condition(screenIsOffPredicate.id());
-    }
-    gaugeMetric->set_sampling_type(sampling_type);
-    gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
-    *gaugeMetric->mutable_dimensions_in_what() =
-            CreateDimensions(ATOM_TAG, {1 /* subsystem name */});
-    gaugeMetric->set_bucket(FIVE_MINUTES);
-    gaugeMetric->set_max_pull_delay_sec(INT_MAX);
-    config.set_hash_strings_in_metric_report(false);
-
-    return config;
-}
-
-}  // namespaces
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
-    auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor =
-            CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                    SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    processor->mPullerManager->ForceClearPullerCache();
-
-    int startBucketNum = processor->mMetricsManagers.begin()
-                                 ->second->mAllMetricProducers[0]
-                                 ->getCurrentBucketNum();
-    EXPECT_GT(startBucketNum, (int64_t)0);
-
-    // When creating the config, the gauge metric producer should register the alarm at the
-    // end of the current bucket.
-    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
-    EXPECT_EQ(bucketSizeNs,
-              processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
-    int64_t& nextPullTimeNs =
-            processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
-    auto screenOffEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    // Pulling alarm arrives on time and reset the sequential pulling alarm.
-    processor->informPullAlarmFired(nextPullTimeNs + 1);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
-
-    auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
-                                                       android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-
-    screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
-                                                   android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    processor->informPullAlarmFired(nextPullTimeNs + 1);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
-
-    processor->informPullAlarmFired(nextPullTimeNs + 1);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
-
-    screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
-                                                  android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-
-    processor->informPullAlarmFired(nextPullTimeNs + 3);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
-
-    screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
-                                                   android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    processor->informPullAlarmFired(nextPullTimeNs + 2);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, nextPullTimeNs);
-
-    processor->informPullAlarmFired(nextPullTimeNs + 2);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
-                            ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    ASSERT_GT((int)gaugeMetrics.data_size(), 1);
-
-    auto data = gaugeMetrics.data(0);
-    EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* subsystem name field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    ASSERT_EQ(6, data.bucket_info_size());
-
-    ASSERT_EQ(1, data.bucket_info(0).atom_size());
-    ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(1).atom_size());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(2).atom_size());
-    ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(3).atom_size());
-    ASSERT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 1, data.bucket_info(3).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(3).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(3).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(4).atom_size());
-    ASSERT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(4).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(4).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(4).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(5).atom_size());
-    ASSERT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs + 2, data.bucket_info(5).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(5).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(5).atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) {
-    auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE);
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor =
-            CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                    SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    processor->mPullerManager->ForceClearPullerCache();
-
-    int startBucketNum = processor->mMetricsManagers.begin()
-                                 ->second->mAllMetricProducers[0]
-                                 ->getCurrentBucketNum();
-    EXPECT_GT(startBucketNum, (int64_t)0);
-
-    auto screenOffEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
-                                                       android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-
-    screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 100,
-                                                   android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 2,
-                                                  android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-
-    screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 1,
-                                                   android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-    screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 3,
-                                                  android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-    screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 5 * bucketSizeNs + 10,
-                                                   android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true,
-                            ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    ASSERT_GT((int)gaugeMetrics.data_size(), 1);
-
-    auto data = gaugeMetrics.data(0);
-    EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* subsystem name field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    ASSERT_EQ(3, data.bucket_info_size());
-
-    ASSERT_EQ(1, data.bucket_info(0).atom_size());
-    ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(1).atom_size());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100, data.bucket_info(1).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(2, data.bucket_info(2).atom_size());
-    ASSERT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 10, data.bucket_info(2).elapsed_timestamp_nanos(1));
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-    EXPECT_TRUE(data.bucket_info(2).atom(1).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(2).atom(1).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
-    auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE);
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor =
-            CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                    SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    processor->mPullerManager->ForceClearPullerCache();
-
-    int startBucketNum = processor->mMetricsManagers.begin()
-                                 ->second->mAllMetricProducers[0]
-                                 ->getCurrentBucketNum();
-    EXPECT_GT(startBucketNum, (int64_t)0);
-
-    // When creating the config, the gauge metric producer should register the alarm at the
-    // end of the current bucket.
-    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
-    EXPECT_EQ(bucketSizeNs,
-              processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
-    int64_t& nextPullTimeNs =
-            processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
-    auto screenOffEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    auto screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + bucketSizeNs + 10,
-                                                       android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-
-    // Pulling alarm arrives one bucket size late.
-    processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
-
-    screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 3 * bucketSizeNs + 11,
-                                                   android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    // Pulling alarm arrives more than one bucket size late.
-    processor->informPullAlarmFired(nextPullTimeNs + bucketSizeNs + 12);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
-                            ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    ASSERT_GT((int)gaugeMetrics.data_size(), 1);
-
-    auto data = gaugeMetrics.data(0);
-    EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* subsystem name field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    ASSERT_EQ(3, data.bucket_info_size());
-
-    ASSERT_EQ(1, data.bucket_info(0).atom_size());
-    ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(1).atom_size());
-    EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11,
-              data.bucket_info(1).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(2).atom_size());
-    ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs + 12, data.bucket_info(2).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation) {
-    auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
-
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
-    auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
-    *config.add_atom_matcher() = batterySaverStartMatcher;
-    const int64_t ttlNs = 2 * bucketSizeNs;  // Two buckets.
-    auto metric_activation = config.add_metric_activation();
-    metric_activation->set_metric_id(metricId);
-    metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
-    auto event_activation = metric_activation->add_event_activation();
-    event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
-    event_activation->set_ttl_seconds(ttlNs / 1000000000);
-
-    ConfigKey cfgKey;
-    auto processor =
-            CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                    SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    processor->mPullerManager->ForceClearPullerCache();
-
-    int startBucketNum = processor->mMetricsManagers.begin()
-                                 ->second->mAllMetricProducers[0]
-                                 ->getCurrentBucketNum();
-    EXPECT_GT(startBucketNum, (int64_t)0);
-    EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
-    // When creating the config, the gauge metric producer should register the alarm at the
-    // end of the current bucket.
-    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
-    EXPECT_EQ(bucketSizeNs,
-              processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
-    int64_t& nextPullTimeNs =
-            processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
-    // Pulling alarm arrives on time and reset the sequential pulling alarm.
-    // Event should not be kept.
-    processor->informPullAlarmFired(nextPullTimeNs + 1);  // 15 mins + 1 ns.
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
-    EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
-    // Activate the metric. A pull occurs upon activation.
-    const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000);  // 2 millis.
-    auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
-    processor->OnLogEvent(batterySaverOnEvent.get());  // 15 mins + 2 ms.
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
-    // This event should be kept. 2 total.
-    processor->informPullAlarmFired(nextPullTimeNs + 1);  // 20 mins + 1 ns.
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, nextPullTimeNs);
-
-    // This event should be kept. 3 total.
-    processor->informPullAlarmFired(nextPullTimeNs + 2);  // 25 mins + 2 ns.
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
-
-    // Create random event to deactivate metric.
-    auto deactivationEvent = CreateScreenBrightnessChangedEvent(activationNs + ttlNs + 1, 50);
-    processor->OnLogEvent(deactivationEvent.get());
-    EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
-    // Event should not be kept. 3 total.
-    processor->informPullAlarmFired(nextPullTimeNs + 3);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
-
-    processor->informPullAlarmFired(nextPullTimeNs + 2);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
-                            ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    ASSERT_GT((int)gaugeMetrics.data_size(), 0);
-
-    auto data = gaugeMetrics.data(0);
-    EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* subsystem name field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    ASSERT_EQ(3, data.bucket_info_size());
-
-    auto bucketInfo = data.bucket_info(0);
-    ASSERT_EQ(1, bucketInfo.atom_size());
-    ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
-    EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0));
-    ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    bucketInfo = data.bucket_info(1);
-    ASSERT_EQ(1, bucketInfo.atom_size());
-    ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0));
-    ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    bucketInfo = data.bucket_info(2);
-    ASSERT_EQ(1, bucketInfo.atom_size());
-    ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0));
-    ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
-              bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(MillisToNano(NanoToMillis(activationNs + ttlNs + 1)),
-              bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) {
-    auto config = CreateStatsdConfig(GaugeMetric::RANDOM_ONE_SAMPLE, /*useCondition=*/false);
-
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
-    int64_t bucketSizeNs =
-        TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
-                                             ATOM_TAG);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    processor->mPullerManager->ForceClearPullerCache();
-
-    int startBucketNum = processor->mMetricsManagers.begin()->second->
-            mAllMetricProducers[0]->getCurrentBucketNum();
-    EXPECT_GT(startBucketNum, (int64_t)0);
-
-    // When creating the config, the gauge metric producer should register the alarm at the
-    // end of the current bucket.
-    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
-    EXPECT_EQ(bucketSizeNs,
-              processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
-    int64_t& nextPullTimeNs =
-            processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs);
-
-    // Pulling alarm arrives on time and reset the sequential pulling alarm.
-    processor->informPullAlarmFired(nextPullTimeNs + 1);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
-
-    processor->informPullAlarmFired(nextPullTimeNs + 4);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs,
-              nextPullTimeNs);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
-                            ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
-    sortMetricDataByDimensionsValue(
-            reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    ASSERT_GT((int)gaugeMetrics.data_size(), 0);
-
-    auto data = gaugeMetrics.data(0);
-    EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* subsystem name field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    ASSERT_EQ(3, data.bucket_info_size());
-
-    ASSERT_EQ(1, data.bucket_info(0).atom_size());
-    ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(1).atom_size());
-    ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
-    ASSERT_EQ(0, data.bucket_info(1).wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
-
-    ASSERT_EQ(1, data.bucket_info(2).atom_size());
-    ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 4, data.bucket_info(2).elapsed_timestamp_nanos(0));
-    ASSERT_EQ(0, data.bucket_info(2).wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
deleted file mode 100644
index a40a948..0000000
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright (C) 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.
-
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfigForPushedEvent(const GaugeMetric::SamplingType sampling_type) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
-    auto atomMatcher = CreateSimpleAtomMatcher("", util::APP_START_OCCURRED);
-    *config.add_atom_matcher() = atomMatcher;
-
-    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
-    *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
-        CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
-    *config.add_predicate() = isInBackgroundPredicate;
-
-    auto gaugeMetric = config.add_gauge_metric();
-    gaugeMetric->set_id(123456);
-    gaugeMetric->set_what(atomMatcher.id());
-    gaugeMetric->set_condition(isInBackgroundPredicate.id());
-    gaugeMetric->mutable_gauge_fields_filter()->set_include_all(false);
-    gaugeMetric->set_sampling_type(sampling_type);
-    auto fieldMatcher = gaugeMetric->mutable_gauge_fields_filter()->mutable_fields();
-    fieldMatcher->set_field(util::APP_START_OCCURRED);
-    fieldMatcher->add_child()->set_field(3);  // type (enum)
-    fieldMatcher->add_child()->set_field(4);  // activity_name(str)
-    fieldMatcher->add_child()->set_field(7);  // activity_start_msec(int64)
-    *gaugeMetric->mutable_dimensions_in_what() =
-        CreateDimensions(util::APP_START_OCCURRED, {1 /* uid field */ });
-    gaugeMetric->set_bucket(FIVE_MINUTES);
-
-    auto links = gaugeMetric->add_links();
-    links->set_condition(isInBackgroundPredicate.id());
-    auto dimensionWhat = links->mutable_fields_in_what();
-    dimensionWhat->set_field(util::APP_START_OCCURRED);
-    dimensionWhat->add_child()->set_field(1);  // uid field.
-    auto dimensionCondition = links->mutable_fields_in_condition();
-    dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
-    dimensionCondition->add_child()->set_field(1);  // uid field.
-    return config;
-}
-
-std::unique_ptr<LogEvent> CreateAppStartOccurredEvent(
-        uint64_t timestampNs, const int uid, const string& pkg_name,
-        AppStartOccurred::TransitionType type, const string& activity_name,
-        const string& calling_pkg_name, const bool is_instant_app, int64_t activity_start_msec) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::APP_START_OCCURRED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_writeString(statsEvent, pkg_name.c_str());
-    AStatsEvent_writeInt32(statsEvent, type);
-    AStatsEvent_writeString(statsEvent, activity_name.c_str());
-    AStatsEvent_writeString(statsEvent, calling_pkg_name.c_str());
-    AStatsEvent_writeInt32(statsEvent, is_instant_app);
-    AStatsEvent_writeInt32(statsEvent, activity_start_msec);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-}  // namespace
-
-TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
-    for (const auto& sampling_type :
-         {GaugeMetric::FIRST_N_SAMPLES, GaugeMetric::RANDOM_ONE_SAMPLE}) {
-        auto config = CreateStatsdConfigForPushedEvent(sampling_type);
-        int64_t bucketStartTimeNs = 10000000000;
-        int64_t bucketSizeNs =
-                TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
-        ConfigKey cfgKey;
-        auto processor =
-                CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-        ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-        EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
-        int appUid1 = 123;
-        int appUid2 = 456;
-        std::vector<std::unique_ptr<LogEvent>> events;
-        events.push_back(CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid1));
-        events.push_back(
-                CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid1));
-        events.push_back(
-                CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid1));
-        events.push_back(
-                CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100, appUid1));
-
-        events.push_back(CreateAppStartOccurredEvent(
-                bucketStartTimeNs + 10, appUid1, "app1", AppStartOccurred::WARM, "activity_name1",
-                "calling_pkg_name1", true /*is_instant_app*/, 101 /*activity_start_msec*/));
-        events.push_back(CreateAppStartOccurredEvent(
-                bucketStartTimeNs + 20, appUid1, "app1", AppStartOccurred::HOT, "activity_name2",
-                "calling_pkg_name2", true /*is_instant_app*/, 102 /*activity_start_msec*/));
-        events.push_back(CreateAppStartOccurredEvent(
-                bucketStartTimeNs + 30, appUid1, "app1", AppStartOccurred::COLD, "activity_name3",
-                "calling_pkg_name3", true /*is_instant_app*/, 103 /*activity_start_msec*/));
-        events.push_back(CreateAppStartOccurredEvent(
-                bucketStartTimeNs + bucketSizeNs + 30, appUid1, "app1", AppStartOccurred::WARM,
-                "activity_name4", "calling_pkg_name4", true /*is_instant_app*/,
-                104 /*activity_start_msec*/));
-        events.push_back(CreateAppStartOccurredEvent(
-                bucketStartTimeNs + 2 * bucketSizeNs, appUid1, "app1", AppStartOccurred::COLD,
-                "activity_name5", "calling_pkg_name5", true /*is_instant_app*/,
-                105 /*activity_start_msec*/));
-        events.push_back(CreateAppStartOccurredEvent(
-                bucketStartTimeNs + 2 * bucketSizeNs + 10, appUid1, "app1", AppStartOccurred::HOT,
-                "activity_name6", "calling_pkg_name6", false /*is_instant_app*/,
-                106 /*activity_start_msec*/));
-
-        events.push_back(
-                CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 10, appUid2));
-        events.push_back(CreateAppStartOccurredEvent(
-                bucketStartTimeNs + 2 * bucketSizeNs + 10, appUid2, "app2", AppStartOccurred::COLD,
-                "activity_name7", "calling_pkg_name7", true /*is_instant_app*/,
-                201 /*activity_start_msec*/));
-
-        sortLogEventsByTimestamp(&events);
-
-        for (const auto& event : events) {
-            processor->OnLogEvent(event.get());
-        }
-        ConfigMetricsReportList reports;
-        vector<uint8_t> buffer;
-        processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, true, ADB_DUMP,
-                                FAST, &buffer);
-        EXPECT_TRUE(buffer.size() > 0);
-        EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-        backfillDimensionPath(&reports);
-        backfillStringInReport(&reports);
-        backfillStartEndTimestamp(&reports);
-        ASSERT_EQ(1, reports.reports_size());
-        ASSERT_EQ(1, reports.reports(0).metrics_size());
-        StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
-        sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(),
-                                        &gaugeMetrics);
-        ASSERT_EQ(2, gaugeMetrics.data_size());
-
-        auto data = gaugeMetrics.data(0);
-        EXPECT_EQ(util::APP_START_OCCURRED, data.dimensions_in_what().field());
-        ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-        EXPECT_EQ(1 /* uid field */,
-                  data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-        EXPECT_EQ(appUid1, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-        ASSERT_EQ(3, data.bucket_info_size());
-        if (sampling_type == GaugeMetric::FIRST_N_SAMPLES) {
-            ASSERT_EQ(2, data.bucket_info(0).atom_size());
-            ASSERT_EQ(2, data.bucket_info(0).elapsed_timestamp_nanos_size());
-            ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
-            EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-            EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
-                      data.bucket_info(0).end_bucket_elapsed_nanos());
-            EXPECT_EQ(AppStartOccurred::HOT,
-                      data.bucket_info(0).atom(0).app_start_occurred().type());
-            EXPECT_EQ("activity_name2",
-                      data.bucket_info(0).atom(0).app_start_occurred().activity_name());
-            EXPECT_EQ(102L,
-                      data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
-            EXPECT_EQ(AppStartOccurred::COLD,
-                      data.bucket_info(0).atom(1).app_start_occurred().type());
-            EXPECT_EQ("activity_name3",
-                      data.bucket_info(0).atom(1).app_start_occurred().activity_name());
-            EXPECT_EQ(103L,
-                      data.bucket_info(0).atom(1).app_start_occurred().activity_start_millis());
-
-            ASSERT_EQ(1, data.bucket_info(1).atom_size());
-            ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
-            EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
-                      data.bucket_info(1).start_bucket_elapsed_nanos());
-            EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-                      data.bucket_info(1).end_bucket_elapsed_nanos());
-            EXPECT_EQ(AppStartOccurred::WARM,
-                      data.bucket_info(1).atom(0).app_start_occurred().type());
-            EXPECT_EQ("activity_name4",
-                      data.bucket_info(1).atom(0).app_start_occurred().activity_name());
-            EXPECT_EQ(104L,
-                      data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
-
-            ASSERT_EQ(2, data.bucket_info(2).atom_size());
-            ASSERT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
-            EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-                      data.bucket_info(2).start_bucket_elapsed_nanos());
-            EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
-                      data.bucket_info(2).end_bucket_elapsed_nanos());
-            EXPECT_EQ(AppStartOccurred::COLD,
-                      data.bucket_info(2).atom(0).app_start_occurred().type());
-            EXPECT_EQ("activity_name5",
-                      data.bucket_info(2).atom(0).app_start_occurred().activity_name());
-            EXPECT_EQ(105L,
-                      data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
-            EXPECT_EQ(AppStartOccurred::HOT,
-                      data.bucket_info(2).atom(1).app_start_occurred().type());
-            EXPECT_EQ("activity_name6",
-                      data.bucket_info(2).atom(1).app_start_occurred().activity_name());
-            EXPECT_EQ(106L,
-                      data.bucket_info(2).atom(1).app_start_occurred().activity_start_millis());
-        } else {
-            ASSERT_EQ(1, data.bucket_info(0).atom_size());
-            ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
-            EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-            EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
-                      data.bucket_info(0).end_bucket_elapsed_nanos());
-            EXPECT_EQ(AppStartOccurred::HOT,
-                      data.bucket_info(0).atom(0).app_start_occurred().type());
-            EXPECT_EQ("activity_name2",
-                      data.bucket_info(0).atom(0).app_start_occurred().activity_name());
-            EXPECT_EQ(102L,
-                      data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
-
-            ASSERT_EQ(1, data.bucket_info(1).atom_size());
-            ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
-            EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
-                      data.bucket_info(1).start_bucket_elapsed_nanos());
-            EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-                      data.bucket_info(1).end_bucket_elapsed_nanos());
-            EXPECT_EQ(AppStartOccurred::WARM,
-                      data.bucket_info(1).atom(0).app_start_occurred().type());
-            EXPECT_EQ("activity_name4",
-                      data.bucket_info(1).atom(0).app_start_occurred().activity_name());
-            EXPECT_EQ(104L,
-                      data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
-
-            ASSERT_EQ(1, data.bucket_info(2).atom_size());
-            ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
-            EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-                      data.bucket_info(2).start_bucket_elapsed_nanos());
-            EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
-                      data.bucket_info(2).end_bucket_elapsed_nanos());
-            EXPECT_EQ(AppStartOccurred::COLD,
-                      data.bucket_info(2).atom(0).app_start_occurred().type());
-            EXPECT_EQ("activity_name5",
-                      data.bucket_info(2).atom(0).app_start_occurred().activity_name());
-            EXPECT_EQ(105L,
-                      data.bucket_info(2).atom(0).app_start_occurred().activity_start_millis());
-        }
-
-        data = gaugeMetrics.data(1);
-
-        EXPECT_EQ(data.dimensions_in_what().field(), util::APP_START_OCCURRED);
-        ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
-        EXPECT_EQ(1 /* uid field */,
-                  data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-        EXPECT_EQ(appUid2, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-        ASSERT_EQ(1, data.bucket_info_size());
-        ASSERT_EQ(1, data.bucket_info(0).atom_size());
-        ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
-        EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-                  data.bucket_info(0).start_bucket_elapsed_nanos());
-        EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
-                  data.bucket_info(0).end_bucket_elapsed_nanos());
-        EXPECT_EQ(AppStartOccurred::COLD, data.bucket_info(0).atom(0).app_start_occurred().type());
-        EXPECT_EQ("activity_name7",
-                  data.bucket_info(0).atom(0).app_start_occurred().activity_name());
-        EXPECT_EQ(201L, data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
-    }
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
deleted file mode 100644
index e320419..0000000
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ /dev/null
@@ -1,1833 +0,0 @@
-// Copyright (C) 2018 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.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
-    auto crashMatcher = CreateProcessCrashAtomMatcher();
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-
-    *config.add_atom_matcher() = saverModeMatcher;
-    *config.add_atom_matcher() = crashMatcher;
-    *config.add_atom_matcher() = screenOnMatcher;
-
-    int64_t metricId = 123456;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(crashMatcher.id());
-    countMetric->set_bucket(FIVE_MINUTES);
-    countMetric->mutable_dimensions_in_what()->set_field(
-        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
-
-    auto metric_activation1 = config.add_metric_activation();
-    metric_activation1->set_metric_id(metricId);
-    auto event_activation1 = metric_activation1->add_event_activation();
-    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
-    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
-    auto event_activation2 = metric_activation1->add_event_activation();
-    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
-    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
-
-    return config;
-}
-
-StatsdConfig CreateStatsdConfigWithOneDeactivation() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
-    auto crashMatcher = CreateProcessCrashAtomMatcher();
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
-
-    *config.add_atom_matcher() = saverModeMatcher;
-    *config.add_atom_matcher() = crashMatcher;
-    *config.add_atom_matcher() = screenOnMatcher;
-    *config.add_atom_matcher() = brightnessChangedMatcher;
-
-    int64_t metricId = 123456;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(crashMatcher.id());
-    countMetric->set_bucket(FIVE_MINUTES);
-    countMetric->mutable_dimensions_in_what()->set_field(
-        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
-
-    auto metric_activation1 = config.add_metric_activation();
-    metric_activation1->set_metric_id(metricId);
-    auto event_activation1 = metric_activation1->add_event_activation();
-    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
-    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
-    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
-    auto event_activation2 = metric_activation1->add_event_activation();
-    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
-    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
-
-    return config;
-}
-
-StatsdConfig CreateStatsdConfigWithTwoDeactivations() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
-    auto crashMatcher = CreateProcessCrashAtomMatcher();
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    auto brightnessChangedMatcher2 = CreateScreenBrightnessChangedAtomMatcher();
-    brightnessChangedMatcher2.set_id(StringToId("ScreenBrightnessChanged2"));
-
-    *config.add_atom_matcher() = saverModeMatcher;
-    *config.add_atom_matcher() = crashMatcher;
-    *config.add_atom_matcher() = screenOnMatcher;
-    *config.add_atom_matcher() = brightnessChangedMatcher;
-    *config.add_atom_matcher() = brightnessChangedMatcher2;
-
-    int64_t metricId = 123456;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(crashMatcher.id());
-    countMetric->set_bucket(FIVE_MINUTES);
-    countMetric->mutable_dimensions_in_what()->set_field(
-        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
-
-    auto metric_activation1 = config.add_metric_activation();
-    metric_activation1->set_metric_id(metricId);
-    auto event_activation1 = metric_activation1->add_event_activation();
-    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
-    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
-    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
-    auto event_activation2 = metric_activation1->add_event_activation();
-    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
-    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
-    event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
-
-    return config;
-}
-
-StatsdConfig CreateStatsdConfigWithSameDeactivations() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
-    auto crashMatcher = CreateProcessCrashAtomMatcher();
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
-
-    *config.add_atom_matcher() = saverModeMatcher;
-    *config.add_atom_matcher() = crashMatcher;
-    *config.add_atom_matcher() = screenOnMatcher;
-    *config.add_atom_matcher() = brightnessChangedMatcher;
-
-    int64_t metricId = 123456;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(crashMatcher.id());
-    countMetric->set_bucket(FIVE_MINUTES);
-    countMetric->mutable_dimensions_in_what()->set_field(
-        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
-
-    auto metric_activation1 = config.add_metric_activation();
-    metric_activation1->set_metric_id(metricId);
-    auto event_activation1 = metric_activation1->add_event_activation();
-    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
-    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
-    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
-    auto event_activation2 = metric_activation1->add_event_activation();
-    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
-    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
-    event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
-
-    return config;
-}
-
-StatsdConfig CreateStatsdConfigWithTwoMetricsTwoDeactivations() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
-    auto crashMatcher = CreateProcessCrashAtomMatcher();
-    auto foregroundMatcher = CreateMoveToForegroundAtomMatcher();
-    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    auto brightnessChangedMatcher2 = CreateScreenBrightnessChangedAtomMatcher();
-    brightnessChangedMatcher2.set_id(StringToId("ScreenBrightnessChanged2"));
-
-    *config.add_atom_matcher() = saverModeMatcher;
-    *config.add_atom_matcher() = crashMatcher;
-    *config.add_atom_matcher() = screenOnMatcher;
-    *config.add_atom_matcher() = brightnessChangedMatcher;
-    *config.add_atom_matcher() = brightnessChangedMatcher2;
-    *config.add_atom_matcher() = foregroundMatcher;
-
-    int64_t metricId = 123456;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(crashMatcher.id());
-    countMetric->set_bucket(FIVE_MINUTES);
-    countMetric->mutable_dimensions_in_what()->set_field(
-        util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
-
-    int64_t metricId2 = 234567;
-    countMetric = config.add_count_metric();
-    countMetric->set_id(metricId2);
-    countMetric->set_what(foregroundMatcher.id());
-    countMetric->set_bucket(FIVE_MINUTES);
-    countMetric->mutable_dimensions_in_what()->set_field(
-        util::ACTIVITY_FOREGROUND_STATE_CHANGED);
-    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
-
-    auto metric_activation1 = config.add_metric_activation();
-    metric_activation1->set_metric_id(metricId);
-    auto event_activation1 = metric_activation1->add_event_activation();
-    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
-    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
-    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
-    auto event_activation2 = metric_activation1->add_event_activation();
-    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
-    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
-    event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
-
-    metric_activation1 = config.add_metric_activation();
-    metric_activation1->set_metric_id(metricId2);
-    event_activation1 = metric_activation1->add_event_activation();
-    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
-    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
-    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
-    event_activation2 = metric_activation1->add_event_activation();
-    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
-    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
-    event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
-
-    return config;
-}
-
-}  // namespace
-
-TEST(MetricActivationE2eTest, TestCountMetric) {
-    auto config = CreateStatsdConfig();
-
-    int64_t bucketStartTimeNs = NS_PER_SEC * 10;  // 10 secs
-    int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    vector<int64_t> activeConfigsBroadcast;
-
-    long timeBase1 = 1;
-    int broadcastCount = 0;
-    StatsLogProcessor processor(
-            m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
-            [](const ConfigKey& key) { return true; },
-            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
-                                                             const vector<int64_t>& activeConfigs) {
-                broadcastCount++;
-                EXPECT_EQ(broadcastUid, uid);
-                activeConfigsBroadcast.clear();
-                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
-                                              activeConfigs.end());
-                return true;
-            });
-
-    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
-    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    auto& eventActivationMap = metricProducer->mEventActivationMap;
-
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
-    // triggered by screen on event (tracker index 2).
-    ASSERT_EQ(eventActivationMap.size(), 2u);
-    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
-    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
-    std::unique_ptr<LogEvent> event;
-
-    event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 0);
-
-    // Activated by battery save mode.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 1);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
-    // First processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
-    // Activated by screen on event.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
-    // 2nd processed event.
-    // The activation by screen_on event expires, but the one by battery save mode is still active.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    // No new broadcast since the config should still be active.
-    EXPECT_EQ(broadcastCount, 1);
-
-    // 3rd processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
-    // All activations expired.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // New broadcast since the config is no longer active.
-    EXPECT_EQ(broadcastCount, 2);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
-    // Re-activate metric via screen on.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
-                                          android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-
-    // 4th processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
-                           ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(4, countMetrics.data_size());
-
-    auto data = countMetrics.data(0);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(1);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(2);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    // Partial bucket as metric is deactivated.
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(3);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation) {
-    auto config = CreateStatsdConfigWithOneDeactivation();
-
-    int64_t bucketStartTimeNs = NS_PER_SEC * 10;  // 10 secs
-    int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    vector<int64_t> activeConfigsBroadcast;
-
-    long timeBase1 = 1;
-    int broadcastCount = 0;
-    StatsLogProcessor processor(
-            m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
-            [](const ConfigKey& key) { return true; },
-            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
-                                                             const vector<int64_t>& activeConfigs) {
-                broadcastCount++;
-                EXPECT_EQ(broadcastUid, uid);
-                activeConfigsBroadcast.clear();
-                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
-                                              activeConfigs.end());
-                return true;
-            });
-
-    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
-    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    auto& eventActivationMap = metricProducer->mEventActivationMap;
-    auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
-    // triggered by screen on event (tracker index 2).
-    ASSERT_EQ(eventActivationMap.size(), 2u);
-    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
-    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    ASSERT_EQ(eventDeactivationMap.size(), 1u);
-    EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
-    ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    std::unique_ptr<LogEvent> event;
-
-    event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 0);
-
-    // Activated by battery save mode.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 1);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    // First processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
-    // Activated by screen on event.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    // 2nd processed event.
-    // The activation by screen_on event expires, but the one by battery save mode is still active.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    // No new broadcast since the config should still be active.
-    EXPECT_EQ(broadcastCount, 1);
-
-    // 3rd processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
-    // All activations expired.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // New broadcast since the config is no longer active.
-    EXPECT_EQ(broadcastCount, 2);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    // Re-activate metric via screen on.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
-                                          android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    // 4th processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
-    // Re-enable battery saver mode activation.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    // 5th processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 777);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-
-    // Cancel battery saver mode activation.
-    event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60, 64);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    // Screen-on activation expired.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 888);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // New broadcast since the config is no longer active.
-    EXPECT_EQ(broadcastCount, 4);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 999);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-
-    // Re-enable battery saver mode activation.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 5);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    // Cancel battery saver mode activation.
-    event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 16, 140);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 6);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
-                           ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(5, countMetrics.data_size());
-
-    auto data = countMetrics.data(0);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(1);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(2);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    // Partial bucket as metric is deactivated.
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(3);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 13,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(4);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 13,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations) {
-    auto config = CreateStatsdConfigWithTwoDeactivations();
-
-    int64_t bucketStartTimeNs = NS_PER_SEC * 10;  // 10 secs
-    int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    vector<int64_t> activeConfigsBroadcast;
-
-    long timeBase1 = 1;
-    int broadcastCount = 0;
-    StatsLogProcessor processor(
-            m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
-            [](const ConfigKey& key) { return true; },
-            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
-                                                             const vector<int64_t>& activeConfigs) {
-                broadcastCount++;
-                EXPECT_EQ(broadcastUid, uid);
-                activeConfigsBroadcast.clear();
-                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
-                                              activeConfigs.end());
-                return true;
-            });
-
-    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
-    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    auto& eventActivationMap = metricProducer->mEventActivationMap;
-    auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
-    // triggered by screen on event (tracker index 2).
-    ASSERT_EQ(eventActivationMap.size(), 2u);
-    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
-    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    ASSERT_EQ(eventDeactivationMap.size(), 2u);
-    EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
-    EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
-    ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
-    ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    std::unique_ptr<LogEvent> event;
-
-    event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 0);
-
-    // Activated by battery save mode.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 1);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    // First processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
-    // Activated by screen on event.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    // 2nd processed event.
-    // The activation by screen_on event expires, but the one by battery save mode is still active.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    // No new broadcast since the config should still be active.
-    EXPECT_EQ(broadcastCount, 1);
-
-    // 3rd processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
-    // All activations expired.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // New broadcast since the config is no longer active.
-    EXPECT_EQ(broadcastCount, 2);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    // Re-activate metric via screen on.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
-                                          android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    // 4th processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
-    // Re-enable battery saver mode activation.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    // 5th processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 777);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-
-    // Cancel battery saver mode and screen on activation.
-    event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60, 64);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // New broadcast since the config is no longer active.
-    EXPECT_EQ(broadcastCount, 4);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    // Screen-on activation expired.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 888);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 4);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 999);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-
-    // Re-enable battery saver mode activation.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 5);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    // Cancel battery saver mode and screen on activation.
-    event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 16, 140);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 6);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
-                           ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(5, countMetrics.data_size());
-
-    auto data = countMetrics.data(0);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(1);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(2);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    // Partial bucket as metric is deactivated.
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(3);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(4);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation) {
-    auto config = CreateStatsdConfigWithSameDeactivations();
-
-    int64_t bucketStartTimeNs = NS_PER_SEC * 10;  // 10 secs
-    int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    vector<int64_t> activeConfigsBroadcast;
-
-    long timeBase1 = 1;
-    int broadcastCount = 0;
-    StatsLogProcessor processor(
-            m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
-            [](const ConfigKey& key) { return true; },
-            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
-                                                             const vector<int64_t>& activeConfigs) {
-                broadcastCount++;
-                EXPECT_EQ(broadcastUid, uid);
-                activeConfigsBroadcast.clear();
-                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
-                                              activeConfigs.end());
-                return true;
-            });
-
-    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
-    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    auto& eventActivationMap = metricProducer->mEventActivationMap;
-    auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
-    // triggered by screen on event (tracker index 2).
-    ASSERT_EQ(eventActivationMap.size(), 2u);
-    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
-    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    ASSERT_EQ(eventDeactivationMap.size(), 1u);
-    EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
-    ASSERT_EQ(eventDeactivationMap[3].size(), 2u);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[3][1], eventActivationMap[2]);
-    EXPECT_EQ(broadcastCount, 0);
-
-    std::unique_ptr<LogEvent> event;
-
-    // Event that should be ignored.
-    event = CreateAppCrashEvent(bucketStartTimeNs + 1, 111);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 1);
-
-    // Activate metric via screen on for 2 minutes.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + 10, android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 1);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
-
-    // 1st processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
-    // Enable battery saver mode activation for 5 minutes.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 + 10);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 1);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 + 10);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
-
-    // 2nd processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 + 40, 333);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 + 40);
-
-    // Cancel battery saver mode and screen on activation.
-    int64_t firstDeactivation = bucketStartTimeNs + NS_PER_SEC * 61;
-    event = CreateScreenBrightnessChangedEvent(firstDeactivation, 64);
-    processor.OnLogEvent(event.get(), firstDeactivation);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    // New broadcast since the config is no longer active.
-    EXPECT_EQ(broadcastCount, 2);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-
-    // Should be ignored
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 61 + 80, 444);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 61 + 80);
-
-    // Re-enable battery saver mode activation.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-
-    // 3rd processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 80, 555);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 80);
-
-    // Cancel battery saver mode activation.
-    int64_t secondDeactivation = bucketStartTimeNs + NS_PER_SEC * 60 * 13;
-    event = CreateScreenBrightnessChangedEvent(secondDeactivation, 140);
-    processor.OnLogEvent(event.get(), secondDeactivation);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(broadcastCount, 4);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-
-    // Should be ignored.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13 + 80, 666);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13 + 80);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
-                           ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(3, countMetrics.data_size());
-
-    auto data = countMetrics.data(0);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(1);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(2);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(555, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    // Partial bucket as metric is deactivated.
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(secondDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations) {
-    auto config = CreateStatsdConfigWithTwoMetricsTwoDeactivations();
-
-    int64_t bucketStartTimeNs = NS_PER_SEC * 10;  // 10 secs
-    int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
-
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    sp<UidMap> m = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> subscriberAlarmMonitor;
-    vector<int64_t> activeConfigsBroadcast;
-
-    long timeBase1 = 1;
-    int broadcastCount = 0;
-    StatsLogProcessor processor(
-            m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
-            [](const ConfigKey& key) { return true; },
-            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
-                                                             const vector<int64_t>& activeConfigs) {
-                broadcastCount++;
-                EXPECT_EQ(broadcastUid, uid);
-                activeConfigsBroadcast.clear();
-                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
-                                              activeConfigs.end());
-                return true;
-            });
-
-    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
-
-    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 2);
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    auto& eventActivationMap = metricProducer->mEventActivationMap;
-    auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
-    sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[1];
-    auto& eventActivationMap2 = metricProducer2->mEventActivationMap;
-    auto& eventDeactivationMap2 = metricProducer2->mEventDeactivationMap;
-
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_FALSE(metricProducer2->mIsActive);
-    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
-    // triggered by screen on event (tracker index 2).
-    ASSERT_EQ(eventActivationMap.size(), 2u);
-    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
-    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    ASSERT_EQ(eventDeactivationMap.size(), 2u);
-    EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
-    EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
-    ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
-    ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-
-    ASSERT_EQ(eventActivationMap2.size(), 2u);
-    EXPECT_TRUE(eventActivationMap2.find(0) != eventActivationMap2.end());
-    EXPECT_TRUE(eventActivationMap2.find(2) != eventActivationMap2.end());
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    ASSERT_EQ(eventDeactivationMap2.size(), 2u);
-    EXPECT_TRUE(eventDeactivationMap2.find(3) != eventDeactivationMap2.end());
-    EXPECT_TRUE(eventDeactivationMap2.find(4) != eventDeactivationMap2.end());
-    ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
-    ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    std::unique_ptr<LogEvent> event;
-
-    event = CreateAppCrashEvent(bucketStartTimeNs + 5, 111);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + 5, 1111);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 5);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_FALSE(metricProducer2->mIsActive);
-    EXPECT_EQ(broadcastCount, 0);
-
-    // Activated by battery save mode.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_EQ(broadcastCount, 1);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_TRUE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, 0);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    // First processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + 15, 222);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + 15, 2222);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 15);
-
-    // Activated by screen on event.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + 20, android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + 20);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_TRUE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    // 2nd processed event.
-    // The activation by screen_on event expires, but the one by battery save mode is still active.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 333);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25, 3333);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_TRUE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-    // No new broadcast since the config should still be active.
-    EXPECT_EQ(broadcastCount, 1);
-
-    // 3rd processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 444);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25, 4444);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
-
-    // All activations expired.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 555);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 8, 5555);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 8);
-    EXPECT_FALSE(metricsManager->isActive());
-    // New broadcast since the config is no longer active.
-    EXPECT_EQ(broadcastCount, 2);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_FALSE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    // Re-activate metric via screen on.
-    event = CreateScreenStateChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10,
-                                          android::view::DISPLAY_STATE_ON);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_TRUE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    // 4th processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 666);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1, 6666);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
-
-    // Re-enable battery saver mode activation.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_EQ(broadcastCount, 3);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_TRUE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    // 5th processed event.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 777);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40, 7777);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
-
-    // Cancel battery saver mode and screen on activation.
-    event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60, 64);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
-    EXPECT_FALSE(metricsManager->isActive());
-    // New broadcast since the config is no longer active.
-    EXPECT_EQ(broadcastCount, 4);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_FALSE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    // Screen-on activation expired.
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 888);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 13, 8888);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_EQ(broadcastCount, 4);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_FALSE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    event = CreateAppCrashEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 999);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-    event = CreateMoveToForegroundEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1, 9999);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
-
-    // Re-enable battery saver mode activation.
-    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_TRUE(metricsManager->isActive());
-    EXPECT_EQ(broadcastCount, 5);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
-    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_TRUE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    // Cancel battery saver mode and screen on activation.
-    event = CreateScreenBrightnessChangedEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 16, 140);
-    processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
-    EXPECT_FALSE(metricsManager->isActive());
-    EXPECT_EQ(broadcastCount, 6);
-    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
-    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
-    EXPECT_FALSE(metricProducer2->mIsActive);
-    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
-    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap2[2]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
-    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
-                           ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(2, reports.reports(0).metrics_size());
-
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(5, countMetrics.data_size());
-
-    auto data = countMetrics.data(0);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(1);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(2);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    // Partial bucket as metric is deactivated.
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(3);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(4);
-    EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    countMetrics.clear_data();
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(1).count_metrics(), &countMetrics);
-    ASSERT_EQ(5, countMetrics.data_size());
-
-    data = countMetrics.data(0);
-    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(2222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(1);
-    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(3333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(2);
-    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(4444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    // Partial bucket as metric is deactivated.
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(3);
-    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(6666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = countMetrics.data(4);
-    EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* uid field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(7777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
-              data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
deleted file mode 100644
index 5e77ee0..0000000
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (C) 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.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-namespace {
-
-StatsdConfig CreateStatsdConfig() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
-    *config.add_atom_matcher() = CreateSyncStartAtomMatcher();
-    *config.add_atom_matcher() = CreateSyncEndAtomMatcher();
-
-    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
-    auto appCrashMatcher = CreateProcessCrashAtomMatcher();
-    *config.add_atom_matcher() = appCrashMatcher;
-
-    auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-
-    auto isSyncingPredicate = CreateIsSyncingPredicate();
-    auto syncDimension = isSyncingPredicate.mutable_simple_predicate()->mutable_dimensions();
-    *syncDimension = CreateAttributionUidDimensions(
-        util::SYNC_STATE_CHANGED, {Position::FIRST});
-    syncDimension->add_child()->set_field(2 /* name field*/);
-
-    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
-    *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
-        CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /* uid field */ });
-
-    *config.add_predicate() = screenIsOffPredicate;
-    *config.add_predicate() = isSyncingPredicate;
-    *config.add_predicate() = isInBackgroundPredicate;
-
-    auto combinationPredicate = config.add_predicate();
-    combinationPredicate->set_id(StringToId("combinationPredicate"));
-    combinationPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
-    addPredicateToPredicateCombination(screenIsOffPredicate, combinationPredicate);
-    addPredicateToPredicateCombination(isSyncingPredicate, combinationPredicate);
-    addPredicateToPredicateCombination(isInBackgroundPredicate, combinationPredicate);
-
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(StringToId("AppCrashes"));
-    countMetric->set_what(appCrashMatcher.id());
-    countMetric->set_condition(combinationPredicate->id());
-    // The metric is dimensioning by uid only.
-    *countMetric->mutable_dimensions_in_what() =
-        CreateDimensions(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, {1});
-    countMetric->set_bucket(FIVE_MINUTES);
-
-    // Links between crash atom and condition of app is in syncing.
-    auto links = countMetric->add_links();
-    links->set_condition(isSyncingPredicate.id());
-    auto dimensionWhat = links->mutable_fields_in_what();
-    dimensionWhat->set_field(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    dimensionWhat->add_child()->set_field(1);  // uid field.
-    *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
-            util::SYNC_STATE_CHANGED, {Position::FIRST});
-
-    // Links between crash atom and condition of app is in background.
-    links = countMetric->add_links();
-    links->set_condition(isInBackgroundPredicate.id());
-    dimensionWhat = links->mutable_fields_in_what();
-    dimensionWhat->set_field(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    dimensionWhat->add_child()->set_field(1);  // uid field.
-    auto dimensionCondition = links->mutable_fields_in_condition();
-    dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
-    dimensionCondition->add_child()->set_field(1);  // uid field.
-    return config;
-}
-}  // namespace
-
-// If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests,
-// we should use the real API which will clear the data after dump data is called.
-TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
-    auto config = CreateStatsdConfig();
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
-    int appUid = 123;
-    auto crashEvent1 = CreateAppCrashEvent(bucketStartTimeNs + 1, appUid);
-    auto crashEvent2 = CreateAppCrashEvent(bucketStartTimeNs + 201, appUid);
-    auto crashEvent3 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 101, appUid);
-
-    auto crashEvent4 = CreateAppCrashEvent(bucketStartTimeNs + 51, appUid);
-    auto crashEvent5 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 299, appUid);
-    auto crashEvent6 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 2001, appUid);
-
-    auto crashEvent7 = CreateAppCrashEvent(bucketStartTimeNs + 16, appUid);
-    auto crashEvent8 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 249, appUid);
-
-    auto crashEvent9 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 351, appUid);
-    auto crashEvent10 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 2, appUid);
-
-    auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 2, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    auto screenTurnedOnEvent2 =
-            CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
-                                          android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
-    std::vector<int> attributionUids = {appUid, appUid + 1};
-    std::vector<string> attributionTags = {"App1", "GMSCoreModule1"};
-
-    auto syncOnEvent1 = CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids,
-                                             attributionTags, "ReadEmail");
-    auto syncOffEvent1 = CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids,
-                                            attributionTags, "ReadEmail");
-    auto syncOnEvent2 = CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs + 2000,
-                                             attributionUids, attributionTags, "ReadDoc");
-
-    auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid);
-    auto moveToForegroundEvent1 =
-            CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid);
-
-    auto moveToBackgroundEvent2 =
-            CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid);
-    auto moveToForegroundEvent2 =
-            CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs - 1, appUid);
-
-    /*
-                    bucket #1                               bucket #2
-
-
-       |      |   |  |                      |   |          |        |   |   |     (crashEvents)
-    |-------------------------------------|-----------------------------------|---------
-
-             |                                           |                        (MoveToBkground)
-
-                                             |                               |    (MoveToForeground)
-
-                |                                                 |                (SyncIsOn)
-                                                  |                                (SyncIsOff)
-          |                                                               |        (ScreenIsOn)
-                   |                                                               (ScreenIsOff)
-    */
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(std::move(crashEvent1));
-    events.push_back(std::move(crashEvent2));
-    events.push_back(std::move(crashEvent3));
-    events.push_back(std::move(crashEvent4));
-    events.push_back(std::move(crashEvent5));
-    events.push_back(std::move(crashEvent6));
-    events.push_back(std::move(crashEvent7));
-    events.push_back(std::move(crashEvent8));
-    events.push_back(std::move(crashEvent9));
-    events.push_back(std::move(crashEvent10));
-    events.push_back(std::move(screenTurnedOnEvent));
-    events.push_back(std::move(screenTurnedOffEvent));
-    events.push_back(std::move(screenTurnedOnEvent2));
-    events.push_back(std::move(syncOnEvent1));
-    events.push_back(std::move(syncOffEvent1));
-    events.push_back(std::move(syncOnEvent2));
-    events.push_back(std::move(moveToBackgroundEvent1));
-    events.push_back(std::move(moveToForegroundEvent1));
-    events.push_back(std::move(moveToBackgroundEvent2));
-    events.push_back(std::move(moveToForegroundEvent2));
-
-    sortLogEventsByTimestamp(&events);
-
-    for (const auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
-    auto data = reports.reports(0).metrics(0).count_metrics().data(0);
-    // Validate dimension value.
-    EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
-    // Uid field.
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
-}
-
-TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2) {
-    auto config = CreateStatsdConfig();
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-
-    int appUid = 123;
-    auto crashEvent1 = CreateAppCrashEvent(bucketStartTimeNs + 1, appUid);
-    auto crashEvent2 = CreateAppCrashEvent(bucketStartTimeNs + 201, appUid);
-    auto crashEvent3 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 101, appUid);
-
-    auto crashEvent4 = CreateAppCrashEvent(bucketStartTimeNs + 51, appUid);
-    auto crashEvent5 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 299, appUid);
-    auto crashEvent6 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 2001, appUid);
-
-    auto crashEvent7 = CreateAppCrashEvent(bucketStartTimeNs + 16, appUid);
-    auto crashEvent8 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 249, appUid);
-
-    auto crashEvent9 = CreateAppCrashEvent(bucketStartTimeNs + bucketSizeNs + 351, appUid);
-    auto crashEvent10 = CreateAppCrashEvent(bucketStartTimeNs + 2 * bucketSizeNs - 2, appUid);
-
-    auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 2, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    auto screenTurnedOnEvent2 =
-            CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs - 100,
-                                          android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
-    std::vector<int> attributionUids = {appUid, appUid + 1};
-    std::vector<string> attributionTags = {"App1", "GMSCoreModule1"};
-
-    auto syncOnEvent1 = CreateSyncStartEvent(bucketStartTimeNs + 50, attributionUids,
-                                             attributionTags, "ReadEmail");
-    auto syncOffEvent1 = CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + 300, attributionUids,
-                                            attributionTags, "ReadEmail");
-    auto syncOnEvent2 = CreateSyncStartEvent(bucketStartTimeNs + bucketSizeNs + 2000,
-                                             attributionUids, attributionTags, "ReadDoc");
-
-    auto moveToBackgroundEvent1 = CreateMoveToBackgroundEvent(bucketStartTimeNs + 15, appUid);
-    auto moveToForegroundEvent1 =
-            CreateMoveToForegroundEvent(bucketStartTimeNs + bucketSizeNs + 250, appUid);
-
-    auto moveToBackgroundEvent2 =
-            CreateMoveToBackgroundEvent(bucketStartTimeNs + bucketSizeNs + 350, appUid);
-    auto moveToForegroundEvent2 =
-            CreateMoveToForegroundEvent(bucketStartTimeNs + 2 * bucketSizeNs - 1, appUid);
-
-    /*
-                    bucket #1                               bucket #2
-
-
-       |      |   |  |                      |   |          |        |   |   |     (crashEvents)
-    |-------------------------------------|-----------------------------------|---------
-
-             |                                           |                        (MoveToBkground)
-
-                                             |                               |    (MoveToForeground)
-
-                |                                                 |                (SyncIsOn)
-                                                  |                                (SyncIsOff)
-          |                                                               |        (ScreenIsOn)
-                   |                                                               (ScreenIsOff)
-    */
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(std::move(crashEvent1));
-    events.push_back(std::move(crashEvent2));
-    events.push_back(std::move(crashEvent3));
-    events.push_back(std::move(crashEvent4));
-    events.push_back(std::move(crashEvent5));
-    events.push_back(std::move(crashEvent6));
-    events.push_back(std::move(crashEvent7));
-    events.push_back(std::move(crashEvent8));
-    events.push_back(std::move(crashEvent9));
-    events.push_back(std::move(crashEvent10));
-    events.push_back(std::move(screenTurnedOnEvent));
-    events.push_back(std::move(screenTurnedOffEvent));
-    events.push_back(std::move(screenTurnedOnEvent2));
-    events.push_back(std::move(syncOnEvent1));
-    events.push_back(std::move(syncOffEvent1));
-    events.push_back(std::move(syncOnEvent2));
-    events.push_back(std::move(moveToBackgroundEvent1));
-    events.push_back(std::move(moveToForegroundEvent1));
-    events.push_back(std::move(moveToBackgroundEvent2));
-    events.push_back(std::move(moveToForegroundEvent2));
-
-    sortLogEventsByTimestamp(&events);
-
-    for (const auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 2);
-    EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(1).count(), 3);
-    auto data = reports.reports(0).metrics(0).count_metrics().data(0);
-    // Validate dimension value.
-    EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
-    // Uid field.
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
deleted file mode 100644
index c03b925..0000000
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-// Copyright (C) 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.
-
-#include <android/binder_ibinder.h>
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include "src/StatsLogProcessor.h"
-#include "src/StatsService.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using::ndk::SharedRefBase;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-namespace {
-const string kApp1 = "app1.sharing.1";
-const int kConfigKey = 789130123;  // Randomly chosen to avoid collisions with existing configs.
-const int kCallingUid = 0; // Randomly chosen
-
-void SendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) {
-    string str;
-    config.SerializeToString(&str);
-    std::vector<uint8_t> configAsVec(str.begin(), str.end());
-    service->addConfiguration(kConfigKey, configAsVec, kCallingUid);
-}
-
-ConfigMetricsReport GetReports(sp<StatsLogProcessor> processor, int64_t timestamp,
-                               bool include_current = false) {
-    vector<uint8_t> output;
-    ConfigKey configKey(AIBinder_getCallingUid(), kConfigKey);
-    processor->onDumpReport(configKey, timestamp, include_current /* include_current_bucket*/,
-                            true /* erase_data */, ADB_DUMP, NO_TIME_CONSTRAINTS, &output);
-    ConfigMetricsReportList reports;
-    reports.ParseFromArray(output.data(), output.size());
-    EXPECT_EQ(1, reports.reports_size());
-    return reports.reports(kCallingUid);
-}
-
-StatsdConfig MakeConfig() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto appCrashMatcher = CreateProcessCrashAtomMatcher();
-    *config.add_atom_matcher() = appCrashMatcher;
-    auto countMetric = config.add_count_metric();
-    countMetric->set_id(StringToId("AppCrashes"));
-    countMetric->set_what(appCrashMatcher.id());
-    countMetric->set_bucket(FIVE_MINUTES);
-    return config;
-}
-
-StatsdConfig MakeValueMetricConfig(int64_t minTime) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
-
-    auto pulledAtomMatcher =
-            CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
-    *config.add_atom_matcher() = pulledAtomMatcher;
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
-    auto valueMetric = config.add_value_metric();
-    valueMetric->set_id(123456);
-    valueMetric->set_what(pulledAtomMatcher.id());
-    *valueMetric->mutable_value_field() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
-    *valueMetric->mutable_dimensions_in_what() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
-    valueMetric->set_bucket(FIVE_MINUTES);
-    valueMetric->set_min_bucket_size_nanos(minTime);
-    valueMetric->set_use_absolute_value_on_reset(true);
-    valueMetric->set_skip_zero_diff_output(false);
-    return config;
-}
-
-StatsdConfig MakeGaugeMetricConfig(int64_t minTime) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-    config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
-
-    auto pulledAtomMatcher =
-                CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
-    *config.add_atom_matcher() = pulledAtomMatcher;
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
-    auto gaugeMetric = config.add_gauge_metric();
-    gaugeMetric->set_id(123456);
-    gaugeMetric->set_what(pulledAtomMatcher.id());
-    gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
-    *gaugeMetric->mutable_dimensions_in_what() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
-    gaugeMetric->set_bucket(FIVE_MINUTES);
-    gaugeMetric->set_min_bucket_size_nanos(minTime);
-    return config;
-}
-}  // anonymous namespace
-
-TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    SendConfig(service, MakeConfig());
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 2, 100).get());
-
-    ConfigMetricsReport report = GetReports(service->mProcessor, start + 3);
-    // Expect no metrics since the bucket has not finished yet.
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    SendConfig(service, MakeConfig());
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-
-    // Force the uidmap to update at timestamp 2.
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
-    // This is a new installation, so there shouldn't be a split (should be same as the without
-    // split case).
-    service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
-                                String16(""));
-    // Goes into the second bucket.
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
-
-    ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    SendConfig(service, MakeConfig());
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-    service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
-                                {String16("")});
-
-    // Force the uidmap to update at timestamp 2.
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
-    service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
-                                String16(""));
-    // Goes into the second bucket.
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
-
-    ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
-    backfillStartEndTimestamp(&report);
-
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
-    ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
-    EXPECT_TRUE(report.metrics(0)
-                        .count_metrics()
-                        .data(0)
-                        .bucket_info(0)
-                        .has_start_bucket_elapsed_nanos());
-    EXPECT_TRUE(report.metrics(0)
-                        .count_metrics()
-                        .data(0)
-                        .bucket_info(0)
-                        .has_end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    SendConfig(service, MakeConfig());
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-    service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
-                                {String16("")});
-
-    // Force the uidmap to update at timestamp 2.
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
-    service->mUidMap->removeApp(start + 2, String16(kApp1.c_str()), 1);
-    // Goes into the second bucket.
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
-
-    ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
-    backfillStartEndTimestamp(&report);
-
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
-    ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
-    EXPECT_TRUE(report.metrics(0)
-                        .count_metrics()
-                        .data(0)
-                        .bucket_info(0)
-                        .has_start_bucket_elapsed_nanos());
-    EXPECT_TRUE(report.metrics(0)
-                        .count_metrics()
-                        .data(0)
-                        .bucket_info(0)
-                        .has_end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
-}
-
-TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    SendConfig(service, MakeConfig());
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-
-    // Goes into the first bucket
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + NS_PER_SEC, 100).get());
-    int64_t bootCompleteTimeNs = start + 2 * NS_PER_SEC;
-    service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
-    // Goes into the second bucket.
-    service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3 * NS_PER_SEC, 100).get());
-
-    ConfigMetricsReport report = GetReports(service->mProcessor, start + 4 * NS_PER_SEC);
-    backfillStartEndTimestamp(&report);
-
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
-    ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
-    EXPECT_TRUE(report.metrics(0)
-                        .count_metrics()
-                        .data(0)
-                        .bucket_info(0)
-                        .has_start_bucket_elapsed_nanos());
-    EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)),
-              report.metrics(0).count_metrics().data(0).bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
-}
-
-TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    service->mPullerManager->RegisterPullAtomCallback(
-            /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
-            SharedRefBase::make<FakeSubsystemSleepCallback>());
-    // Partial buckets don't occur when app is first installed.
-    service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
-    SendConfig(service, MakeValueMetricConfig(0));
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-
-    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-    int64_t appUpgradeTimeNs = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC;
-    service->mUidMap->updateApp(appUpgradeTimeNs, String16(kApp1.c_str()), 1, 2, String16("v2"),
-                                String16(""));
-
-    ConfigMetricsReport report =
-            GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
-    backfillStartEndTimestamp(&report);
-
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(0, report.metrics(0).value_metrics().skipped_size());
-
-    // The fake subsystem state sleep puller returns two atoms.
-    ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
-    ASSERT_EQ(2, report.metrics(0).value_metrics().data(0).bucket_info_size());
-    EXPECT_EQ(MillisToNano(NanoToMillis(appUpgradeTimeNs)),
-              report.metrics(0).value_metrics().data(0).bucket_info(1).end_bucket_elapsed_nanos());
-}
-
-TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    service->mPullerManager->RegisterPullAtomCallback(
-            /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
-            SharedRefBase::make<FakeSubsystemSleepCallback>());
-    // Partial buckets don't occur when app is first installed.
-    service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
-    SendConfig(service, MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */));
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-
-    const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC;
-    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-    service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
-                               String16(""));
-
-    ConfigMetricsReport report =
-            GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
-    backfillStartEndTimestamp(&report);
-
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(1, report.metrics(0).value_metrics().skipped_size());
-    EXPECT_TRUE(report.metrics(0).value_metrics().skipped(0).has_start_bucket_elapsed_nanos());
-    // Can't test the start time since it will be based on the actual time when the pulling occurs.
-    EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)),
-              report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
-
-    ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
-    ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
-}
-
-TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    // Initial pull will fail since puller is not registered.
-    SendConfig(service, MakeValueMetricConfig(0));
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-
-    service->mPullerManager->RegisterPullAtomCallback(
-            /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
-            SharedRefBase::make<FakeSubsystemSleepCallback>());
-
-    int64_t bootCompleteTimeNs = start + NS_PER_SEC;
-    service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
-
-    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-
-    ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
-    backfillStartEndTimestamp(&report);
-
-    // First bucket is dropped due to the initial pull failing
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(1, report.metrics(0).value_metrics().skipped_size());
-    EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)),
-              report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
-
-    // The fake subsystem state sleep puller returns two atoms.
-    ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
-    ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
-    EXPECT_EQ(
-            MillisToNano(NanoToMillis(bootCompleteTimeNs)),
-            report.metrics(0).value_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos());
-}
-
-TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    service->mPullerManager->RegisterPullAtomCallback(
-            /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
-            SharedRefBase::make<FakeSubsystemSleepCallback>());
-    // Partial buckets don't occur when app is first installed.
-    service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
-    SendConfig(service, MakeGaugeMetricConfig(0));
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-
-    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-    service->mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2,
-                               String16("v2"), String16(""));
-
-    ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
-    backfillStartEndTimestamp(&report);
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
-    // The fake subsystem state sleep puller returns two atoms.
-    ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
-    ASSERT_EQ(2, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
-}
-
-TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    // Partial buckets don't occur when app is first installed.
-    service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
-    service->mPullerManager->RegisterPullAtomCallback(
-            /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
-            SharedRefBase::make<FakeSubsystemSleepCallback>());
-    SendConfig(service, MakeGaugeMetricConfig(60 * NS_PER_SEC /* One minute */));
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-
-    const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2;
-    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-    service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
-                                String16(""));
-
-    ConfigMetricsReport report =
-            GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
-    backfillStartEndTimestamp(&report);
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(1, report.metrics(0).gauge_metrics().skipped_size());
-    // Can't test the start time since it will be based on the actual time when the pulling occurs.
-    EXPECT_TRUE(report.metrics(0).gauge_metrics().skipped(0).has_start_bucket_elapsed_nanos());
-    EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)),
-              report.metrics(0).gauge_metrics().skipped(0).end_bucket_elapsed_nanos());
-    ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
-    ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
-}
-
-TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket) {
-    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
-    // Initial pull will fail since puller hasn't been registered.
-    SendConfig(service, MakeGaugeMetricConfig(0));
-    int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
-                                             // initialized with.
-
-    service->mPullerManager->RegisterPullAtomCallback(
-            /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
-            SharedRefBase::make<FakeSubsystemSleepCallback>());
-
-    int64_t bootCompleteTimeNs = start + NS_PER_SEC;
-    service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
-
-    service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
-
-    ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
-    backfillStartEndTimestamp(&report);
-
-    ASSERT_EQ(1, report.metrics_size());
-    ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
-    // The fake subsystem state sleep puller returns two atoms.
-    ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
-    // No data in the first bucket, so nothing is reported
-    ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
-    EXPECT_EQ(
-            MillisToNano(NanoToMillis(bootCompleteTimeNs)),
-            report.metrics(0).gauge_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
deleted file mode 100644
index 4d39282..0000000
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ /dev/null
@@ -1,679 +0,0 @@
-// Copyright (C) 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.
-
-#include <android/binder_interface_utils.h>
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-using ::ndk::SharedRefBase;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-const int64_t metricId = 123456;
-
-StatsdConfig CreateStatsdConfig(bool useCondition = true) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
-    auto pulledAtomMatcher =
-            CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
-    *config.add_atom_matcher() = pulledAtomMatcher;
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-
-    auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-    *config.add_predicate() = screenIsOffPredicate;
-
-    auto valueMetric = config.add_value_metric();
-    valueMetric->set_id(metricId);
-    valueMetric->set_what(pulledAtomMatcher.id());
-    if (useCondition) {
-        valueMetric->set_condition(screenIsOffPredicate.id());
-    }
-    *valueMetric->mutable_value_field() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
-    *valueMetric->mutable_dimensions_in_what() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
-    valueMetric->set_bucket(FIVE_MINUTES);
-    valueMetric->set_use_absolute_value_on_reset(true);
-    valueMetric->set_skip_zero_diff_output(false);
-    valueMetric->set_max_pull_delay_sec(INT_MAX);
-    return config;
-}
-
-StatsdConfig CreateStatsdConfigWithStates() {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");     // LogEvent defaults to UID of root.
-    config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
-
-    auto pulledAtomMatcher = CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
-    *config.add_atom_matcher() = pulledAtomMatcher;
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
-    *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
-
-    auto screenOnPredicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = screenOnPredicate;
-
-    auto screenOffPredicate = CreateScreenIsOffPredicate();
-    *config.add_predicate() = screenOffPredicate;
-
-    auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
-    *config.add_predicate() = deviceUnpluggedPredicate;
-
-    auto screenOnOnBatteryPredicate = config.add_predicate();
-    screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate"));
-    screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
-    addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate);
-    addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate);
-
-    auto screenOffOnBatteryPredicate = config.add_predicate();
-    screenOffOnBatteryPredicate->set_id(StringToId("ScreenOffOnBattery"));
-    screenOffOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
-    addPredicateToPredicateCombination(screenOffPredicate, screenOffOnBatteryPredicate);
-    addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOffOnBatteryPredicate);
-
-    const State screenState =
-            CreateScreenStateWithSimpleOnOffMap(/*screen on id=*/321, /*screen off id=*/123);
-    *config.add_state() = screenState;
-
-    // ValueMetricSubsystemSleepWhileScreenOnOnBattery
-    auto valueMetric1 = config.add_value_metric();
-    valueMetric1->set_id(metricId);
-    valueMetric1->set_what(pulledAtomMatcher.id());
-    valueMetric1->set_condition(screenOnOnBatteryPredicate->id());
-    *valueMetric1->mutable_value_field() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
-    valueMetric1->set_bucket(FIVE_MINUTES);
-    valueMetric1->set_use_absolute_value_on_reset(true);
-    valueMetric1->set_skip_zero_diff_output(false);
-    valueMetric1->set_max_pull_delay_sec(INT_MAX);
-
-    // ValueMetricSubsystemSleepWhileScreenOffOnBattery
-    ValueMetric* valueMetric2 = config.add_value_metric();
-    valueMetric2->set_id(StringToId("ValueMetricSubsystemSleepWhileScreenOffOnBattery"));
-    valueMetric2->set_what(pulledAtomMatcher.id());
-    valueMetric2->set_condition(screenOffOnBatteryPredicate->id());
-    *valueMetric2->mutable_value_field() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
-    valueMetric2->set_bucket(FIVE_MINUTES);
-    valueMetric2->set_use_absolute_value_on_reset(true);
-    valueMetric2->set_skip_zero_diff_output(false);
-    valueMetric2->set_max_pull_delay_sec(INT_MAX);
-
-    // ValueMetricSubsystemSleepWhileOnBatterySliceScreen
-    ValueMetric* valueMetric3 = config.add_value_metric();
-    valueMetric3->set_id(StringToId("ValueMetricSubsystemSleepWhileOnBatterySliceScreen"));
-    valueMetric3->set_what(pulledAtomMatcher.id());
-    valueMetric3->set_condition(deviceUnpluggedPredicate.id());
-    *valueMetric3->mutable_value_field() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
-    valueMetric3->add_slice_by_state(screenState.id());
-    valueMetric3->set_bucket(FIVE_MINUTES);
-    valueMetric3->set_use_absolute_value_on_reset(true);
-    valueMetric3->set_skip_zero_diff_output(false);
-    valueMetric3->set_max_pull_delay_sec(INT_MAX);
-    return config;
-}
-
-}  // namespace
-
-/**
- * Tests the initial condition and condition after the first log events for
- * value metrics with either a combination condition or simple condition.
- *
- * Metrics should be initialized with condition kUnknown (given that the
- * predicate is using the default InitialValue of UNKNOWN). The condition should
- * be updated to either kFalse or kTrue if a condition event is logged for all
- * children conditions.
- */
-TEST(ValueMetricE2eTest, TestInitialConditionChanges) {
-    StatsdConfig config = CreateStatsdConfigWithStates();
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    int32_t tagId = util::SUBSYSTEM_SLEEP_STATE;
-    auto processor =
-            CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                    SharedRefBase::make<FakeSubsystemSleepCallback>(), tagId);
-
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(3, metricsManager->mAllMetricProducers.size());
-
-    // Combination condition metric - screen on and device unplugged
-    sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0];
-    // Simple condition metric - device unplugged
-    sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[2];
-
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
-    auto screenOnEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 30, android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
-    auto screenOffEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 40, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
-    EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
-
-    auto pluggedUsbEvent = CreateBatteryStateChangedEvent(
-            configAddedTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
-    processor->OnLogEvent(pluggedUsbEvent.get());
-    EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
-    EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition);
-
-    auto pluggedNoneEvent = CreateBatteryStateChangedEvent(
-            configAddedTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
-    processor->OnLogEvent(pluggedNoneEvent.get());
-    EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
-    EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition);
-}
-
-TEST(ValueMetricE2eTest, TestPulledEvents) {
-    auto config = CreateStatsdConfig();
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
-                                             util::SUBSYSTEM_SLEEP_STATE);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    processor->mPullerManager->ForceClearPullerCache();
-
-    int startBucketNum = processor->mMetricsManagers.begin()
-                                 ->second->mAllMetricProducers[0]
-                                 ->getCurrentBucketNum();
-    EXPECT_GT(startBucketNum, (int64_t)0);
-
-    // When creating the config, the value metric producer should register the alarm at the
-    // end of the current bucket.
-    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
-    EXPECT_EQ(bucketSizeNs,
-              processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
-    int64_t& expectedPullTimeNs =
-            processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
-
-    auto screenOffEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    auto screenOnEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-
-    screenOffEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    // Pulling alarm arrives on time and reset the sequential pulling alarm.
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
-    screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 2 * bucketSizeNs + 15,
-                                                  android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
-    screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 11,
-                                                   android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
-                            ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::ValueMetricDataWrapper valueMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
-    ASSERT_GT((int)valueMetrics.data_size(), 1);
-
-    auto data = valueMetrics.data(0);
-    EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* subsystem name field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    // We have 4 buckets, the first one was incomplete since the condition was unknown.
-    ASSERT_EQ(4, data.bucket_info_size());
-
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    ASSERT_EQ(1, data.bucket_info(0).values_size());
-
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-    ASSERT_EQ(1, data.bucket_info(1).values_size());
-
-    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
-    ASSERT_EQ(1, data.bucket_info(2).values_size());
-
-    EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
-    ASSERT_EQ(1, data.bucket_info(3).values_size());
-}
-
-TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
-    auto config = CreateStatsdConfig();
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    // 10 mins == 2 bucket durations.
-    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
-                                             util::SUBSYSTEM_SLEEP_STATE);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    processor->mPullerManager->ForceClearPullerCache();
-
-    int startBucketNum = processor->mMetricsManagers.begin()
-                                 ->second->mAllMetricProducers[0]
-                                 ->getCurrentBucketNum();
-    EXPECT_GT(startBucketNum, (int64_t)0);
-
-    // When creating the config, the value metric producer should register the alarm at the
-    // end of the current bucket.
-    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
-    EXPECT_EQ(bucketSizeNs,
-              processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
-    int64_t& expectedPullTimeNs =
-            processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
-
-    // Screen off/on/off events.
-    auto screenOffEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    auto screenOnEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-
-    screenOffEvent =
-            CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    // Pulling alarm arrives late by 2 buckets and 1 ns. 2 buckets late is too far away in the
-    // future, data will be skipped.
-    processor->informPullAlarmFired(expectedPullTimeNs + 2 * bucketSizeNs + 1);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
-
-    // This screen state change will start a new bucket.
-    screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 65,
-                                                  android::view::DISPLAY_STATE_ON);
-    processor->OnLogEvent(screenOnEvent.get());
-
-    // The alarm is delayed but we already created a bucket thanks to the screen state condition.
-    // This bucket does not have to be skipped since the alarm arrives in time for the next bucket.
-    processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
-
-    screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 6 * bucketSizeNs + 31,
-                                                   android::view::DISPLAY_STATE_OFF);
-    processor->OnLogEvent(screenOffEvent.get());
-
-    processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 8 * bucketSizeNs, expectedPullTimeNs);
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 9 * bucketSizeNs, expectedPullTimeNs);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, true,
-                            ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::ValueMetricDataWrapper valueMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
-    ASSERT_GT((int)valueMetrics.data_size(), 1);
-
-    auto data = valueMetrics.data(0);
-    EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* subsystem name field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    ASSERT_EQ(3, data.bucket_info_size());
-
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    ASSERT_EQ(1, data.bucket_info(0).values_size());
-
-    EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-    ASSERT_EQ(1, data.bucket_info(1).values_size());
-
-    EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 10 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
-    ASSERT_EQ(1, data.bucket_info(2).values_size());
-}
-
-TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation) {
-    auto config = CreateStatsdConfig(false);
-    int64_t baseTimeNs = getElapsedRealtimeNs();
-    int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
-
-    auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
-    *config.add_atom_matcher() = batterySaverStartMatcher;
-    const int64_t ttlNs = 2 * bucketSizeNs;  // Two buckets.
-    auto metric_activation = config.add_metric_activation();
-    metric_activation->set_metric_id(metricId);
-    metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
-    auto event_activation = metric_activation->add_event_activation();
-    event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
-    event_activation->set_ttl_seconds(ttlNs / 1000000000);
-
-    ConfigKey cfgKey;
-    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
-                                             SharedRefBase::make<FakeSubsystemSleepCallback>(),
-                                             util::SUBSYSTEM_SLEEP_STATE);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    processor->mPullerManager->ForceClearPullerCache();
-
-    int startBucketNum = processor->mMetricsManagers.begin()
-                                 ->second->mAllMetricProducers[0]
-                                 ->getCurrentBucketNum();
-    EXPECT_GT(startBucketNum, (int64_t)0);
-    EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
-    // When creating the config, the value metric producer should register the alarm at the
-    // end of the current bucket.
-    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
-    EXPECT_EQ(bucketSizeNs,
-              processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
-    int64_t& expectedPullTimeNs =
-            processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
-
-    // Pulling alarm arrives on time and reset the sequential pulling alarm.
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);  // 15 mins + 1 ns.
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
-    EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
-    // Activate the metric. A pull occurs here
-    const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000);  // 2 millis.
-    auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
-    processor->OnLogEvent(batterySaverOnEvent.get());  // 15 mins + 2 ms.
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);  // 20 mins + 1 ns.
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, expectedPullTimeNs);
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 2);  // 25 mins + 2 ns.
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
-
-    // Create random event to deactivate metric.
-    auto deactivationEvent = CreateScreenBrightnessChangedEvent(activationNs + ttlNs + 1, 50);
-    processor->OnLogEvent(deactivationEvent.get());
-    EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 3);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, expectedPullTimeNs);
-
-    processor->informPullAlarmFired(expectedPullTimeNs + 4);
-    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
-                            ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    StatsLogReport::ValueMetricDataWrapper valueMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
-    ASSERT_GT((int)valueMetrics.data_size(), 0);
-
-    auto data = valueMetrics.data(0);
-    EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1 /* subsystem name field */,
-              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    // We have 2 full buckets, the two surrounding the activation are dropped.
-    ASSERT_EQ(2, data.bucket_info_size());
-
-    auto bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-    ASSERT_EQ(1, bucketInfo.values_size());
-
-    bucketInfo = data.bucket_info(1);
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-    ASSERT_EQ(1, bucketInfo.values_size());
-}
-
-/**
- * Test initialization of a simple value metric that is sliced by a state.
- *
- * ValueCpuUserTimePerScreenState
- */
-TEST(ValueMetricE2eTest, TestInitWithSlicedState) {
-    // Create config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto pulledAtomMatcher =
-            CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
-    *config.add_atom_matcher() = pulledAtomMatcher;
-
-    auto screenState = CreateScreenState();
-    *config.add_state() = screenState;
-
-    // Create value metric that slices by screen state without a map.
-    int64_t metricId = 123456;
-    auto valueMetric = config.add_value_metric();
-    valueMetric->set_id(metricId);
-    valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    valueMetric->set_what(pulledAtomMatcher.id());
-    *valueMetric->mutable_value_field() =
-            CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
-    valueMetric->add_slice_by_state(screenState.id());
-    valueMetric->set_max_pull_delay_sec(INT_MAX);
-
-    // Initialize StatsLogProcessor.
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000LL;
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // Check that StateTrackers were initialized correctly.
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
-    // Check that ValueMetricProducer was initialized correctly.
-    ASSERT_EQ(1U, processor->mMetricsManagers.size());
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
-    ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
-}
-
-/**
- * Test initialization of a value metric that is sliced by state and has
- * dimensions_in_what.
- *
- * ValueCpuUserTimePerUidPerUidProcessState
- */
-TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions) {
-    // Create config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto cpuTimePerUidMatcher =
-            CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
-    *config.add_atom_matcher() = cpuTimePerUidMatcher;
-
-    auto uidProcessState = CreateUidProcessState();
-    *config.add_state() = uidProcessState;
-
-    // Create value metric that slices by screen state with a complete map.
-    int64_t metricId = 123456;
-    auto valueMetric = config.add_value_metric();
-    valueMetric->set_id(metricId);
-    valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    valueMetric->set_what(cpuTimePerUidMatcher.id());
-    *valueMetric->mutable_value_field() =
-            CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
-    *valueMetric->mutable_dimensions_in_what() =
-            CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
-    valueMetric->add_slice_by_state(uidProcessState.id());
-    MetricStateLink* stateLink = valueMetric->add_state_link();
-    stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
-    auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
-    auto fieldsInState = stateLink->mutable_fields_in_state();
-    *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-    valueMetric->set_max_pull_delay_sec(INT_MAX);
-
-    // Initialize StatsLogProcessor.
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // Check that StateTrackers were initialized correctly.
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
-    // Check that ValueMetricProducer was initialized correctly.
-    ASSERT_EQ(1U, processor->mMetricsManagers.size());
-    sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
-    EXPECT_TRUE(metricsManager->isConfigValid());
-    ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
-    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
-    ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
-}
-
-/**
- * Test initialization of a value metric that is sliced by state and has
- * dimensions_in_what.
- *
- * ValueCpuUserTimePerUidPerUidProcessState
- */
-TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions) {
-    // Create config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    auto cpuTimePerUidMatcher =
-            CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
-    *config.add_atom_matcher() = cpuTimePerUidMatcher;
-
-    auto uidProcessState = CreateUidProcessState();
-    *config.add_state() = uidProcessState;
-
-    // Create value metric that slices by screen state with a complete map.
-    int64_t metricId = 123456;
-    auto valueMetric = config.add_value_metric();
-    valueMetric->set_id(metricId);
-    valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    valueMetric->set_what(cpuTimePerUidMatcher.id());
-    *valueMetric->mutable_value_field() =
-            CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
-    valueMetric->add_slice_by_state(uidProcessState.id());
-    MetricStateLink* stateLink = valueMetric->add_state_link();
-    stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
-    auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
-    auto fieldsInState = stateLink->mutable_fields_in_state();
-    *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-    valueMetric->set_max_pull_delay_sec(INT_MAX);
-
-    // Initialize StatsLogProcessor.
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // No StateTrackers are initialized.
-    EXPECT_EQ(0, StateManager::getInstance().getStateTrackersCount());
-
-    // Config initialization fails.
-    ASSERT_EQ(0, processor->mMetricsManagers.size());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
deleted file mode 100644
index 52bc222..0000000
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright (C) 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.
-
-#include <gtest/gtest.h>
-
-#include "src/StatsLogProcessor.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-
-StatsdConfig CreateStatsdConfig(DurationMetric::AggregationType aggregationType) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-
-    auto screenIsOffPredicate = CreateScreenIsOffPredicate();
-    *config.add_predicate() = screenIsOffPredicate;
-
-    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    // The predicate is dimensioning by any attribution node and both by uid and tag.
-    FieldMatcher dimensions = CreateAttributionUidAndTagDimensions(
-            util::WAKELOCK_STATE_CHANGED, {Position::FIRST, Position::LAST});
-    // Also slice by the wakelock tag
-    dimensions.add_child()->set_field(3);  // The wakelock tag is set in field 3 of the wakelock.
-    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    auto durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("WakelockDuration"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->set_condition(screenIsOffPredicate.id());
-    durationMetric->set_aggregation_type(aggregationType);
-    // The metric is dimensioning by first attribution node and only by uid.
-    *durationMetric->mutable_dimensions_in_what() =
-        CreateAttributionUidDimensions(
-            util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    durationMetric->set_bucket(FIVE_MINUTES);
-    return config;
-}
-
-std::vector<int> attributionUids1 = {111, 222, 222};
-std::vector<string> attributionTags1 = {"App1", "GMSCoreModule1", "GMSCoreModule2"};
-
-std::vector<int> attributionUids2 = {111, 222, 222};
-std::vector<string> attributionTags2 = {"App2", "GMSCoreModule1", "GMSCoreModule2"};
-
-/*
-Events:
-Screen off is met from (200ns,1 min+500ns].
-Acquire event for wl1 from 2ns to 1min+2ns
-Acquire event for wl2 from 1min-10ns to 2min-15ns
-*/
-void FeedEvents(StatsdConfig config, sp<StatsLogProcessor> processor) {
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-
-    auto screenTurnedOnEvent = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    auto screenTurnedOffEvent = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 200, android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    auto screenTurnedOnEvent2 =
-            CreateScreenStateChangedEvent(bucketStartTimeNs + bucketSizeNs + 500,
-                                          android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
-    auto acquireEvent1 = CreateAcquireWakelockEvent(bucketStartTimeNs + 2, attributionUids1,
-                                                    attributionTags1, "wl1");
-    auto releaseEvent1 = CreateReleaseWakelockEvent(bucketStartTimeNs + bucketSizeNs + 2,
-                                                    attributionUids1, attributionTags1, "wl1");
-    auto acquireEvent2 = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 10,
-                                                    attributionUids2, attributionTags2, "wl2");
-    auto releaseEvent2 = CreateReleaseWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs - 15,
-                                                    attributionUids2, attributionTags2, "wl2");
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-
-    events.push_back(std::move(screenTurnedOnEvent));
-    events.push_back(std::move(screenTurnedOffEvent));
-    events.push_back(std::move(screenTurnedOnEvent2));
-    events.push_back(std::move(acquireEvent1));
-    events.push_back(std::move(acquireEvent2));
-    events.push_back(std::move(releaseEvent1));
-    events.push_back(std::move(releaseEvent2));
-
-    sortLogEventsByTimestamp(&events);
-
-    for (const auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-}
-
-}  // namespace
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1) {
-    ConfigKey cfgKey;
-    auto config = CreateStatsdConfig(DurationMetric::SUM);
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    FeedEvents(config, processor);
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    // Only 1 dimension output. The tag dimension in the predicate has been aggregated.
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
-
-    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
-    // Validate dimension value.
-    ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    util::WAKELOCK_STATE_CHANGED, 111);
-    // Validate bucket info.
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
-    data = reports.reports(0).metrics(0).duration_metrics().data(0);
-    // The wakelock holding interval starts from the screen off event and to the end of the 1st
-    // bucket.
-    EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs - 200);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2) {
-    ConfigKey cfgKey;
-    auto config = CreateStatsdConfig(DurationMetric::SUM);
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    FeedEvents(config, processor);
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
-    // Dump the report after the end of 2nd bucket.
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
-    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
-    // Validate dimension value.
-    ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    util::WAKELOCK_STATE_CHANGED, 111);
-    // Two output buckets.
-    // The wakelock holding interval in the 1st bucket starts from the screen off event and to
-    // the end of the 1st bucket.
-    EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(),
-              bucketStartTimeNs + bucketSizeNs - (bucketStartTimeNs + 200));
-    // The wakelock holding interval in the 2nd bucket starts at the beginning of the bucket and
-    // ends at the second screen on event.
-    EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 500UL);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3) {
-    ConfigKey cfgKey;
-    auto config = CreateStatsdConfig(DurationMetric::SUM);
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    FeedEvents(config, processor);
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(
-            CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 90,
-                                          android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
-                                                attributionUids1, attributionTags1, "wl3"));
-    events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs + 100,
-                                                attributionUids1, attributionTags1, "wl3"));
-    sortLogEventsByTimestamp(&events);
-    for (const auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
-    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
-    ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    util::WAKELOCK_STATE_CHANGED, 111);
-    // The last wakelock holding spans 4 buckets.
-    EXPECT_EQ((unsigned long long)data.bucket_info(2).duration_nanos(), bucketSizeNs - 100);
-    EXPECT_EQ((unsigned long long)data.bucket_info(3).duration_nanos(), bucketSizeNs);
-    EXPECT_EQ((unsigned long long)data.bucket_info(4).duration_nanos(), bucketSizeNs);
-    EXPECT_EQ((unsigned long long)data.bucket_info(5).duration_nanos(), 100UL);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1) {
-    ConfigKey cfgKey;
-    auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    FeedEvents(config, processor);
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(reports.reports_size(), 1);
-
-    // When using ProtoOutputStream, if nothing written to a sub msg, it won't be treated as
-    // one. It was previsouly 1 because we had a fake onDumpReport which calls add_metric() by
-    // itself.
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    ASSERT_EQ(0, reports.reports(0).metrics(0).duration_metrics().data_size());
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
-    ConfigKey cfgKey;
-    auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    FeedEvents(config, processor);
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
-    // Dump the report after the end of 2nd bucket. One dimension with one bucket.
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
-    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
-    // Validate dimension value.
-    ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    util::WAKELOCK_STATE_CHANGED, 111);
-    // The max is acquire event for wl1 to screen off start.
-    EXPECT_EQ((unsigned long long)data.bucket_info(0).duration_nanos(), bucketSizeNs + 2 - 200);
-}
-
-TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3) {
-    ConfigKey cfgKey;
-    auto config = CreateStatsdConfig(DurationMetric::MAX_SPARSE);
-    uint64_t bucketStartTimeNs = 10000000000;
-    uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
-    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
-    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    FeedEvents(config, processor);
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(
-            CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * bucketSizeNs + 90,
-                                          android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
-    events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 2 * bucketSizeNs + 100,
-                                                attributionUids1, attributionTags1, "wl3"));
-    events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 5 * bucketSizeNs + 100,
-                                                attributionUids1, attributionTags1, "wl3"));
-    sortLogEventsByTimestamp(&events);
-    for (const auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
-    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
-    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
-    ValidateAttributionUidDimension(data.dimensions_in_what(),
-                                    util::WAKELOCK_STATE_CHANGED, 111);
-    // The last wakelock holding spans 4 buckets.
-    EXPECT_EQ((unsigned long long)data.bucket_info(1).duration_nanos(), 3 * bucketSizeNs);
-    EXPECT_EQ((unsigned long long)data.bucket_info(1).start_bucket_elapsed_nanos(),
-              bucketStartTimeNs + 5 * bucketSizeNs);
-    EXPECT_EQ((unsigned long long)data.bucket_info(1).end_bucket_elapsed_nanos(),
-              bucketStartTimeNs + 6 * bucketSizeNs);
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
deleted file mode 100644
index 85a6088..0000000
--- a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (C) 2019 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.
-
-#include "src/external/StatsCallbackPuller.h"
-
-#include <aidl/android/os/BnPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <aidl/android/util/StatsEventParcel.h>
-#include <android/binder_interface_utils.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <chrono>
-#include <thread>
-#include <vector>
-
-#include "../metrics/metrics_test_helper.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::os::BnPullAtomCallback;
-using aidl::android::os::IPullAtomResultReceiver;
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-using std::this_thread::sleep_for;
-using testing::Contains;
-
-namespace {
-int pullTagId = -12;
-bool pullSuccess;
-vector<int64_t> values;
-int64_t pullDelayNs;
-int64_t pullTimeoutNs;
-int64_t pullCoolDownNs;
-std::thread pullThread;
-
-AStatsEvent* createSimpleEvent(int64_t value) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, pullTagId);
-    AStatsEvent_writeInt64(event, value);
-    AStatsEvent_build(event);
-    return event;
-}
-
-void executePull(const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
-    // Convert stats_events into StatsEventParcels.
-    vector<StatsEventParcel> parcels;
-    for (int i = 0; i < values.size(); i++) {
-        AStatsEvent* event = createSimpleEvent(values[i]);
-        size_t size;
-        uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
-
-        StatsEventParcel p;
-        // vector.assign() creates a copy, but this is inevitable unless
-        // stats_event.h/c uses a vector as opposed to a buffer.
-        p.buffer.assign(buffer, buffer + size);
-        parcels.push_back(std::move(p));
-        AStatsEvent_release(event);
-    }
-
-    sleep_for(std::chrono::nanoseconds(pullDelayNs));
-    resultReceiver->pullFinished(pullTagId, pullSuccess, parcels);
-}
-
-class FakePullAtomCallback : public BnPullAtomCallback {
-public:
-    Status onPullAtom(int atomTag,
-                      const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override {
-        // Force pull to happen in separate thread to simulate binder.
-        pullThread = std::thread(executePull, resultReceiver);
-        return Status::ok();
-    }
-};
-
-class StatsCallbackPullerTest : public ::testing::Test {
-public:
-    StatsCallbackPullerTest() {
-    }
-
-    void SetUp() override {
-        pullSuccess = false;
-        pullDelayNs = 0;
-        values.clear();
-        pullTimeoutNs = 10000000000LL;  // 10 seconds.
-        pullCoolDownNs = 1000000000;    // 1 second.
-    }
-
-    void TearDown() override {
-        if (pullThread.joinable()) {
-            pullThread.join();
-        }
-        values.clear();
-    }
-};
-}  // Anonymous namespace.
-
-TEST_F(StatsCallbackPullerTest, PullSuccess) {
-    shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
-    int64_t value = 43;
-    pullSuccess = true;
-    values.push_back(value);
-
-    StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    int64_t startTimeNs = getElapsedRealtimeNs();
-    EXPECT_TRUE(puller.PullInternal(&dataHolder));
-    int64_t endTimeNs = getElapsedRealtimeNs();
-
-    ASSERT_EQ(1, dataHolder.size());
-    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
-    EXPECT_LT(startTimeNs, dataHolder[0]->GetElapsedTimestampNs());
-    EXPECT_GT(endTimeNs, dataHolder[0]->GetElapsedTimestampNs());
-    ASSERT_EQ(1, dataHolder[0]->size());
-    EXPECT_EQ(value, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-TEST_F(StatsCallbackPullerTest, PullFail) {
-    shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
-    pullSuccess = false;
-    int64_t value = 1234;
-    values.push_back(value);
-
-    StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
-
-    vector<shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.PullInternal(&dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsCallbackPullerTest, PullTimeout) {
-    shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
-    pullSuccess = true;
-    pullDelayNs = MillisToNano(5);  // 5ms.
-    pullTimeoutNs = 10000;    // 10 microseconds.
-    int64_t value = 4321;
-    values.push_back(value);
-
-    StatsCallbackPuller puller(pullTagId, cb, pullCoolDownNs, pullTimeoutNs, {});
-
-    vector<shared_ptr<LogEvent>> dataHolder;
-    int64_t startTimeNs = getElapsedRealtimeNs();
-    // Returns true to let StatsPuller code evaluate the timeout.
-    EXPECT_TRUE(puller.PullInternal(&dataHolder));
-    int64_t endTimeNs = getElapsedRealtimeNs();
-    int64_t actualPullDurationNs = endTimeNs - startTimeNs;
-
-    // Pull should take at least the timeout amount of time, but should stop early because the delay
-    // is bigger.
-    EXPECT_LT(pullTimeoutNs, actualPullDurationNs);
-    EXPECT_GT(pullDelayNs, actualPullDurationNs);
-    ASSERT_EQ(0, dataHolder.size());
-
-    // Let the pull return and make sure that the dataHolder is not modified.
-    pullThread.join();
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-// Register a puller and ensure that the timeout logic works.
-TEST_F(StatsCallbackPullerTest, RegisterAndTimeout) {
-    shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
-    pullSuccess = true;
-    pullDelayNs = MillisToNano(5);  // 5 ms.
-    pullTimeoutNs = 10000;    // 10 microsseconds.
-    int64_t value = 4321;
-    int32_t uid = 123;
-    values.push_back(value);
-
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    pullerManager->RegisterPullAtomCallback(uid, pullTagId, pullCoolDownNs, pullTimeoutNs,
-                                            vector<int32_t>(), cb);
-    vector<shared_ptr<LogEvent>> dataHolder;
-    int64_t startTimeNs = getElapsedRealtimeNs();
-    // Returns false, since StatsPuller code will evaluate the timeout.
-    EXPECT_FALSE(pullerManager->Pull(pullTagId, {uid}, startTimeNs, &dataHolder));
-    int64_t endTimeNs = getElapsedRealtimeNs();
-    int64_t actualPullDurationNs = endTimeNs - startTimeNs;
-
-    // Pull should take at least the timeout amount of time, but should stop early because the delay
-    // is bigger. Make sure that the time is closer to the timeout, than to the intended delay.
-    EXPECT_LT(pullTimeoutNs, actualPullDurationNs);
-    EXPECT_GT(pullDelayNs / 5, actualPullDurationNs);
-    ASSERT_EQ(0, dataHolder.size());
-
-    // Let the pull return and make sure that the dataHolder is not modified.
-    pullThread.join();
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/external/StatsPullerManager_test.cpp b/cmds/statsd/tests/external/StatsPullerManager_test.cpp
deleted file mode 100644
index 0d539f4..0000000
--- a/cmds/statsd/tests/external/StatsPullerManager_test.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (C) 2020 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.
-
-#include "src/external/StatsPullerManager.h"
-
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <aidl/android/util/StatsEventParcel.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using aidl::android::util::StatsEventParcel;
-using ::ndk::SharedRefBase;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-int pullTagId1 = 10101;
-int pullTagId2 = 10102;
-int uid1 = 9999;
-int uid2 = 8888;
-ConfigKey configKey(50, 12345);
-ConfigKey badConfigKey(60, 54321);
-int unregisteredUid = 98765;
-int64_t coolDownNs = NS_PER_SEC;
-int64_t timeoutNs = NS_PER_SEC / 2;
-
-AStatsEvent* createSimpleEvent(int32_t atomId, int32_t value) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeInt32(event, value);
-    AStatsEvent_build(event);
-    return event;
-}
-
-class FakePullAtomCallback : public BnPullAtomCallback {
-public:
-    FakePullAtomCallback(int32_t uid) : mUid(uid){};
-    Status onPullAtom(int atomTag,
-                      const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override {
-        vector<StatsEventParcel> parcels;
-        AStatsEvent* event = createSimpleEvent(atomTag, mUid);
-        size_t size;
-        uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
-
-        StatsEventParcel p;
-        // vector.assign() creates a copy, but this is inevitable unless
-        // stats_event.h/c uses a vector as opposed to a buffer.
-        p.buffer.assign(buffer, buffer + size);
-        parcels.push_back(std::move(p));
-        AStatsEvent_release(event);
-        resultReceiver->pullFinished(atomTag, /*success*/ true, parcels);
-        return Status::ok();
-    }
-    int32_t mUid;
-};
-
-class FakePullUidProvider : public PullUidProvider {
-public:
-    vector<int32_t> getPullAtomUids(int atomId) override {
-        if (atomId == pullTagId1) {
-            return {uid2, uid1};
-        } else if (atomId == pullTagId2) {
-            return {uid2};
-        }
-        return {};
-    }
-};
-
-sp<StatsPullerManager> createPullerManagerAndRegister() {
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    shared_ptr<FakePullAtomCallback> cb1 = SharedRefBase::make<FakePullAtomCallback>(uid1);
-    pullerManager->RegisterPullAtomCallback(uid1, pullTagId1, coolDownNs, timeoutNs, {}, cb1);
-    shared_ptr<FakePullAtomCallback> cb2 = SharedRefBase::make<FakePullAtomCallback>(uid2);
-    pullerManager->RegisterPullAtomCallback(uid2, pullTagId1, coolDownNs, timeoutNs, {}, cb2);
-    pullerManager->RegisterPullAtomCallback(uid1, pullTagId2, coolDownNs, timeoutNs, {}, cb1);
-    return pullerManager;
-}
-}  // anonymous namespace
-
-TEST(StatsPullerManagerTest, TestPullInvalidUid) {
-    sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
-
-    vector<shared_ptr<LogEvent>> data;
-    EXPECT_FALSE(pullerManager->Pull(pullTagId1, {unregisteredUid}, /*timestamp =*/1, &data));
-}
-
-TEST(StatsPullerManagerTest, TestPullChoosesCorrectUid) {
-    sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
-
-    vector<shared_ptr<LogEvent>> data;
-    EXPECT_TRUE(pullerManager->Pull(pullTagId1, {uid1}, /*timestamp =*/1, &data));
-    ASSERT_EQ(data.size(), 1);
-    EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
-    ASSERT_EQ(data[0]->getValues().size(), 1);
-    EXPECT_EQ(data[0]->getValues()[0].mValue.int_value, uid1);
-}
-
-TEST(StatsPullerManagerTest, TestPullInvalidConfigKey) {
-    sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
-    sp<FakePullUidProvider> uidProvider = new FakePullUidProvider();
-    pullerManager->RegisterPullUidProvider(configKey, uidProvider);
-
-    vector<shared_ptr<LogEvent>> data;
-    EXPECT_FALSE(pullerManager->Pull(pullTagId1, badConfigKey, /*timestamp =*/1, &data));
-}
-
-TEST(StatsPullerManagerTest, TestPullConfigKeyGood) {
-    sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
-    sp<FakePullUidProvider> uidProvider = new FakePullUidProvider();
-    pullerManager->RegisterPullUidProvider(configKey, uidProvider);
-
-    vector<shared_ptr<LogEvent>> data;
-    EXPECT_TRUE(pullerManager->Pull(pullTagId1, configKey, /*timestamp =*/1, &data));
-    EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
-    ASSERT_EQ(data[0]->getValues().size(), 1);
-    EXPECT_EQ(data[0]->getValues()[0].mValue.int_value, uid2);
-}
-
-TEST(StatsPullerManagerTest, TestPullConfigKeyNoPullerWithUid) {
-    sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
-    sp<FakePullUidProvider> uidProvider = new FakePullUidProvider();
-    pullerManager->RegisterPullUidProvider(configKey, uidProvider);
-
-    vector<shared_ptr<LogEvent>> data;
-    EXPECT_FALSE(pullerManager->Pull(pullTagId2, configKey, /*timestamp =*/1, &data));
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/tests/external/StatsPuller_test.cpp b/cmds/statsd/tests/external/StatsPuller_test.cpp
deleted file mode 100644
index 55a9036..0000000
--- a/cmds/statsd/tests/external/StatsPuller_test.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright (C) 2018 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.
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <chrono>
-#include <thread>
-#include <vector>
-
-#include "../metrics/metrics_test_helper.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-using std::this_thread::sleep_for;
-using testing::Contains;
-
-namespace {
-int pullTagId = 10014;
-
-bool pullSuccess;
-vector<std::shared_ptr<LogEvent>> pullData;
-long pullDelayNs;
-
-class FakePuller : public StatsPuller {
-public:
-    FakePuller()
-        : StatsPuller(pullTagId, /*coolDownNs=*/MillisToNano(10), /*timeoutNs=*/MillisToNano(5)){};
-
-private:
-    bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override {
-        (*data) = pullData;
-        sleep_for(std::chrono::nanoseconds(pullDelayNs));
-        return pullSuccess;
-    }
-};
-
-FakePuller puller;
-
-std::unique_ptr<LogEvent> createSimpleEvent(int64_t eventTimeNs, int64_t value) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, pullTagId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-    AStatsEvent_writeInt64(statsEvent, value);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-class StatsPullerTest : public ::testing::Test {
-public:
-    StatsPullerTest() {
-    }
-
-    void SetUp() override {
-        puller.ForceClearCache();
-        pullSuccess = false;
-        pullDelayNs = 0;
-        pullData.clear();
-    }
-};
-
-}  // Anonymous namespace.
-
-TEST_F(StatsPullerTest, PullSuccess) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-
-    pullSuccess = true;
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(1, dataHolder.size());
-    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
-    EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    ASSERT_EQ(1, dataHolder[0]->size());
-    EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
-    sleep_for(std::chrono::milliseconds(11));
-
-    pullData.clear();
-    pullData.push_back(createSimpleEvent(2222L, 44));
-
-    pullSuccess = true;
-
-    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(1, dataHolder.size());
-    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
-    EXPECT_EQ(2222L, dataHolder[0]->GetElapsedTimestampNs());
-    ASSERT_EQ(1, dataHolder[0]->size());
-    EXPECT_EQ(44, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-TEST_F(StatsPullerTest, PullFailAfterSuccess) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-
-    pullSuccess = true;
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(1, dataHolder.size());
-    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
-    EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    ASSERT_EQ(1, dataHolder[0]->size());
-    EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
-    sleep_for(std::chrono::milliseconds(11));
-
-    pullData.clear();
-    pullData.push_back(createSimpleEvent(2222L, 44));
-
-    pullSuccess = false;
-    dataHolder.clear();
-    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-
-    // Fails due to hitting the cool down.
-    pullSuccess = true;
-    dataHolder.clear();
-    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-// Test pull takes longer than timeout, 2nd pull happens shorter than cooldown
-TEST_F(StatsPullerTest, PullTakeTooLongAndPullFast) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-    pullSuccess = true;
-    // timeout is 5ms
-    pullDelayNs = MillisToNano(6);
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-
-    pullData.clear();
-    pullData.push_back(createSimpleEvent(2222L, 44));
-    pullDelayNs = 0;
-
-    pullSuccess = true;
-    dataHolder.clear();
-    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullFail) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-
-    pullSuccess = false;
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullTakeTooLong) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-
-    pullSuccess = true;
-    pullDelayNs = MillisToNano(6);
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullTooFast) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-
-    pullSuccess = true;
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(1, dataHolder.size());
-    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
-    EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    ASSERT_EQ(1, dataHolder[0]->size());
-    EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
-    pullData.clear();
-    pullData.push_back(createSimpleEvent(2222L, 44));
-
-    pullSuccess = true;
-
-    dataHolder.clear();
-    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(1, dataHolder.size());
-    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
-    EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    ASSERT_EQ(1, dataHolder[0]->size());
-    EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-TEST_F(StatsPullerTest, PullFailsAndTooFast) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-
-    pullSuccess = false;
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-
-    pullData.clear();
-    pullData.push_back(createSimpleEvent(2222L, 44));
-
-    pullSuccess = true;
-
-    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullSameEventTime) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-
-    pullSuccess = true;
-    int64_t eventTimeNs = getElapsedRealtimeNs();
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
-    ASSERT_EQ(1, dataHolder.size());
-    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
-    EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    ASSERT_EQ(1, dataHolder[0]->size());
-    EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-
-    pullData.clear();
-    pullData.push_back(createSimpleEvent(2222L, 44));
-
-    // Sleep to ensure the cool down expires.
-    sleep_for(std::chrono::milliseconds(11));
-    pullSuccess = true;
-
-    dataHolder.clear();
-    EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
-    ASSERT_EQ(1, dataHolder.size());
-    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
-    EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    ASSERT_EQ(1, dataHolder[0]->size());
-    EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
-}
-
-// Test pull takes longer than timeout, 2nd pull happens at same event time
-TEST_F(StatsPullerTest, PullTakeTooLongAndPullSameEventTime) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-    pullSuccess = true;
-    int64_t eventTimeNs = getElapsedRealtimeNs();
-    // timeout is 5ms
-    pullDelayNs = MillisToNano(6);
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-
-    // Sleep to ensure the cool down expires. 6ms is taken by the delay, so only 5 is needed here.
-    sleep_for(std::chrono::milliseconds(5));
-
-    pullData.clear();
-    pullData.push_back(createSimpleEvent(2222L, 44));
-    pullDelayNs = 0;
-
-    pullSuccess = true;
-    dataHolder.clear();
-    EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-TEST_F(StatsPullerTest, PullFailsAndPullSameEventTime) {
-    pullData.push_back(createSimpleEvent(1111L, 33));
-
-    pullSuccess = false;
-    int64_t eventTimeNs = getElapsedRealtimeNs();
-
-    vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-
-    // Sleep to ensure the cool down expires.
-    sleep_for(std::chrono::milliseconds(11));
-
-    pullData.clear();
-    pullData.push_back(createSimpleEvent(2222L, 44));
-
-    pullSuccess = true;
-
-    EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
-    ASSERT_EQ(0, dataHolder.size());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp
deleted file mode 100644
index a21dc87..0000000
--- a/cmds/statsd/tests/external/puller_util_test.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (C) 2018 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.
-
-#include "external/puller_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "../metrics/metrics_test_helper.h"
-#include "FieldValue.h"
-#include "annotations.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using std::shared_ptr;
-using std::vector;
-/*
- * Test merge isolated and host uid
- */
-namespace {
-const int uidAtomTagId = 100;
-const vector<int> additiveFields = {3};
-const int nonUidAtomTagId = 200;
-const int timestamp = 1234;
-const int isolatedUid1 = 30;
-const int isolatedUid2 = 40;
-const int isolatedNonAdditiveData = 32;
-const int isolatedAdditiveData = 31;
-const int hostUid = 20;
-const int hostNonAdditiveData = 22;
-const int hostAdditiveData = 21;
-const int attributionAtomTagId = 300;
-
-sp<MockUidMap> makeMockUidMap() {
-    return makeMockUidMapForOneHost(hostUid, {isolatedUid1, isolatedUid2});
-}
-
-}  // anonymous namespace
-
-TEST(PullerUtilTest, MergeNoDimension) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 30->22->31
-            makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
-                            isolatedAdditiveData),
-
-            // 20->22->21
-            makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
-                            hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
-    ASSERT_EQ(1, (int)data.size());
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MergeWithDimension) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 30->32->31
-            makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
-                            isolatedAdditiveData),
-
-            // 20->32->21
-            makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
-                            hostAdditiveData),
-
-            // 20->22->21
-            makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
-                            hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
-    ASSERT_EQ(2, (int)data.size());
-
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, NoMergeHostUidOnly) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 20->32->31
-            makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
-                            isolatedAdditiveData),
-
-            // 20->22->21
-            makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData,
-                            hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
-    ASSERT_EQ(2, (int)data.size());
-
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, IsolatedUidOnly) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 30->32->31
-            makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
-                            isolatedAdditiveData),
-
-            // 30->22->21
-            makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
-                            hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
-    ASSERT_EQ(2, (int)data.size());
-
-    // 20->32->31
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-
-    // 20->22->21
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUid) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 30->32->31
-            makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData,
-                            isolatedAdditiveData),
-
-            // 31->32->21
-            makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid2, isolatedNonAdditiveData,
-                            hostAdditiveData),
-
-            // 20->32->21
-            makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData,
-                            hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
-    ASSERT_EQ(1, (int)data.size());
-
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(3, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
-              actualFieldValues->at(2).mValue.int_value);
-}
-
-TEST(PullerUtilTest, NoNeedToMerge) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 32->31
-            CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, isolatedNonAdditiveData,
-                                   isolatedAdditiveData),
-
-            // 22->21
-            CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, hostNonAdditiveData,
-                                   hostAdditiveData),
-
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, nonUidAtomTagId, {} /*no additive fields*/);
-
-    ASSERT_EQ(2, (int)data.size());
-
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(2, actualFieldValues->size());
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(1).mValue.int_value);
-
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(2, actualFieldValues->size());
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(1).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MergeNoDimensionAttributionChain) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 30->tag1->400->tag2->22->31
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
-                                    {"tag1", "tag2"}, hostNonAdditiveData, isolatedAdditiveData),
-
-            // 20->tag1->400->tag2->22->21
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
-                                    {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
-    ASSERT_EQ(1, (int)data.size());
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MergeWithDimensionAttributionChain) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 200->tag1->30->tag2->32->31
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, isolatedUid1},
-                                    {"tag1", "tag2"}, isolatedNonAdditiveData,
-                                    isolatedAdditiveData),
-
-            // 200->tag1->20->tag2->32->21
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
-                                    {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
-
-            // 200->tag1->20->tag2->22->21
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid},
-                                    {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
-    ASSERT_EQ(2, (int)data.size());
-
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, NoMergeHostUidOnlyAttributionChain) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 20->tag1->400->tag2->32->31
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
-                                    {"tag1", "tag2"}, isolatedNonAdditiveData,
-                                    isolatedAdditiveData),
-
-            // 20->tag1->400->tag2->22->21
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
-                                    {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
-    ASSERT_EQ(2, (int)data.size());
-
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, IsolatedUidOnlyAttributionChain) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 30->tag1->400->tag2->32->31
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
-                                    {"tag1", "tag2"}, isolatedNonAdditiveData,
-                                    isolatedAdditiveData),
-
-            // 30->tag1->400->tag2->22->21
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
-                                    {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
-    ASSERT_EQ(2, (int)data.size());
-
-    // 20->tag1->400->tag2->32->31
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value);
-
-    // 20->tag1->400->tag2->22->21
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value);
-}
-
-TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUidAttributionChain) {
-    vector<shared_ptr<LogEvent>> data = {
-            // 30->tag1->400->tag2->32->31
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400},
-                                    {"tag1", "tag2"}, isolatedNonAdditiveData,
-                                    isolatedAdditiveData),
-
-            // 31->tag1->400->tag2->32->21
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid2, 400},
-                                    {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
-
-            // 20->tag1->400->tag2->32->21
-            makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400},
-                                    {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields);
-
-    ASSERT_EQ(1, (int)data.size());
-
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
-    EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value);
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData,
-              actualFieldValues->at(5).mValue.int_value);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
deleted file mode 100644
index 428c46f..0000000
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/guardrail/StatsdStats.h"
-#include "statslog_statsdtest.h"
-#include "tests/statsd_test_util.h"
-
-#include <gtest/gtest.h>
-#include <vector>
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using std::vector;
-
-TEST(StatsdStatsTest, TestValidConfigAdd) {
-    StatsdStats stats;
-    ConfigKey key(0, 12345);
-    const int metricsCount = 10;
-    const int conditionsCount = 20;
-    const int matchersCount = 30;
-    const int alertsCount = 10;
-    stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
-                             true /*valid config*/);
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false /*reset stats*/);
-
-    StatsdStatsReport report;
-    bool good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-    ASSERT_EQ(1, report.config_stats_size());
-    const auto& configReport = report.config_stats(0);
-    EXPECT_EQ(0, configReport.uid());
-    EXPECT_EQ(12345, configReport.id());
-    EXPECT_EQ(metricsCount, configReport.metric_count());
-    EXPECT_EQ(conditionsCount, configReport.condition_count());
-    EXPECT_EQ(matchersCount, configReport.matcher_count());
-    EXPECT_EQ(alertsCount, configReport.alert_count());
-    EXPECT_EQ(true, configReport.is_valid());
-    EXPECT_FALSE(configReport.has_deletion_time_sec());
-}
-
-TEST(StatsdStatsTest, TestInvalidConfigAdd) {
-    StatsdStats stats;
-    ConfigKey key(0, 12345);
-    const int metricsCount = 10;
-    const int conditionsCount = 20;
-    const int matchersCount = 30;
-    const int alertsCount = 10;
-    stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
-                             false /*bad config*/);
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-
-    StatsdStatsReport report;
-    bool good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-    ASSERT_EQ(1, report.config_stats_size());
-    const auto& configReport = report.config_stats(0);
-    // The invalid config should be put into icebox with a deletion time.
-    EXPECT_TRUE(configReport.has_deletion_time_sec());
-}
-
-TEST(StatsdStatsTest, TestConfigRemove) {
-    StatsdStats stats;
-    ConfigKey key(0, 12345);
-    const int metricsCount = 10;
-    const int conditionsCount = 20;
-    const int matchersCount = 30;
-    const int alertsCount = 10;
-    stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
-                             true);
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-    StatsdStatsReport report;
-    bool good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-    ASSERT_EQ(1, report.config_stats_size());
-    const auto& configReport = report.config_stats(0);
-    EXPECT_FALSE(configReport.has_deletion_time_sec());
-
-    stats.noteConfigRemoved(key);
-    stats.dumpStats(&output, false);
-    good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-    ASSERT_EQ(1, report.config_stats_size());
-    const auto& configReport2 = report.config_stats(0);
-    EXPECT_TRUE(configReport2.has_deletion_time_sec());
-}
-
-TEST(StatsdStatsTest, TestSubStats) {
-    StatsdStats stats;
-    ConfigKey key(0, 12345);
-    stats.noteConfigReceived(key, 2, 3, 4, 5, {std::make_pair(123, 456)}, true);
-
-    stats.noteMatcherMatched(key, StringToId("matcher1"));
-    stats.noteMatcherMatched(key, StringToId("matcher1"));
-    stats.noteMatcherMatched(key, StringToId("matcher2"));
-
-    stats.noteConditionDimensionSize(key, StringToId("condition1"), 250);
-    stats.noteConditionDimensionSize(key, StringToId("condition1"), 240);
-
-    stats.noteMetricDimensionSize(key, StringToId("metric1"), 201);
-    stats.noteMetricDimensionSize(key, StringToId("metric1"), 202);
-
-    stats.noteAnomalyDeclared(key, StringToId("alert1"));
-    stats.noteAnomalyDeclared(key, StringToId("alert1"));
-    stats.noteAnomalyDeclared(key, StringToId("alert2"));
-
-    // broadcast-> 2
-    stats.noteBroadcastSent(key);
-    stats.noteBroadcastSent(key);
-
-    // data drop -> 1
-    stats.noteDataDropped(key, 123);
-
-    // dump report -> 3
-    stats.noteMetricsReportSent(key, 0);
-    stats.noteMetricsReportSent(key, 0);
-    stats.noteMetricsReportSent(key, 0);
-
-    // activation_time_sec -> 2
-    stats.noteActiveStatusChanged(key, true);
-    stats.noteActiveStatusChanged(key, true);
-
-    // deactivation_time_sec -> 1
-    stats.noteActiveStatusChanged(key, false);
-
-    vector<uint8_t> output;
-    stats.dumpStats(&output, true);  // Dump and reset stats
-    StatsdStatsReport report;
-    bool good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-    ASSERT_EQ(1, report.config_stats_size());
-    const auto& configReport = report.config_stats(0);
-    ASSERT_EQ(2, configReport.broadcast_sent_time_sec_size());
-    ASSERT_EQ(1, configReport.data_drop_time_sec_size());
-    ASSERT_EQ(1, configReport.data_drop_bytes_size());
-    EXPECT_EQ(123, configReport.data_drop_bytes(0));
-    ASSERT_EQ(3, configReport.dump_report_time_sec_size());
-    ASSERT_EQ(3, configReport.dump_report_data_size_size());
-    ASSERT_EQ(2, configReport.activation_time_sec_size());
-    ASSERT_EQ(1, configReport.deactivation_time_sec_size());
-    ASSERT_EQ(1, configReport.annotation_size());
-    EXPECT_EQ(123, configReport.annotation(0).field_int64());
-    EXPECT_EQ(456, configReport.annotation(0).field_int32());
-
-    ASSERT_EQ(2, configReport.matcher_stats_size());
-    // matcher1 is the first in the list
-    if (configReport.matcher_stats(0).id() == StringToId("matcher1")) {
-        EXPECT_EQ(2, configReport.matcher_stats(0).matched_times());
-        EXPECT_EQ(1, configReport.matcher_stats(1).matched_times());
-        EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(1).id());
-    } else {
-        // matcher1 is the second in the list.
-        EXPECT_EQ(1, configReport.matcher_stats(0).matched_times());
-        EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(0).id());
-
-        EXPECT_EQ(2, configReport.matcher_stats(1).matched_times());
-        EXPECT_EQ(StringToId("matcher1"), configReport.matcher_stats(1).id());
-    }
-
-    ASSERT_EQ(2, configReport.alert_stats_size());
-    bool alert1first = configReport.alert_stats(0).id() == StringToId("alert1");
-    EXPECT_EQ(StringToId("alert1"), configReport.alert_stats(alert1first ? 0 : 1).id());
-    EXPECT_EQ(2, configReport.alert_stats(alert1first ? 0 : 1).alerted_times());
-    EXPECT_EQ(StringToId("alert2"), configReport.alert_stats(alert1first ? 1 : 0).id());
-    EXPECT_EQ(1, configReport.alert_stats(alert1first ? 1 : 0).alerted_times());
-
-    ASSERT_EQ(1, configReport.condition_stats_size());
-    EXPECT_EQ(StringToId("condition1"), configReport.condition_stats(0).id());
-    EXPECT_EQ(250, configReport.condition_stats(0).max_tuple_counts());
-
-    ASSERT_EQ(1, configReport.metric_stats_size());
-    EXPECT_EQ(StringToId("metric1"), configReport.metric_stats(0).id());
-    EXPECT_EQ(202, configReport.metric_stats(0).max_tuple_counts());
-
-    // after resetting the stats, some new events come
-    stats.noteMatcherMatched(key, StringToId("matcher99"));
-    stats.noteConditionDimensionSize(key, StringToId("condition99"), 300);
-    stats.noteMetricDimensionSize(key, StringToId("metric99tion99"), 270);
-    stats.noteAnomalyDeclared(key, StringToId("alert99"));
-
-    // now the config stats should only contain the stats about the new event.
-    stats.dumpStats(&output, false);
-    good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-    ASSERT_EQ(1, report.config_stats_size());
-    const auto& configReport2 = report.config_stats(0);
-    ASSERT_EQ(1, configReport2.matcher_stats_size());
-    EXPECT_EQ(StringToId("matcher99"), configReport2.matcher_stats(0).id());
-    EXPECT_EQ(1, configReport2.matcher_stats(0).matched_times());
-
-    ASSERT_EQ(1, configReport2.condition_stats_size());
-    EXPECT_EQ(StringToId("condition99"), configReport2.condition_stats(0).id());
-    EXPECT_EQ(300, configReport2.condition_stats(0).max_tuple_counts());
-
-    ASSERT_EQ(1, configReport2.metric_stats_size());
-    EXPECT_EQ(StringToId("metric99tion99"), configReport2.metric_stats(0).id());
-    EXPECT_EQ(270, configReport2.metric_stats(0).max_tuple_counts());
-
-    ASSERT_EQ(1, configReport2.alert_stats_size());
-    EXPECT_EQ(StringToId("alert99"), configReport2.alert_stats(0).id());
-    EXPECT_EQ(1, configReport2.alert_stats(0).alerted_times());
-}
-
-TEST(StatsdStatsTest, TestAtomLog) {
-    StatsdStats stats;
-    time_t now = time(nullptr);
-    // old event, we get it from the stats buffer. should be ignored.
-    stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, 1000);
-
-    stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 1);
-    stats.noteAtomLogged(util::SENSOR_STATE_CHANGED, now + 2);
-    stats.noteAtomLogged(util::APP_CRASH_OCCURRED, now + 3);
-
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-    StatsdStatsReport report;
-    bool good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-
-    ASSERT_EQ(2, report.atom_stats_size());
-    bool sensorAtomGood = false;
-    bool dropboxAtomGood = false;
-
-    for (const auto& atomStats : report.atom_stats()) {
-        if (atomStats.tag() == util::SENSOR_STATE_CHANGED && atomStats.count() == 3) {
-            sensorAtomGood = true;
-        }
-        if (atomStats.tag() == util::APP_CRASH_OCCURRED && atomStats.count() == 1) {
-            dropboxAtomGood = true;
-        }
-    }
-
-    EXPECT_TRUE(dropboxAtomGood);
-    EXPECT_TRUE(sensorAtomGood);
-}
-
-TEST(StatsdStatsTest, TestNonPlatformAtomLog) {
-    StatsdStats stats;
-    time_t now = time(nullptr);
-    int newAtom1 = StatsdStats::kMaxPushedAtomId + 1;
-    int newAtom2 = StatsdStats::kMaxPushedAtomId + 2;
-
-    stats.noteAtomLogged(newAtom1, now + 1);
-    stats.noteAtomLogged(newAtom1, now + 2);
-    stats.noteAtomLogged(newAtom2, now + 3);
-
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-    StatsdStatsReport report;
-    bool good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-
-    ASSERT_EQ(2, report.atom_stats_size());
-    bool newAtom1Good = false;
-    bool newAtom2Good = false;
-
-    for (const auto& atomStats : report.atom_stats()) {
-        if (atomStats.tag() == newAtom1 && atomStats.count() == 2) {
-            newAtom1Good = true;
-        }
-        if (atomStats.tag() == newAtom2 && atomStats.count() == 1) {
-            newAtom2Good = true;
-        }
-    }
-
-    EXPECT_TRUE(newAtom1Good);
-    EXPECT_TRUE(newAtom2Good);
-}
-
-TEST(StatsdStatsTest, TestPullAtomStats) {
-    StatsdStats stats;
-
-    stats.updateMinPullIntervalSec(util::DISK_SPACE, 3333L);
-    stats.updateMinPullIntervalSec(util::DISK_SPACE, 2222L);
-    stats.updateMinPullIntervalSec(util::DISK_SPACE, 4444L);
-
-    stats.notePull(util::DISK_SPACE);
-    stats.notePullTime(util::DISK_SPACE, 1111L);
-    stats.notePullDelay(util::DISK_SPACE, 1111L);
-    stats.notePull(util::DISK_SPACE);
-    stats.notePullTime(util::DISK_SPACE, 3333L);
-    stats.notePullDelay(util::DISK_SPACE, 3335L);
-    stats.notePull(util::DISK_SPACE);
-    stats.notePullFromCache(util::DISK_SPACE);
-    stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
-    stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, false);
-    stats.notePullerCallbackRegistrationChanged(util::DISK_SPACE, true);
-    stats.notePullBinderCallFailed(util::DISK_SPACE);
-    stats.notePullUidProviderNotFound(util::DISK_SPACE);
-    stats.notePullerNotFound(util::DISK_SPACE);
-    stats.notePullerNotFound(util::DISK_SPACE);
-    stats.notePullTimeout(util::DISK_SPACE, 3000L, 6000L);
-    stats.notePullTimeout(util::DISK_SPACE, 4000L, 7000L);
-
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-    StatsdStatsReport report;
-    bool good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-
-    ASSERT_EQ(1, report.pulled_atom_stats_size());
-
-    EXPECT_EQ(util::DISK_SPACE, report.pulled_atom_stats(0).atom_id());
-    EXPECT_EQ(3, report.pulled_atom_stats(0).total_pull());
-    EXPECT_EQ(1, report.pulled_atom_stats(0).total_pull_from_cache());
-    EXPECT_EQ(2222L, report.pulled_atom_stats(0).min_pull_interval_sec());
-    EXPECT_EQ(2222L, report.pulled_atom_stats(0).average_pull_time_nanos());
-    EXPECT_EQ(3333L, report.pulled_atom_stats(0).max_pull_time_nanos());
-    EXPECT_EQ(2223L, report.pulled_atom_stats(0).average_pull_delay_nanos());
-    EXPECT_EQ(3335L, report.pulled_atom_stats(0).max_pull_delay_nanos());
-    EXPECT_EQ(2L, report.pulled_atom_stats(0).registered_count());
-    EXPECT_EQ(1L, report.pulled_atom_stats(0).unregistered_count());
-    EXPECT_EQ(1L, report.pulled_atom_stats(0).binder_call_failed());
-    EXPECT_EQ(1L, report.pulled_atom_stats(0).failed_uid_provider_not_found());
-    EXPECT_EQ(2L, report.pulled_atom_stats(0).puller_not_found());
-    ASSERT_EQ(2, report.pulled_atom_stats(0).pull_atom_metadata_size());
-    EXPECT_EQ(3000L, report.pulled_atom_stats(0).pull_atom_metadata(0).pull_timeout_uptime_millis());
-    EXPECT_EQ(4000L, report.pulled_atom_stats(0).pull_atom_metadata(1).pull_timeout_uptime_millis());
-    EXPECT_EQ(6000L, report.pulled_atom_stats(0).pull_atom_metadata(0)
-            .pull_timeout_elapsed_millis());
-    EXPECT_EQ(7000L, report.pulled_atom_stats(0).pull_atom_metadata(1)
-            .pull_timeout_elapsed_millis());
-}
-
-TEST(StatsdStatsTest, TestAtomMetricsStats) {
-    StatsdStats stats;
-    time_t now = time(nullptr);
-    // old event, we get it from the stats buffer. should be ignored.
-    stats.noteBucketDropped(1000L);
-
-    stats.noteBucketBoundaryDelayNs(1000L, -1L);
-    stats.noteBucketBoundaryDelayNs(1000L, -10L);
-    stats.noteBucketBoundaryDelayNs(1000L, 2L);
-
-    stats.noteBucketBoundaryDelayNs(1001L, 1L);
-
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-    StatsdStatsReport report;
-    bool good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-
-    ASSERT_EQ(2, report.atom_metric_stats().size());
-
-    auto atomStats = report.atom_metric_stats(0);
-    EXPECT_EQ(1000L, atomStats.metric_id());
-    EXPECT_EQ(1L, atomStats.bucket_dropped());
-    EXPECT_EQ(-10L, atomStats.min_bucket_boundary_delay_ns());
-    EXPECT_EQ(2L, atomStats.max_bucket_boundary_delay_ns());
-
-    auto atomStats2 = report.atom_metric_stats(1);
-    EXPECT_EQ(1001L, atomStats2.metric_id());
-    EXPECT_EQ(0L, atomStats2.bucket_dropped());
-    EXPECT_EQ(0L, atomStats2.min_bucket_boundary_delay_ns());
-    EXPECT_EQ(1L, atomStats2.max_bucket_boundary_delay_ns());
-}
-
-TEST(StatsdStatsTest, TestAnomalyMonitor) {
-    StatsdStats stats;
-    stats.noteRegisteredAnomalyAlarmChanged();
-    stats.noteRegisteredAnomalyAlarmChanged();
-
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-    StatsdStatsReport report;
-    bool good = report.ParseFromArray(&output[0], output.size());
-    EXPECT_TRUE(good);
-
-    EXPECT_EQ(2, report.anomaly_alarm_stats().alarms_registered());
-}
-
-TEST(StatsdStatsTest, TestTimestampThreshold) {
-    StatsdStats stats;
-    vector<int32_t> timestamps;
-    for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
-        timestamps.push_back(i);
-    }
-    ConfigKey key(0, 12345);
-    stats.noteConfigReceived(key, 2, 3, 4, 5, {}, true);
-
-    for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
-        stats.noteDataDropped(key, timestamps[i]);
-        stats.noteBroadcastSent(key, timestamps[i]);
-        stats.noteMetricsReportSent(key, 0, timestamps[i]);
-        stats.noteActiveStatusChanged(key, true, timestamps[i]);
-        stats.noteActiveStatusChanged(key, false, timestamps[i]);
-    }
-
-    int32_t newTimestamp = 10000;
-
-    // now it should trigger removing oldest timestamp
-    stats.noteDataDropped(key, 123, 10000);
-    stats.noteBroadcastSent(key, 10000);
-    stats.noteMetricsReportSent(key, 0, 10000);
-    stats.noteActiveStatusChanged(key, true, 10000);
-    stats.noteActiveStatusChanged(key, false, 10000);
-
-    EXPECT_TRUE(stats.mConfigStats.find(key) != stats.mConfigStats.end());
-    const auto& configStats = stats.mConfigStats[key];
-
-    size_t maxCount = StatsdStats::kMaxTimestampCount;
-    ASSERT_EQ(maxCount, configStats->broadcast_sent_time_sec.size());
-    ASSERT_EQ(maxCount, configStats->data_drop_time_sec.size());
-    ASSERT_EQ(maxCount, configStats->dump_report_stats.size());
-    ASSERT_EQ(maxCount, configStats->activation_time_sec.size());
-    ASSERT_EQ(maxCount, configStats->deactivation_time_sec.size());
-
-    // the oldest timestamp is the second timestamp in history
-    EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front());
-    EXPECT_EQ(1, configStats->data_drop_bytes.front());
-    EXPECT_EQ(1, configStats->dump_report_stats.front().first);
-    EXPECT_EQ(1, configStats->activation_time_sec.front());
-    EXPECT_EQ(1, configStats->deactivation_time_sec.front());
-
-    // the last timestamp is the newest timestamp.
-    EXPECT_EQ(newTimestamp, configStats->broadcast_sent_time_sec.back());
-    EXPECT_EQ(newTimestamp, configStats->data_drop_time_sec.back());
-    EXPECT_EQ(123, configStats->data_drop_bytes.back());
-    EXPECT_EQ(newTimestamp, configStats->dump_report_stats.back().first);
-    EXPECT_EQ(newTimestamp, configStats->activation_time_sec.back());
-    EXPECT_EQ(newTimestamp, configStats->deactivation_time_sec.back());
-}
-
-TEST(StatsdStatsTest, TestSystemServerCrash) {
-    StatsdStats stats;
-    vector<int32_t> timestamps;
-    for (int i = 0; i < StatsdStats::kMaxSystemServerRestarts; i++) {
-        timestamps.push_back(i);
-        stats.noteSystemServerRestart(timestamps[i]);
-    }
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-    StatsdStatsReport report;
-    EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
-    const int maxCount = StatsdStats::kMaxSystemServerRestarts;
-    ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
-
-    stats.noteSystemServerRestart(StatsdStats::kMaxSystemServerRestarts + 1);
-    output.clear();
-    stats.dumpStats(&output, false);
-    EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
-    ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
-    EXPECT_EQ(StatsdStats::kMaxSystemServerRestarts + 1, report.system_restart_sec(maxCount - 1));
-}
-
-TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit) {
-    StatsdStats stats;
-    int uid1 = 1;
-    int uid2 = 2;
-    stats.noteActivationBroadcastGuardrailHit(uid1, 10);
-    stats.noteActivationBroadcastGuardrailHit(uid1, 20);
-
-    // Test that we only keep 20 timestamps.
-    for (int i = 0; i < 100; i++) {
-        stats.noteActivationBroadcastGuardrailHit(uid2, i);
-    }
-
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-    StatsdStatsReport report;
-    EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
-
-    ASSERT_EQ(2, report.activation_guardrail_stats_size());
-    bool uid1Good = false;
-    bool uid2Good = false;
-    for (const auto& guardrailTimes : report.activation_guardrail_stats()) {
-        if (uid1 == guardrailTimes.uid()) {
-            uid1Good = true;
-            ASSERT_EQ(2, guardrailTimes.guardrail_met_sec_size());
-            EXPECT_EQ(10, guardrailTimes.guardrail_met_sec(0));
-            EXPECT_EQ(20, guardrailTimes.guardrail_met_sec(1));
-        } else if (uid2 == guardrailTimes.uid()) {
-            int maxCount = StatsdStats::kMaxTimestampCount;
-            uid2Good = true;
-            ASSERT_EQ(maxCount, guardrailTimes.guardrail_met_sec_size());
-            for (int i = 0; i < maxCount; i++) {
-                EXPECT_EQ(100 - maxCount + i, guardrailTimes.guardrail_met_sec(i));
-            }
-        } else {
-            FAIL() << "Unexpected uid.";
-        }
-    }
-    EXPECT_TRUE(uid1Good);
-    EXPECT_TRUE(uid2Good);
-}
-
-TEST(StatsdStatsTest, TestAtomErrorStats) {
-    StatsdStats stats;
-
-    int pushAtomTag = 100;
-    int pullAtomTag = 1000;
-    int numErrors = 10;
-
-    for (int i = 0; i < numErrors; i++) {
-        // We must call noteAtomLogged as well because only those pushed atoms
-        // that have been logged will have stats printed about them in the
-        // proto.
-        stats.noteAtomLogged(pushAtomTag, /*timeSec=*/0);
-        stats.noteAtomError(pushAtomTag, /*pull=*/false);
-
-        stats.noteAtomError(pullAtomTag, /*pull=*/true);
-    }
-
-    vector<uint8_t> output;
-    stats.dumpStats(&output, false);
-    StatsdStatsReport report;
-    EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
-
-    // Check error count = numErrors for push atom
-    ASSERT_EQ(1, report.atom_stats_size());
-    const auto& pushedAtomStats = report.atom_stats(0);
-    EXPECT_EQ(pushAtomTag, pushedAtomStats.tag());
-    EXPECT_EQ(numErrors, pushedAtomStats.error_count());
-
-    // Check error count = numErrors for pull atom
-    ASSERT_EQ(1, report.pulled_atom_stats_size());
-    const auto& pulledAtomStats = report.pulled_atom_stats(0);
-    EXPECT_EQ(pullAtomTag, pulledAtomStats.atom_id());
-    EXPECT_EQ(numErrors, pulledAtomStats.atom_error_count());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/indexed_priority_queue_test.cpp b/cmds/statsd/tests/indexed_priority_queue_test.cpp
deleted file mode 100644
index 3a65456..0000000
--- a/cmds/statsd/tests/indexed_priority_queue_test.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "src/anomaly/indexed_priority_queue.h"
-
-#include <gtest/gtest.h>
-
-using namespace android::os::statsd;
-
-/** struct for template in indexed_priority_queue */
-struct AATest : public RefBase {
-    AATest(uint32_t val, std::string a, std::string b) : val(val), a(a), b(b) {
-    }
-
-    const int val;
-    const std::string a;
-    const std::string b;
-
-    struct Smaller {
-        bool operator()(const sp<const AATest> a, const sp<const AATest> b) const {
-            return (a->val < b->val);
-        }
-    };
-};
-
-#ifdef __ANDROID__
-TEST(indexed_priority_queue, empty_and_size) {
-    std::string emptyMetricId;
-    std::string emptyDimensionId;
-    indexed_priority_queue<AATest, AATest::Smaller> ipq;
-    sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
-    sp<const AATest> aa8 = new AATest{8, emptyMetricId, emptyDimensionId};
-
-    ASSERT_EQ(0u, ipq.size());
-    EXPECT_TRUE(ipq.empty());
-
-    ipq.push(aa4);
-    ASSERT_EQ(1u, ipq.size());
-    EXPECT_FALSE(ipq.empty());
-
-    ipq.push(aa8);
-    ASSERT_EQ(2u, ipq.size());
-    EXPECT_FALSE(ipq.empty());
-
-    ipq.remove(aa4);
-    ASSERT_EQ(1u, ipq.size());
-    EXPECT_FALSE(ipq.empty());
-
-    ipq.remove(aa8);
-    ASSERT_EQ(0u, ipq.size());
-    EXPECT_TRUE(ipq.empty());
-}
-
-TEST(indexed_priority_queue, top) {
-    std::string emptyMetricId;
-    std::string emptyDimensionId;
-    indexed_priority_queue<AATest, AATest::Smaller> ipq;
-    sp<const AATest> aa2 = new AATest{2, emptyMetricId, emptyDimensionId};
-    sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
-    sp<const AATest> aa8 = new AATest{8, emptyMetricId, emptyDimensionId};
-    sp<const AATest> aa12 = new AATest{12, emptyMetricId, emptyDimensionId};
-    sp<const AATest> aa16 = new AATest{16, emptyMetricId, emptyDimensionId};
-    sp<const AATest> aa20 = new AATest{20, emptyMetricId, emptyDimensionId};
-
-    EXPECT_EQ(ipq.top(), nullptr);
-
-    // add 8, 4, 12
-    ipq.push(aa8);
-    EXPECT_EQ(ipq.top(), aa8);
-
-    ipq.push(aa12);
-    EXPECT_EQ(ipq.top(), aa8);
-
-    ipq.push(aa4);
-    EXPECT_EQ(ipq.top(), aa4);
-
-    // remove 12, 4
-    ipq.remove(aa12);
-    EXPECT_EQ(ipq.top(), aa4);
-
-    ipq.remove(aa4);
-    EXPECT_EQ(ipq.top(), aa8);
-
-    // add 16, 2, 20
-    ipq.push(aa16);
-    EXPECT_EQ(ipq.top(), aa8);
-
-    ipq.push(aa2);
-    EXPECT_EQ(ipq.top(), aa2);
-
-    ipq.push(aa20);
-    EXPECT_EQ(ipq.top(), aa2);
-
-    // remove 2, 20, 16, 8
-    ipq.remove(aa2);
-    EXPECT_EQ(ipq.top(), aa8);
-
-    ipq.remove(aa20);
-    EXPECT_EQ(ipq.top(), aa8);
-
-    ipq.remove(aa16);
-    EXPECT_EQ(ipq.top(), aa8);
-
-    ipq.remove(aa8);
-    EXPECT_EQ(ipq.top(), nullptr);
-}
-
-TEST(indexed_priority_queue, push_same_aa) {
-    std::string emptyMetricId;
-    std::string emptyDimensionId;
-    indexed_priority_queue<AATest, AATest::Smaller> ipq;
-    sp<const AATest> aa4_a = new AATest{4, emptyMetricId, emptyDimensionId};
-    sp<const AATest> aa4_b = new AATest{4, emptyMetricId, emptyDimensionId};
-
-    ipq.push(aa4_a);
-    ASSERT_EQ(1u, ipq.size());
-    EXPECT_TRUE(ipq.contains(aa4_a));
-    EXPECT_FALSE(ipq.contains(aa4_b));
-
-    ipq.push(aa4_a);
-    ASSERT_EQ(1u, ipq.size());
-    EXPECT_TRUE(ipq.contains(aa4_a));
-    EXPECT_FALSE(ipq.contains(aa4_b));
-
-    ipq.push(aa4_b);
-    ASSERT_EQ(2u, ipq.size());
-    EXPECT_TRUE(ipq.contains(aa4_a));
-    EXPECT_TRUE(ipq.contains(aa4_b));
-}
-
-TEST(indexed_priority_queue, remove_nonexistant) {
-    std::string emptyMetricId;
-    std::string emptyDimensionId;
-    indexed_priority_queue<AATest, AATest::Smaller> ipq;
-    sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
-    sp<const AATest> aa5 = new AATest{5, emptyMetricId, emptyDimensionId};
-
-    ipq.push(aa4);
-    ipq.remove(aa5);
-    ASSERT_EQ(1u, ipq.size());
-    EXPECT_TRUE(ipq.contains(aa4));
-    EXPECT_FALSE(ipq.contains(aa5));
-}
-
-TEST(indexed_priority_queue, remove_same_aa) {
-    indexed_priority_queue<AATest, AATest::Smaller> ipq;
-    std::string emptyMetricId;
-    std::string emptyDimensionId;
-    sp<const AATest> aa4_a = new AATest{4, emptyMetricId, emptyDimensionId};
-    sp<const AATest> aa4_b = new AATest{4, emptyMetricId, emptyDimensionId};
-
-    ipq.push(aa4_a);
-    ipq.push(aa4_b);
-    ASSERT_EQ(2u, ipq.size());
-    EXPECT_TRUE(ipq.contains(aa4_a));
-    EXPECT_TRUE(ipq.contains(aa4_b));
-
-    ipq.remove(aa4_b);
-    ASSERT_EQ(1u, ipq.size());
-    EXPECT_TRUE(ipq.contains(aa4_a));
-    EXPECT_FALSE(ipq.contains(aa4_b));
-
-    ipq.remove(aa4_a);
-    ASSERT_EQ(0u, ipq.size());
-    EXPECT_FALSE(ipq.contains(aa4_a));
-    EXPECT_FALSE(ipq.contains(aa4_b));
-}
-
-TEST(indexed_priority_queue, nulls) {
-    indexed_priority_queue<AATest, AATest::Smaller> ipq;
-
-    EXPECT_TRUE(ipq.empty());
-    EXPECT_FALSE(ipq.contains(nullptr));
-
-    ipq.push(nullptr);
-    EXPECT_TRUE(ipq.empty());
-    EXPECT_FALSE(ipq.contains(nullptr));
-
-    ipq.remove(nullptr);
-    EXPECT_TRUE(ipq.empty());
-    EXPECT_FALSE(ipq.contains(nullptr));
-}
-
-TEST(indexed_priority_queue, pop) {
-    indexed_priority_queue<AATest, AATest::Smaller> ipq;
-    std::string emptyMetricId;
-    std::string emptyDimensionId;
-    sp<const AATest> a = new AATest{1, emptyMetricId, emptyDimensionId};
-    sp<const AATest> b = new AATest{2, emptyMetricId, emptyDimensionId};
-    sp<const AATest> c = new AATest{3, emptyMetricId, emptyDimensionId};
-
-    ipq.push(c);
-    ipq.push(b);
-    ipq.push(a);
-    ASSERT_EQ(3u, ipq.size());
-
-    ipq.pop();
-    ASSERT_EQ(2u, ipq.size());
-    EXPECT_FALSE(ipq.contains(a));
-    EXPECT_TRUE(ipq.contains(b));
-    EXPECT_TRUE(ipq.contains(c));
-
-    ipq.pop();
-    ASSERT_EQ(1u, ipq.size());
-    EXPECT_FALSE(ipq.contains(a));
-    EXPECT_FALSE(ipq.contains(b));
-    EXPECT_TRUE(ipq.contains(c));
-
-    ipq.pop();
-    ASSERT_EQ(0u, ipq.size());
-    EXPECT_FALSE(ipq.contains(a));
-    EXPECT_FALSE(ipq.contains(b));
-    EXPECT_FALSE(ipq.contains(c));
-    EXPECT_TRUE(ipq.empty());
-
-    ipq.pop(); // pop an empty queue
-    EXPECT_TRUE(ipq.empty());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp b/cmds/statsd/tests/log_event/LogEventQueue_test.cpp
deleted file mode 100644
index a15f95b..0000000
--- a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (C) 2019 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.
-
-#include "logd/LogEventQueue.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <thread>
-
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace android;
-using namespace testing;
-
-using std::unique_ptr;
-
-namespace {
-
-std::unique_ptr<LogEvent> makeLogEvent(uint64_t timestampNs) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, 10);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-} // anonymous namespace
-
-#ifdef __ANDROID__
-TEST(LogEventQueue_test, TestGoodConsumer) {
-    LogEventQueue queue(50);
-    int64_t timeBaseNs = 100;
-    std::thread writer([&queue, timeBaseNs] {
-        for (int i = 0; i < 100; i++) {
-            int64_t oldestEventNs;
-            bool success = queue.push(makeLogEvent(timeBaseNs + i * 1000), &oldestEventNs);
-            EXPECT_TRUE(success);
-            std::this_thread::sleep_for(std::chrono::milliseconds(1));
-        }
-    });
-
-    std::thread reader([&queue, timeBaseNs] {
-        for (int i = 0; i < 100; i++) {
-            auto event = queue.waitPop();
-            EXPECT_TRUE(event != nullptr);
-            // All events are in right order.
-            EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs());
-        }
-    });
-
-    reader.join();
-    writer.join();
-}
-
-TEST(LogEventQueue_test, TestSlowConsumer) {
-    LogEventQueue queue(50);
-    int64_t timeBaseNs = 100;
-    std::thread writer([&queue, timeBaseNs] {
-        int failure_count = 0;
-        int64_t oldestEventNs;
-        for (int i = 0; i < 100; i++) {
-            bool success = queue.push(makeLogEvent(timeBaseNs + i * 1000), &oldestEventNs);
-            if (!success) failure_count++;
-            std::this_thread::sleep_for(std::chrono::milliseconds(1));
-        }
-
-        // There is some remote chance that reader thread not get chance to run before writer thread
-        // ends. That's why the following comparison is not "==".
-        // There will be at least 45 events lost due to overflow.
-        EXPECT_TRUE(failure_count >= 45);
-        // The oldest event must be at least the 6th event.
-        EXPECT_TRUE(oldestEventNs <= (100 + 5 * 1000));
-    });
-
-    std::thread reader([&queue, timeBaseNs] {
-        // The consumer quickly processed 5 events, then it got stuck (not reading anymore).
-        for (int i = 0; i < 5; i++) {
-            auto event = queue.waitPop();
-            EXPECT_TRUE(event != nullptr);
-            // All events are in right order.
-            EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs());
-        }
-    });
-
-    reader.join();
-    writer.join();
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/metadata_util_test.cpp b/cmds/statsd/tests/metadata_util_test.cpp
deleted file mode 100644
index 7707890..0000000
--- a/cmds/statsd/tests/metadata_util_test.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-#include <gtest/gtest.h>
-
-#include "metadata_util.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-TEST(MetadataUtilTest, TestWriteAndReadMetricDimensionKey) {
-    HashableDimensionKey dim;
-    HashableDimensionKey dim2;
-    int pos1[] = {1, 1, 1};
-    int pos2[] = {1, 1, 2};
-    int pos3[] = {1, 1, 3};
-    int pos4[] = {2, 0, 0};
-    Field field1(10, pos1, 2);
-    Field field2(10, pos2, 2);
-    Field field3(10, pos3, 2);
-    Field field4(10, pos4, 0);
-
-    Value value1((int32_t)10025);
-    Value value2("tag");
-    Value value3((int32_t)987654);
-    Value value4((int32_t)99999);
-
-    dim.addValue(FieldValue(field1, value1));
-    dim.addValue(FieldValue(field2, value2));
-    dim.addValue(FieldValue(field3, value3));
-    dim.addValue(FieldValue(field4, value4));
-
-    dim2.addValue(FieldValue(field1, value1));
-    dim2.addValue(FieldValue(field2, value2));
-
-    MetricDimensionKey dimKey(dim, dim2);
-
-    metadata::MetricDimensionKey metadataDimKey;
-    writeMetricDimensionKeyToMetadataDimensionKey(dimKey, &metadataDimKey);
-
-    MetricDimensionKey loadedDimKey = loadMetricDimensionKeyFromProto(metadataDimKey);
-
-    ASSERT_EQ(loadedDimKey, dimKey);
-    ASSERT_EQ(std::hash<MetricDimensionKey>{}(loadedDimKey),
-            std::hash<MetricDimensionKey>{}(dimKey));
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
deleted file mode 100644
index 8e2864c..0000000
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ /dev/null
@@ -1,477 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/metrics/CountMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-namespace {
-const ConfigKey kConfigKey(0, 12345);
-const uint64_t protoHash = 0x1234567890;
-
-void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId, string uid) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-    AStatsEvent_writeString(statsEvent, uid.c_str());
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-}  // namespace
-
-// Setup for parameterized tests.
-class CountMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(CountMetricProducerTest_PartialBucket,
-                         CountMetricProducerTest_PartialBucket,
-                         testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-TEST(CountMetricProducerTest, TestFirstBucket) {
-    CountMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
-    EXPECT_EQ(600500000000, countProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(10, countProducer.mCurrentBucketNum);
-    EXPECT_EQ(660000000005, countProducer.getCurrentBucketEndTimeNs());
-}
-
-TEST(CountMetricProducerTest, TestNonDimensionalEvents) {
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-    int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-    int tagId = 1;
-
-    CountMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, bucketStartTimeNs, bucketStartTimeNs);
-
-    // 2 events in bucket 1.
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
-
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    // Flushes at event #2.
-    countProducer.flushIfNeededLocked(bucketStartTimeNs + 2);
-    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
-    // Flushes.
-    countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
-    EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
-                countProducer.mPastBuckets.end());
-    const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(1UL, buckets.size());
-    EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
-    EXPECT_EQ(2LL, buckets[0].mCount);
-
-    // 1 matched event happens in bucket 2.
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 2, tagId);
-
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-
-    countProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
-    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
-    EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
-                countProducer.mPastBuckets.end());
-    ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    const auto& bucketInfo2 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1];
-    EXPECT_EQ(bucket2StartTimeNs, bucketInfo2.mBucketStartNs);
-    EXPECT_EQ(bucket2StartTimeNs + bucketSizeNs, bucketInfo2.mBucketEndNs);
-    EXPECT_EQ(1LL, bucketInfo2.mCount);
-
-    // nothing happens in bucket 3. we should not record anything for bucket 3.
-    countProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
-    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
-    EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
-                countProducer.mPastBuckets.end());
-    const auto& buckets3 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(2UL, buckets3.size());
-}
-
-TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition) {
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
-    CountMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_condition(StringToId("SCREEN_ON"));
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    CountMetricProducer countProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
-                                      protoHash, bucketStartTimeNs, bucketStartTimeNs);
-
-    countProducer.onConditionChanged(true, bucketStartTimeNs);
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, bucketStartTimeNs + 1, /*atomId=*/1);
-    countProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
-
-    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
-    countProducer.onConditionChanged(false /*new condition*/, bucketStartTimeNs + 2);
-
-    // Upon this match event, the matched event1 is flushed.
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, bucketStartTimeNs + 10, /*atomId=*/1);
-    countProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
-    countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
-    EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
-                countProducer.mPastBuckets.end());
-
-    const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(1UL, buckets.size());
-    const auto& bucketInfo = buckets[0];
-    EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
-    EXPECT_EQ(1LL, bucketInfo.mCount);
-}
-
-TEST(CountMetricProducerTest, TestEventsWithSlicedCondition) {
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
-    int tagId = 1;
-    int conditionTagId = 2;
-
-    CountMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
-    MetricConditionLink* link = metric.add_links();
-    link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
-    buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
-    buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, bucketStartTimeNs + 10, tagId, /*uid=*/"222");
-
-    ConditionKey key1;
-    key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
-            getMockedDimensionKey(conditionTagId, 2, "111")};
-
-    ConditionKey key2;
-    key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
-            getMockedDimensionKey(conditionTagId, 2, "222")};
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
-
-    EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
-
-    CountMetricProducer countProducer(kConfigKey, metric, 0 /*condition tracker index*/,
-                                      {ConditionState::kUnknown}, wizard, protoHash,
-                                      bucketStartTimeNs, bucketStartTimeNs);
-
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    countProducer.flushIfNeededLocked(bucketStartTimeNs + 1);
-    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-    countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
-    EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
-                countProducer.mPastBuckets.end());
-    const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(1UL, buckets.size());
-    const auto& bucketInfo = buckets[0];
-    EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
-    EXPECT_EQ(1LL, bucketInfo.mCount);
-}
-
-TEST_P(CountMetricProducerTest_PartialBucket, TestSplitInCurrentBucket) {
-    sp<AlarmMonitor> alarmMonitor;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-    int64_t eventTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-
-    int tagId = 1;
-    int conditionTagId = 2;
-
-    CountMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    Alert alert;
-    alert.set_num_buckets(3);
-    alert.set_trigger_if_sum_gt(2);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
-                                      protoHash, bucketStartTimeNs, bucketStartTimeNs);
-
-    sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
-    EXPECT_TRUE(anomalyTracker != nullptr);
-
-    // Bucket is not flushed yet.
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-    EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
-    // App upgrade or boot complete forces bucket flush.
-    // Check that there's a past bucket and the bucket end is not adjusted.
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            countProducer.notifyAppUpgrade(eventTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            countProducer.onStatsdInitCompleted(eventTimeNs);
-            break;
-    }
-    ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(bucketStartTimeNs,
-              countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
-    EXPECT_EQ(eventTimeNs,
-              countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
-    EXPECT_EQ(0, countProducer.getCurrentBucketNum());
-    EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
-    // Anomaly tracker only contains full buckets.
-    EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
-    int64_t lastEndTimeNs = countProducer.getCurrentBucketEndTimeNs();
-    // Next event occurs in same bucket as partial bucket created.
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, bucketStartTimeNs + 59 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-    ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(0, countProducer.getCurrentBucketNum());
-    EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
-    // Third event in following bucket.
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event3, bucketStartTimeNs + 62 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(lastEndTimeNs, countProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(1, countProducer.getCurrentBucketNum());
-    EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-}
-
-TEST_P(CountMetricProducerTest_PartialBucket, TestSplitInNextBucket) {
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-    int64_t eventTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
-
-    int tagId = 1;
-    int conditionTagId = 2;
-
-    CountMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, {}, wizard,
-                                      protoHash, bucketStartTimeNs, bucketStartTimeNs);
-
-    // Bucket is flushed yet.
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
-
-    // App upgrade or boot complete forces bucket flush.
-    // Check that there's a past bucket and the bucket end is not adjusted since the upgrade
-    // occurred after the bucket end time.
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            countProducer.notifyAppUpgrade(eventTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            countProducer.onStatsdInitCompleted(eventTimeNs);
-            break;
-    }
-    ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(bucketStartTimeNs,
-              countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
-              countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
-    EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
-
-    // Next event occurs in same bucket as partial bucket created.
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, bucketStartTimeNs + 70 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-    ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-
-    // Third event in following bucket.
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event3, bucketStartTimeNs + 121 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ((int64_t)eventTimeNs,
-              countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
-              countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketEndNs);
-}
-
-TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced) {
-    sp<AlarmMonitor> alarmMonitor;
-    Alert alert;
-    alert.set_id(11);
-    alert.set_metric_id(1);
-    alert.set_trigger_if_sum_gt(2);
-    alert.set_num_buckets(2);
-    const int32_t refPeriodSec = 1;
-    alert.set_refractory_period_secs(refPeriodSec);
-
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-    int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-
-    CountMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, bucketStartTimeNs, bucketStartTimeNs);
-
-    sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
-
-    int tagId = 1;
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event3, bucketStartTimeNs + 2 * bucketSizeNs + 1, tagId);
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event4, bucketStartTimeNs + 3 * bucketSizeNs + 1, tagId);
-    LogEvent event5(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event5, bucketStartTimeNs + 3 * bucketSizeNs + 2, tagId);
-    LogEvent event6(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event6, bucketStartTimeNs + 3 * bucketSizeNs + 3, tagId);
-    LogEvent event7(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event7, bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC, tagId);
-
-    // Two events in bucket #0.
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
-    EXPECT_EQ(2L, countProducer.mCurrentSlicedCounter->begin()->second);
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
-    // One event in bucket #2. No alarm as bucket #0 is trashed out.
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
-    EXPECT_EQ(1L, countProducer.mCurrentSlicedCounter->begin()->second);
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
-    // Two events in bucket #3.
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
-    ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
-    EXPECT_EQ(3L, countProducer.mCurrentSlicedCounter->begin()->second);
-    // Anomaly at event 6 is within refractory period. The alarm is at event 5 timestamp not event 6
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-              std::ceil(1.0 * event5.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-
-    countProducer.onMatchedLogEvent(1 /*log matcher index*/, event7);
-    ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
-    EXPECT_EQ(4L, countProducer.mCurrentSlicedCounter->begin()->second);
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-              std::ceil(1.0 * event7.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-}
-
-TEST(CountMetricProducerTest, TestOneWeekTimeUnit) {
-    CountMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_WEEK);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    int64_t oneDayNs = 24 * 60 * 60 * 1e9;
-    int64_t fiveWeeksNs = 5 * 7 * oneDayNs;
-
-    CountMetricProducer countProducer(kConfigKey, metric, -1 /* meaning no condition */, {}, wizard,
-                                      protoHash, oneDayNs, fiveWeeksNs);
-
-    int64_t fiveWeeksOneDayNs = fiveWeeksNs + oneDayNs;
-
-    EXPECT_EQ(fiveWeeksNs, countProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(4, countProducer.mCurrentBucketNum);
-    EXPECT_EQ(fiveWeeksOneDayNs, countProducer.getCurrentBucketEndTimeNs());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
deleted file mode 100644
index bb2ede4..0000000
--- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ /dev/null
@@ -1,518 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/metrics/DurationMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "src/condition/ConditionWizard.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace android::os::statsd;
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-const uint64_t protoHash = 0x1234567890;
-void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-}  // namespace
-
-// Setup for parameterized tests.
-class DurationMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(DurationMetricProducerTest_PartialBucket,
-                         DurationMetricProducerTest_PartialBucket,
-                         testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-TEST(DurationMetricTrackerTest, TestFirstBucket) {
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    DurationMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
-    FieldMatcher dimensions;
-
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, -1 /*no condition*/, {}, -1 /*what index not needed*/,
-            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2);
-
-    EXPECT_EQ(600500000000, durationProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(10, durationProducer.mCurrentBucketNum);
-    EXPECT_EQ(660000000005, durationProducer.getCurrentBucketEndTimeNs());
-}
-
-TEST(DurationMetricTrackerTest, TestNoCondition) {
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
-    DurationMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
-    int tagId = 1;
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, bucketStartTimeNs + bucketSizeNs + 2, tagId);
-
-    FieldMatcher dimensions;
-
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, -1 /*no condition*/, {}, -1 /*what index not needed*/,
-            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-    durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
-    ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
-    EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
-                durationProducer.mPastBuckets.end());
-    const auto& buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(2UL, buckets.size());
-    EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
-    EXPECT_EQ(bucketSizeNs - 1LL, buckets[0].mDuration);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[1].mBucketEndNs);
-    EXPECT_EQ(2LL, buckets[1].mDuration);
-}
-
-TEST(DurationMetricTrackerTest, TestNonSlicedCondition) {
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
-    DurationMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
-    int tagId = 1;
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 1, tagId);
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
-
-    FieldMatcher dimensions;
-
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
-            -1 /*what index not needed*/, 1 /* start index */, 2 /* stop index */,
-            3 /* stop_all index */, false /*nesting*/, wizard, protoHash, dimensions,
-            bucketStartTimeNs, bucketStartTimeNs);
-    durationProducer.mCondition = ConditionState::kFalse;
-
-    EXPECT_FALSE(durationProducer.mCondition);
-    EXPECT_FALSE(durationProducer.isConditionSliced());
-
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-    durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
-    durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
-    durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
-    ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
-    EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
-                durationProducer.mPastBuckets.end());
-    const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(1UL, buckets2.size());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
-    EXPECT_EQ(1LL, buckets2[0].mDuration);
-}
-
-TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState) {
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-
-    DurationMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-
-    int tagId = 1;
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, bucketStartTimeNs + 1, tagId);
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, bucketStartTimeNs + 2, tagId);
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event3, bucketStartTimeNs + bucketSizeNs + 1, tagId);
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event4, bucketStartTimeNs + bucketSizeNs + 3, tagId);
-
-    FieldMatcher dimensions;
-
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, 0 /* condition index */, {ConditionState::kUnknown},
-            -1 /*what index not needed*/, 1 /* start index */, 2 /* stop index */,
-            3 /* stop_all index */, false /*nesting*/, wizard, protoHash, dimensions,
-            bucketStartTimeNs, bucketStartTimeNs);
-
-    EXPECT_EQ(ConditionState::kUnknown, durationProducer.mCondition);
-    EXPECT_FALSE(durationProducer.isConditionSliced());
-
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-    durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
-    durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
-    durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
-    ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
-    const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(1UL, buckets2.size());
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
-    EXPECT_EQ(1LL, buckets2[0].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDuration) {
-    /**
-     * The duration starts from the first bucket, through the two partial buckets (10-70sec),
-     * another bucket, and ends at the beginning of the next full bucket.
-     * Expected buckets:
-     *  - [10,25]: 14 secs
-     *  - [25,70]: All 45 secs
-     *  - [70,130]: All 60 secs
-     *  - [130, 210]: Only 5 secs (event ended at 135sec)
-     */
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-    int tagId = 1;
-
-    DurationMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    FieldMatcher dimensions;
-
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
-            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
-    int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, startTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-    EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
-    int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    ASSERT_EQ(1UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    std::vector<DurationBucket> buckets =
-            durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
-    EXPECT_EQ(partialBucketSplitTimeNs, buckets[0].mBucketEndNs);
-    EXPECT_EQ(partialBucketSplitTimeNs - startTimeNs, buckets[0].mDuration);
-    EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(0, durationProducer.getCurrentBucketNum());
-
-    // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
-    int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, endTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-    buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(3UL, buckets.size());
-    EXPECT_EQ(partialBucketSplitTimeNs, buckets[1].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketEndNs);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - partialBucketSplitTimeNs, buckets[1].mDuration);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[2].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
-    EXPECT_EQ(bucketSizeNs, buckets[2].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDurationWithSplitInFollowingBucket) {
-    /**
-     * Expected buckets (start at 11s, upgrade at 75s, end at 135s):
-     *  - [10,70]: 59 secs
-     *  - [70,75]: 5 sec
-     *  - [75,130]: 55 secs
-     */
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-    int tagId = 1;
-
-    DurationMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    FieldMatcher dimensions;
-
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
-            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
-    int64_t startTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, startTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-    EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
-    int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    ASSERT_EQ(2UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    std::vector<DurationBucket> buckets =
-            durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs, buckets[0].mDuration);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketStartNs);
-    EXPECT_EQ(partialBucketSplitTimeNs, buckets[1].mBucketEndNs);
-    EXPECT_EQ(partialBucketSplitTimeNs - (bucketStartTimeNs + bucketSizeNs), buckets[1].mDuration);
-    EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(1, durationProducer.getCurrentBucketNum());
-
-    // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
-    int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, endTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-    buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(3UL, buckets.size());
-    EXPECT_EQ(partialBucketSplitTimeNs, buckets[2].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs - partialBucketSplitTimeNs,
-              buckets[2].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestSumDurationAnomaly) {
-    sp<AlarmMonitor> alarmMonitor;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-    int tagId = 1;
-
-    // Setup metric with alert.
-    DurationMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-    Alert alert;
-    alert.set_num_buckets(3);
-    alert.set_trigger_if_sum_gt(2);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    FieldMatcher dimensions;
-
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
-            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
-    sp<AnomalyTracker> anomalyTracker = durationProducer.addAnomalyTracker(alert, alarmMonitor);
-    EXPECT_TRUE(anomalyTracker != nullptr);
-
-    int64_t startTimeNs = bucketStartTimeNs + 1;
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, startTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-
-    int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-
-    // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
-    int64_t endTimeNs = startTimeNs + 65 * NS_PER_SEC;
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, endTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - startTimeNs,
-              anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestMaxDuration) {
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-    int tagId = 1;
-
-    DurationMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    FieldMatcher dimensions;
-
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
-            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
-    int64_t startTimeNs = bucketStartTimeNs + 1;
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, startTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-    EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
-    int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(0, durationProducer.getCurrentBucketNum());
-
-    // We skip ahead one bucket, so we fill in the first two partial buckets and one full bucket.
-    int64_t endTimeNs = startTimeNs + 125 * NS_PER_SEC;
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, endTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-
-    durationProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
-    std::vector<DurationBucket> buckets =
-            durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(1UL, buckets.size());
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[0].mBucketEndNs);
-    EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
-}
-
-TEST_P(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket) {
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-    int tagId = 1;
-
-    DurationMetric metric;
-    metric.set_id(1);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    FieldMatcher dimensions;
-
-    DurationMetricProducer durationProducer(
-            kConfigKey, metric, -1 /* no condition */, {}, -1 /*what index not needed*/,
-            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, protoHash, dimensions, bucketStartTimeNs, bucketStartTimeNs);
-
-    int64_t startTimeNs = bucketStartTimeNs + 1;
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, startTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
-    EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
-    int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            durationProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(1, durationProducer.getCurrentBucketNum());
-
-    // Stop occurs in the same partial bucket as created for the app upgrade.
-    int64_t endTimeNs = startTimeNs + 115 * NS_PER_SEC;
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, endTimeNs, tagId);
-    durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-    ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
-
-    durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
-    std::vector<DurationBucket> buckets =
-            durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    ASSERT_EQ(1UL, buckets.size());
-    EXPECT_EQ(partialBucketSplitTimeNs, buckets[0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketEndNs);
-    EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
deleted file mode 100644
index 4bbbd2c..0000000
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/metrics/EventMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-
-namespace {
-const ConfigKey kConfigKey(0, 12345);
-const uint64_t protoHash = 0x1234567890;
-
-void makeLogEvent(LogEvent* logEvent, int32_t atomId, int64_t timestampNs, string str) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-    AStatsEvent_writeString(statsEvent, str.c_str());
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-}  // anonymous namespace
-
-TEST(EventMetricProducerTest, TestNoCondition) {
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
-    EventMetric metric;
-    metric.set_id(1);
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 2);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    EventMetricProducer eventProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, bucketStartTimeNs);
-
-    eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
-    eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-
-    // Check dump report content.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/,
-                               true /*erase data*/, FAST, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_event_metrics());
-    ASSERT_EQ(2, report.event_metrics().data_size());
-    EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
-    EXPECT_EQ(bucketStartTimeNs + 2, report.event_metrics().data(1).elapsed_timestamp_nanos());
-}
-
-TEST(EventMetricProducerTest, TestEventsWithNonSlicedCondition) {
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
-    EventMetric metric;
-    metric.set_id(1);
-    metric.set_condition(StringToId("SCREEN_ON"));
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateNoValuesLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateNoValuesLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
-                                      {ConditionState::kUnknown}, wizard, protoHash,
-                                      bucketStartTimeNs);
-
-    eventProducer.onConditionChanged(true /*condition*/, bucketStartTimeNs);
-    eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
-
-    eventProducer.onConditionChanged(false /*condition*/, bucketStartTimeNs + 2);
-
-    eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-
-    // Check dump report content.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/,
-                               true /*erase data*/, FAST, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_event_metrics());
-    ASSERT_EQ(1, report.event_metrics().data_size());
-    EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
-}
-
-TEST(EventMetricProducerTest, TestEventsWithSlicedCondition) {
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
-    int tagId = 1;
-    int conditionTagId = 2;
-
-    EventMetric metric;
-    metric.set_id(1);
-    metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
-    MetricConditionLink* link = metric.add_links();
-    link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
-    buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
-    buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event1, 1 /*tagId*/, bucketStartTimeNs + 1, "111");
-    ConditionKey key1;
-    key1[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
-            getMockedDimensionKey(conditionTagId, 2, "111")};
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeLogEvent(&event2, 1 /*tagId*/, bucketStartTimeNs + 10, "222");
-    ConditionKey key2;
-    key2[StringToId("APP_IN_BACKGROUND_PER_UID")] = {
-            getMockedDimensionKey(conditionTagId, 2, "222")};
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    // Condition is false for first event.
-    EXPECT_CALL(*wizard, query(_, key1, _)).WillOnce(Return(ConditionState::kFalse));
-    // Condition is true for second event.
-    EXPECT_CALL(*wizard, query(_, key2, _)).WillOnce(Return(ConditionState::kTrue));
-
-    EventMetricProducer eventProducer(kConfigKey, metric, 0 /*condition index*/,
-                                      {ConditionState::kUnknown}, wizard, protoHash,
-                                      bucketStartTimeNs);
-
-    eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
-    eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-
-    // Check dump report content.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    eventProducer.onDumpReport(bucketStartTimeNs + 20, true /*include current partial bucket*/,
-                               true /*erase data*/, FAST, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_event_metrics());
-    ASSERT_EQ(1, report.event_metrics().data_size());
-    EXPECT_EQ(bucketStartTimeNs + 10, report.event_metrics().data(0).elapsed_timestamp_nanos());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
deleted file mode 100644
index 1060681..0000000
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ /dev/null
@@ -1,828 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/metrics/GaugeMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "logd/LogEvent.h"
-#include "metrics_test_helper.h"
-#include "src/matchers/SimpleAtomMatchingTracker.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-using std::make_shared;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-const int tagId = 1;
-const int64_t metricId = 123;
-const uint64_t protoHash = 0x123456789;
-const int logEventMatcherIndex = 0;
-const int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
-const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
-const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
-const int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-
-shared_ptr<LogEvent> makeLogEvent(int32_t atomId, int64_t timestampNs, int32_t value1, string str1,
-                                  int32_t value2) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    AStatsEvent_writeInt32(statsEvent, value1);
-    AStatsEvent_writeString(statsEvent, str1.c_str());
-    AStatsEvent_writeInt32(statsEvent, value2);
-
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-}  // anonymous namespace
-
-// Setup for parameterized tests.
-class GaugeMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(GaugeMetricProducerTest_PartialBucket,
-                         GaugeMetricProducerTest_PartialBucket,
-                         testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-/*
- * Tests that the first bucket works correctly
- */
-TEST(GaugeMetricProducerTest, TestFirstBucket) {
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.mutable_gauge_fields_filter()->set_include_all(false);
-    auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
-    gaugeFieldMatcher->set_field(tagId);
-    gaugeFieldMatcher->add_child()->set_field(1);
-    gaugeFieldMatcher->add_child()->set_field(3);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    // statsd started long ago.
-    // The metric starts in the middle of the bucket
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      -1, -1, tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2,
-                                      pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    EXPECT_EQ(600500000000, gaugeProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(10, gaugeProducer.mCurrentBucketNum);
-    EXPECT_EQ(660000000005, gaugeProducer.getCurrentBucketEndTimeNs());
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.mutable_gauge_fields_filter()->set_include_all(false);
-    metric.set_max_pull_delay_sec(INT_MAX);
-    auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
-    gaugeFieldMatcher->set_field(tagId);
-    gaugeFieldMatcher->add_child()->set_field(1);
-    gaugeFieldMatcher->add_child()->set_field(3);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(makeLogEvent(tagId, eventTimeNs + 10, 3, "some value", 11));
-                return true;
-            }));
-
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(makeLogEvent(tagId, bucket2StartTimeNs + 1, 10, "some value", 11));
-
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
-    EXPECT_EQ(INT, it->mValue.getType());
-    EXPECT_EQ(10, it->mValue.int_value);
-    it++;
-    EXPECT_EQ(11, it->mValue.int_value);
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    EXPECT_EQ(3, gaugeProducer.mPastBuckets.begin()
-                         ->second.back()
-                         .mGaugeAtoms.front()
-                         .mFields->begin()
-                         ->mValue.int_value);
-
-    allData.clear();
-    allData.push_back(makeLogEvent(tagId, bucket3StartTimeNs + 10, 24, "some value", 25));
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
-    EXPECT_EQ(INT, it->mValue.getType());
-    EXPECT_EQ(24, it->mValue.int_value);
-    it++;
-    EXPECT_EQ(INT, it->mValue.getType());
-    EXPECT_EQ(25, it->mValue.int_value);
-    // One dimension.
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
-    it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
-    EXPECT_EQ(INT, it->mValue.getType());
-    EXPECT_EQ(10L, it->mValue.int_value);
-    it++;
-    EXPECT_EQ(INT, it->mValue.getType());
-    EXPECT_EQ(11L, it->mValue.int_value);
-
-    gaugeProducer.flushIfNeededLocked(bucket4StartTimeNs);
-    ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
-    // One dimension.
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    ASSERT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.size());
-    it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
-    EXPECT_EQ(INT, it->mValue.getType());
-    EXPECT_EQ(24L, it->mValue.int_value);
-    it++;
-    EXPECT_EQ(INT, it->mValue.getType());
-    EXPECT_EQ(25L, it->mValue.int_value);
-}
-
-TEST_P(GaugeMetricProducerTest_PartialBucket, TestPushedEvents) {
-    sp<AlarmMonitor> alarmMonitor;
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.mutable_gauge_fields_filter()->set_include_all(true);
-
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(metricId);
-    alert.set_trigger_if_sum_gt(25);
-    alert.set_num_buckets(100);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      -1 /* -1 means no pulling */, -1, tagId, bucketStartTimeNs,
-                                      bucketStartTimeNs, pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
-    EXPECT_TRUE(anomalyTracker != nullptr);
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    EXPECT_EQ(1UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
-
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    EXPECT_EQ(0UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(bucketStartTimeNs,
-              gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
-    EXPECT_EQ(partialBucketSplitTimeNs,
-              gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
-    EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
-    EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
-    // Partial buckets are not sent to anomaly tracker.
-    EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
-    // Create an event in the same partial bucket.
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 1, 10);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-    EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(bucketStartTimeNs,
-              gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
-    EXPECT_EQ(partialBucketSplitTimeNs,
-              gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
-    EXPECT_EQ((int64_t)partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
-    // Partial buckets are not sent to anomaly tracker.
-    EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
-    // Next event should trigger creation of new bucket and send previous full bucket to anomaly
-    // tracker.
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    CreateTwoValueLogEvent(&event3, tagId, bucketStartTimeNs + 65 * NS_PER_SEC, 1, 10);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    EXPECT_EQ(1L, gaugeProducer.mCurrentBucketNum);
-    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ((int64_t)bucketStartTimeNs + bucketSizeNs, gaugeProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(1, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-
-    // Next event should trigger creation of new bucket.
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    CreateTwoValueLogEvent(&event4, tagId, bucketStartTimeNs + 125 * NS_PER_SEC, 1, 10);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-    EXPECT_EQ(2L, gaugeProducer.mCurrentBucketNum);
-    ASSERT_EQ(3UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
-}
-
-TEST_P(GaugeMetricProducerTest_PartialBucket, TestPulled) {
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_max_pull_delay_sec(INT_MAX);
-    auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
-    gaugeFieldMatcher->set_field(tagId);
-    gaugeFieldMatcher->add_child()->set_field(2);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Return(false))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 2));
-                return true;
-            }));
-
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
-                         ->second.front()
-                         .mFields->begin()
-                         ->mValue.int_value);
-
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(bucketStartTimeNs,
-              gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
-    EXPECT_EQ(partialBucketSplitTimeNs,
-              gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
-    EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
-    EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(2, gaugeProducer.mCurrentSlicedBucket->begin()
-                         ->second.front()
-                         .mFields->begin()
-                         ->mValue.int_value);
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + bucketSizeNs + 1, 3));
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
-    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(3, gaugeProducer.mCurrentSlicedBucket->begin()
-                         ->second.front()
-                         .mFields->begin()
-                         ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_max_pull_delay_sec(INT_MAX);
-    metric.set_split_bucket_for_app_upgrade(false);
-    auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
-    gaugeFieldMatcher->set_field(tagId);
-    gaugeFieldMatcher->add_child()->set_field(2);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Return(false));
-
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
-                         ->second.front()
-                         .mFields->begin()
-                         ->mValue.int_value);
-
-    gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-    ASSERT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
-    EXPECT_EQ(bucketStartTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
-                         ->second.front()
-                         .mFields->begin()
-                         ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) {
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_max_pull_delay_sec(INT_MAX);
-    auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
-    gaugeFieldMatcher->set_field(tagId);
-    gaugeFieldMatcher->add_child()->set_field(2);
-    metric.set_condition(StringToId("SCREEN_ON"));
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    int64_t conditionChangeNs = bucketStartTimeNs + 8;
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, conditionChangeNs, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs + 10, 100));
-                return true;
-            }));
-
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
-                                      {ConditionState::kUnknown}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    gaugeProducer.onConditionChanged(true, conditionChangeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(100, gaugeProducer.mCurrentSlicedBucket->begin()
-                           ->second.front()
-                           .mFields->begin()
-                           ->mValue.int_value);
-    ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(110, gaugeProducer.mCurrentSlicedBucket->begin()
-                           ->second.front()
-                           .mFields->begin()
-                           ->mValue.int_value);
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    EXPECT_EQ(100, gaugeProducer.mPastBuckets.begin()
-                           ->second.back()
-                           .mGaugeAtoms.front()
-                           .mFields->begin()
-                           ->mValue.int_value);
-
-    gaugeProducer.onConditionChanged(false, bucket2StartTimeNs + 10);
-    gaugeProducer.flushIfNeededLocked(bucket3StartTimeNs + 10);
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
-    EXPECT_EQ(110L, gaugeProducer.mPastBuckets.begin()
-                            ->second.back()
-                            .mGaugeAtoms.front()
-                            .mFields->begin()
-                            ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
-    const int conditionTag = 65;
-    GaugeMetric metric;
-    metric.set_id(1111111);
-    metric.set_bucket(ONE_MINUTE);
-    metric.mutable_gauge_fields_filter()->set_include_all(true);
-    metric.set_condition(StringToId("APP_DIED"));
-    metric.set_max_pull_delay_sec(INT_MAX);
-    auto dim = metric.mutable_dimensions_in_what();
-    dim->set_field(tagId);
-    dim->add_child()->set_field(1);
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    EXPECT_CALL(*wizard, query(_, _, _))
-            .WillRepeatedly(
-                    Invoke([](const int conditionIndex, const ConditionKey& conditionParameters,
-                              const bool isPartialLink) {
-                        int pos[] = {1, 0, 0};
-                        Field f(conditionTag, pos, 0);
-                        HashableDimensionKey key;
-                        key.mutableValues()->emplace_back(f, Value((int32_t)1000000));
-
-                        return ConditionState::kTrue;
-                    }));
-
-    int64_t sliceConditionChangeNs = bucketStartTimeNs + 8;
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, sliceConditionChangeNs, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs + 10, 1000, 100));
-                return true;
-            }));
-
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 0 /*condition index*/,
-                                      {ConditionState::kUnknown}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    gaugeProducer.onSlicedConditionMayChange(true, sliceConditionChangeNs);
-
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    const auto& key = gaugeProducer.mCurrentSlicedBucket->begin()->first;
-    ASSERT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-
-    ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1000, 110));
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-}
-
-TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
-    sp<AlarmMonitor> alarmMonitor;
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Return(false));
-
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_max_pull_delay_sec(INT_MAX);
-    auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
-    gaugeFieldMatcher->set_field(tagId);
-    gaugeFieldMatcher->add_child()->set_field(2);
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(metricId);
-    alert.set_trigger_if_sum_gt(25);
-    alert.set_num_buckets(2);
-    const int32_t refPeriodSec = 60;
-    alert.set_refractory_period_secs(refPeriodSec);
-    sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
-
-    int tagId = 1;
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 13));
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(13L, gaugeProducer.mCurrentSlicedBucket->begin()
-                           ->second.front()
-                           .mFields->begin()
-                           ->mValue.int_value);
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
-    std::shared_ptr<LogEvent> event2 =
-            CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + bucketSizeNs + 20, 15);
-
-    allData.clear();
-    allData.push_back(event2);
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(15L, gaugeProducer.mCurrentSlicedBucket->begin()
-                           ->second.front()
-                           .mFields->begin()
-                           ->mValue.int_value);
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-              std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC) + refPeriodSec);
-
-    allData.clear();
-    allData.push_back(
-            CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 10, 26));
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 2 * bucketSizeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(26L, gaugeProducer.mCurrentSlicedBucket->begin()
-                           ->second.front()
-                           .mFields->begin()
-                           ->mValue.int_value);
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-              std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-
-    // This event does not have the gauge field. Thus the current bucket value is 0.
-    allData.clear();
-    allData.push_back(CreateNoValuesLogEvent(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10));
-    gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 3 * bucketSizeNs);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty());
-}
-
-TEST(GaugeMetricProducerTest, TestPullOnTrigger) {
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
-    metric.mutable_gauge_fields_filter()->set_include_all(false);
-    metric.set_max_pull_delay_sec(INT_MAX);
-    auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
-    gaugeFieldMatcher->set_field(tagId);
-    gaugeFieldMatcher->add_child()->set_field(1);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 4));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 5));
-                return true;
-            }))
-            .WillOnce(Return(true));
-
-    int triggerId = 5;
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
-
-    LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
-    CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 10);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
-    triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
-    triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-
-    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.size());
-    EXPECT_EQ(4, gaugeProducer.mPastBuckets.begin()
-                         ->second.back()
-                         .mGaugeAtoms[0]
-                         .mFields->begin()
-                         ->mValue.int_value);
-    EXPECT_EQ(5, gaugeProducer.mPastBuckets.begin()
-                         ->second.back()
-                         .mGaugeAtoms[1]
-                         .mFields->begin()
-                         ->mValue.int_value);
-}
-
-TEST(GaugeMetricProducerTest, TestRemoveDimensionInOutput) {
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
-    metric.mutable_gauge_fields_filter()->set_include_all(true);
-    metric.set_max_pull_delay_sec(INT_MAX);
-    auto dimensionMatcher = metric.mutable_dimensions_in_what();
-    // use field 1 as dimension.
-    dimensionMatcher->set_field(tagId);
-    dimensionMatcher->add_child()->set_field(1);
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 3, 4));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 5));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 6));
-                return true;
-            }))
-            .WillOnce(Return(true));
-
-    int triggerId = 5;
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
-    CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 3);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 10);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->size());
-    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
-    triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
-    triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-
-    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.size());
-    auto bucketIt = gaugeProducer.mPastBuckets.begin();
-    ASSERT_EQ(1UL, bucketIt->second.back().mGaugeAtoms.size());
-    EXPECT_EQ(3, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
-    EXPECT_EQ(4, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
-    bucketIt++;
-    ASSERT_EQ(2UL, bucketIt->second.back().mGaugeAtoms.size());
-    EXPECT_EQ(4, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
-    EXPECT_EQ(5, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
-    EXPECT_EQ(6, bucketIt->second.back().mGaugeAtoms[1].mFields->begin()->mValue.int_value);
-}
-
-/*
- * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
- * is smaller than the "min_bucket_size_nanos" specified in the metric config.
- */
-TEST(GaugeMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
-    GaugeMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(FIVE_MINUTES);
-    metric.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
-    metric.set_min_bucket_size_nanos(10000000000);  // 10 seconds
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 3, _))
-            // Bucket start.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 10));
-                return true;
-            }));
-
-    int triggerId = 5;
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
-    gaugeProducer.prepareFirstBucket();
-
-    LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
-    CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 3);
-    gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    gaugeProducer.onDumpReport(bucketStartTimeNs + 9000000, true /* include recent buckets */, true,
-                               FAST /* dump_latency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_gauge_metrics());
-    ASSERT_EQ(0, report.gauge_metrics().data_size());
-    ASSERT_EQ(1, report.gauge_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.gauge_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000),
-              report.gauge_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.gauge_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.gauge_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000), dropEvent.drop_time_millis());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
deleted file mode 100644
index fda3daa..0000000
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/metrics/duration_helper/MaxDurationTracker.h"
-#include "src/condition/ConditionWizard.h"
-#include "metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-using namespace android::os::statsd;
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-
-const int TagId = 1;
-
-const HashableDimensionKey eventKey = getMockedDimensionKey(TagId, 0, "1");
-const HashableDimensionKey conditionKey = getMockedDimensionKey(TagId, 4, "1");
-const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
-const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-const int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-
-TEST(MaxDurationTrackerTest, TestSimpleMaxDuration) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
-    const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
-    const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t bucketNum = 0;
-
-    int64_t metricId = 1;
-    MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs,
-                               bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
-    tracker.noteStart(key1, true, bucketStartTimeNs, ConditionKey());
-    // Event starts again. This would not change anything as it already starts.
-    tracker.noteStart(key1, true, bucketStartTimeNs + 3, ConditionKey());
-    // Stopped.
-    tracker.noteStop(key1, bucketStartTimeNs + 10, false);
-
-    // Another event starts in this bucket.
-    tracker.noteStart(key2, true, bucketStartTimeNs + 20, ConditionKey());
-    tracker.noteStop(key2, bucketStartTimeNs + 40, false /*stop all*/);
-
-    tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(20LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(MaxDurationTrackerTest, TestStopAll) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
-    const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
-    const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t bucketNum = 0;
-
-    int64_t metricId = 1;
-    MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs,
-                               bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
-    tracker.noteStart(key1, true, bucketStartTimeNs + 1, ConditionKey());
-
-    // Another event starts in this bucket.
-    tracker.noteStart(key2, true, bucketStartTimeNs + 20, ConditionKey());
-    tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 40, &buckets);
-    tracker.noteStopAll(bucketStartTimeNs + bucketSizeNs + 40);
-    EXPECT_TRUE(tracker.mInfos.empty());
-    EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
-
-    tracker.flushIfNeeded(bucketStartTimeNs + 3 * bucketSizeNs + 40, &buckets);
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(bucketSizeNs + 40 - 1, buckets[eventKey][0].mDuration);
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[eventKey][0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[eventKey][0].mBucketEndNs);
-}
-
-TEST(MaxDurationTrackerTest, TestCrossBucketBoundary) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
-    const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
-    const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t bucketNum = 0;
-
-    int64_t metricId = 1;
-    MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, false, bucketStartTimeNs,
-                               bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
-    // The event starts.
-    tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + 1, ConditionKey());
-
-    // Starts again. Does not DEFAULT_DIMENSION_KEY anything.
-    tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + bucketSizeNs + 1,
-                      ConditionKey());
-
-    // The event stops at early 4th bucket.
-    // Notestop is called from DurationMetricProducer's onMatchedLogEvent, which calls
-    // flushIfneeded.
-    tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 20, &buckets);
-    tracker.noteStop(DEFAULT_DIMENSION_KEY, bucketStartTimeNs + (3 * bucketSizeNs) + 20,
-                     false /*stop all*/);
-    EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
-
-    tracker.flushIfNeeded(bucketStartTimeNs + 4 * bucketSizeNs, &buckets);
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ((3 * bucketSizeNs) + 20 - 1, buckets[eventKey][0].mDuration);
-    EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[eventKey][0].mBucketStartNs);
-    EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs, buckets[eventKey][0].mBucketEndNs);
-}
-
-TEST(MaxDurationTrackerTest, TestCrossBucketBoundary_nested) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "1");
-    const HashableDimensionKey key1 = getMockedDimensionKey(TagId, 1, "1");
-    const HashableDimensionKey key2 = getMockedDimensionKey(TagId, 1, "2");
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t bucketNum = 0;
-
-    int64_t metricId = 1;
-    MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, -1, true, bucketStartTimeNs,
-                               bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
-    // 2 starts
-    tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + 1, ConditionKey());
-    tracker.noteStart(DEFAULT_DIMENSION_KEY, true, bucketStartTimeNs + 10, ConditionKey());
-    // one stop
-    tracker.noteStop(DEFAULT_DIMENSION_KEY, bucketStartTimeNs + 20, false /*stop all*/);
-
-    tracker.flushIfNeeded(bucketStartTimeNs + (2 * bucketSizeNs) + 1, &buckets);
-    // Because of nesting, still not stopped.
-    EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
-
-    // real stop now.
-    tracker.noteStop(DEFAULT_DIMENSION_KEY,
-                     bucketStartTimeNs + (2 * bucketSizeNs) + 5, false);
-    tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 1, &buckets);
-
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(2 * bucketSizeNs + 5 - 1, buckets[eventKey][0].mDuration);
-}
-
-TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition) {
-    const HashableDimensionKey conditionDimKey = key1;
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    ConditionKey conditionKey1;
-    MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 1, "1");
-    conditionKey1[StringToId("APP_BACKGROUND")] = conditionDimKey;
-
-    /**
-    Start in first bucket, stop in second bucket. Condition turns on and off in the first bucket
-    and again turns on and off in the second bucket.
-    */
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1 * NS_PER_SEC;
-    int64_t conditionStarts1 = bucketStartTimeNs + 11 * NS_PER_SEC;
-    int64_t conditionStops1 = bucketStartTimeNs + 14 * NS_PER_SEC;
-    int64_t conditionStarts2 = bucketStartTimeNs + bucketSizeNs + 5 * NS_PER_SEC;
-    int64_t conditionStops2 = conditionStarts2 + 10 * NS_PER_SEC;
-    int64_t eventStopTimeNs = conditionStops2 + 8 * NS_PER_SEC;
-
-    int64_t metricId = 1;
-    MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
-                               0, bucketStartTimeNs, bucketSizeNs, true, false, {});
-    EXPECT_TRUE(tracker.mAnomalyTrackers.empty());
-
-    tracker.noteStart(key1, false, eventStartTimeNs, conditionKey1);
-    tracker.noteConditionChanged(key1, true, conditionStarts1);
-    tracker.noteConditionChanged(key1, false, conditionStops1);
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-    tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
-    ASSERT_EQ(0U, buckets.size());
-
-    tracker.noteConditionChanged(key1, true, conditionStarts2);
-    tracker.noteConditionChanged(key1, false, conditionStops2);
-    tracker.noteStop(key1, eventStopTimeNs, false);
-    tracker.flushIfNeeded(bucketStartTimeNs + 2 * bucketSizeNs + 1, &buckets);
-    ASSERT_EQ(1U, buckets.size());
-    vector<DurationBucket> item = buckets.begin()->second;
-    ASSERT_EQ(1UL, item.size());
-    EXPECT_EQ((int64_t)(13LL * NS_PER_SEC), item[0].mDuration);
-}
-
-TEST(MaxDurationTrackerTest, TestAnomalyDetection) {
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    ConditionKey conditionKey1;
-    MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 2, "maps");
-    conditionKey1[StringToId("APP_BACKGROUND")] = conditionKey;
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = 13000000000;
-    int64_t durationTimeNs = 2 * 1000;
-
-    int64_t metricId = 1;
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(1);
-    alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
-    alert.set_num_buckets(2);
-    const int32_t refPeriodSec = 45;
-    alert.set_refractory_period_secs(refPeriodSec);
-    sp<AlarmMonitor> alarmMonitor;
-    sp<DurationAnomalyTracker> anomalyTracker =
-        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
-    MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
-                               bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
-                               {anomalyTracker});
-
-    tracker.noteStart(key1, true, eventStartTimeNs, conditionKey1);
-    sp<const InternalAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
-    EXPECT_EQ((long long)(53ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-
-    // Remove the anomaly alarm when the duration is no longer fully met.
-    tracker.noteConditionChanged(key1, false, eventStartTimeNs + 15 * NS_PER_SEC);
-    ASSERT_EQ(0U, anomalyTracker->mAlarms.size());
-
-    // Since the condition was off for 10 seconds, the anomaly should trigger 10 sec later.
-    tracker.noteConditionChanged(key1, true, eventStartTimeNs + 25 * NS_PER_SEC);
-    ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
-    alarm = anomalyTracker->mAlarms.begin()->second;
-    EXPECT_EQ((long long)(63ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-}
-
-// This tests that we correctly compute the predicted time of an anomaly assuming that the current
-// state continues forward as-is.
-TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp) {
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    ConditionKey conditionKey1;
-    MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 2, "maps");
-    conditionKey1[StringToId("APP_BACKGROUND")] = conditionKey;
-    ConditionKey conditionKey2;
-    conditionKey2[StringToId("APP_BACKGROUND")] = getMockedDimensionKey(TagId, 4, "2");
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    /**
-     * Suppose we have two sub-dimensions that we're taking the MAX over. In the first of these
-     * nested dimensions, we enter the pause state after 3 seconds. When we resume, the second
-     * dimension has already been running for 4 seconds. Thus, we have 40-4=36 seconds remaining
-     * before we trigger the anomaly.
-     */
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 5 * NS_PER_SEC;  // Condition is off at start.
-    int64_t conditionStarts1 = bucketStartTimeNs + 11 * NS_PER_SEC;
-    int64_t conditionStops1 = bucketStartTimeNs + 14 * NS_PER_SEC;
-    int64_t conditionStarts2 = bucketStartTimeNs + 20 * NS_PER_SEC;
-    int64_t eventStartTimeNs2 = conditionStarts2 - 4 * NS_PER_SEC;
-
-    int64_t metricId = 1;
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(1);
-    alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
-    alert.set_num_buckets(2);
-    const int32_t refPeriodSec = 45;
-    alert.set_refractory_period_secs(refPeriodSec);
-    sp<AlarmMonitor> alarmMonitor;
-    sp<DurationAnomalyTracker> anomalyTracker =
-        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
-    MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
-                               bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
-                               {anomalyTracker});
-
-    tracker.noteStart(key1, false, eventStartTimeNs, conditionKey1);
-    tracker.noteConditionChanged(key1, true, conditionStarts1);
-    tracker.noteConditionChanged(key1, false, conditionStops1);
-    tracker.noteStart(key2, true, eventStartTimeNs2, conditionKey2);  // Condition is on already.
-    tracker.noteConditionChanged(key1, true, conditionStarts2);
-    ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
-    auto alarm = anomalyTracker->mAlarms.begin()->second;
-    int64_t anomalyFireTimeSec = alarm->timestampSec;
-    EXPECT_EQ(conditionStarts2 + 36 * NS_PER_SEC,
-            (long long)anomalyFireTimeSec * NS_PER_SEC);
-
-    // Now we test the calculation now that there's a refractory period.
-    // At the correct time, declare the anomaly. This will set a refractory period. Make sure it
-    // gets correctly taken into account in future predictAnomalyTimestampNs calculations.
-    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarms({alarm});
-    anomalyTracker->informAlarmsFired(anomalyFireTimeSec * NS_PER_SEC, firedAlarms);
-    ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
-    int64_t refractoryPeriodEndsSec = anomalyFireTimeSec + refPeriodSec;
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), refractoryPeriodEndsSec);
-
-    // Now stop and start again. Make sure the new predictAnomalyTimestampNs takes into account
-    // the refractory period correctly.
-    int64_t eventStopTimeNs = anomalyFireTimeSec * NS_PER_SEC + 10;
-    tracker.noteStop(key1, eventStopTimeNs, false);
-    tracker.noteStop(key2, eventStopTimeNs, false);
-    tracker.noteStart(key1, true, eventStopTimeNs + 1000000, conditionKey1);
-    // Anomaly is ongoing, but we're still in the refractory period.
-    ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
-    alarm = anomalyTracker->mAlarms.begin()->second;
-    EXPECT_EQ(refractoryPeriodEndsSec, (long long)(alarm->timestampSec));
-
-    // Makes sure it is correct after the refractory period is over.
-    tracker.noteStop(key1, eventStopTimeNs + 2000000, false);
-    int64_t justBeforeRefPeriodNs = (refractoryPeriodEndsSec - 2) * NS_PER_SEC;
-    tracker.noteStart(key1, true, justBeforeRefPeriodNs, conditionKey1);
-    alarm = anomalyTracker->mAlarms.begin()->second;
-    EXPECT_EQ(justBeforeRefPeriodNs + 40 * NS_PER_SEC,
-                (unsigned long long)(alarm->timestampSec * NS_PER_SEC));
-}
-
-// Suppose that within one tracker there are two dimensions A and B.
-// Suppose A starts, then B starts, and then A stops. We still need to set an anomaly based on the
-// elapsed duration of B.
-TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp_UpdatedOnStop) {
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    ConditionKey conditionKey1;
-    MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 2, "maps");
-    conditionKey1[StringToId("APP_BACKGROUND")] = conditionKey;
-    ConditionKey conditionKey2;
-    conditionKey2[StringToId("APP_BACKGROUND")] = getMockedDimensionKey(TagId, 4, "2");
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    /**
-     * Suppose we have two sub-dimensions that we're taking the MAX over. In the first of these
-     * nested dimensions, are started for 8 seconds. When we stop, the other nested dimension has
-     * been started for 5 seconds. So we can only allow 35 more seconds from now.
-     */
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs1 = bucketStartTimeNs + 5 * NS_PER_SEC;  // Condition is off at start.
-    int64_t eventStopTimeNs1 = bucketStartTimeNs + 13 * NS_PER_SEC;
-    int64_t eventStartTimeNs2 = bucketStartTimeNs + 8 * NS_PER_SEC;
-
-    int64_t metricId = 1;
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(1);
-    alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
-    alert.set_num_buckets(2);
-    const int32_t refPeriodSec = 45;
-    alert.set_refractory_period_secs(refPeriodSec);
-    sp<AlarmMonitor> alarmMonitor;
-    sp<DurationAnomalyTracker> anomalyTracker =
-        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
-    MaxDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false, bucketStartTimeNs,
-                               bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
-                               {anomalyTracker});
-
-    tracker.noteStart(key1, true, eventStartTimeNs1, conditionKey1);
-    tracker.noteStart(key2, true, eventStartTimeNs2, conditionKey2);
-    tracker.noteStop(key1, eventStopTimeNs1, false);
-    ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
-    auto alarm = anomalyTracker->mAlarms.begin()->second;
-    EXPECT_EQ(eventStopTimeNs1 + 35 * NS_PER_SEC,
-              (unsigned long long)(alarm->timestampSec * NS_PER_SEC));
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
deleted file mode 100644
index 1d6f7de..0000000
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/metrics/duration_helper/OringDurationTracker.h"
-#include "src/condition/ConditionWizard.h"
-#include "metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-using namespace testing;
-using android::sp;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-namespace android {
-namespace os {
-namespace statsd {
-
-const ConfigKey kConfigKey(0, 12345);
-const int TagId = 1;
-const int64_t metricId = 123;
-const HashableDimensionKey eventKey = getMockedDimensionKey(TagId, 0, "event");
-
-const HashableDimensionKey kConditionKey1 = getMockedDimensionKey(TagId, 1, "maps");
-const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-const int64_t bucketSizeNs = 30 * NS_PER_SEC;
-
-TEST(OringDurationTrackerTest, TestDurationOverlap) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-    int64_t durationTimeNs = 2 * 1000;
-
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false,
-                                 bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
-                                 false, false, {});
-
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
-    EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs + 10, ConditionKey());  // overlapping wl
-    EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
-
-    tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
-    tracker.flushIfNeeded(eventStartTimeNs + bucketSizeNs + 1, &buckets);
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(durationTimeNs, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationNested) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
-                                 bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs + 10, ConditionKey());  // overlapping wl
-
-    tracker.noteStop(kEventKey1, eventStartTimeNs + 2000, false);
-    tracker.noteStop(kEventKey1, eventStartTimeNs + 2003, false);
-
-    tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(2003LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestStopAll) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const std::vector<HashableDimensionKey> kConditionKey1 =
-        {getMockedDimensionKey(TagId, 1, "maps")};
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
-                                 bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
-    tracker.noteStart(kEventKey2, true, eventStartTimeNs + 10, ConditionKey());  // overlapping wl
-
-    tracker.noteStopAll(eventStartTimeNs + 2003);
-
-    tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(2003LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestCrossBucketBoundary) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-    int64_t durationTimeNs = 2 * 1000;
-
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
-                                 bucketNum, bucketStartTimeNs, bucketSizeNs, false, false, {});
-
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
-    EXPECT_EQ((long long)eventStartTimeNs, tracker.mLastStartTime);
-    tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs, &buckets);
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs + 2 * bucketSizeNs, ConditionKey());
-    EXPECT_EQ((long long)(bucketStartTimeNs + 2 * bucketSizeNs), tracker.mLastStartTime);
-
-    ASSERT_EQ(2u, buckets[eventKey].size());
-    EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
-    EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
-
-    tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 10, false);
-    tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 12, false);
-    tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 12, &buckets);
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    ASSERT_EQ(2u, buckets[eventKey].size());
-    EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
-    EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationConditionChange) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    ConditionKey key1;
-    key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
-
-    EXPECT_CALL(*wizard, query(_, key1, _))  // #4
-            .WillOnce(Return(ConditionState::kFalse));
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-    int64_t durationTimeNs = 2 * 1000;
-
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false,
-                                 bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
-                                 true, false, {});
-
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
-
-    tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
-
-    tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
-
-    tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(5LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationConditionChange2) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    ConditionKey key1;
-    key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
-
-    EXPECT_CALL(*wizard, query(_, key1, _))
-            .Times(2)
-            .WillOnce(Return(ConditionState::kFalse))
-            .WillOnce(Return(ConditionState::kTrue));
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-    int64_t durationTimeNs = 2 * 1000;
-
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, false,
-                                 bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
-                                 true, false, {});
-
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
-    // condition to false; record duration 5n
-    tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
-    // condition to true.
-    tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 1000);
-    // 2nd duration: 1000ns
-    tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
-
-    tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(1005LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    ConditionKey key1;
-    key1[StringToId("APP_BACKGROUND")] = kConditionKey1;
-
-    EXPECT_CALL(*wizard, query(_, key1, _))  // #4
-            .WillOnce(Return(ConditionState::kFalse));
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + 1;
-
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
-                                 bucketNum, bucketStartTimeNs, bucketSizeNs, true, false, {});
-
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs + 2, key1);
-
-    tracker.noteStop(kEventKey1, eventStartTimeNs + 3, false);
-
-    tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 15);
-
-    tracker.noteStop(kEventKey1, eventStartTimeNs + 2003, false);
-
-    tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(15LL, buckets[eventKey][0].mDuration);
-}
-
-TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(1);
-    alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
-    alert.set_num_buckets(2);
-    alert.set_refractory_period_secs(1);
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
-
-    sp<AlarmMonitor> alarmMonitor;
-    sp<DurationAnomalyTracker> anomalyTracker =
-        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true, bucketStartTimeNs,
-                                 bucketNum, bucketStartTimeNs, bucketSizeNs, true, false,
-                                 {anomalyTracker});
-
-    // Nothing in the past bucket.
-    tracker.noteStart(DEFAULT_DIMENSION_KEY, true, eventStartTimeNs, ConditionKey());
-    EXPECT_EQ((long long)(alert.trigger_if_sum_gt() + eventStartTimeNs),
-              tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
-
-    tracker.noteStop(DEFAULT_DIMENSION_KEY, eventStartTimeNs + 3, false);
-    ASSERT_EQ(0u, buckets[eventKey].size());
-
-    int64_t event1StartTimeNs = eventStartTimeNs + 10;
-    tracker.noteStart(kEventKey1, true, event1StartTimeNs, ConditionKey());
-    // No past buckets. The anomaly will happen in bucket #0.
-    EXPECT_EQ((long long)(event1StartTimeNs + alert.trigger_if_sum_gt() - 3),
-              tracker.predictAnomalyTimestampNs(*anomalyTracker, event1StartTimeNs));
-
-    int64_t event1StopTimeNs = eventStartTimeNs + bucketSizeNs + 10;
-    tracker.flushIfNeeded(event1StopTimeNs, &buckets);
-    tracker.noteStop(kEventKey1, event1StopTimeNs, false);
-
-    EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    ASSERT_EQ(1u, buckets[eventKey].size());
-    EXPECT_EQ(3LL + bucketStartTimeNs + bucketSizeNs - eventStartTimeNs - 10,
-              buckets[eventKey][0].mDuration);
-
-    const int64_t bucket0Duration = 3ULL + bucketStartTimeNs + bucketSizeNs - eventStartTimeNs - 10;
-    const int64_t bucket1Duration = eventStartTimeNs + 10 - bucketStartTimeNs;
-
-    // One past buckets. The anomaly will happen in bucket #1.
-    int64_t event2StartTimeNs = eventStartTimeNs + bucketSizeNs + 15;
-    tracker.noteStart(kEventKey1, true, event2StartTimeNs, ConditionKey());
-    EXPECT_EQ((long long)(event2StartTimeNs + alert.trigger_if_sum_gt() - bucket0Duration -
-                          bucket1Duration),
-              tracker.predictAnomalyTimestampNs(*anomalyTracker, event2StartTimeNs));
-    tracker.noteStop(kEventKey1, event2StartTimeNs + 1, false);
-
-    // Only one past buckets is applicable. Bucket +0 should be trashed. The anomaly will happen in
-    // bucket #2.
-    int64_t event3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs - 9 * NS_PER_SEC;
-    tracker.noteStart(kEventKey1, true, event3StartTimeNs, ConditionKey());
-    EXPECT_EQ((long long)(event3StartTimeNs + alert.trigger_if_sum_gt() - bucket1Duration - 1LL),
-              tracker.predictAnomalyTimestampNs(*anomalyTracker, event3StartTimeNs));
-}
-
-TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp2) {
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(1);
-    alert.set_trigger_if_sum_gt(5 * NS_PER_SEC);
-    alert.set_num_buckets(1);
-    alert.set_refractory_period_secs(20);
-
-    int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
-    int64_t bucketNum = 0;
-
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<AlarmMonitor> alarmMonitor;
-    sp<DurationAnomalyTracker> anomalyTracker =
-        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
-    OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY, wizard, 1,
-
-                                 true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
-                                 bucketSizeNs, true, false, {anomalyTracker});
-
-    int64_t eventStartTimeNs = bucketStartTimeNs + 9 * NS_PER_SEC;
-    tracker.noteStart(DEFAULT_DIMENSION_KEY, true, eventStartTimeNs, ConditionKey());
-    // Anomaly happens in the bucket #1.
-    EXPECT_EQ((long long)(bucketStartTimeNs + 14 * NS_PER_SEC),
-              tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
-
-    tracker.noteStop(DEFAULT_DIMENSION_KEY, bucketStartTimeNs + 14 * NS_PER_SEC, false);
-
-    EXPECT_EQ((long long)(bucketStartTimeNs + 34 * NS_PER_SEC) / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY));
-
-    int64_t event2StartTimeNs = bucketStartTimeNs + 22 * NS_PER_SEC;
-    EXPECT_EQ((long long)(bucketStartTimeNs + 34 * NS_PER_SEC) / NS_PER_SEC,
-              anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY));
-    EXPECT_EQ((long long)(bucketStartTimeNs + 35 * NS_PER_SEC),
-              tracker.predictAnomalyTimestampNs(*anomalyTracker, event2StartTimeNs));
-}
-
-TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp3) {
-    // Test the cases where the refractory period is smaller than the bucket size, longer than
-    // the bucket size, and longer than 2x of the anomaly detection window.
-    for (int j = 0; j < 3; j++) {
-        int64_t thresholdNs = j * bucketSizeNs + 5 * NS_PER_SEC;
-        for (int i = 0; i <= 7; ++i) {
-
-            Alert alert;
-            alert.set_id(101);
-            alert.set_metric_id(1);
-            alert.set_trigger_if_sum_gt(thresholdNs);
-            alert.set_num_buckets(3);
-            alert.set_refractory_period_secs(
-                bucketSizeNs / NS_PER_SEC / 2 + i * bucketSizeNs / NS_PER_SEC);
-
-            int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
-            int64_t bucketNum = 101;
-
-            sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-            sp<AlarmMonitor> alarmMonitor;
-            sp<DurationAnomalyTracker> anomalyTracker =
-                new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
-            OringDurationTracker tracker(kConfigKey, metricId, DEFAULT_METRIC_DIMENSION_KEY, wizard,
-                                         1, true, bucketStartTimeNs, bucketNum, bucketStartTimeNs,
-                                         bucketSizeNs, true, false, {anomalyTracker});
-
-            int64_t eventStartTimeNs = bucketStartTimeNs + 9 * NS_PER_SEC;
-            tracker.noteStart(DEFAULT_DIMENSION_KEY, true, eventStartTimeNs, ConditionKey());
-            EXPECT_EQ((long long)(eventStartTimeNs + thresholdNs),
-                      tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
-            int64_t eventStopTimeNs = eventStartTimeNs + thresholdNs + NS_PER_SEC;
-            tracker.noteStop(DEFAULT_DIMENSION_KEY, eventStopTimeNs, false);
-
-            int64_t refractoryPeriodEndSec =
-                anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY);
-            EXPECT_EQ(eventStopTimeNs / (int64_t)NS_PER_SEC + alert.refractory_period_secs(),
-                       refractoryPeriodEndSec);
-
-            // Acquire and release a wakelock in the next bucket.
-            int64_t event2StartTimeNs = eventStopTimeNs + bucketSizeNs;
-            tracker.noteStart(DEFAULT_DIMENSION_KEY, true, event2StartTimeNs, ConditionKey());
-            int64_t event2StopTimeNs = event2StartTimeNs + 4 * NS_PER_SEC;
-            tracker.noteStop(DEFAULT_DIMENSION_KEY, event2StopTimeNs, false);
-
-            // Test the alarm prediction works well when seeing another wakelock start event.
-            for (int k = 0; k <= 2; ++k) {
-                int64_t event3StartTimeNs = event2StopTimeNs + NS_PER_SEC + k * bucketSizeNs;
-                int64_t alarmTimestampNs =
-                    tracker.predictAnomalyTimestampNs(*anomalyTracker, event3StartTimeNs);
-                EXPECT_GT(alarmTimestampNs, 0u);
-                EXPECT_GE(alarmTimestampNs, event3StartTimeNs);
-                EXPECT_GE(alarmTimestampNs, refractoryPeriodEndSec *(int64_t) NS_PER_SEC);
-            }
-        }
-    }
-}
-
-TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(1);
-    alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
-    alert.set_num_buckets(2);
-    const int32_t refPeriodSec = 45;
-    alert.set_refractory_period_secs(refPeriodSec);
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-
-    int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
-    int64_t bucketNum = 0;
-    int64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1;
-
-    sp<AlarmMonitor> alarmMonitor;
-    sp<DurationAnomalyTracker> anomalyTracker =
-        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true /*nesting*/,
-                                 bucketStartTimeNs, bucketNum, bucketStartTimeNs, bucketSizeNs,
-                                 false, false, {anomalyTracker});
-
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs, ConditionKey());
-    tracker.noteStop(kEventKey1, eventStartTimeNs + 10, false);
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-    EXPECT_TRUE(tracker.mStarted.empty());
-    EXPECT_EQ(10LL, tracker.mStateKeyDurationMap[DEFAULT_DIMENSION_KEY].mDuration);  // 10ns
-
-    ASSERT_EQ(0u, tracker.mStarted.size());
-
-    tracker.noteStart(kEventKey1, true, eventStartTimeNs + 20, ConditionKey());
-    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
-    EXPECT_EQ((long long)(52ULL * NS_PER_SEC),  // (10s + 1s + 1ns + 20ns) - 10ns + 40s, rounded up
-              (long long)(anomalyTracker->mAlarms.begin()->second->timestampSec * NS_PER_SEC));
-    // The alarm is set to fire at 52s, and when it does, an anomaly would be declared. However,
-    // because this is a unit test, the alarm won't actually fire at all. Since the alarm fails
-    // to fire in time, the anomaly is instead caught when noteStop is called, at around 71s.
-    tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 25, &buckets);
-    tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 25, false);
-    EXPECT_EQ(anomalyTracker->getSumOverPastBuckets(eventKey), (long long)(bucketSizeNs));
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey),
-              std::ceil((eventStartTimeNs + 2 * bucketSizeNs + 25.0) / NS_PER_SEC + refPeriodSec));
-}
-
-TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm) {
-    const MetricDimensionKey eventKey = getMockedMetricDimensionKey(TagId, 0, "event");
-
-    const HashableDimensionKey kEventKey1 = getMockedDimensionKey(TagId, 2, "maps");
-    const HashableDimensionKey kEventKey2 = getMockedDimensionKey(TagId, 3, "maps");
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(1);
-    alert.set_trigger_if_sum_gt(40 * NS_PER_SEC);
-    alert.set_num_buckets(2);
-    const int32_t refPeriodSec = 45;
-    alert.set_refractory_period_secs(refPeriodSec);
-
-    unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    ConditionKey conkey;
-    conkey[StringToId("APP_BACKGROUND")] = kConditionKey1;
-    int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
-    int64_t bucketSizeNs = 30 * NS_PER_SEC;
-
-    sp<AlarmMonitor> alarmMonitor;
-    sp<DurationAnomalyTracker> anomalyTracker =
-        new DurationAnomalyTracker(alert, kConfigKey, alarmMonitor);
-    OringDurationTracker tracker(kConfigKey, metricId, eventKey, wizard, 1, true /*nesting*/,
-                                 bucketStartTimeNs, 0, bucketStartTimeNs, bucketSizeNs, false,
-                                 false, {anomalyTracker});
-
-    tracker.noteStart(kEventKey1, true, 15 * NS_PER_SEC, conkey);  // start key1
-    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
-    sp<const InternalAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
-    EXPECT_EQ((long long)(55ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
-    tracker.noteStop(kEventKey1, 17 * NS_PER_SEC, false); // stop key1 (2 seconds later)
-    ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
-    tracker.noteStart(kEventKey1, true, 22 * NS_PER_SEC, conkey);  // start key1 again
-    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
-    alarm = anomalyTracker->mAlarms.begin()->second;
-    EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
-    tracker.noteStart(kEventKey2, true, 32 * NS_PER_SEC, conkey);  // start key2
-    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
-    alarm = anomalyTracker->mAlarms.begin()->second;
-    EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
-    tracker.noteStop(kEventKey1, 47 * NS_PER_SEC, false); // stop key1
-    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
-    alarm = anomalyTracker->mAlarms.begin()->second;
-    EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
-
-    // Now, at 60s, which is 38s after key1 started again, we have reached 40s of 'on' time.
-    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarms({alarm});
-    anomalyTracker->informAlarmsFired(62 * NS_PER_SEC, firedAlarms);
-    ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 62U + refPeriodSec);
-
-    tracker.noteStop(kEventKey2, 69 * NS_PER_SEC, false); // stop key2
-    ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 62U + refPeriodSec);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
deleted file mode 100644
index 6cf4192..0000000
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ /dev/null
@@ -1,6919 +0,0 @@
-// Copyright (C) 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.
-
-#include "src/metrics/ValueMetricProducer.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <vector>
-
-#include "metrics_test_helper.h"
-#include "src/matchers/SimpleAtomMatchingTracker.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/stats_log_util.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using std::make_shared;
-using std::set;
-using std::shared_ptr;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-const ConfigKey kConfigKey(0, 12345);
-const int tagId = 1;
-const int64_t metricId = 123;
-const uint64_t protoHash = 0x1234567890;
-const int logEventMatcherIndex = 0;
-const int64_t bucketStartTimeNs = 10000000000;
-const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
-const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
-const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
-const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
-const int64_t bucket5StartTimeNs = bucketStartTimeNs + 4 * bucketSizeNs;
-const int64_t bucket6StartTimeNs = bucketStartTimeNs + 5 * bucketSizeNs;
-double epsilon = 0.001;
-
-static void assertPastBucketValuesSingleKey(
-        const std::unordered_map<MetricDimensionKey, std::vector<PastValueBucket>>& mPastBuckets,
-        const std::initializer_list<int>& expectedValuesList,
-        const std::initializer_list<int64_t>& expectedDurationNsList,
-        const std::initializer_list<int64_t>& expectedStartTimeNsList,
-        const std::initializer_list<int64_t>& expectedEndTimeNsList) {
-    vector<int> expectedValues(expectedValuesList);
-    vector<int64_t> expectedDurationNs(expectedDurationNsList);
-    vector<int64_t> expectedStartTimeNs(expectedStartTimeNsList);
-    vector<int64_t> expectedEndTimeNs(expectedEndTimeNsList);
-
-    ASSERT_EQ(expectedValues.size(), expectedDurationNs.size());
-    ASSERT_EQ(expectedValues.size(), expectedStartTimeNs.size());
-    ASSERT_EQ(expectedValues.size(), expectedEndTimeNs.size());
-
-    if (expectedValues.size() == 0) {
-        ASSERT_EQ(0, mPastBuckets.size());
-        return;
-    }
-
-    ASSERT_EQ(1, mPastBuckets.size());
-    ASSERT_EQ(expectedValues.size(), mPastBuckets.begin()->second.size());
-
-    const vector<PastValueBucket>& buckets = mPastBuckets.begin()->second;
-    for (int i = 0; i < expectedValues.size(); i++) {
-        EXPECT_EQ(expectedValues[i], buckets[i].values[0].long_value)
-                << "Values differ at index " << i;
-        EXPECT_EQ(expectedDurationNs[i], buckets[i].mConditionTrueNs)
-                << "Condition duration value differ at index " << i;
-        EXPECT_EQ(expectedStartTimeNs[i], buckets[i].mBucketStartNs)
-                << "Start time differs at index " << i;
-        EXPECT_EQ(expectedEndTimeNs[i], buckets[i].mBucketEndNs)
-                << "End time differs at index " << i;
-    }
-}
-
-static void assertConditionTimer(const ConditionTimer& conditionTimer, bool condition,
-                                 int64_t timerNs, int64_t lastConditionTrueTimestampNs) {
-    EXPECT_EQ(condition, conditionTimer.mCondition);
-    EXPECT_EQ(timerNs, conditionTimer.mTimerNs);
-    EXPECT_EQ(lastConditionTrueTimestampNs, conditionTimer.mLastConditionChangeTimestampNs);
-}
-
-}  // anonymous namespace
-
-class ValueMetricProducerTestHelper {
-public:
-    static sp<ValueMetricProducer> createValueProducerNoConditions(
-            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric) {
-        sp<EventMatcherWizard> eventMatcherWizard =
-                createEventMatcherWizard(tagId, logEventMatcherIndex);
-        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
-                .WillOnce(Return());
-        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
-                .WillRepeatedly(Return());
-
-        sp<ValueMetricProducer> valueProducer =
-                new ValueMetricProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                        wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                        tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-        valueProducer->prepareFirstBucket();
-        return valueProducer;
-    }
-
-    static sp<ValueMetricProducer> createValueProducerWithCondition(
-            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
-            ConditionState conditionAfterFirstBucketPrepared) {
-        sp<EventMatcherWizard> eventMatcherWizard =
-                createEventMatcherWizard(tagId, logEventMatcherIndex);
-        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
-                .WillOnce(Return());
-        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
-                .WillRepeatedly(Return());
-
-        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-                kConfigKey, metric, 0 /*condition index*/, {ConditionState::kUnknown}, wizard,
-                protoHash, logEventMatcherIndex, eventMatcherWizard, tagId, bucketStartTimeNs,
-                bucketStartTimeNs, pullerManager);
-        valueProducer->prepareFirstBucket();
-        valueProducer->mCondition = conditionAfterFirstBucketPrepared;
-        return valueProducer;
-    }
-
-    static sp<ValueMetricProducer> createValueProducerWithState(
-            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
-            vector<int32_t> slicedStateAtoms,
-            unordered_map<int, unordered_map<int, int64_t>> stateGroupMap) {
-        sp<EventMatcherWizard> eventMatcherWizard =
-                createEventMatcherWizard(tagId, logEventMatcherIndex);
-        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
-                .WillOnce(Return());
-        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
-                .WillRepeatedly(Return());
-
-        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-                kConfigKey, metric, -1 /* no condition */, {}, wizard, protoHash,
-                logEventMatcherIndex, eventMatcherWizard, tagId, bucketStartTimeNs,
-                bucketStartTimeNs, pullerManager, {}, {}, slicedStateAtoms, stateGroupMap);
-        valueProducer->prepareFirstBucket();
-        return valueProducer;
-    }
-
-    static sp<ValueMetricProducer> createValueProducerWithConditionAndState(
-            sp<MockStatsPullerManager>& pullerManager, ValueMetric& metric,
-            vector<int32_t> slicedStateAtoms,
-            unordered_map<int, unordered_map<int, int64_t>> stateGroupMap,
-            ConditionState conditionAfterFirstBucketPrepared) {
-        sp<EventMatcherWizard> eventMatcherWizard =
-                createEventMatcherWizard(tagId, logEventMatcherIndex);
-        sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-        EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _))
-                .WillOnce(Return());
-        EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _))
-                .WillRepeatedly(Return());
-
-        sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
-                kConfigKey, metric, 0 /* condition tracker index */, {ConditionState::kUnknown},
-                wizard, protoHash, logEventMatcherIndex, eventMatcherWizard, tagId,
-                bucketStartTimeNs, bucketStartTimeNs, pullerManager, {}, {}, slicedStateAtoms,
-                stateGroupMap);
-        valueProducer->prepareFirstBucket();
-        valueProducer->mCondition = conditionAfterFirstBucketPrepared;
-        return valueProducer;
-    }
-
-    static ValueMetric createMetric() {
-        ValueMetric metric;
-        metric.set_id(metricId);
-        metric.set_bucket(ONE_MINUTE);
-        metric.mutable_value_field()->set_field(tagId);
-        metric.mutable_value_field()->add_child()->set_field(2);
-        metric.set_max_pull_delay_sec(INT_MAX);
-        return metric;
-    }
-
-    static ValueMetric createMetricWithCondition() {
-        ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-        metric.set_condition(StringToId("SCREEN_ON"));
-        return metric;
-    }
-
-    static ValueMetric createMetricWithState(string state) {
-        ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-        metric.add_slice_by_state(StringToId(state));
-        return metric;
-    }
-
-    static ValueMetric createMetricWithConditionAndState(string state) {
-        ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-        metric.set_condition(StringToId("SCREEN_ON"));
-        metric.add_slice_by_state(StringToId(state));
-        return metric;
-    }
-};
-
-// Setup for parameterized tests.
-class ValueMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
-
-INSTANTIATE_TEST_SUITE_P(ValueMetricProducerTest_PartialBucket,
-                         ValueMetricProducerTest_PartialBucket,
-                         testing::Values(APP_UPGRADE, BOOT_COMPLETE));
-
-/*
- * Tests that the first bucket works correctly
- */
-TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    int64_t startTimeBase = 11;
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    // statsd started long ago.
-    // The metric starts in the middle of the bucket
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      -1, startTimeBase, 22, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
-    EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
-    EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
-              valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
-    EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
-              valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
-}
-
-/*
- * Tests that the first bucket works correctly
- */
-TEST(ValueMetricProducerTest, TestFirstBucket) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    // statsd started long ago.
-    // The metric starts in the middle of the bucket
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      -1, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
-    EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
-}
-
-/*
- * Tests pulled atoms with no conditions
- */
-TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(11, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(8, curInterval.value.long_value);
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(23, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(12, curInterval.value.long_value);
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    ASSERT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
-    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-    EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(36, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(13, curInterval.value.long_value);
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    ASSERT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
-    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-    EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
-    EXPECT_EQ(13, valueProducer->mPastBuckets.begin()->second[2].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[2].mConditionTrueNs);
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPartialBucketCreated) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Initialize bucket.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
-                return true;
-            }))
-            // Partial bucket.
-            .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
-                                                        const int64_t eventTimeNs,
-                                                        vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs + 8, 5));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    // First bucket ends.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 2));
-    valueProducer->onDataPulled(allData, /** success */ true, bucket2StartTimeNs);
-
-    // Partial buckets created in 2nd bucket.
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs);
-    EXPECT_EQ(1, valueProducer->getCurrentBucketNum());
-
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1, 3},
-                                    {bucketSizeNs, partialBucketSplitTimeNs - bucket2StartTimeNs},
-                                    {bucketStartTimeNs, bucket2StartTimeNs},
-                                    {bucket2StartTimeNs, partialBucketSplitTimeNs});
-}
-
-/*
- * Tests pulled atoms with filtering
- */
-TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    FieldValueMatcher fvm;
-    fvm.set_field(1);
-    fvm.set_eq_int(3);
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex, {fvm});
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 3, 3));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            new ValueMetricProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {}, wizard,
-                                    protoHash, logEventMatcherIndex, eventMatcherWizard, tagId,
-                                    bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer->prepareFirstBucket();
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 3, 11));
-
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(11, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(8, curInterval.value.long_value);
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket3StartTimeNs + 1, 4, 23));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    // No new data seen, so data has been cleared.
-    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(11, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(8, curInterval.value.long_value);
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 3, 36));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-
-    // the base was reset
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(36, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
-    EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-}
-
-/*
- * Tests pulled atoms with no conditions and take absolute value after reset
- */
-TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_use_absolute_value_on_reset(true);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Return(true));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(11, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(10, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(10, curInterval.value.long_value);
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(36, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(26, curInterval.value.long_value);
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    ASSERT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
-    EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-    EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[1].mConditionTrueNs);
-}
-
-/*
- * Tests pulled atoms with no conditions and take zero value after reset
- */
-TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Return(false));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(11, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(10, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(36, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(26, curInterval.value.long_value);
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
-}
-
-/*
- * Test pulled event with non sliced condition.
- */
-TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);  // First condition change.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1);  // Second condition change.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 130));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 1);  // Third condition change.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 180));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    // startUpdated:false sum:0 start:100
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(100, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(110, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(10, curInterval.value.long_value);
-
-    valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(20, curInterval.value.long_value);
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-
-    valueProducer->onConditionChanged(true, bucket3StartTimeNs + 1);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10, 20}, {bucketSizeNs - 8, 1},
-                                    {bucketStartTimeNs, bucket2StartTimeNs},
-                                    {bucket2StartTimeNs, bucket3StartTimeNs});
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPushedEvents) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, -1,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-
-    int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 150;
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            valueProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            valueProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10},
-                                    {partialBucketSplitTimeNs - bucketStartTimeNs},
-                                    {bucketStartTimeNs}, {partialBucketSplitTimeNs});
-    EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(0, valueProducer.getCurrentBucketNum());
-
-    // Event arrives after the bucket split.
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 20);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10},
-                                    {partialBucketSplitTimeNs - bucketStartTimeNs},
-                                    {bucketStartTimeNs}, {partialBucketSplitTimeNs});
-    EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(0, valueProducer.getCurrentBucketNum());
-
-    // Next value should create a new bucket.
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 5 * NS_PER_SEC, 10);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10, 20},
-                                    {partialBucketSplitTimeNs - bucketStartTimeNs,
-                                     bucket2StartTimeNs - partialBucketSplitTimeNs},
-                                    {bucketStartTimeNs, partialBucketSplitTimeNs},
-                                    {partialBucketSplitTimeNs, bucket2StartTimeNs});
-    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(1, valueProducer.getCurrentBucketNum());
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValue) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 150;
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Return(true))
-            .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
-                                                        const int64_t eventTimeNs,
-                                                        vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 120));
-                return true;
-            }));
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
-
-    valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            valueProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            valueProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    EXPECT_EQ(partialBucketSplitTimeNs, valueProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(1, valueProducer.getCurrentBucketNum());
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {150}, {bucket2StartTimeNs},
-                                    {partialBucketSplitTimeNs});
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 150));
-    valueProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    EXPECT_EQ(bucket3StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(2, valueProducer.getCurrentBucketNum());
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20, 30}, {150, bucketSizeNs - 150},
-                                    {bucket2StartTimeNs, partialBucketSplitTimeNs},
-                                    {partialBucketSplitTimeNs, bucket3StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_split_bucket_for_app_upgrade(false);
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Return(true));
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
-
-    valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-
-    valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150);
-    ASSERT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1);  // Condition change to true time.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs,
-                          bucket2StartTimeNs - 100);  // Condition change to false time.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 120));
-                return true;
-            }));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
-
-    valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100);
-    EXPECT_FALSE(valueProducer->mCondition);
-
-    int64_t partialBucketSplitTimeNs = bucket2StartTimeNs - 50;
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    // Expect one full buckets already done and starting a partial bucket.
-    EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs);
-    EXPECT_EQ(0, valueProducer->getCurrentBucketNum());
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20},
-                                    {(bucket2StartTimeNs - 100) - (bucketStartTimeNs + 1)},
-                                    {bucketStartTimeNs}, {partialBucketSplitTimeNs});
-    EXPECT_FALSE(valueProducer->mCondition);
-}
-
-TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, -1,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(10, curInterval.value.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(30, curInterval.value.long_value);
-
-    valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {30}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
-                                      protoHash, logEventMatcherIndex, eventMatcherWizard, -1,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-    valueProducer.mCondition = ConditionState::kFalse;
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    // has 1 slice
-    ASSERT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
-
-    valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(20, curInterval.value.long_value);
-
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event3, tagId, bucketStartTimeNs + 30, 30);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(50, curInterval.value.long_value);
-
-    valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
-
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event4, tagId, bucketStartTimeNs + 40, 40);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(50, curInterval.value.long_value);
-
-    valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {50}, {20}, {bucketStartTimeNs},
-                                    {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestAnomalyDetection) {
-    sp<AlarmMonitor> alarmMonitor;
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(metricId);
-    alert.set_trigger_if_sum_gt(130);
-    alert.set_num_buckets(2);
-    const int32_t refPeriodSec = 3;
-    alert.set_refractory_period_secs(refPeriodSec);
-
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, {},
-                                      wizard, protoHash, logEventMatcherIndex, eventMatcherWizard,
-                                      -1 /*not pulled*/, bucketStartTimeNs, bucketStartTimeNs,
-                                      pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 1 * NS_PER_SEC, 10);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 2 + NS_PER_SEC, 20);
-
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event3, tagId,
-                                bucketStartTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, 130);
-
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event4, tagId,
-                                bucketStartTimeNs + 3 * bucketSizeNs + 1 * NS_PER_SEC, 1);
-
-    LogEvent event5(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event5, tagId,
-                                bucketStartTimeNs + 3 * bucketSizeNs + 2 * NS_PER_SEC, 150);
-
-    LogEvent event6(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event6, tagId,
-                                bucketStartTimeNs + 3 * bucketSizeNs + 10 * NS_PER_SEC, 160);
-
-    // Two events in bucket #0.
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-    // Value sum == 30 <= 130.
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
-    // One event in bucket #2. No alarm as bucket #0 is trashed out.
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    // Value sum == 130 <= 130.
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-
-    // Three events in bucket #3.
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-    // Anomaly at event 4 since Value sum == 131 > 130!
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-              std::ceil(1.0 * event4.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
-    // Event 5 is within 3 sec refractory period. Thus last alarm timestamp is still event4.
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-              std::ceil(1.0 * event4.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
-    // Anomaly at event 6 since Value sum == 160 > 130 and after refractory period.
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
-              std::ceil(1.0 * event6.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
-}
-
-TEST(ValueMetricProducerTest, TestAnomalyDetectionMultipleBucketsSkipped) {
-    sp<AlarmMonitor> alarmMonitor;
-    Alert alert;
-    alert.set_id(101);
-    alert.set_metric_id(metricId);
-    alert.set_trigger_if_sum_gt(100);
-    alert.set_num_buckets(1);
-    const int32_t refPeriodSec = 3;
-    alert.set_refractory_period_secs(refPeriodSec);
-
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1);  // Condition change to true time.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 0));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs,
-                          bucket3StartTimeNs + 100);  // Condition changed to false time.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 100, 120));
-                return true;
-            }));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-    sp<AnomalyTracker> anomalyTracker = valueProducer->addAnomalyTracker(alert, alarmMonitor);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
-
-    // multiple buckets should be skipped here.
-    valueProducer->onConditionChanged(false, bucket3StartTimeNs + 100);
-
-    // No alert is fired when multiple buckets are skipped.
-    EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
-}
-
-// Test value metric no condition, the pull on bucket boundary come in time and too late
-TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Return(true));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    vector<shared_ptr<LogEvent>> allData;
-    // pull 1
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 11));
-
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-
-    // startUpdated:true sum:0 start:11
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(11, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
-    // pull 2 at correct time
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    // tartUpdated:false sum:12
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(23, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs},
-                                    {bucket2StartTimeNs}, {bucket3StartTimeNs});
-
-    // pull 3 come late.
-    // The previous bucket gets closed with error. (Has start value 23, no ending)
-    // Another bucket gets closed with error. (No start, but ending with 36)
-    // The new bucket is back to normal.
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket6StartTimeNs + 1, 36));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket6StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    // startUpdated:false sum:12
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(36, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {12}, {bucketSizeNs},
-                                    {bucket2StartTimeNs}, {bucket3StartTimeNs});
-    // The 1st bucket is dropped because of no data
-    // The 3rd bucket is dropped due to multiple buckets being skipped.
-    ASSERT_EQ(2, valueProducer->mSkippedBuckets.size());
-
-    EXPECT_EQ(bucketStartTimeNs, valueProducer->mSkippedBuckets[0].bucketStartTimeNs);
-    EXPECT_EQ(bucket2StartTimeNs, valueProducer->mSkippedBuckets[0].bucketEndTimeNs);
-    ASSERT_EQ(1, valueProducer->mSkippedBuckets[0].dropEvents.size());
-    EXPECT_EQ(NO_DATA, valueProducer->mSkippedBuckets[0].dropEvents[0].reason);
-    EXPECT_EQ(bucket2StartTimeNs, valueProducer->mSkippedBuckets[0].dropEvents[0].dropTimeNs);
-
-    EXPECT_EQ(bucket3StartTimeNs, valueProducer->mSkippedBuckets[1].bucketStartTimeNs);
-    EXPECT_EQ(bucket6StartTimeNs, valueProducer->mSkippedBuckets[1].bucketEndTimeNs);
-    ASSERT_EQ(1, valueProducer->mSkippedBuckets[1].dropEvents.size());
-    EXPECT_EQ(MULTIPLE_BUCKETS_SKIPPED, valueProducer->mSkippedBuckets[1].dropEvents[0].reason);
-    EXPECT_EQ(bucket6StartTimeNs, valueProducer->mSkippedBuckets[1].dropEvents[0].dropTimeNs);
-}
-
-/*
- * Test pulled event with non sliced condition. The pull on boundary come late because the alarm
- * was delivered late.
- */
-TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);  // First condition change.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
-                return true;
-            }))
-            // condition becomes false
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1);  // Second condition change.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
-                return true;
-            }));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(100, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
-    // pull on bucket boundary come late, condition change happens before it
-    valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-
-    // Now the alarm is delivered.
-    // since the condition turned to off before this pull finish, it has no effect
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(false, curInterval.hasValue);
-}
-
-/*
- * Test pulled event with non sliced condition. The pull on boundary come late, after the condition
- * change to false, and then true again. This is due to alarm delivered late.
- */
-TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
-                return true;
-            }))
-            // condition becomes false
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
-                return true;
-            }))
-            // condition becomes true again
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 25);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 25, 130));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    // startUpdated:false sum:0 start:100
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(100, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
-    // pull on bucket boundary come late, condition change happens before it
-    valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(false, curInterval.hasValue);
-
-    // condition changed to true again, before the pull alarm is delivered
-    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 25);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(130, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-
-    // Now the alarm is delivered, but it is considered late, the data will be used
-    // for the new bucket since it was just pulled.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 50, 140));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 50);
-
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(140, curBaseInfo.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(10, curInterval.value.long_value);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 160));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    assertPastBucketValuesSingleKey(
-            valueProducer->mPastBuckets, {20, 30}, {bucketSizeNs - 8, bucketSizeNs - 24},
-            {bucketStartTimeNs, bucket2StartTimeNs}, {bucket2StartTimeNs, bucket3StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_aggregation_type(ValueMetric::MIN);
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, -1,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(10, curInterval.value.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(10, curInterval.value.long_value);
-
-    valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {10}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_aggregation_type(ValueMetric::MAX);
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, -1,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(10, curInterval.value.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(20, curInterval.value.long_value);
-
-    valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {20}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_aggregation_type(ValueMetric::AVG);
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, -1,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval;
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(10, curInterval.value.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(1, curInterval.sampleSize);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(25, curInterval.value.long_value);
-    EXPECT_EQ(2, curInterval.sampleSize);
-
-    valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer.mPastBuckets.size());
-    ASSERT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
-
-    EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value -
-                         12.5) < epsilon);
-}
-
-TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_aggregation_type(ValueMetric::SUM);
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, -1,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(10, curInterval.value.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(25, curInterval.value.long_value);
-
-    valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {25}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_aggregation_type(ValueMetric::MIN);
-    metric.set_use_diff(true);
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, -1,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(10, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 15);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(5, curInterval.value.long_value);
-
-    // no change in data.
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 15);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(15, curBaseInfo.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(0, curInterval.value.long_value);
-
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 15);
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(15, curBaseInfo.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(0, curInterval.value.long_value);
-
-    valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
-    assertPastBucketValuesSingleKey(valueProducer.mPastBuckets, {5}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestSkipZeroDiffOutputMultiValue) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.mutable_value_field()->add_child()->set_field(3);
-    metric.set_aggregation_type(ValueMetric::MIN);
-    metric.set_use_diff(true);
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, -1,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    CreateThreeValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10, 20);
-
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    CreateThreeValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 1, 15, 22);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(10, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[1];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(20, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(5, curInterval.value.long_value);
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[1];
-    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[1];
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(2, curInterval.value.long_value);
-
-    // no change in first value field
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    CreateThreeValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 1, 15, 25);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[0];
-
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(15, curBaseInfo.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[1];
-    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[1];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(25, curBaseInfo.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-
-    LogEvent event4(/*uid=*/0, /*pid=*/0);
-    CreateThreeValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 1, 15, 29);
-
-    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(15, curBaseInfo.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second.intervals[1];
-    curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second.baseInfos[1];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(29, curBaseInfo.base.long_value);
-    EXPECT_EQ(true, curInterval.hasValue);
-
-    valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
-
-    ASSERT_EQ(1UL, valueProducer.mPastBuckets.size());
-    ASSERT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
-    ASSERT_EQ(2UL, valueProducer.mPastBuckets.begin()->second[0].values.size());
-    ASSERT_EQ(1UL, valueProducer.mPastBuckets.begin()->second[1].values.size());
-
-    EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[0].mConditionTrueNs);
-    EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
-    EXPECT_EQ(0, valueProducer.mPastBuckets.begin()->second[0].valueIndex[0]);
-    EXPECT_EQ(2, valueProducer.mPastBuckets.begin()->second[0].values[1].long_value);
-    EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[0].valueIndex[1]);
-
-    EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[1].mConditionTrueNs);
-    EXPECT_EQ(3, valueProducer.mPastBuckets.begin()->second[1].values[0].long_value);
-    EXPECT_EQ(1, valueProducer.mPastBuckets.begin()->second[1].valueIndex[0]);
-}
-
-/*
- * Tests zero default base.
- */
-TEST(ValueMetricProducerTest, TestUseZeroDefaultBase) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.mutable_dimensions_in_what()->set_field(tagId);
-    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-    metric.set_use_zero_default_base(true);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    auto iter = valueProducer->mCurrentSlicedBucket.begin();
-    auto& interval1 = iter->second.intervals[0];
-    auto iterBase = valueProducer->mCurrentBaseInfo.begin();
-    auto& baseInfo1 = iterBase->second.baseInfos[0];
-    EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(true, baseInfo1.hasBase);
-    EXPECT_EQ(3, baseInfo1.base.long_value);
-    EXPECT_EQ(false, interval1.hasValue);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-    vector<shared_ptr<LogEvent>> allData;
-
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4));
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
-
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(true, baseInfo1.hasBase);
-    EXPECT_EQ(11, baseInfo1.base.long_value);
-    EXPECT_EQ(false, interval1.hasValue);
-    EXPECT_EQ(8, interval1.value.long_value);
-
-    auto it = valueProducer->mCurrentSlicedBucket.begin();
-    for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) {
-        if (it != iter) {
-            break;
-        }
-    }
-    auto itBase = valueProducer->mCurrentBaseInfo.begin();
-    for (; itBase != valueProducer->mCurrentBaseInfo.end(); it++) {
-        if (itBase != iterBase) {
-            break;
-        }
-    }
-    EXPECT_TRUE(it != iter);
-    EXPECT_TRUE(itBase != iterBase);
-    auto& interval2 = it->second.intervals[0];
-    auto& baseInfo2 = itBase->second.baseInfos[0];
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(true, baseInfo2.hasBase);
-    EXPECT_EQ(4, baseInfo2.base.long_value);
-    EXPECT_EQ(false, interval2.hasValue);
-    EXPECT_EQ(4, interval2.value.long_value);
-
-    ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-    auto iterator = valueProducer->mPastBuckets.begin();
-    EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
-    EXPECT_EQ(8, iterator->second[0].values[0].long_value);
-    iterator++;
-    EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
-    EXPECT_EQ(4, iterator->second[0].values[0].long_value);
-}
-
-/*
- * Tests using zero default base with failed pull.
- */
-TEST(ValueMetricProducerTest, TestUseZeroDefaultBaseWithPullFailures) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.mutable_dimensions_in_what()->set_field(tagId);
-    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-    metric.set_use_zero_default_base(true);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    const auto& it = valueProducer->mCurrentSlicedBucket.begin();
-    ValueMetricProducer::Interval& interval1 = it->second.intervals[0];
-    ValueMetricProducer::BaseInfo& baseInfo1 =
-            valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat())
-                    ->second.baseInfos[0];
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(true, baseInfo1.hasBase);
-    EXPECT_EQ(3, baseInfo1.base.long_value);
-    EXPECT_EQ(false, interval1.hasValue);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-    vector<shared_ptr<LogEvent>> allData;
-
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4));
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
-
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(true, baseInfo1.hasBase);
-    EXPECT_EQ(11, baseInfo1.base.long_value);
-    EXPECT_EQ(false, interval1.hasValue);
-    EXPECT_EQ(8, interval1.value.long_value);
-
-    auto it2 = valueProducer->mCurrentSlicedBucket.begin();
-    for (; it2 != valueProducer->mCurrentSlicedBucket.end(); it2++) {
-        if (it2 != it) {
-            break;
-        }
-    }
-    EXPECT_TRUE(it2 != it);
-    ValueMetricProducer::Interval& interval2 = it2->second.intervals[0];
-    ValueMetricProducer::BaseInfo& baseInfo2 =
-            valueProducer->mCurrentBaseInfo.find(it2->first.getDimensionKeyInWhat())
-                    ->second.baseInfos[0];
-    EXPECT_EQ(2, it2->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(true, baseInfo2.hasBase);
-    EXPECT_EQ(4, baseInfo2.base.long_value);
-    EXPECT_EQ(false, interval2.hasValue);
-    EXPECT_EQ(4, interval2.value.long_value);
-    ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-
-    // next pull somehow did not happen, skip to end of bucket 3
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 2, 5));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(true, baseInfo2.hasBase);
-    EXPECT_EQ(5, baseInfo2.base.long_value);
-    EXPECT_EQ(false, interval2.hasValue);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-    ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 2, 13));
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 1, 5));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs);
-
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    // Get new references now that entries have been deleted from the map
-    const auto& it3 = valueProducer->mCurrentSlicedBucket.begin();
-    const auto& it4 = std::next(valueProducer->mCurrentSlicedBucket.begin());
-    ASSERT_EQ(it3->second.intervals.size(), 1);
-    ASSERT_EQ(it4->second.intervals.size(), 1);
-    ValueMetricProducer::Interval& interval3 = it3->second.intervals[0];
-    ValueMetricProducer::Interval& interval4 = it4->second.intervals[0];
-    ValueMetricProducer::BaseInfo& baseInfo3 =
-            valueProducer->mCurrentBaseInfo.find(it3->first.getDimensionKeyInWhat())
-                    ->second.baseInfos[0];
-    ValueMetricProducer::BaseInfo& baseInfo4 =
-            valueProducer->mCurrentBaseInfo.find(it4->first.getDimensionKeyInWhat())
-                    ->second.baseInfos[0];
-
-    EXPECT_EQ(true, baseInfo3.hasBase);
-    EXPECT_EQ(5, baseInfo3.base.long_value);
-    EXPECT_EQ(false, interval3.hasValue);
-    EXPECT_EQ(5, interval3.value.long_value);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
-    EXPECT_EQ(true, baseInfo4.hasBase);
-    EXPECT_EQ(13, baseInfo4.base.long_value);
-    EXPECT_EQ(false, interval4.hasValue);
-    EXPECT_EQ(8, interval4.value.long_value);
-
-    ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-}
-
-/*
- * Tests trim unused dimension key if no new data is seen in an entire bucket.
- */
-TEST(ValueMetricProducerTest, TestTrimUnusedDimensionKey) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.mutable_dimensions_in_what()->set_field(tagId);
-    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    auto iter = valueProducer->mCurrentSlicedBucket.begin();
-    auto& interval1 = iter->second.intervals[0];
-    auto iterBase = valueProducer->mCurrentBaseInfo.begin();
-    auto& baseInfo1 = iterBase->second.baseInfos[0];
-    EXPECT_EQ(1, iter->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(true, baseInfo1.hasBase);
-    EXPECT_EQ(3, baseInfo1.base.long_value);
-    EXPECT_EQ(false, interval1.hasValue);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 2, 4));
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(true, baseInfo1.hasBase);
-    EXPECT_EQ(11, baseInfo1.base.long_value);
-    EXPECT_EQ(false, interval1.hasValue);
-    EXPECT_EQ(8, interval1.value.long_value);
-    EXPECT_FALSE(interval1.seenNewData);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-
-    auto it = valueProducer->mCurrentSlicedBucket.begin();
-    for (; it != valueProducer->mCurrentSlicedBucket.end(); it++) {
-        if (it != iter) {
-            break;
-        }
-    }
-    auto itBase = valueProducer->mCurrentBaseInfo.begin();
-    for (; itBase != valueProducer->mCurrentBaseInfo.end(); it++) {
-        if (itBase != iterBase) {
-            break;
-        }
-    }
-    EXPECT_TRUE(it != iter);
-    EXPECT_TRUE(itBase != iterBase);
-    auto interval2 = it->second.intervals[0];
-    auto baseInfo2 = itBase->second.baseInfos[0];
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(true, baseInfo2.hasBase);
-    EXPECT_EQ(4, baseInfo2.base.long_value);
-    EXPECT_EQ(false, interval2.hasValue);
-    EXPECT_FALSE(interval2.seenNewData);
-
-    // next pull somehow did not happen, skip to end of bucket 3
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 2, 5));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-    // Only one interval left. One was trimmed.
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    interval2 = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    baseInfo2 = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(true, baseInfo2.hasBase);
-    EXPECT_EQ(5, baseInfo2.base.long_value);
-    EXPECT_EQ(false, interval2.hasValue);
-    EXPECT_FALSE(interval2.seenNewData);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {8}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 2, 14));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs);
-
-    interval2 = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    baseInfo2 = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, baseInfo2.hasBase);
-    EXPECT_EQ(14, baseInfo2.base.long_value);
-    EXPECT_EQ(false, interval2.hasValue);
-    EXPECT_FALSE(interval2.seenNewData);
-    ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
-    auto iterator = valueProducer->mPastBuckets.begin();
-    EXPECT_EQ(bucket4StartTimeNs, iterator->second[0].mBucketStartNs);
-    EXPECT_EQ(bucket5StartTimeNs, iterator->second[0].mBucketEndNs);
-    EXPECT_EQ(9, iterator->second[0].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
-    iterator++;
-    EXPECT_EQ(bucketStartTimeNs, iterator->second[0].mBucketStartNs);
-    EXPECT_EQ(bucket2StartTimeNs, iterator->second[0].mBucketEndNs);
-    EXPECT_EQ(8, iterator->second[0].values[0].long_value);
-    EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange_EndOfBucket) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    // Used by onConditionChanged.
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval& curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo& curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(100, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-
-    vector<shared_ptr<LogEvent>> allData;
-    valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFailAfterConditionChange) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);  // Condition change to true.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
-                return true;
-            }))
-            .WillOnce(Return(false));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval& curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo& curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(100, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 20);
-
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullFailBeforeConditionChange) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 50));
-                return false;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1);  // Condition change to false.
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Don't directly set mCondition; the real code never does that. Go through regular code path
-    // to avoid unexpected behaviors.
-    // valueProducer->mCondition = ConditionState::kTrue;
-    valueProducer->onConditionChanged(true, bucketStartTimeNs);
-
-    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 1);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval& curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullDelayExceeded) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_condition(StringToId("SCREEN_ON"));
-    metric.set_max_pull_delay_sec(0);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 120));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Max delay is set to 0 so pull will exceed max delay.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
-    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-}
-
-TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard,
-                                      protoHash, logEventMatcherIndex, eventMatcherWizard, tagId,
-                                      bucket2StartTimeNs, bucket2StartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-    valueProducer.mCondition = ConditionState::kFalse;
-
-    // Event should be skipped since it is from previous bucket.
-    // Pull should not be called.
-    valueProducer.onConditionChanged(true, bucketStartTimeNs);
-    ASSERT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
-}
-
-TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-    valueProducer->mHasGlobalBase = false;
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
-    valueProducer->mHasGlobalBase = true;
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval& curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(100, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-}
-
-/*
- * Tests that a bucket is marked invalid when a condition change pull fails.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenOneConditionFailed) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // First onConditionChanged
-            .WillOnce(Return(false))
-            // Second onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kTrue);
-
-    // Bucket start.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-
-    // This will fail and should invalidate the whole bucket since we do not have all the data
-    // needed to compute the metric value when the screen was on.
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
-
-    // Bucket end.
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
-
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-    // Contains base from last pull which was successful.
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval& curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(140, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 10, false /* include partial bucket */, true,
-                                FAST /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 2), dropEvent.drop_time_millis());
-}
-
-/*
- * Tests that a bucket is marked invalid when the guardrail is hit.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenGuardRailHit) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.mutable_dimensions_in_what()->set_field(tagId);
-    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-    metric.set_condition(StringToId("SCREEN_ON"));
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 2, _))
-            // First onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                for (int i = 0; i < 2000; i++) {
-                    data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
-                }
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 2);
-    EXPECT_EQ(true, valueProducer->mCurrentBucketIsSkipped);
-    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(0UL, valueProducer->mSkippedBuckets.size());
-
-    // Bucket 2 start.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 10));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    // First bucket added to mSkippedBuckets after flush.
-    ASSERT_EQ(1UL, valueProducer->mSkippedBuckets.size());
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 10000, false /* include recent buckets */,
-                                true, FAST /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::DIMENSION_GUARDRAIL_REACHED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 2), dropEvent.drop_time_millis());
-}
-
-/*
- * Tests that a bucket is marked invalid when the bucket's initial pull fails.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // First onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
-                return true;
-            }))
-            // Second onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kTrue);
-
-    // Bucket start.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110));
-    valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs);
-
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
-
-    // Bucket end.
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
-
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-    // Contains base from last pull which was successful.
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval& curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(140, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 10000, false /* include recent buckets */,
-                                true, FAST /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 2), dropEvent.drop_time_millis());
-}
-
-/*
- * Tests that a bucket is marked invalid when the bucket's final pull fails
- * (i.e. failed pull on bucket boundary).
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenLastPullFailed) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // First onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
-                return true;
-            }))
-            // Second onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kTrue);
-
-    // Bucket start.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 2);
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 3);
-
-    // Bucket end.
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140));
-    valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
-
-    valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
-
-    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
-    // Last pull failed so base has been reset.
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval& curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 10000, false /* include recent buckets */,
-                                true, FAST /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), dropEvent.drop_time_millis());
-}
-
-TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            // Start bucket.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    // Bucket 2 start.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-
-    // Bucket 3 empty.
-    allData.clear();
-    allData.push_back(CreateNoValuesLogEvent(tagId, bucket3StartTimeNs + 1));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    // Data has been trimmed.
-    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-}
-
-TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // First onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval& curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
-    // Empty pull.
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(false, valueProducer->mHasGlobalBase);
-}
-
-TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onBucketBoundary) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // First onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 11);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 2));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 12);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 5));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 11);
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 12);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval& curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
-    // End of bucket
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    // Data is empty, base should be reset.
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(5, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-
-    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPartialResetOnBucketBoundaries) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.mutable_dimensions_in_what()->set_field(tagId);
-    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-    metric.set_condition(StringToId("SCREEN_ON"));
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _))
-            // First onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-
-    // End of bucket
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 2));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    // Key 1 should be reset since in not present in the most pull.
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    auto iterator = valueProducer->mCurrentSlicedBucket.begin();
-    auto baseInfoIter = valueProducer->mCurrentBaseInfo.begin();
-    EXPECT_EQ(true, baseInfoIter->second.baseInfos[0].hasBase);
-    EXPECT_EQ(2, baseInfoIter->second.baseInfos[0].base.long_value);
-    EXPECT_EQ(false, iterator->second.intervals[0].hasValue);
-    iterator++;
-    baseInfoIter++;
-    EXPECT_EQ(false, baseInfoIter->second.baseInfos[0].hasBase);
-    EXPECT_EQ(1, baseInfoIter->second.baseInfos[0].base.long_value);
-    EXPECT_EQ(false, iterator->second.intervals[0].hasValue);
-
-    EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestFullBucketResetWhenLastBucketInvalid) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    int64_t partialBucketSplitTimeNs = bucketStartTimeNs + bucketSizeNs / 2;
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Initialization.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                return true;
-            }))
-            // notifyAppUpgrade.
-            .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
-                                                        const int64_t eventTimeNs,
-                                                        vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
-                return true;
-            }));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-    ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
-
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-    EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mCurrentBucketStartTimeNs);
-    EXPECT_EQ(0, valueProducer->getCurrentBucketNum());
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9},
-                                    {partialBucketSplitTimeNs - bucketStartTimeNs},
-                                    {bucketStartTimeNs}, {partialBucketSplitTimeNs});
-    ASSERT_EQ(1UL, valueProducer->mCurrentFullBucket.size());
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 4));
-    // Pull fails and arrives late.
-    valueProducer->onDataPulled(allData, /** fails */ false, bucket3StartTimeNs + 1);
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9},
-                                    {partialBucketSplitTimeNs - bucketStartTimeNs},
-                                    {bucketStartTimeNs}, {partialBucketSplitTimeNs});
-    ASSERT_EQ(1, valueProducer->mSkippedBuckets.size());
-    ASSERT_EQ(2, valueProducer->mSkippedBuckets[0].dropEvents.size());
-    EXPECT_EQ(PULL_FAILED, valueProducer->mSkippedBuckets[0].dropEvents[0].reason);
-    EXPECT_EQ(MULTIPLE_BUCKETS_SKIPPED, valueProducer->mSkippedBuckets[0].dropEvents[1].reason);
-    EXPECT_EQ(partialBucketSplitTimeNs, valueProducer->mSkippedBuckets[0].bucketStartTimeNs);
-    EXPECT_EQ(bucket3StartTimeNs, valueProducer->mSkippedBuckets[0].bucketEndTimeNs);
-    ASSERT_EQ(0UL, valueProducer->mCurrentFullBucket.size());
-}
-
-TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Second onConditionChanged.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5));
-                return true;
-            }))
-            // Third onConditionChanged.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 10, 7));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(
-                    pullerManager, metric, ConditionState::kUnknown);
-
-    valueProducer->onConditionChanged(false, bucketStartTimeNs);
-    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
-    // End of first bucket
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 4));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
-    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
-    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curBaseInfo.hasBase);
-    EXPECT_EQ(5, curBaseInfo.base.long_value);
-    EXPECT_EQ(false, curInterval.hasValue);
-
-    valueProducer->onConditionChanged(false, bucket3StartTimeNs + 10);
-
-    // Bucket should have been completed.
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {bucketSizeNs - 10},
-                                    {bucket2StartTimeNs}, {bucket3StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestLateOnDataPulledWithoutDiff) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_use_diff(false);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    // Bucket should have been completed.
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestLateOnDataPulledWithDiff) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            // Initialization.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 30);
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    // Bucket should have been completed.
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {19}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST_P(ValueMetricProducerTest_PartialBucket, TestBucketBoundariesOnPartialBucket) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Initialization.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                return true;
-            }))
-            // notifyAppUpgrade.
-            .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
-                                                        const int64_t eventTimeNs,
-                                                        vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    switch (GetParam()) {
-        case APP_UPGRADE:
-            valueProducer->notifyAppUpgrade(partialBucketSplitTimeNs);
-            break;
-        case BOOT_COMPLETE:
-            valueProducer->onStatsdInitCompleted(partialBucketSplitTimeNs);
-            break;
-    }
-
-    // Bucket should have been completed.
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {9}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestDataIsNotUpdatedWhenNoConditionChanged) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // First on condition changed.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                return true;
-            }))
-            // Second on condition changed.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 12);
-
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(2, curInterval.value.long_value);
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 10));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 1);
-
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {2}, {2}, {bucketStartTimeNs},
-                                    {bucket2StartTimeNs});
-}
-
-// TODO: b/145705635 fix or delete this test
-TEST(ValueMetricProducerTest, TestBucketInvalidIfGlobalBaseIsNotSet) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // First condition change.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                return true;
-            }))
-            // 2nd condition change.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 8);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
-                return true;
-            }))
-            // 3rd condition change.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 3, 10));
-    valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs + 3);
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 20));
-    valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
-
-    valueProducer->onConditionChanged(false, bucket2StartTimeNs + 8);
-    valueProducer->onConditionChanged(true, bucket2StartTimeNs + 10);
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs, 30));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    // There was not global base available so all buckets are invalid.
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {});
-}
-
-TEST(ValueMetricProducerTest, TestPullNeededFastDump) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            // Initial pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
-                return true;
-            }));
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
-                               FAST, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    // Bucket is invalid since we did not pull when dump report was called.
-    ASSERT_EQ(0, report.value_metrics().data_size());
-}
-
-TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _))
-            // Initial pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
-                return true;
-            }));
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 1, tagId, 2, 2));
-    valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer.onDumpReport(bucket4StartTimeNs, false /* include recent buckets */, true, FAST,
-                               &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    // Previous bucket is part of the report.
-    ASSERT_EQ(1, report.value_metrics().data_size());
-    EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num());
-}
-
-TEST(ValueMetricProducerTest, TestPullNeededNoTimeConstraints) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-
-    sp<EventMatcherWizard> eventMatcherWizard =
-            createEventMatcherWizard(tagId, logEventMatcherIndex);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
-
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Initial pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
-                return true;
-            }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                data->push_back(
-                        CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 10, tagId, 3, 3));
-                return true;
-            }));
-
-    ValueMetricProducer valueProducer(kConfigKey, metric, -1, {}, wizard, protoHash,
-                                      logEventMatcherIndex, eventMatcherWizard, tagId,
-                                      bucketStartTimeNs, bucketStartTimeNs, pullerManager);
-    valueProducer.prepareFirstBucket();
-
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer.onDumpReport(bucketStartTimeNs + 10, true /* include recent buckets */, true,
-                               NO_TIME_CONSTRAINTS, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    ASSERT_EQ(1, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().data(0).bucket_info_size());
-    EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_withoutCondition) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
-    metric.set_use_diff(false);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
-
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 10));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 30);
-
-    // Bucket should have been completed.
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_withMultipleConditionChanges) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-    metric.set_use_diff(false);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
-                return true;
-            }))
-            // condition becomes false
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 20));
-                return true;
-            }));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
-    // has one slice
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(true, curInterval.hasValue);
-    EXPECT_EQ(20, curInterval.value.long_value);
-
-    // Now the alarm is delivered. Condition is off though.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 110));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {50 - 8},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-    curInterval = valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(false, curInterval.hasValue);
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryTrue) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-    metric.set_use_diff(false);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _))
-            // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
-                return true;
-            }));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-
-    // Now the alarm is delivered. Condition is off though.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {30}, {bucketSizeNs - 8},
-                                    {bucketStartTimeNs}, {bucket2StartTimeNs});
-    ValueMetricProducer::Interval curInterval =
-            valueProducer->mCurrentSlicedBucket.begin()->second.intervals[0];
-    ValueMetricProducer::BaseInfo curBaseInfo =
-            valueProducer->mCurrentBaseInfo.begin()->second.baseInfos[0];
-    EXPECT_EQ(false, curBaseInfo.hasBase);
-    EXPECT_EQ(false, curInterval.hasValue);
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_bucketBoundaryFalse) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-    metric.set_use_diff(false);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Now the alarm is delivered. Condition is off though.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    // Condition was always false.
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {});
-}
-
-TEST(ValueMetricProducerTest, TestPulledData_noDiff_withFailure) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-    metric.set_use_diff(false);
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
-                return true;
-            }))
-            .WillOnce(Return(false));
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
-
-    // Now the alarm is delivered. Condition is off though.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 30, 30));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    // No buckets, we had a failure.
-    assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {}, {}, {}, {});
-}
-
-/*
- * Test that DUMP_REPORT_REQUESTED dump reason is logged.
- *
- * For the bucket to be marked invalid during a dump report requested,
- * three things must be true:
- * - we want to include the current partial bucket
- * - we need a pull (metric is pulled and condition is true)
- * - the dump latency must be FAST
- */
-
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenDumpReportRequested) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 20, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20, 10));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Condition change event.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 20);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucketStartTimeNs + 40, true /* include recent buckets */, true,
-                                FAST /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late condition
- * change event (i.e. the condition change occurs in the wrong bucket).
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionEventWrongBucket) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 50, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Condition change event.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
-    // Bucket boundary pull.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15));
-    valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
-    // Late condition change event.
-    valueProducer->onConditionChanged(false, bucket2StartTimeNs - 100);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(1, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(2, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(1);
-    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that EVENT_IN_WRONG_BUCKET dump reason is logged for a late accumulate
- * event (i.e. the accumulate events call occurs in the wrong bucket).
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenAccumulateEventWrongBucket) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
-                return true;
-            }))
-            // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 100);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 100, 15));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Condition change event.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
-    // Bucket boundary pull.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 15));
-    valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 20));
-
-    // Late accumulateEvents event.
-    valueProducer->accumulateEvents(allData, bucket2StartTimeNs - 100, bucket2StartTimeNs - 100);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 100, true /* include recent buckets */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(1, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs - 100), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that CONDITION_UNKNOWN dump reason is logged due to an unknown condition
- * when a metric is initialized.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenConditionUnknown) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
-                return true;
-            }))
-            // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10000);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 100, 15));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(
-                    pullerManager, metric, ConditionState::kUnknown);
-
-    // Condition change event.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
-    valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that PULL_FAILED dump reason is logged due to a pull failure in
- * #pullAndMatchEventsLocked.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenPullFailed) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
-                return true;
-            }))
-            // Dump report requested, pull fails.
-            .WillOnce(Return(false));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Condition change event.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    int64_t dumpReportTimeNs = bucketStartTimeNs + 10000;
-    valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that MULTIPLE_BUCKETS_SKIPPED dump reason is logged when a log event
- * skips over more than one bucket.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenMultipleBucketsSkipped) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
-                return true;
-            }))
-            // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket4StartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1000, 15));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Condition change event.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
-    // Condition change event that skips forward by three buckets.
-    valueProducer->onConditionChanged(false, bucket4StartTimeNs + 10);
-
-    int64_t dumpTimeNs = bucket4StartTimeNs + 1000;
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(dumpTimeNs, true /* include current buckets */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(2, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucket4StartTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::MULTIPLE_BUCKETS_SKIPPED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucket4StartTimeNs + 10), dropEvent.drop_time_millis());
-
-    // This bucket is skipped because a dumpReport with include current buckets is called.
-    // This creates a new bucket from bucket4StartTimeNs to dumpTimeNs in which we have no data
-    // since the condition is false for the entire bucket interval.
-    EXPECT_EQ(NanoToMillis(bucket4StartTimeNs),
-              report.value_metrics().skipped(1).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(dumpTimeNs),
-              report.value_metrics().skipped(1).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(1).drop_event_size());
-
-    dropEvent = report.value_metrics().skipped(1).drop_event(0);
-    EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(dumpTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that BUCKET_TOO_SMALL dump reason is logged when a flushed bucket size
- * is smaller than the "min_bucket_size_nanos" specified in the metric config.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenBucketTooSmall) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-    metric.set_min_bucket_size_nanos(10000000000);  // 10 seconds
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
-                return true;
-            }))
-            // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 9000000);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 9000000, 15));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Condition change event.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    int64_t dumpReportTimeNs = bucketStartTimeNs + 9000000;
-    valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that NO_DATA dump reason is logged when a flushed bucket contains no data.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenDataUnavailable) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(
-                    pullerManager, metric, ConditionState::kFalse);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    int64_t dumpReportTimeNs = bucketStartTimeNs + 10000000000; // 10 seconds
-    valueProducer->onDumpReport(dumpReportTimeNs, true /* include current bucket */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that all buckets are dropped due to condition unknown until the first onConditionChanged.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestConditionUnknownMultipleBuckets) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucket2StartTimeNs + 10 * NS_PER_SEC, 10));
-                return true;
-            }))
-            // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 15 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucket2StartTimeNs + 15 * NS_PER_SEC, 15));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(
-                    pullerManager, metric, ConditionState::kUnknown);
-
-    // Bucket should be dropped because of condition unknown.
-    int64_t appUpgradeTimeNs = bucketStartTimeNs + 5 * NS_PER_SEC;
-    valueProducer->notifyAppUpgrade(appUpgradeTimeNs);
-
-    // Bucket also dropped due to condition unknown
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 3));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    // This bucket is also dropped due to condition unknown.
-    int64_t conditionChangeTimeNs = bucket2StartTimeNs + 10 * NS_PER_SEC;
-    valueProducer->onConditionChanged(true, conditionChangeTimeNs);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    int64_t dumpReportTimeNs = bucket2StartTimeNs + 15 * NS_PER_SEC; // 15 seconds
-    valueProducer->onDumpReport(dumpReportTimeNs, true /* include current bucket */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(3, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(appUpgradeTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(appUpgradeTimeNs), dropEvent.drop_time_millis());
-
-    EXPECT_EQ(NanoToMillis(appUpgradeTimeNs),
-              report.value_metrics().skipped(1).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-              report.value_metrics().skipped(1).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(1).drop_event_size());
-
-    dropEvent = report.value_metrics().skipped(1).drop_event(0);
-    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs), dropEvent.drop_time_millis());
-
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-              report.value_metrics().skipped(2).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
-              report.value_metrics().skipped(2).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(2).drop_event_size());
-
-    dropEvent = report.value_metrics().skipped(2).drop_event(0);
-    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(conditionChangeTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that a skipped bucket is logged when a forced bucket split occurs when the previous bucket
- * was not flushed in time.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestBucketDropWhenForceBucketSplitBeforeBucketFlush) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
-                return true;
-            }))
-            // App Update.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1000);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1000, 15));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric,
-                                                                            ConditionState::kFalse);
-
-    // Condition changed event
-    int64_t conditionChangeTimeNs = bucketStartTimeNs + 10;
-    valueProducer->onConditionChanged(true, conditionChangeTimeNs);
-
-    // App update event.
-    int64_t appUpdateTimeNs = bucket2StartTimeNs + 1000;
-    valueProducer->notifyAppUpgrade(appUpdateTimeNs);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    int64_t dumpReportTimeNs = bucket2StartTimeNs + 10000000000; // 10 seconds
-    valueProducer->onDumpReport(dumpReportTimeNs, false /* include current buckets */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(1, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    ASSERT_EQ(1, report.value_metrics().data(0).bucket_info_size());
-    auto data = report.value_metrics().data(0);
-    ASSERT_EQ(0, data.bucket_info(0).bucket_num());
-    EXPECT_EQ(5, data.bucket_info(0).values(0).value_long());
-
-    EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(appUpdateTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::NO_DATA, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(appUpdateTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test multiple bucket drop events in the same bucket.
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestMultipleBucketDropEvents) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _))
-            // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(
-                    pullerManager, metric, ConditionState::kUnknown);
-
-    // Condition change event.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    int64_t dumpReportTimeNs = bucketStartTimeNs + 1000;
-    valueProducer->onDumpReport(dumpReportTimeNs, true /* include recent buckets */, true,
-                                FAST /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(2, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 10), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(1);
-    EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs), dropEvent.drop_time_millis());
-}
-
-/*
- * Test that the number of logged bucket drop events is capped at the maximum.
- * The maximum is currently 10 and is set in MetricProducer::maxDropEventsReached().
- */
-TEST(ValueMetricProducerTest_BucketDrop, TestMaxBucketDropEvents) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // First condition change event.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
-                for (int i = 0; i < 2000; i++) {
-                    data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
-                }
-                return true;
-            }))
-            .WillOnce(Return(false))
-            .WillOnce(Return(false))
-            .WillOnce(Return(false))
-            .WillOnce(Return(false))
-            .WillOnce(Return(false))
-            .WillOnce(Return(false))
-            .WillOnce(Return(false))
-            .WillOnce(Return(false))
-            .WillOnce(Return(false))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 220);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 220, 10));
-                return true;
-            }));
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(
-                    pullerManager, metric, ConditionState::kUnknown);
-
-    // First condition change event causes guardrail to be reached.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-
-    // 2-10 condition change events result in failed pulls.
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 30);
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 50);
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 70);
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 90);
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 100);
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 150);
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 170);
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 190);
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 200);
-
-    // Condition change event 11
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 220);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    int64_t dumpReportTimeNs = bucketStartTimeNs + 1000;
-    // Because we already have 10 dump events in the current bucket,
-    // this case should not be added to the list of dump events.
-    valueProducer->onDumpReport(bucketStartTimeNs + 1000, true /* include recent buckets */, true,
-                                FAST /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(10, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 10), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(1);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 30), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(2);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 50), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(3);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 70), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(4);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 90), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(5);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 100), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(6);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 150), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(7);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 170), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(8);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 190), dropEvent.drop_time_millis());
-
-    dropEvent = report.value_metrics().skipped(0).drop_event(9);
-    EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 200), dropEvent.drop_time_millis());
-}
-
-/*
- * Test metric with a simple sliced state
- * - Increasing values
- * - Using diff
- * - Second field is value field
- */
-TEST(ValueMetricProducerTest, TestSlicedState) {
-    // Set up ValueMetricProducer.
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE");
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // ValueMetricProducer initialized.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                return true;
-            }))
-            // Screen state change to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5 * NS_PER_SEC, 5));
-                return true;
-            }))
-            // Screen state change to OFF.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10 * NS_PER_SEC, 9));
-                return true;
-            }))
-            // Screen state change to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucketStartTimeNs + 15 * NS_PER_SEC, 21));
-                return true;
-            }))
-            // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucketStartTimeNs + 50 * NS_PER_SEC, 30));
-                return true;
-            }));
-
-    StateManager::getInstance().clear();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithState(
-                    pullerManager, metric, {util::SCREEN_STATE_CHANGED}, {});
-    EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
-    // Set up StateManager and check that StateTrackers are initialized.
-    StateManager::getInstance().registerListener(SCREEN_STATE_ATOM_ID, valueProducer);
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
-    // Bucket status after metric initialized.
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    auto it = valueProducer->mCurrentSlicedBucket.begin();
-    auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(3, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, kStateUnknown}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs);
-
-    // Bucket status after screen state change kStateUnknown->ON.
-    auto screenEvent = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 5 * NS_PER_SEC, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    StateManager::getInstance().onLogEvent(*screenEvent);
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(5, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, ON}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_EQ(0, it->second.intervals.size());
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 5 * NS_PER_SEC);
-    // Value for dimension, state key {{}, kStateUnknown}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(2, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 5 * NS_PER_SEC);
-
-    // Bucket status after screen state change ON->OFF.
-    screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 10 * NS_PER_SEC,
-                                                android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    StateManager::getInstance().onLogEvent(*screenEvent);
-    ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(9, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, OFF}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_EQ(0, it->second.intervals.size());
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 10 * NS_PER_SEC);
-    // Value for dimension, state key {{}, ON}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(4, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 10 * NS_PER_SEC);
-    // Value for dimension, state key {{}, kStateUnknown}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(2, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 5 * NS_PER_SEC);
-
-    // Bucket status after screen state change OFF->ON.
-    screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 15 * NS_PER_SEC,
-                                                android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    StateManager::getInstance().onLogEvent(*screenEvent);
-    ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(21, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, OFF}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(12, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 15 * NS_PER_SEC);
-    // Value for dimension, state key {{}, ON}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(4, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, true, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 15 * NS_PER_SEC);
-    // Value for dimension, state key {{}, kStateUnknown}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(2, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 5 * NS_PER_SEC);
-
-    // Start dump report and check output.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucketStartTimeNs + 50 * NS_PER_SEC,
-                                true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
-                                &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(3, report.value_metrics().data_size());
-
-    // {{}, kStateUnknown}
-    auto data = report.value_metrics().data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
-    EXPECT_EQ(5 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {{}, ON}
-    data = report.value_metrics().data(1);
-    ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
-    EXPECT_EQ(13, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
-    EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {{}, OFF}
-    data = report.value_metrics().data(2);
-    ASSERT_EQ(1, report.value_metrics().data(2).bucket_info_size());
-    EXPECT_EQ(12, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
-    EXPECT_EQ(5 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-}
-
-/*
- * Test metric with sliced state with map
- * - Increasing values
- * - Using diff
- * - Second field is value field
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithMap) {
-    // Set up ValueMetricProducer.
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE_ONOFF");
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // ValueMetricProducer initialized.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                return true;
-            }))
-            // Screen state change to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5 * NS_PER_SEC, 5));
-                return true;
-            }))
-            // Screen state change to VR has no pull because it is in the same
-            // state group as ON.
-
-            // Screen state change to ON has no pull because it is in the same
-            // state group as VR.
-
-            // Screen state change to OFF.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucketStartTimeNs + 15 * NS_PER_SEC, 21));
-                return true;
-            }))
-            // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucketStartTimeNs + 50 * NS_PER_SEC, 30));
-                return true;
-            }));
-
-    const StateMap& stateMap =
-            CreateScreenStateOnOffMap(/*screen on id=*/321, /*screen off id=*/123);
-    const StateMap_StateGroup screenOnGroup = stateMap.group(0);
-    const StateMap_StateGroup screenOffGroup = stateMap.group(1);
-
-    unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
-    for (auto group : stateMap.group()) {
-        for (auto value : group.value()) {
-            stateGroupMap[SCREEN_STATE_ATOM_ID][value] = group.group_id();
-        }
-    }
-
-    StateManager::getInstance().clear();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithState(
-                    pullerManager, metric, {util::SCREEN_STATE_CHANGED}, stateGroupMap);
-
-    // Set up StateManager and check that StateTrackers are initialized.
-    StateManager::getInstance().registerListener(SCREEN_STATE_ATOM_ID, valueProducer);
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
-
-    // Bucket status after metric initialized.
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    auto it = valueProducer->mCurrentSlicedBucket.begin();
-    auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(3, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, {kStateUnknown}}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs);
-
-    // Bucket status after screen state change kStateUnknown->ON.
-    auto screenEvent = CreateScreenStateChangedEvent(
-            bucketStartTimeNs + 5 * NS_PER_SEC, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    StateManager::getInstance().onLogEvent(*screenEvent);
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(5, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(screenOnGroup.group_id(),
-              itBase->second.currentState.getValues()[0].mValue.long_value);
-    // Value for dimension, state key {{}, ON GROUP}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(screenOnGroup.group_id(),
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 5 * NS_PER_SEC);
-    // Value for dimension, state key {{}, kStateUnknown}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(2, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 5 * NS_PER_SEC);
-
-    // Bucket status after screen state change ON->VR.
-    // Both ON and VR are in the same state group, so the base should not change.
-    screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 10 * NS_PER_SEC,
-                                                android::view::DisplayStateEnum::DISPLAY_STATE_VR);
-    StateManager::getInstance().onLogEvent(*screenEvent);
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(5, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(screenOnGroup.group_id(),
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, ON GROUP}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(screenOnGroup.group_id(),
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 5 * NS_PER_SEC);
-    // Value for dimension, state key {{}, kStateUnknown}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(2, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 5 * NS_PER_SEC);
-
-    // Bucket status after screen state change VR->ON.
-    // Both ON and VR are in the same state group, so the base should not change.
-    screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 12 * NS_PER_SEC,
-                                                android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    StateManager::getInstance().onLogEvent(*screenEvent);
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(5, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(screenOnGroup.group_id(),
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, ON GROUP}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(screenOnGroup.group_id(),
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 5 * NS_PER_SEC);
-    // Value for dimension, state key {{}, kStateUnknown}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(2, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 5 * NS_PER_SEC);
-
-    // Bucket status after screen state change VR->OFF.
-    screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 15 * NS_PER_SEC,
-                                                android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    StateManager::getInstance().onLogEvent(*screenEvent);
-    ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(21, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(screenOffGroup.group_id(),
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, OFF GROUP}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(screenOffGroup.group_id(),
-              it->first.getStateValuesKey().getValues()[0].mValue.long_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 15 * NS_PER_SEC);
-    // Value for dimension, state key {{}, ON GROUP}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(screenOnGroup.group_id(),
-              it->first.getStateValuesKey().getValues()[0].mValue.long_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(16, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 15 * NS_PER_SEC);
-    // Value for dimension, state key {{}, kStateUnknown}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(2, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 5 * NS_PER_SEC,
-                         bucketStartTimeNs + 5 * NS_PER_SEC);
-
-    // Start dump report and check output.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucketStartTimeNs + 50 * NS_PER_SEC,
-                                true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
-                                &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(3, report.value_metrics().data_size());
-
-    // {{}, kStateUnknown}
-    auto data = report.value_metrics().data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, data.slice_by_state(0).value());
-    EXPECT_EQ(5 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {{}, ON GROUP}
-    data = report.value_metrics().data(1);
-    ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
-    EXPECT_EQ(16, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOnGroup.group_id(), data.slice_by_state(0).group_id());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {{}, OFF GROUP}
-    data = report.value_metrics().data(2);
-    ASSERT_EQ(1, report.value_metrics().data(2).bucket_info_size());
-    EXPECT_EQ(9, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(screenOffGroup.group_id(), data.slice_by_state(0).group_id());
-    EXPECT_EQ(35 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-}
-
-/*
- * Test metric that slices by state with a primary field and has dimensions
- * - Increasing values
- * - Using diff
- * - Second field is value field
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithPrimaryField_WithDimensions) {
-    // Set up ValueMetricProducer.
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("UID_PROCESS_STATE");
-    metric.mutable_dimensions_in_what()->set_field(tagId);
-    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-
-    MetricStateLink* stateLink = metric.add_state_link();
-    stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
-    auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(tagId, {1 /* uid */});
-    auto fieldsInState = stateLink->mutable_fields_in_state();
-    *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
-    /*
-    NOTE: "1" denotes uid 1 and "2" denotes uid 2.
-                    bucket # 1                            bucket # 2
-    10     20     30     40     50     60     70     80     90    100    110    120 (seconds)
-    |------------------------------------------|---------------------------------|--
-
-                                                                                    (kStateUnknown)
-    1
-    |-------------|
-          20
-
-    2
-    |----------------------------|
-                 40
-
-                                                                                    (FOREGROUND)
-                  1                                                       1
-                  |----------------------------|-------------|            |------|
-                               40                     20                     10
-
-
-                                                                                    (BACKGROUND)
-                                                             1
-                                                             |------------|
-                                                                   20
-                                 2
-                                 |-------------|---------------------------------|
-                                       20                      50
-    */
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // ValueMetricProducer initialized.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 2 /*uid*/, 7));
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1 /*uid*/, 3));
-                return true;
-            }))
-            // Uid 1 process state change from kStateUnknown -> Foreground
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 20 * NS_PER_SEC,
-                                                       1 /*uid*/, 6));
-
-                // This event should be skipped.
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 20 * NS_PER_SEC,
-                                                       2 /*uid*/, 8));
-                return true;
-            }))
-            // Uid 2 process state change from kStateUnknown -> Background
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 40 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 40 * NS_PER_SEC,
-                                                       2 /*uid*/, 9));
-
-                // This event should be skipped.
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 40 * NS_PER_SEC,
-                                                       1 /*uid*/, 12));
-                return true;
-            }))
-            // Uid 1 process state change from Foreground -> Background
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 20 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 20 * NS_PER_SEC,
-                                                       1 /*uid*/, 13));
-
-                // This event should be skipped.
-                data->push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 20 * NS_PER_SEC,
-                                                       2 /*uid*/, 11));
-                return true;
-            }))
-            // Uid 1 process state change from Background -> Foreground
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 40 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 40 * NS_PER_SEC,
-                                                       1 /*uid*/, 17));
-
-                // This event should be skipped.
-                data->push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 40 * NS_PER_SEC,
-                                                       2 /*uid */, 15));
-                return true;
-            }))
-            // Dump report pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 50 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 50 * NS_PER_SEC,
-                                                       2 /*uid*/, 20));
-                data->push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 50 * NS_PER_SEC,
-                                                       1 /*uid*/, 21));
-                return true;
-            }));
-
-    StateManager::getInstance().clear();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithState(
-                    pullerManager, metric, {UID_PROCESS_STATE_ATOM_ID}, {});
-
-    // Set up StateManager and check that StateTrackers are initialized.
-    StateManager::getInstance().registerListener(UID_PROCESS_STATE_ATOM_ID, valueProducer);
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
-    // Bucket status after metric initialized.
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {uid 1}.
-    auto it = valueProducer->mCurrentSlicedBucket.begin();
-    auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(3, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{uid 1}, kStateUnknown}
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs);
-    // Base for dimension key {uid 2}
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(7, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{uid 2}, kStateUnknown}
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs);
-
-    // Bucket status after uid 1 process state change kStateUnknown -> Foreground.
-    auto uidProcessEvent =
-            CreateUidProcessStateChangedEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /* uid */,
-                                              android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
-    StateManager::getInstance().onLogEvent(*uidProcessEvent);
-    ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {uid 1}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(6, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 1, kStateUnknown}.
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(3, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-    // Value for key {uid 1, FOREGROUND}.
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Base for dimension key {uid 2}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(7, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 2, kStateUnknown}.
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs);
-
-    // Bucket status after uid 2 process state change kStateUnknown -> Background.
-    uidProcessEvent =
-            CreateUidProcessStateChangedEvent(bucketStartTimeNs + 40 * NS_PER_SEC, 2 /* uid */,
-                                              android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
-    StateManager::getInstance().onLogEvent(*uidProcessEvent);
-    ASSERT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {uid 2}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(9, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 2, BACKGROUND}.
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 40 * NS_PER_SEC);
-
-    // Base for dimension key {uid 1}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(6, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 1, kStateUnknown}.
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(3, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {uid 1, FOREGROUND}.
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {uid 2, kStateUnknown}
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(2, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 40 * NS_PER_SEC,
-                         bucketStartTimeNs + 40 * NS_PER_SEC);
-
-    // Pull at end of first bucket.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs, 1 /*uid*/, 10));
-    allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs, 2 /*uid*/, 15));
-    valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
-    // Buckets flushed after end of first bucket.
-    // None of the buckets should have a value.
-    ASSERT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(4UL, valueProducer->mPastBuckets.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
-    // Base for dimension key {uid 2}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(15, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 2, BACKGROUND}.
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-    EXPECT_EQ(20 * NS_PER_SEC, valueProducer->mPastBuckets[it->first][0].mConditionTrueNs);
-
-    // Base for dimension key {uid 1}
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(10, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 1, kStateUnknown}
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* kStateTracker::kUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-    EXPECT_EQ(20 * NS_PER_SEC, valueProducer->mPastBuckets[it->first][0].mConditionTrueNs);
-
-    // Value for key {uid 1, FOREGROUND}
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-    EXPECT_EQ(40 * NS_PER_SEC, valueProducer->mPastBuckets[it->first][0].mConditionTrueNs);
-
-    // Value for key {uid 2, kStateUnknown}
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* kStateTracker::kUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 40 * NS_PER_SEC);
-    EXPECT_EQ(40 * NS_PER_SEC, valueProducer->mPastBuckets[it->first][0].mConditionTrueNs);
-
-    // Bucket status after uid 1 process state change from Foreground -> Background.
-    uidProcessEvent =
-            CreateUidProcessStateChangedEvent(bucket2StartTimeNs + 20 * NS_PER_SEC, 1 /* uid */,
-                                              android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
-    StateManager::getInstance().onLogEvent(*uidProcessEvent);
-
-    ASSERT_EQ(5UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(4UL, valueProducer->mPastBuckets.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
-    // Base for dimension key {uid 2}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(15, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 2, BACKGROUND}.
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-
-    // Base for dimension key {uid 1}
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(13, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 1, kStateUnknown}
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {uid 1, BACKGROUND}
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {uid 1, FOREGROUND}
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(3, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 20 * NS_PER_SEC,
-                         bucket2StartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {uid 2, kStateUnknown}
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 40 * NS_PER_SEC);
-
-    // Bucket status after uid 1 process state change Background->Foreground.
-    uidProcessEvent =
-            CreateUidProcessStateChangedEvent(bucket2StartTimeNs + 40 * NS_PER_SEC, 1 /* uid */,
-                                              android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
-    StateManager::getInstance().onLogEvent(*uidProcessEvent);
-
-    ASSERT_EQ(5UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
-    // Base for dimension key {uid 2}
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(15, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 2, BACKGROUND}
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-
-    // Base for dimension key {uid 1}
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(17, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {uid 1, kStateUnknown}
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {uid 1, BACKGROUND}
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(4, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 20 * NS_PER_SEC,
-                         bucket2StartTimeNs + 40 * NS_PER_SEC);
-
-    // Value for key {uid 1, FOREGROUND}
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(3, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, true, 20 * NS_PER_SEC,
-                         bucket2StartTimeNs + 40 * NS_PER_SEC);
-
-    // Value for key {uid 2, kStateUnknown}
-    it++;
-    ASSERT_EQ(1, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 40 * NS_PER_SEC);
-
-    // Start dump report and check output.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 50 * NS_PER_SEC,
-                                true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
-                                &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(5, report.value_metrics().data_size());
-
-    // {uid 1, BACKGROUND}
-    auto data = report.value_metrics().data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(4, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {uid 2, kStateUnknown}
-    data = report.value_metrics().data(1);
-    ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
-    EXPECT_EQ(2, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, data.slice_by_state(0).value());
-    EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {uid 1, FOREGROUND}
-    data = report.value_metrics().data(2);
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(2, report.value_metrics().data(2).bucket_info_size());
-    EXPECT_EQ(4, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(7, report.value_metrics().data(2).bucket_info(1).values(0).value_long());
-    EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-    EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(1).condition_true_nanos());
-
-    // {uid 1, kStateUnknown}
-    data = report.value_metrics().data(3);
-    ASSERT_EQ(1, report.value_metrics().data(3).bucket_info_size());
-    EXPECT_EQ(3, report.value_metrics().data(3).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, data.slice_by_state(0).value());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {uid 2, BACKGROUND}
-    data = report.value_metrics().data(4);
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(2, report.value_metrics().data(4).bucket_info_size());
-    EXPECT_EQ(6, report.value_metrics().data(4).bucket_info(0).values(0).value_long());
-    EXPECT_EQ(5, report.value_metrics().data(4).bucket_info(1).values(0).value_long());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-    EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(1).condition_true_nanos());
-}
-
-/*
- * Test slicing condition_true_nanos by state for metric that slices by state when data is not
- * present in pulled data during a state change.
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithMissingDataInStateChange) {
-    // Set up ValueMetricProducer.
-    ValueMetric metric =
-            ValueMetricProducerTestHelper::createMetricWithState("BATTERY_SAVER_MODE_STATE");
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    /*
-    NOTE: "-" means that the data was not present in the pulled data.
-
-                             bucket # 1
-    10         20         30         40         50         60   (seconds)
-    |-------------------------------------------------------|--
-    x                                                           (kStateUnknown)
-    |-----------|
-         10
-
-                x                               x               (ON)
-                |---------------------|         |-----------|
-                           20                        10
-
-                                      -                         (OFF)
-    */
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // ValueMetricProducer initialized.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                return true;
-            }))
-            // Battery saver mode state changed to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10 * NS_PER_SEC, 5));
-                return true;
-            }))
-            // Battery saver mode state changed to OFF but data for dimension key {} is not present
-            // in the pulled data.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 30 * NS_PER_SEC);
-                data->clear();
-                return true;
-            }))
-            // Battery saver mode state changed to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 40 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 40 * NS_PER_SEC, 7));
-                return true;
-            }))
-            // Dump report pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucketStartTimeNs + 50 * NS_PER_SEC, 15));
-                return true;
-            }));
-
-    StateManager::getInstance().clear();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithState(
-                    pullerManager, metric, {util::BATTERY_SAVER_MODE_STATE_CHANGED}, {});
-    EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
-    // Set up StateManager and check that StateTrackers are initialized.
-    StateManager::getInstance().registerListener(util::BATTERY_SAVER_MODE_STATE_CHANGED,
-                                                 valueProducer);
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(
-                         util::BATTERY_SAVER_MODE_STATE_CHANGED));
-
-    // Bucket status after metric initialized.
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    auto it = valueProducer->mCurrentSlicedBucket.begin();
-    auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, kStateUnknown}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs);
-
-    // Bucket status after battery saver mode ON event.
-    unique_ptr<LogEvent> batterySaverOnEvent =
-            CreateBatterySaverOnEvent(/*timestamp=*/bucketStartTimeNs + 10 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOnEvent);
-
-    // Base for dimension key {}
-
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, ON}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 10 * NS_PER_SEC);
-
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 10 * NS_PER_SEC);
-
-    // Bucket status after battery saver mode OFF event which is not present
-    // in the pulled data.
-    unique_ptr<LogEvent> batterySaverOffEvent =
-            CreateBatterySaverOffEvent(/*timestamp=*/bucketStartTimeNs + 30 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOffEvent);
-
-    // Base for dimension key {}
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_FALSE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, ON}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 30 * NS_PER_SEC);
-
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 10 * NS_PER_SEC);
-
-    // Bucket status after battery saver mode ON event.
-    batterySaverOnEvent =
-            CreateBatterySaverOnEvent(/*timestamp=*/bucketStartTimeNs + 40 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOnEvent);
-
-    // Base for dimension key {}
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, ON}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 40 * NS_PER_SEC);
-
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 10 * NS_PER_SEC);
-
-    // Start dump report and check output.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucketStartTimeNs + 50 * NS_PER_SEC,
-                                true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
-                                &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(2, report.value_metrics().data_size());
-
-    // {{}, kStateUnknown}
-    ValueMetricData data = report.value_metrics().data(0);
-    EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {{}, ON}
-    data = report.value_metrics().data(1);
-    EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-}
-
-/*
- * Test for metric that slices by state when data is not present in pulled data
- * during an event and then a flush occurs for the current bucket. With the new
- * condition timer behavior, a "new" MetricDimensionKey is inserted into
- * `mCurrentSlicedBucket` before intervals are closed/added to that new
- * MetricDimensionKey.
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithMissingDataThenFlushBucket) {
-    // Set up ValueMetricProducer.
-    ValueMetric metric =
-            ValueMetricProducerTestHelper::createMetricWithState("BATTERY_SAVER_MODE_STATE");
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    /*
-    NOTE: "-" means that the data was not present in the pulled data.
-
-                             bucket # 1
-    10         20         30         40         50         60   (seconds)
-    |-------------------------------------------------------|--
-    -                                                           (kStateUnknown)
-
-                -                                               (ON)
-    */
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // ValueMetricProducer initialized  but data for dimension key {} is not present
-            // in the pulled data..
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                return true;
-            }))
-            // Battery saver mode state changed to ON but data for dimension key {} is not present
-            // in the pulled data.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10 * NS_PER_SEC);
-                data->clear();
-                return true;
-            }))
-            // Dump report pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucketStartTimeNs + 50 * NS_PER_SEC, 15));
-                return true;
-            }));
-
-    StateManager::getInstance().clear();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithState(
-                    pullerManager, metric, {util::BATTERY_SAVER_MODE_STATE_CHANGED}, {});
-    EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
-    // Set up StateManager and check that StateTrackers are initialized.
-    StateManager::getInstance().registerListener(util::BATTERY_SAVER_MODE_STATE_CHANGED,
-                                                 valueProducer);
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(
-                         util::BATTERY_SAVER_MODE_STATE_CHANGED));
-
-    // Bucket status after metric initialized.
-    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(0UL, valueProducer->mCurrentBaseInfo.size());
-
-    // Bucket status after battery saver mode ON event which is not present
-    // in the pulled data.
-    unique_ptr<LogEvent> batterySaverOnEvent =
-            CreateBatterySaverOnEvent(/*timestamp=*/bucketStartTimeNs + 10 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOnEvent);
-
-    ASSERT_EQ(0UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-
-    // Start dump report and check output.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucketStartTimeNs + 50 * NS_PER_SEC,
-                                true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
-                                &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-}
-
-TEST(ValueMetricProducerTest, TestSlicedStateWithNoPullOnBucketBoundary) {
-    // Set up ValueMetricProducer.
-    ValueMetric metric =
-            ValueMetricProducerTestHelper::createMetricWithState("BATTERY_SAVER_MODE_STATE");
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    /*
-                 bucket # 1                         bucket # 2
-    10    20    30    40    50    60    70    80   90   100   110   120  (seconds)
-    |------------------------------------|---------------------------|--
-    x                                                                    (kStateUnknown)
-    |-----|
-      10
-          x                                              x               (ON)
-          |-----|                                        |-----------|
-             10                                               20
-                x                                                        (OFF)
-                |------------------------|
-                          40
-    */
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // ValueMetricProducer initialized.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                return true;
-            }))
-            // Battery saver mode state changed to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10 * NS_PER_SEC, 5));
-                return true;
-            }))
-            // Battery saver mode state changed to OFF.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20 * NS_PER_SEC, 7));
-                return true;
-            }))
-            // Battery saver mode state changed to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 30 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucket2StartTimeNs + 30 * NS_PER_SEC, 10));
-                return true;
-            }))
-            // Dump report pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 50 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucket2StartTimeNs + 50 * NS_PER_SEC, 15));
-                return true;
-            }));
-
-    StateManager::getInstance().clear();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithState(
-                    pullerManager, metric, {util::BATTERY_SAVER_MODE_STATE_CHANGED}, {});
-    EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
-    // Set up StateManager and check that StateTrackers are initialized.
-    StateManager::getInstance().registerListener(util::BATTERY_SAVER_MODE_STATE_CHANGED,
-                                                 valueProducer);
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(
-                         util::BATTERY_SAVER_MODE_STATE_CHANGED));
-
-    // Bucket status after metric initialized.
-    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    auto it = valueProducer->mCurrentSlicedBucket.begin();
-    auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for dimension, state key {{}, kStateUnknown}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs);
-
-    // Bucket status after battery saver mode ON event.
-    unique_ptr<LogEvent> batterySaverOnEvent =
-            CreateBatterySaverOnEvent(/*timestamp=*/bucketStartTimeNs + 10 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOnEvent);
-
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, ON}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 10 * NS_PER_SEC);
-
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 10 * NS_PER_SEC);
-
-    // Bucket status after battery saver mode OFF event.
-    unique_ptr<LogEvent> batterySaverOffEvent =
-            CreateBatterySaverOffEvent(/*timestamp=*/bucketStartTimeNs + 20 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOffEvent);
-
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, OFF}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{}, ON}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 10 * NS_PER_SEC);
-
-    // Bucket status after battery saver mode ON event.
-    batterySaverOnEvent =
-            CreateBatterySaverOnEvent(/*timestamp=*/bucket2StartTimeNs + 30 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOnEvent);
-
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, OFF}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 30 * NS_PER_SEC,
-                         bucket2StartTimeNs + 30 * NS_PER_SEC);
-
-    // Value for key {{}, ON}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs + 30 * NS_PER_SEC);
-
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 10 * NS_PER_SEC);
-
-    // Start dump report and check output.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 50 * NS_PER_SEC,
-                                true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
-                                &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(3, report.value_metrics().data_size());
-
-    // {{}, kStateUnknown}
-    ValueMetricData data = report.value_metrics().data(0);
-    EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {{}, ON}
-    data = report.value_metrics().data(1);
-    EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON, data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(1).condition_true_nanos());
-
-    // {{}, OFF}
-    data = report.value_metrics().data(2);
-    EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-}
-
-/*
- * Test slicing condition_true_nanos by state for metric that slices by state when data is not
- * present in pulled data during a condition change.
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithDataMissingInConditionChange) {
-    // Set up ValueMetricProducer.
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithConditionAndState(
-            "BATTERY_SAVER_MODE_STATE");
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    /*
-    NOTE: "-" means that the data was not present in the pulled data.
-
-                             bucket # 1
-    10         20         30         40         50         60   (seconds)
-    |-------------------------------------------------------|--
-
-    T                                 F         T               (Condition)
-               x                                                (ON)
-               |----------------------|         -
-                         20
-    */
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Battery saver mode state changed to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10 * NS_PER_SEC, 3));
-                return true;
-            }))
-            // Condition changed to false.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 30 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30 * NS_PER_SEC, 5));
-                return true;
-            }))
-            // Condition changed to true but data for dimension key {} is not present in the
-            // pulled data.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 40 * NS_PER_SEC);
-                data->clear();
-                return true;
-            }))
-            // Dump report pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucketStartTimeNs + 50 * NS_PER_SEC, 20));
-                return true;
-            }));
-
-    StateManager::getInstance().clear();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithConditionAndState(
-                    pullerManager, metric, {util::BATTERY_SAVER_MODE_STATE_CHANGED}, {},
-                    ConditionState::kTrue);
-    EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
-    // Set up StateManager and check that StateTrackers are initialized.
-    StateManager::getInstance().registerListener(util::BATTERY_SAVER_MODE_STATE_CHANGED,
-                                                 valueProducer);
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(
-                         util::BATTERY_SAVER_MODE_STATE_CHANGED));
-
-    // Bucket status after battery saver mode ON event.
-    unique_ptr<LogEvent> batterySaverOnEvent =
-            CreateBatterySaverOnEvent(/*timestamp=*/bucketStartTimeNs + 10 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOnEvent);
-    // Base for dimension key {}
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    auto it = valueProducer->mCurrentSlicedBucket.begin();
-    auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, ON}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 10 * NS_PER_SEC);
-
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Bucket status after condition change to false.
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 30 * NS_PER_SEC);
-    // Base for dimension key {}
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, ON}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 30 * NS_PER_SEC);
-
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Bucket status after condition change to true.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 40 * NS_PER_SEC);
-    // Base for dimension key {}
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_FALSE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, ON}
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 30 * NS_PER_SEC);
-
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Start dump report and check output.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucketStartTimeNs + 50 * NS_PER_SEC,
-                                true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
-                                &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(1, report.value_metrics().data_size());
-
-    // {{}, ON}
-    ValueMetricData data = report.value_metrics().data(0);
-    EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-}
-
-/*
- * Test slicing condition_true_nanos by state for metric that slices by state with a primary field,
- * condition, and has multiple dimensions.
- */
-TEST(ValueMetricProducerTest, TestSlicedStateWithMultipleDimensions) {
-    // Set up ValueMetricProducer.
-    ValueMetric metric =
-            ValueMetricProducerTestHelper::createMetricWithConditionAndState("UID_PROCESS_STATE");
-    metric.mutable_dimensions_in_what()->set_field(tagId);
-    metric.mutable_dimensions_in_what()->add_child()->set_field(1);
-    metric.mutable_dimensions_in_what()->add_child()->set_field(3);
-
-    MetricStateLink* stateLink = metric.add_state_link();
-    stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
-    auto fieldsInWhat = stateLink->mutable_fields_in_what();
-    *fieldsInWhat = CreateDimensions(tagId, {1 /* uid */});
-    auto fieldsInState = stateLink->mutable_fields_in_state();
-    *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
-
-    /*
-                    bucket # 1                            bucket # 2
-    10     20     30     40     50     60     70     80     90    100    110    120 (seconds)
-    |------------------------------------------|---------------------------------|--
-
-    T                           F   T                                               (Condition)
-                                                                                    (FOREGROUND)
-           x                                                                        {1, 14}
-           |------|
-              10
-
-           x                                                                        {1, 16}
-           |------|
-              10
-                                                                   x                {2, 8}
-                                                                   |-------------|
-                                                                         20
-
-                                                                                    (BACKGROUND)
-                  x                                                                 {1, 14}
-                  |-------------|   |----------|---------------------------------|
-                        20              15                     50
-
-                  x                                                                 {1, 16}
-                  |-------------|   |----------|---------------------------------|
-                        20              15                     50
-
-                     x                                                              {2, 8}
-                     |----------|   |----------|-------------------|
-                         15             15              30
-    */
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Uid 1 process state change from kStateUnknown -> Foreground
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 10 * NS_PER_SEC,
-                                                         1 /*uid*/, 3, 14 /*tag*/));
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 10 * NS_PER_SEC,
-                                                         1 /*uid*/, 3, 16 /*tag*/));
-
-                // This event should be skipped.
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 10 * NS_PER_SEC,
-                                                         2 /*uid*/, 5, 8 /*tag*/));
-                return true;
-            }))
-            // Uid 1 process state change from Foreground -> Background
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 20 * NS_PER_SEC,
-                                                         1 /*uid*/, 5, 14 /*tag*/));
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 20 * NS_PER_SEC,
-                                                         1 /*uid*/, 5, 16 /*tag*/));
-
-                // This event should be skipped.
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 20 * NS_PER_SEC,
-                                                         2 /*uid*/, 7, 8 /*tag*/));
-
-                return true;
-            }))
-            // Uid 2 process state change from kStateUnknown -> Background
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 25 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 25 * NS_PER_SEC,
-                                                         2 /*uid*/, 9, 8 /*tag*/));
-
-                // This event should be skipped.
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 25 * NS_PER_SEC,
-                                                         1 /*uid*/, 9, 14 /* tag */));
-
-                // This event should be skipped.
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 25 * NS_PER_SEC,
-                                                         1 /*uid*/, 9, 16 /* tag */));
-
-                return true;
-            }))
-            // Condition changed to false.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 40 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 40 * NS_PER_SEC,
-                                                         1 /*uid*/, 11, 14 /* tag */));
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 40 * NS_PER_SEC,
-                                                         1 /*uid*/, 11, 16 /* tag */));
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 40 * NS_PER_SEC,
-                                                         2 /*uid*/, 11, 8 /*tag*/));
-
-                return true;
-            }))
-            // Condition changed to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 45 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 45 * NS_PER_SEC,
-                                                         1 /*uid*/, 13, 14 /* tag */));
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 45 * NS_PER_SEC,
-                                                         1 /*uid*/, 13, 16 /* tag */));
-                data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 45 * NS_PER_SEC,
-                                                         2 /*uid*/, 13, 8 /*tag*/));
-                return true;
-            }))
-            // Uid 2 process state change from Background -> Foreground
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 30 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(
-                        tagId, bucket2StartTimeNs + 30 * NS_PER_SEC, 2 /*uid*/, 18, 8 /*tag*/));
-
-                // This event should be skipped.
-                data->push_back(CreateThreeValueLogEvent(
-                        tagId, bucket2StartTimeNs + 30 * NS_PER_SEC, 1 /*uid*/, 18, 14 /* tag */));
-                // This event should be skipped.
-                data->push_back(CreateThreeValueLogEvent(
-                        tagId, bucket2StartTimeNs + 30 * NS_PER_SEC, 1 /*uid*/, 18, 16 /* tag */));
-
-                return true;
-            }))
-            // Dump report pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 50 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateThreeValueLogEvent(
-                        tagId, bucket2StartTimeNs + 50 * NS_PER_SEC, 1 /*uid*/, 21, 14 /* tag */));
-                data->push_back(CreateThreeValueLogEvent(
-                        tagId, bucket2StartTimeNs + 50 * NS_PER_SEC, 1 /*uid*/, 21, 16 /* tag */));
-                data->push_back(CreateThreeValueLogEvent(
-                        tagId, bucket2StartTimeNs + 50 * NS_PER_SEC, 2 /*uid*/, 21, 8 /*tag*/));
-                return true;
-            }));
-
-    StateManager::getInstance().clear();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithConditionAndState(
-                    pullerManager, metric, {UID_PROCESS_STATE_ATOM_ID}, {}, ConditionState::kTrue);
-    EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
-    // Set up StateManager and check that StateTrackers are initialized.
-    StateManager::getInstance().registerListener(UID_PROCESS_STATE_ATOM_ID, valueProducer);
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
-
-    // Condition is true.
-    // Bucket status after uid 1 process state change kStateUnknown -> Foreground.
-    auto uidProcessEvent =
-            CreateUidProcessStateChangedEvent(bucketStartTimeNs + 10 * NS_PER_SEC, 1 /* uid */,
-                                              android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
-    StateManager::getInstance().onLogEvent(*uidProcessEvent);
-    ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension {uid 1, tag 16}.
-    auto it = valueProducer->mCurrentSlicedBucket.begin();
-    auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, uid 16}, FOREGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 10 * NS_PER_SEC);
-    // Value for key {{uid 1, tag 16}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Base for dimension key {uid 1, tag 14}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, tag 14}, FOREGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 10 * NS_PER_SEC);
-    // Value for key {{uid 1, tag 14}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Bucket status after uid 1 process state change Foreground -> Background.
-    uidProcessEvent =
-            CreateUidProcessStateChangedEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /* uid */,
-                                              android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
-    StateManager::getInstance().onLogEvent(*uidProcessEvent);
-    ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(6UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension {uid 1, tag 16}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, uid 16}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Base for dimension key {uid 1, tag 14}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, tag 14}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, uid 16}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 16}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Value for key {{uid 1, tag 14}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 14}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Bucket status after uid 2 process state change kStateUnknown -> Background.
-    uidProcessEvent =
-            CreateUidProcessStateChangedEvent(bucketStartTimeNs + 25 * NS_PER_SEC, 2 /* uid */,
-                                              android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
-    StateManager::getInstance().onLogEvent(*uidProcessEvent);
-    ASSERT_EQ(3UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(8UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension {uid 2, tag 8}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 2, uid 8}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 25 * NS_PER_SEC);
-
-    // Value for key {{uid 2, uid 8}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Base for dimension {uid 1, tag 16}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, uid 16}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Base for dimension key {uid 1, tag 14}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, tag 14}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, uid 16}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 16}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Value for key {{uid 1, tag 14}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 14}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Bucket 1 status after condition change to false.
-    // All condition timers should be turned off.
-    valueProducer->onConditionChanged(false, bucketStartTimeNs + 40 * NS_PER_SEC);
-    ASSERT_EQ(3UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(8UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension {uid 2, tag 8}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 2, uid 8}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 15 * NS_PER_SEC,
-                         bucketStartTimeNs + 40 * NS_PER_SEC);
-
-    // Value for key {{uid 2, uid 8}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Base for dimension {uid 1, tag 16}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, uid 16}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 40 * NS_PER_SEC);
-
-    // Base for dimension key {uid 1, tag 14}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, tag 14}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 40 * NS_PER_SEC);
-
-    // Value for key {{uid 1, uid 16}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 16}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Value for key {{uid 1, tag 14}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 14}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Bucket 1 status after condition change to true.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 45 * NS_PER_SEC);
-    ASSERT_EQ(3UL, valueProducer->mCurrentBaseInfo.size());
-    ASSERT_EQ(8UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension {uid 2, tag 8}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 2, uid 8}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 15 * NS_PER_SEC,
-                         bucketStartTimeNs + 45 * NS_PER_SEC);
-
-    // Value for key {{uid 2, uid 8}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Base for dimension {uid 1, tag 16}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, uid 16}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 45 * NS_PER_SEC);
-
-    // Base for dimension key {uid 1, tag 14}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, tag 14}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 20 * NS_PER_SEC,
-                         bucketStartTimeNs + 45 * NS_PER_SEC);
-
-    // Value for key {{uid 1, uid 16}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 16}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Value for key {{uid 1, tag 14}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 14}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Pull at end of first bucket.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.push_back(
-            CreateThreeValueLogEvent(tagId, bucket2StartTimeNs, 1 /*uid*/, 13, 14 /* tag */));
-    allData.push_back(
-            CreateThreeValueLogEvent(tagId, bucket2StartTimeNs, 1 /*uid*/, 13, 16 /* tag */));
-    allData.push_back(
-            CreateThreeValueLogEvent(tagId, bucket2StartTimeNs, 2 /*uid*/, 13, 8 /*tag*/));
-    valueProducer->onDataPulled(allData, /** succeeds */ true, bucket2StartTimeNs + 1);
-
-    // Buckets flushed after end of first bucket.
-    // All condition timers' behavior should rollover to bucket 2.
-    ASSERT_EQ(8UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(5UL, valueProducer->mPastBuckets.size());
-    ASSERT_EQ(3UL, valueProducer->mCurrentBaseInfo.size());
-    // Base for dimension {uid 2, tag 8}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 2, uid 8}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-    ASSERT_EQ(1, valueProducer->mPastBuckets[it->first].size());
-    EXPECT_EQ(30 * NS_PER_SEC, valueProducer->mPastBuckets[it->first][0].mConditionTrueNs);
-
-    // Value for key {{uid 2, uid 8}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Base for dimension {uid 1, tag 16}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, uid 16}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-    ASSERT_EQ(1, valueProducer->mPastBuckets[it->first].size());
-    EXPECT_EQ(35 * NS_PER_SEC, valueProducer->mPastBuckets[it->first][0].mConditionTrueNs);
-
-    // Base for dimension key {uid 1, tag 14}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, tag 14}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-    ASSERT_EQ(1, valueProducer->mPastBuckets[it->first].size());
-    EXPECT_EQ(35 * NS_PER_SEC, valueProducer->mPastBuckets[it->first][0].mConditionTrueNs);
-
-    // Value for key {{uid 1, uid 16}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-    ASSERT_EQ(1, valueProducer->mPastBuckets[it->first].size());
-    EXPECT_EQ(10 * NS_PER_SEC, valueProducer->mPastBuckets[it->first][0].mConditionTrueNs);
-
-    // Value for key {{uid 1, tag 16}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Value for key {{uid 1, tag 14}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-    ASSERT_EQ(1, valueProducer->mPastBuckets[it->first].size());
-    EXPECT_EQ(10 * NS_PER_SEC, valueProducer->mPastBuckets[it->first][0].mConditionTrueNs);
-
-    // Value for key {{uid 1, tag 14}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Bucket 2 status after uid 2 process state change Background->Foreground.
-    uidProcessEvent =
-            CreateUidProcessStateChangedEvent(bucket2StartTimeNs + 30 * NS_PER_SEC, 2 /* uid */,
-                                              android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
-    StateManager::getInstance().onLogEvent(*uidProcessEvent);
-
-    ASSERT_EQ(9UL, valueProducer->mCurrentSlicedBucket.size());
-    ASSERT_EQ(3UL, valueProducer->mCurrentBaseInfo.size());
-    // Base for dimension {uid 2, tag 8}.
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 2, uid 8}, FOREGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs + 30 * NS_PER_SEC);
-
-    // Value for key {{uid 2, uid 8}, BACKGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 30 * NS_PER_SEC,
-                         bucket2StartTimeNs + 30 * NS_PER_SEC);
-
-    // Value for key {{uid 2, uid 8}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(8, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Base for dimension {uid 1, tag 16}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, uid 16}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-
-    // Base for dimension key {uid 1, tag 14}.
-    it++;
-    itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{uid 1, tag 14}, BACKGROUND}.
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-
-    // Value for key {{uid 1, uid 16}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 16}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(16, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Value for key {{uid 1, tag 14}, FOREGROUND}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-
-    // Value for key {{uid 1, tag 14}, kStateUnknown}.
-    it++;
-    ASSERT_EQ(2, it->first.getDimensionKeyInWhat().getValues().size());
-    EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
-    EXPECT_EQ(14, it->first.getDimensionKeyInWhat().getValues()[1].mValue.int_value);
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /* StateTracker::kStateUnknown */,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Start dump report and check output.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 50 * NS_PER_SEC,
-                                true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
-                                &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(6, report.value_metrics().data_size());
-
-    // {{uid 1, tag 14}, FOREGROUND}.
-    auto data = report.value_metrics().data(0);
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {{uid 1, tag 16}, BACKGROUND}.
-    data = report.value_metrics().data(1);
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(35 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-    EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(1).condition_true_nanos());
-
-    // {{uid 1, tag 14}, BACKGROUND}.
-    data = report.value_metrics().data(2);
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(35 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-    EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(1).condition_true_nanos());
-
-    // {{uid 1, tag 16}, FOREGROUND}.
-    data = report.value_metrics().data(3);
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {{uid 2, tag 8}, FOREGROUND}.
-    data = report.value_metrics().data(4);
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    // {{uid 2, tag 8}, BACKGROUND}.
-    data = report.value_metrics().data(5);
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-    EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(1).condition_true_nanos());
-}
-
-TEST(ValueMetricProducerTest, TestSlicedStateWithCondition) {
-    // Set up ValueMetricProducer.
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithConditionAndState(
-            "BATTERY_SAVER_MODE_STATE");
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // Condition changed to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20 * NS_PER_SEC, 3));
-                return true;
-            }))
-            // Battery saver mode state changed to OFF.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 30 * NS_PER_SEC);
-                data->clear();
-                data->push_back(
-                        CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30 * NS_PER_SEC, 5));
-                return true;
-            }))
-            // Condition changed to false.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
-                                vector<std::shared_ptr<LogEvent>>* data) {
-                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10 * NS_PER_SEC);
-                data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(
-                        tagId, bucket2StartTimeNs + 10 * NS_PER_SEC, 15));
-                return true;
-            }));
-
-    StateManager::getInstance().clear();
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithConditionAndState(
-                    pullerManager, metric, {util::BATTERY_SAVER_MODE_STATE_CHANGED}, {},
-                    ConditionState::kFalse);
-    EXPECT_EQ(1, valueProducer->mSlicedStateAtoms.size());
-
-    // Set up StateManager and check that StateTrackers are initialized.
-    StateManager::getInstance().registerListener(util::BATTERY_SAVER_MODE_STATE_CHANGED,
-                                                 valueProducer);
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getListenersCount(
-                         util::BATTERY_SAVER_MODE_STATE_CHANGED));
-
-    // Bucket status after battery saver mode ON event.
-    // Condition is false so we do nothing.
-    unique_ptr<LogEvent> batterySaverOnEvent =
-            CreateBatterySaverOnEvent(/*timestamp=*/bucketStartTimeNs + 10 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOnEvent);
-    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(0UL, valueProducer->mCurrentBaseInfo.size());
-
-    // Bucket status after condition change to true.
-    valueProducer->onConditionChanged(true, bucketStartTimeNs + 20 * NS_PER_SEC);
-    // Base for dimension key {}
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    std::unordered_map<HashableDimensionKey, ValueMetricProducer::DimensionsInWhatInfo>::iterator
-            itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(3, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, ON}
-    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
-    std::unordered_map<MetricDimensionKey, ValueMetricProducer::CurrentValueBucket>::iterator it =
-            valueProducer->mCurrentSlicedBucket.begin();
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 20 * NS_PER_SEC);
-    // Value for key {{}, -1}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(-1 /*StateTracker::kUnknown*/,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Bucket status after battery saver mode OFF event.
-    unique_ptr<LogEvent> batterySaverOffEvent =
-            CreateBatterySaverOffEvent(/*timestamp=*/bucketStartTimeNs + 30 * NS_PER_SEC);
-    StateManager::getInstance().onLogEvent(*batterySaverOffEvent);
-    // Base for dimension key {}
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(5, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, OFF}
-    ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucketStartTimeNs + 30 * NS_PER_SEC);
-    // Value for key {{}, ON}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(2, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucketStartTimeNs + 30 * NS_PER_SEC);
-    // Value for key {{}, -1}
-    it++;
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Pull at end of first bucket.
-    vector<shared_ptr<LogEvent>> allData;
-    allData.clear();
-    allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 11));
-    valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-
-    EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
-    // Base for dimension key {}
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
-    EXPECT_TRUE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_EQ(11, itBase->second.baseInfos[0].base.long_value);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, OFF}
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    assertConditionTimer(it->second.conditionTimer, true, 0, bucket2StartTimeNs);
-    // Value for key {{}, ON}
-    it++;
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 30 * NS_PER_SEC);
-    // Value for key {{}, -1}
-    it++;
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Bucket 2 status after condition change to false.
-    valueProducer->onConditionChanged(false, bucket2StartTimeNs + 10 * NS_PER_SEC);
-    // Base for dimension key {}
-    ASSERT_EQ(1UL, valueProducer->mCurrentBaseInfo.size());
-    itBase = valueProducer->mCurrentBaseInfo.find(DEFAULT_DIMENSION_KEY);
-    EXPECT_FALSE(itBase->second.baseInfos[0].hasBase);
-    EXPECT_TRUE(itBase->second.hasCurrentState);
-    ASSERT_EQ(1, itBase->second.currentState.getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF,
-              itBase->second.currentState.getValues()[0].mValue.int_value);
-    // Value for key {{}, OFF}
-    ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
-    it = valueProducer->mCurrentSlicedBucket.begin();
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_TRUE(it->second.intervals[0].hasValue);
-    EXPECT_EQ(4, it->second.intervals[0].value.long_value);
-    assertConditionTimer(it->second.conditionTimer, false, 10 * NS_PER_SEC,
-                         bucket2StartTimeNs + 10 * NS_PER_SEC);
-    // Value for key {{}, ON}
-    it++;
-    EXPECT_EQ(0, it->first.getDimensionKeyInWhat().getValues().size());
-    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON,
-              it->first.getStateValuesKey().getValues()[0].mValue.int_value);
-    EXPECT_FALSE(it->second.intervals[0].hasValue);
-    assertConditionTimer(it->second.conditionTimer, false, 0, bucketStartTimeNs + 30 * NS_PER_SEC);
-    // Value for key {{}, -1}
-    it++;
-    assertConditionTimer(it->second.conditionTimer, false, 0, 0);
-
-    // Start dump report and check output.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    valueProducer->onDumpReport(bucket2StartTimeNs + 50 * NS_PER_SEC,
-                                true /* include recent buckets */, true, NO_TIME_CONSTRAINTS,
-                                &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(2, report.value_metrics().data_size());
-
-    ValueMetricData data = report.value_metrics().data(0);
-    EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(BatterySaverModeStateChanged::ON, data.slice_by_state(0).value());
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(2, data.bucket_info(0).values(0).value_long());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-
-    data = report.value_metrics().data(1);
-    EXPECT_EQ(util::BATTERY_SAVER_MODE_STATE_CHANGED, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(BatterySaverModeStateChanged::OFF, data.slice_by_state(0).value());
-    ASSERT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(6, data.bucket_info(0).values(0).value_long());
-    EXPECT_EQ(4, data.bucket_info(1).values(0).value_long());
-    EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(0).condition_true_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(1).condition_true_nanos());
-}
-
-/*
- * Test bucket splits when condition is unknown.
- */
-TEST(ValueMetricProducerTest, TestForcedBucketSplitWhenConditionUnknownSkipsBucket) {
-    ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-
-    sp<ValueMetricProducer> valueProducer =
-            ValueMetricProducerTestHelper::createValueProducerWithCondition(
-                    pullerManager, metric,
-                    ConditionState::kUnknown);
-
-    // App update event.
-    int64_t appUpdateTimeNs = bucketStartTimeNs + 1000;
-    valueProducer->notifyAppUpgrade(appUpdateTimeNs);
-
-    // Check dump report.
-    ProtoOutputStream output;
-    std::set<string> strSet;
-    int64_t dumpReportTimeNs = bucketStartTimeNs + 10000000000; // 10 seconds
-    valueProducer->onDumpReport(dumpReportTimeNs, false /* include current buckets */, true,
-                                NO_TIME_CONSTRAINTS /* dumpLatency */, &strSet, &output);
-
-    StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_TRUE(report.has_value_metrics());
-    ASSERT_EQ(0, report.value_metrics().data_size());
-    ASSERT_EQ(1, report.value_metrics().skipped_size());
-
-    EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
-              report.value_metrics().skipped(0).start_bucket_elapsed_millis());
-    EXPECT_EQ(NanoToMillis(appUpdateTimeNs),
-              report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
-
-    auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
-    EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
-    EXPECT_EQ(NanoToMillis(appUpdateTimeNs), dropEvent.drop_time_millis());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.cpp b/cmds/statsd/tests/metrics/metrics_test_helper.cpp
deleted file mode 100644
index 108df04b..0000000
--- a/cmds/statsd/tests/metrics/metrics_test_helper.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (C) 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.
-
-#include "metrics_test_helper.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-HashableDimensionKey getMockedDimensionKey(int tagId, int key, string value) {
-    HashableDimensionKey dimension;
-    int pos[] = {key, 0, 0};
-    dimension.addValue(FieldValue(Field(tagId, pos, 0), Value(value)));
-
-    return dimension;
-}
-
-HashableDimensionKey getMockedDimensionKeyLongValue(int tagId, int key, int64_t value) {
-    HashableDimensionKey dimension;
-    int pos[] = {key, 0, 0};
-    dimension.addValue(FieldValue(Field(tagId, pos, 0), Value(value)));
-
-    return dimension;
-}
-
-MetricDimensionKey getMockedMetricDimensionKey(int tagId, int key, string value) {
-    return MetricDimensionKey(getMockedDimensionKey(tagId, key, value), DEFAULT_DIMENSION_KEY);
-}
-
-MetricDimensionKey getMockedStateDimensionKey(int tagId, int key, int64_t value) {
-    return MetricDimensionKey(DEFAULT_DIMENSION_KEY,
-                              getMockedDimensionKeyLongValue(tagId, key, value));
-}
-
-void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher) {
-    matcher->set_field(tagId);
-}
-
-void buildSimpleAtomFieldMatcher(const int tagId, const int fieldNum, FieldMatcher* matcher) {
-    matcher->set_field(tagId);
-    matcher->add_child()->set_field(fieldNum);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
deleted file mode 100644
index 39232c1..0000000
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 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.
-#pragma once
-
-#include "src/condition/ConditionWizard.h"
-#include "src/external/StatsPullerManager.h"
-#include "src/packages/UidMap.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class MockConditionWizard : public ConditionWizard {
-public:
-    MOCK_METHOD3(query,
-                 ConditionState(const int conditionIndex, const ConditionKey& conditionParameters,
-                                const bool isPartialLink));
-};
-
-class MockStatsPullerManager : public StatsPullerManager {
-public:
-    MOCK_METHOD5(RegisterReceiver,
-                 void(int tagId, const ConfigKey& key, wp<PullDataReceiver> receiver,
-                      int64_t nextPulltimeNs, int64_t intervalNs));
-    MOCK_METHOD3(UnRegisterReceiver,
-                 void(int tagId, const ConfigKey& key, wp<PullDataReceiver> receiver));
-    MOCK_METHOD4(Pull, bool(const int pullCode, const ConfigKey& key, const int64_t eventTimeNs,
-                            vector<std::shared_ptr<LogEvent>>* data));
-    MOCK_METHOD4(Pull, bool(const int pullCode, const vector<int32_t>& uids,
-                            const int64_t eventTimeNs, vector<std::shared_ptr<LogEvent>>* data));
-    MOCK_METHOD2(RegisterPullUidProvider,
-                 void(const ConfigKey& configKey, wp<PullUidProvider> provider));
-    MOCK_METHOD2(UnregisterPullUidProvider,
-                 void(const ConfigKey& configKey, wp<PullUidProvider> provider));
-};
-
-HashableDimensionKey getMockedDimensionKey(int tagId, int key, std::string value);
-MetricDimensionKey getMockedMetricDimensionKey(int tagId, int key, std::string value);
-
-HashableDimensionKey getMockedDimensionKeyLongValue(int tagId, int key, int64_t value);
-MetricDimensionKey getMockedStateDimensionKey(int tagId, int key, int64_t value);
-
-// Utils to build FieldMatcher proto for simple one-depth atoms.
-void buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum, FieldMatcher* matcher);
-void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
deleted file mode 100644
index d78c14c..0000000
--- a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
+++ /dev/null
@@ -1,3632 +0,0 @@
-// Copyright (C) 2020 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.
-
-#include "src/metrics/parsing_utils/config_update_utils.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-#include <stdio.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "src/condition/CombinationConditionTracker.h"
-#include "src/condition/SimpleConditionTracker.h"
-#include "src/matchers/CombinationAtomMatchingTracker.h"
-#include "src/metrics/DurationMetricProducer.h"
-#include "src/metrics/GaugeMetricProducer.h"
-#include "src/metrics/ValueMetricProducer.h"
-#include "src/metrics/parsing_utils/metrics_manager_util.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using android::os::statsd::Predicate;
-using std::map;
-using std::nullopt;
-using std::optional;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-
-ConfigKey key(123, 456);
-const int64_t timeBaseNs = 1000 * NS_PER_SEC;
-
-sp<UidMap> uidMap = new UidMap();
-sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-sp<AlarmMonitor> anomalyAlarmMonitor;
-sp<AlarmMonitor> periodicAlarmMonitor = new AlarmMonitor(
-        /*minDiffToUpdateRegisteredAlarmTimeSec=*/0,
-        [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
-        [](const shared_ptr<IStatsCompanionService>&) {});
-set<int> allTagIds;
-vector<sp<AtomMatchingTracker>> oldAtomMatchingTrackers;
-unordered_map<int64_t, int> oldAtomMatchingTrackerMap;
-vector<sp<ConditionTracker>> oldConditionTrackers;
-unordered_map<int64_t, int> oldConditionTrackerMap;
-vector<sp<MetricProducer>> oldMetricProducers;
-unordered_map<int64_t, int> oldMetricProducerMap;
-std::vector<sp<AnomalyTracker>> oldAnomalyTrackers;
-unordered_map<int64_t, int> oldAlertTrackerMap;
-std::vector<sp<AlarmTracker>> oldAlarmTrackers;
-unordered_map<int, std::vector<int>> tmpConditionToMetricMap;
-unordered_map<int, std::vector<int>> tmpTrackerToMetricMap;
-unordered_map<int, std::vector<int>> tmpTrackerToConditionMap;
-unordered_map<int, std::vector<int>> tmpActivationAtomTrackerToMetricMap;
-unordered_map<int, std::vector<int>> tmpDeactivationAtomTrackerToMetricMap;
-vector<int> metricsWithActivation;
-map<int64_t, uint64_t> oldStateHashes;
-std::set<int64_t> noReportMetricIds;
-
-class ConfigUpdateTest : public ::testing::Test {
-public:
-    ConfigUpdateTest() {
-    }
-
-    void SetUp() override {
-        allTagIds.clear();
-        oldAtomMatchingTrackers.clear();
-        oldAtomMatchingTrackerMap.clear();
-        oldConditionTrackers.clear();
-        oldConditionTrackerMap.clear();
-        oldMetricProducers.clear();
-        oldMetricProducerMap.clear();
-        oldAnomalyTrackers.clear();
-        oldAlarmTrackers.clear();
-        tmpConditionToMetricMap.clear();
-        tmpTrackerToMetricMap.clear();
-        tmpTrackerToConditionMap.clear();
-        tmpActivationAtomTrackerToMetricMap.clear();
-        tmpDeactivationAtomTrackerToMetricMap.clear();
-        oldAlertTrackerMap.clear();
-        metricsWithActivation.clear();
-        oldStateHashes.clear();
-        noReportMetricIds.clear();
-        StateManager::getInstance().clear();
-    }
-};
-
-bool initConfig(const StatsdConfig& config) {
-    return initStatsdConfig(
-            key, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseNs, timeBaseNs, allTagIds, oldAtomMatchingTrackers, oldAtomMatchingTrackerMap,
-            oldConditionTrackers, oldConditionTrackerMap, oldMetricProducers, oldMetricProducerMap,
-            oldAnomalyTrackers, oldAlarmTrackers, tmpConditionToMetricMap, tmpTrackerToMetricMap,
-            tmpTrackerToConditionMap, tmpActivationAtomTrackerToMetricMap,
-            tmpDeactivationAtomTrackerToMetricMap, oldAlertTrackerMap, metricsWithActivation,
-            oldStateHashes, noReportMetricIds);
-}
-
-EventMetric createEventMetric(string name, int64_t what, optional<int64_t> condition) {
-    EventMetric metric;
-    metric.set_id(StringToId(name));
-    metric.set_what(what);
-    if (condition) {
-        metric.set_condition(condition.value());
-    }
-    return metric;
-}
-
-CountMetric createCountMetric(string name, int64_t what, optional<int64_t> condition,
-                              vector<int64_t> states) {
-    CountMetric metric;
-    metric.set_id(StringToId(name));
-    metric.set_what(what);
-    metric.set_bucket(TEN_MINUTES);
-    if (condition) {
-        metric.set_condition(condition.value());
-    }
-    for (const int64_t state : states) {
-        metric.add_slice_by_state(state);
-    }
-    return metric;
-}
-
-GaugeMetric createGaugeMetric(string name, int64_t what, GaugeMetric::SamplingType samplingType,
-                              optional<int64_t> condition, optional<int64_t> triggerEvent) {
-    GaugeMetric metric;
-    metric.set_id(StringToId(name));
-    metric.set_what(what);
-    metric.set_bucket(TEN_MINUTES);
-    metric.set_sampling_type(samplingType);
-    if (condition) {
-        metric.set_condition(condition.value());
-    }
-    if (triggerEvent) {
-        metric.set_trigger_event(triggerEvent.value());
-    }
-    metric.mutable_gauge_fields_filter()->set_include_all(true);
-    return metric;
-}
-
-DurationMetric createDurationMetric(string name, int64_t what, optional<int64_t> condition,
-                                    vector<int64_t> states) {
-    DurationMetric metric;
-    metric.set_id(StringToId(name));
-    metric.set_what(what);
-    metric.set_bucket(TEN_MINUTES);
-    if (condition) {
-        metric.set_condition(condition.value());
-    }
-    for (const int64_t state : states) {
-        metric.add_slice_by_state(state);
-    }
-    return metric;
-}
-
-ValueMetric createValueMetric(string name, const AtomMatcher& what, optional<int64_t> condition,
-                              vector<int64_t> states) {
-    ValueMetric metric;
-    metric.set_id(StringToId(name));
-    metric.set_what(what.id());
-    metric.set_bucket(TEN_MINUTES);
-    metric.mutable_value_field()->set_field(what.simple_atom_matcher().atom_id());
-    metric.mutable_value_field()->add_child()->set_field(2);
-    if (condition) {
-        metric.set_condition(condition.value());
-    }
-    for (const int64_t state : states) {
-        metric.add_slice_by_state(state);
-    }
-    return metric;
-}
-
-Alert createAlert(string name, int64_t metricId, int buckets, int64_t triggerSum) {
-    Alert alert;
-    alert.set_id(StringToId(name));
-    alert.set_metric_id(metricId);
-    alert.set_num_buckets(buckets);
-    alert.set_trigger_if_sum_gt(triggerSum);
-    return alert;
-}
-
-Subscription createSubscription(string name, Subscription_RuleType type, int64_t ruleId) {
-    Subscription subscription;
-    subscription.set_id(StringToId(name));
-    subscription.set_rule_type(type);
-    subscription.set_rule_id(ruleId);
-    subscription.mutable_broadcast_subscriber_details();
-    return subscription;
-}
-
-Alarm createAlarm(string name, int64_t offsetMillis, int64_t periodMillis) {
-    Alarm alarm;
-    alarm.set_id(StringToId(name));
-    alarm.set_offset_millis(offsetMillis);
-    alarm.set_period_millis(periodMillis);
-    return alarm;
-}
-}  // anonymous namespace
-
-TEST_F(ConfigUpdateTest, TestSimpleMatcherPreserve) {
-    StatsdConfig config;
-    AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
-    int64_t matcherId = matcher.id();
-    *config.add_atom_matcher() = matcher;
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(1, false);
-    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    newAtomMatchingTrackerMap[matcherId] = 0;
-    EXPECT_TRUE(determineMatcherUpdateStatus(config, 0, oldAtomMatchingTrackerMap,
-                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                             matchersToUpdate, cycleTracker));
-    EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestSimpleMatcherReplace) {
-    StatsdConfig config;
-    AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
-    *config.add_atom_matcher() = matcher;
-
-    EXPECT_TRUE(initConfig(config));
-
-    StatsdConfig newConfig;
-    // Same id, different atom, so should be replaced.
-    AtomMatcher newMatcher = CreateSimpleAtomMatcher("TEST", /*atom=*/11);
-    int64_t matcherId = newMatcher.id();
-    EXPECT_EQ(matcherId, matcher.id());
-    *newConfig.add_atom_matcher() = newMatcher;
-
-    vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(1, false);
-    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    newAtomMatchingTrackerMap[matcherId] = 0;
-    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 0, oldAtomMatchingTrackerMap,
-                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                             matchersToUpdate, cycleTracker));
-    EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestSimpleMatcherNew) {
-    StatsdConfig config;
-    AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
-    *config.add_atom_matcher() = matcher;
-
-    EXPECT_TRUE(initConfig(config));
-
-    StatsdConfig newConfig;
-    // Different id, so should be a new matcher.
-    AtomMatcher newMatcher = CreateSimpleAtomMatcher("DIFFERENT_NAME", /*atom=*/10);
-    int64_t matcherId = newMatcher.id();
-    EXPECT_NE(matcherId, matcher.id());
-    *newConfig.add_atom_matcher() = newMatcher;
-
-    vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(1, false);
-    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    newAtomMatchingTrackerMap[matcherId] = 0;
-    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 0, oldAtomMatchingTrackerMap,
-                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                             matchersToUpdate, cycleTracker));
-    EXPECT_EQ(matchersToUpdate[0], UPDATE_NEW);
-}
-
-TEST_F(ConfigUpdateTest, TestCombinationMatcherPreserve) {
-    StatsdConfig config;
-    AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
-    *config.add_atom_matcher() = matcher2;
-    int64_t matcher2Id = matcher2.id();
-
-    AtomMatcher matcher3;
-    matcher3.set_id(StringToId("TEST3"));
-    AtomMatcher_Combination* combination = matcher3.mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_matcher(matcher1Id);
-    combination->add_matcher(matcher2Id);
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    EXPECT_TRUE(initConfig(config));
-
-    StatsdConfig newConfig;
-    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    // Same matchers, different order, all should be preserved.
-    *newConfig.add_atom_matcher() = matcher2;
-    newAtomMatchingTrackerMap[matcher2Id] = 0;
-    *newConfig.add_atom_matcher() = matcher3;
-    newAtomMatchingTrackerMap[matcher3Id] = 1;
-    *newConfig.add_atom_matcher() = matcher1;
-    newAtomMatchingTrackerMap[matcher1Id] = 2;
-
-    vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(3, false);
-    // Only update the combination. It should recurse the two child matchers and preserve all 3.
-    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
-                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                             matchersToUpdate, cycleTracker));
-    EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
-    EXPECT_EQ(matchersToUpdate[1], UPDATE_PRESERVE);
-    EXPECT_EQ(matchersToUpdate[2], UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestCombinationMatcherReplace) {
-    StatsdConfig config;
-    AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
-    *config.add_atom_matcher() = matcher2;
-    int64_t matcher2Id = matcher2.id();
-
-    AtomMatcher matcher3;
-    matcher3.set_id(StringToId("TEST3"));
-    AtomMatcher_Combination* combination = matcher3.mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_matcher(matcher1Id);
-    combination->add_matcher(matcher2Id);
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Change the logical operation of the combination matcher, causing a replacement.
-    matcher3.mutable_combination()->set_operation(LogicalOperation::AND);
-
-    StatsdConfig newConfig;
-    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    *newConfig.add_atom_matcher() = matcher2;
-    newAtomMatchingTrackerMap[matcher2Id] = 0;
-    *newConfig.add_atom_matcher() = matcher3;
-    newAtomMatchingTrackerMap[matcher3Id] = 1;
-    *newConfig.add_atom_matcher() = matcher1;
-    newAtomMatchingTrackerMap[matcher1Id] = 2;
-
-    vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(3, false);
-    // Only update the combination. The simple matchers should not be evaluated.
-    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
-                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                             matchersToUpdate, cycleTracker));
-    EXPECT_EQ(matchersToUpdate[0], UPDATE_UNKNOWN);
-    EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
-    EXPECT_EQ(matchersToUpdate[2], UPDATE_UNKNOWN);
-}
-
-TEST_F(ConfigUpdateTest, TestCombinationMatcherDepsChange) {
-    StatsdConfig config;
-    AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
-    *config.add_atom_matcher() = matcher2;
-    int64_t matcher2Id = matcher2.id();
-
-    AtomMatcher matcher3;
-    matcher3.set_id(StringToId("TEST3"));
-    AtomMatcher_Combination* combination = matcher3.mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_matcher(matcher1Id);
-    combination->add_matcher(matcher2Id);
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Change a dependency of matcher 3.
-    matcher2.mutable_simple_atom_matcher()->set_atom_id(12);
-
-    StatsdConfig newConfig;
-    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    *newConfig.add_atom_matcher() = matcher2;
-    newAtomMatchingTrackerMap[matcher2Id] = 0;
-    *newConfig.add_atom_matcher() = matcher3;
-    newAtomMatchingTrackerMap[matcher3Id] = 1;
-    *newConfig.add_atom_matcher() = matcher1;
-    newAtomMatchingTrackerMap[matcher1Id] = 2;
-
-    vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(3, false);
-    // Only update the combination.
-    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
-                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
-                                             matchersToUpdate, cycleTracker));
-    // Matcher 2 and matcher3 must be reevaluated. Matcher 1 might, but does not need to be.
-    EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
-    EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateMatchers) {
-    StatsdConfig config;
-    // Will be preserved.
-    AtomMatcher simple1 = CreateSimpleAtomMatcher("SIMPLE1", /*atom=*/10);
-    int64_t simple1Id = simple1.id();
-    *config.add_atom_matcher() = simple1;
-
-    // Will be replaced.
-    AtomMatcher simple2 = CreateSimpleAtomMatcher("SIMPLE2", /*atom=*/11);
-    *config.add_atom_matcher() = simple2;
-    int64_t simple2Id = simple2.id();
-
-    // Will be removed.
-    AtomMatcher simple3 = CreateSimpleAtomMatcher("SIMPLE3", /*atom=*/12);
-    *config.add_atom_matcher() = simple3;
-    int64_t simple3Id = simple3.id();
-
-    // Will be preserved.
-    AtomMatcher combination1;
-    combination1.set_id(StringToId("combination1"));
-    AtomMatcher_Combination* combination = combination1.mutable_combination();
-    combination->set_operation(LogicalOperation::NOT);
-    combination->add_matcher(simple1Id);
-    int64_t combination1Id = combination1.id();
-    *config.add_atom_matcher() = combination1;
-
-    // Will be replaced since it depends on simple2.
-    AtomMatcher combination2;
-    combination2.set_id(StringToId("combination2"));
-    combination = combination2.mutable_combination();
-    combination->set_operation(LogicalOperation::AND);
-    combination->add_matcher(simple1Id);
-    combination->add_matcher(simple2Id);
-    int64_t combination2Id = combination2.id();
-    *config.add_atom_matcher() = combination2;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Change simple2, causing simple2 and combination2 to be replaced.
-    simple2.mutable_simple_atom_matcher()->set_atom_id(111);
-
-    // 2 new matchers: simple4 and combination3:
-    AtomMatcher simple4 = CreateSimpleAtomMatcher("SIMPLE4", /*atom=*/13);
-    int64_t simple4Id = simple4.id();
-
-    AtomMatcher combination3;
-    combination3.set_id(StringToId("combination3"));
-    combination = combination3.mutable_combination();
-    combination->set_operation(LogicalOperation::AND);
-    combination->add_matcher(simple4Id);
-    combination->add_matcher(simple2Id);
-    int64_t combination3Id = combination3.id();
-
-    StatsdConfig newConfig;
-    *newConfig.add_atom_matcher() = combination3;
-    *newConfig.add_atom_matcher() = simple2;
-    *newConfig.add_atom_matcher() = combination2;
-    *newConfig.add_atom_matcher() = simple1;
-    *newConfig.add_atom_matcher() = simple4;
-    *newConfig.add_atom_matcher() = combination1;
-
-    set<int> newTagIds;
-    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
-    set<int64_t> replacedMatchers;
-    EXPECT_TRUE(updateAtomMatchingTrackers(
-            newConfig, uidMap, oldAtomMatchingTrackerMap, oldAtomMatchingTrackers, newTagIds,
-            newAtomMatchingTrackerMap, newAtomMatchingTrackers, replacedMatchers));
-
-    ASSERT_EQ(newTagIds.size(), 3);
-    EXPECT_EQ(newTagIds.count(10), 1);
-    EXPECT_EQ(newTagIds.count(111), 1);
-    EXPECT_EQ(newTagIds.count(13), 1);
-
-    ASSERT_EQ(newAtomMatchingTrackerMap.size(), 6);
-    EXPECT_EQ(newAtomMatchingTrackerMap.at(combination3Id), 0);
-    EXPECT_EQ(newAtomMatchingTrackerMap.at(simple2Id), 1);
-    EXPECT_EQ(newAtomMatchingTrackerMap.at(combination2Id), 2);
-    EXPECT_EQ(newAtomMatchingTrackerMap.at(simple1Id), 3);
-    EXPECT_EQ(newAtomMatchingTrackerMap.at(simple4Id), 4);
-    EXPECT_EQ(newAtomMatchingTrackerMap.at(combination1Id), 5);
-
-    ASSERT_EQ(newAtomMatchingTrackers.size(), 6);
-    // Make sure all atom matchers are initialized:
-    for (const sp<AtomMatchingTracker>& tracker : newAtomMatchingTrackers) {
-        EXPECT_TRUE(tracker->mInitialized);
-    }
-    // Make sure preserved atom matchers are the same.
-    EXPECT_EQ(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(simple1Id)],
-              newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(simple1Id)]);
-    EXPECT_EQ(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(combination1Id)],
-              newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(combination1Id)]);
-    // Make sure replaced matchers are different.
-    EXPECT_NE(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(simple2Id)],
-              newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(simple2Id)]);
-    EXPECT_NE(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(combination2Id)],
-              newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(combination2Id)]);
-
-    // Validation, make sure the matchers have the proper ids/indices. Could do more checks here.
-    EXPECT_EQ(newAtomMatchingTrackers[0]->getId(), combination3Id);
-    EXPECT_EQ(newAtomMatchingTrackers[0]->mIndex, 0);
-    EXPECT_EQ(newAtomMatchingTrackers[1]->getId(), simple2Id);
-    EXPECT_EQ(newAtomMatchingTrackers[1]->mIndex, 1);
-    EXPECT_EQ(newAtomMatchingTrackers[2]->getId(), combination2Id);
-    EXPECT_EQ(newAtomMatchingTrackers[2]->mIndex, 2);
-    EXPECT_EQ(newAtomMatchingTrackers[3]->getId(), simple1Id);
-    EXPECT_EQ(newAtomMatchingTrackers[3]->mIndex, 3);
-    EXPECT_EQ(newAtomMatchingTrackers[4]->getId(), simple4Id);
-    EXPECT_EQ(newAtomMatchingTrackers[4]->mIndex, 4);
-    EXPECT_EQ(newAtomMatchingTrackers[5]->getId(), combination1Id);
-    EXPECT_EQ(newAtomMatchingTrackers[5]->mIndex, 5);
-
-    // Verify child indices of Combination Matchers are correct.
-    CombinationAtomMatchingTracker* combinationTracker1 =
-            static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[5].get());
-    vector<int>* childMatchers = &combinationTracker1->mChildren;
-    EXPECT_EQ(childMatchers->size(), 1);
-    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 3), childMatchers->end());
-
-    CombinationAtomMatchingTracker* combinationTracker2 =
-            static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[2].get());
-    childMatchers = &combinationTracker2->mChildren;
-    EXPECT_EQ(childMatchers->size(), 2);
-    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 1), childMatchers->end());
-    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 3), childMatchers->end());
-
-    CombinationAtomMatchingTracker* combinationTracker3 =
-            static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[0].get());
-    childMatchers = &combinationTracker3->mChildren;
-    EXPECT_EQ(childMatchers->size(), 2);
-    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 1), childMatchers->end());
-    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 4), childMatchers->end());
-
-    // Expect replacedMatchers to have simple2 and combination2
-    ASSERT_EQ(replacedMatchers.size(), 2);
-    EXPECT_NE(replacedMatchers.find(simple2Id), replacedMatchers.end());
-    EXPECT_NE(replacedMatchers.find(combination2Id), replacedMatchers.end());
-}
-
-TEST_F(ConfigUpdateTest, TestSimpleConditionPreserve) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    set<int64_t> replacedMatchers;
-    vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(1, false);
-    unordered_map<int64_t, int> newConditionTrackerMap;
-    newConditionTrackerMap[predicate.id()] = 0;
-    EXPECT_TRUE(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
-                                               oldConditionTrackers, newConditionTrackerMap,
-                                               replacedMatchers, conditionsToUpdate, cycleTracker));
-    EXPECT_EQ(conditionsToUpdate[0], UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestSimpleConditionReplace) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Modify the predicate.
-    config.mutable_predicate(0)->mutable_simple_predicate()->set_count_nesting(true);
-
-    set<int64_t> replacedMatchers;
-    vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(1, false);
-    unordered_map<int64_t, int> newConditionTrackerMap;
-    newConditionTrackerMap[predicate.id()] = 0;
-    EXPECT_TRUE(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
-                                               oldConditionTrackers, newConditionTrackerMap,
-                                               replacedMatchers, conditionsToUpdate, cycleTracker));
-    EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestSimpleConditionDepsChange) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    int64_t startMatcherId = startMatcher.id();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Start matcher was replaced.
-    set<int64_t> replacedMatchers;
-    replacedMatchers.insert(startMatcherId);
-
-    vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(1, false);
-    unordered_map<int64_t, int> newConditionTrackerMap;
-    newConditionTrackerMap[predicate.id()] = 0;
-    EXPECT_TRUE(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
-                                               oldConditionTrackers, newConditionTrackerMap,
-                                               replacedMatchers, conditionsToUpdate, cycleTracker));
-    EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestCombinationConditionPreserve) {
-    StatsdConfig config;
-    AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = screenOnMatcher;
-    AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = screenOffMatcher;
-
-    Predicate simple1 = CreateScreenIsOnPredicate();
-    *config.add_predicate() = simple1;
-    Predicate simple2 = CreateScreenIsOffPredicate();
-    *config.add_predicate() = simple2;
-
-    Predicate combination1;
-    combination1.set_id(StringToId("COMBINATION1"));
-    Predicate_Combination* combinationInternal = combination1.mutable_combination();
-    combinationInternal->set_operation(LogicalOperation::NAND);
-    combinationInternal->add_predicate(simple1.id());
-    combinationInternal->add_predicate(simple2.id());
-    *config.add_predicate() = combination1;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Same predicates, different order
-    StatsdConfig newConfig;
-    unordered_map<int64_t, int> newConditionTrackerMap;
-    *newConfig.add_predicate() = combination1;
-    newConditionTrackerMap[combination1.id()] = 0;
-    *newConfig.add_predicate() = simple2;
-    newConditionTrackerMap[simple2.id()] = 1;
-    *newConfig.add_predicate() = simple1;
-    newConditionTrackerMap[simple1.id()] = 2;
-
-    set<int64_t> replacedMatchers;
-    vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(3, false);
-    // Only update the combination. It should recurse the two child predicates and preserve all 3.
-    EXPECT_TRUE(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
-                                               oldConditionTrackers, newConditionTrackerMap,
-                                               replacedMatchers, conditionsToUpdate, cycleTracker));
-    EXPECT_EQ(conditionsToUpdate[0], UPDATE_PRESERVE);
-    EXPECT_EQ(conditionsToUpdate[1], UPDATE_PRESERVE);
-    EXPECT_EQ(conditionsToUpdate[2], UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestCombinationConditionReplace) {
-    StatsdConfig config;
-    AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = screenOnMatcher;
-    AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = screenOffMatcher;
-
-    Predicate simple1 = CreateScreenIsOnPredicate();
-    *config.add_predicate() = simple1;
-    Predicate simple2 = CreateScreenIsOffPredicate();
-    *config.add_predicate() = simple2;
-
-    Predicate combination1;
-    combination1.set_id(StringToId("COMBINATION1"));
-    Predicate_Combination* combinationInternal = combination1.mutable_combination();
-    combinationInternal->set_operation(LogicalOperation::NAND);
-    combinationInternal->add_predicate(simple1.id());
-    combinationInternal->add_predicate(simple2.id());
-    *config.add_predicate() = combination1;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Changing the logical operation changes the predicate definition, so it should be replaced.
-    combination1.mutable_combination()->set_operation(LogicalOperation::OR);
-
-    StatsdConfig newConfig;
-    unordered_map<int64_t, int> newConditionTrackerMap;
-    *newConfig.add_predicate() = combination1;
-    newConditionTrackerMap[combination1.id()] = 0;
-    *newConfig.add_predicate() = simple2;
-    newConditionTrackerMap[simple2.id()] = 1;
-    *newConfig.add_predicate() = simple1;
-    newConditionTrackerMap[simple1.id()] = 2;
-
-    set<int64_t> replacedMatchers;
-    vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(3, false);
-    // Only update the combination. The simple conditions should not be evaluated.
-    EXPECT_TRUE(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
-                                               oldConditionTrackers, newConditionTrackerMap,
-                                               replacedMatchers, conditionsToUpdate, cycleTracker));
-    EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
-    EXPECT_EQ(conditionsToUpdate[1], UPDATE_UNKNOWN);
-    EXPECT_EQ(conditionsToUpdate[2], UPDATE_UNKNOWN);
-}
-
-TEST_F(ConfigUpdateTest, TestCombinationConditionDepsChange) {
-    StatsdConfig config;
-    AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = screenOnMatcher;
-    AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = screenOffMatcher;
-
-    Predicate simple1 = CreateScreenIsOnPredicate();
-    *config.add_predicate() = simple1;
-    Predicate simple2 = CreateScreenIsOffPredicate();
-    *config.add_predicate() = simple2;
-
-    Predicate combination1;
-    combination1.set_id(StringToId("COMBINATION1"));
-    Predicate_Combination* combinationInternal = combination1.mutable_combination();
-    combinationInternal->set_operation(LogicalOperation::NAND);
-    combinationInternal->add_predicate(simple1.id());
-    combinationInternal->add_predicate(simple2.id());
-    *config.add_predicate() = combination1;
-
-    EXPECT_TRUE(initConfig(config));
-
-    simple2.mutable_simple_predicate()->set_count_nesting(false);
-
-    StatsdConfig newConfig;
-    unordered_map<int64_t, int> newConditionTrackerMap;
-    *newConfig.add_predicate() = combination1;
-    newConditionTrackerMap[combination1.id()] = 0;
-    *newConfig.add_predicate() = simple2;
-    newConditionTrackerMap[simple2.id()] = 1;
-    *newConfig.add_predicate() = simple1;
-    newConditionTrackerMap[simple1.id()] = 2;
-
-    set<int64_t> replacedMatchers;
-    vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
-    vector<bool> cycleTracker(3, false);
-    // Only update the combination. Simple2 and combination1 must be evaluated.
-    EXPECT_TRUE(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
-                                               oldConditionTrackers, newConditionTrackerMap,
-                                               replacedMatchers, conditionsToUpdate, cycleTracker));
-    EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
-    EXPECT_EQ(conditionsToUpdate[1], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateConditions) {
-    StatsdConfig config;
-    // Add atom matchers. These are mostly needed for initStatsdConfig
-    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
-    int64_t matcher2Id = matcher2.id();
-    *config.add_atom_matcher() = matcher2;
-
-    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
-    int64_t matcher4Id = matcher4.id();
-    *config.add_atom_matcher() = matcher4;
-
-    AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
-    int64_t matcher5Id = matcher5.id();
-    *config.add_atom_matcher() = matcher5;
-
-    AtomMatcher matcher6 = CreateBatterySaverModeStopAtomMatcher();
-    int64_t matcher6Id = matcher6.id();
-    *config.add_atom_matcher() = matcher6;
-
-    // Add the predicates.
-    // Will be preserved.
-    Predicate simple1 = CreateScreenIsOnPredicate();
-    int64_t simple1Id = simple1.id();
-    *config.add_predicate() = simple1;
-
-    // Will be preserved.
-    Predicate simple2 = CreateScheduledJobPredicate();
-    int64_t simple2Id = simple2.id();
-    *config.add_predicate() = simple2;
-
-    // Will be replaced.
-    Predicate simple3 = CreateBatterySaverModePredicate();
-    int64_t simple3Id = simple3.id();
-    *config.add_predicate() = simple3;
-
-    // Will be preserved
-    Predicate combination1;
-    combination1.set_id(StringToId("COMBINATION1"));
-    combination1.mutable_combination()->set_operation(LogicalOperation::AND);
-    combination1.mutable_combination()->add_predicate(simple1Id);
-    combination1.mutable_combination()->add_predicate(simple2Id);
-    int64_t combination1Id = combination1.id();
-    *config.add_predicate() = combination1;
-
-    // Will be replaced since simple3 will be replaced.
-    Predicate combination2;
-    combination2.set_id(StringToId("COMBINATION2"));
-    combination2.mutable_combination()->set_operation(LogicalOperation::OR);
-    combination2.mutable_combination()->add_predicate(simple1Id);
-    combination2.mutable_combination()->add_predicate(simple3Id);
-    int64_t combination2Id = combination2.id();
-    *config.add_predicate() = combination2;
-
-    // Will be removed.
-    Predicate combination3;
-    combination3.set_id(StringToId("COMBINATION3"));
-    combination3.mutable_combination()->set_operation(LogicalOperation::NOT);
-    combination3.mutable_combination()->add_predicate(simple2Id);
-    int64_t combination3Id = combination3.id();
-    *config.add_predicate() = combination3;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Mark marcher 5 as replaced. Causes simple3, and therefore combination2 to be replaced.
-    set<int64_t> replacedMatchers;
-    replacedMatchers.insert(matcher6Id);
-
-    // Change the condition of simple1 to false.
-    ASSERT_EQ(oldConditionTrackers[0]->getConditionId(), simple1Id);
-    LogEvent event(/*uid=*/0, /*pid=*/0);  // Empty event is fine since there are no dimensions.
-    // Mark the stop matcher as matched, condition should be false.
-    vector<MatchingState> eventMatcherValues(6, MatchingState::kNotMatched);
-    eventMatcherValues[1] = MatchingState::kMatched;
-    vector<ConditionState> tmpConditionCache(6, ConditionState::kNotEvaluated);
-    vector<bool> conditionChangeCache(6, false);
-    oldConditionTrackers[0]->evaluateCondition(event, eventMatcherValues, oldConditionTrackers,
-                                               tmpConditionCache, conditionChangeCache);
-    EXPECT_EQ(tmpConditionCache[0], ConditionState::kFalse);
-    EXPECT_EQ(conditionChangeCache[0], true);
-
-    // New combination predicate. Should have an initial condition of true since it is NOT(simple1).
-    Predicate combination4;
-    combination4.set_id(StringToId("COMBINATION4"));
-    combination4.mutable_combination()->set_operation(LogicalOperation::NOT);
-    combination4.mutable_combination()->add_predicate(simple1Id);
-    int64_t combination4Id = combination4.id();
-    *config.add_predicate() = combination4;
-
-    // Map the matchers in reverse order to force the indices to change.
-    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    const int matcher6Index = 0;
-    newAtomMatchingTrackerMap[matcher6Id] = 0;
-    const int matcher5Index = 1;
-    newAtomMatchingTrackerMap[matcher5Id] = 1;
-    const int matcher4Index = 2;
-    newAtomMatchingTrackerMap[matcher4Id] = 2;
-    const int matcher3Index = 3;
-    newAtomMatchingTrackerMap[matcher3Id] = 3;
-    const int matcher2Index = 4;
-    newAtomMatchingTrackerMap[matcher2Id] = 4;
-    const int matcher1Index = 5;
-    newAtomMatchingTrackerMap[matcher1Id] = 5;
-
-    StatsdConfig newConfig;
-    *newConfig.add_predicate() = simple3;
-    const int simple3Index = 0;
-    *newConfig.add_predicate() = combination2;
-    const int combination2Index = 1;
-    *newConfig.add_predicate() = combination4;
-    const int combination4Index = 2;
-    *newConfig.add_predicate() = simple2;
-    const int simple2Index = 3;
-    *newConfig.add_predicate() = combination1;
-    const int combination1Index = 4;
-    *newConfig.add_predicate() = simple1;
-    const int simple1Index = 5;
-
-    unordered_map<int64_t, int> newConditionTrackerMap;
-    vector<sp<ConditionTracker>> newConditionTrackers;
-    unordered_map<int, vector<int>> trackerToConditionMap;
-    std::vector<ConditionState> conditionCache;
-    std::set<int64_t> replacedConditions;
-    EXPECT_TRUE(updateConditions(key, newConfig, newAtomMatchingTrackerMap, replacedMatchers,
-                                 oldConditionTrackerMap, oldConditionTrackers,
-                                 newConditionTrackerMap, newConditionTrackers,
-                                 trackerToConditionMap, conditionCache, replacedConditions));
-
-    unordered_map<int64_t, int> expectedConditionTrackerMap = {
-            {simple1Id, simple1Index},           {simple2Id, simple2Index},
-            {simple3Id, simple3Index},           {combination1Id, combination1Index},
-            {combination2Id, combination2Index}, {combination4Id, combination4Index},
-    };
-    EXPECT_THAT(newConditionTrackerMap, ContainerEq(expectedConditionTrackerMap));
-
-    ASSERT_EQ(newConditionTrackers.size(), 6);
-    // Make sure all conditions are initialized:
-    for (const sp<ConditionTracker>& tracker : newConditionTrackers) {
-        EXPECT_TRUE(tracker->mInitialized);
-    }
-
-    // Make sure preserved conditions are the same.
-    EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(simple1Id)],
-              newConditionTrackers[newConditionTrackerMap.at(simple1Id)]);
-    EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(simple2Id)],
-              newConditionTrackers[newConditionTrackerMap.at(simple2Id)]);
-    EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(combination1Id)],
-              newConditionTrackers[newConditionTrackerMap.at(combination1Id)]);
-
-    // Make sure replaced conditions are different and included in replacedConditions.
-    EXPECT_NE(oldConditionTrackers[oldConditionTrackerMap.at(simple3Id)],
-              newConditionTrackers[newConditionTrackerMap.at(simple3Id)]);
-    EXPECT_NE(oldConditionTrackers[oldConditionTrackerMap.at(combination2Id)],
-              newConditionTrackers[newConditionTrackerMap.at(combination2Id)]);
-    EXPECT_THAT(replacedConditions, ContainerEq(set({simple3Id, combination2Id})));
-
-    // Verify the trackerToConditionMap
-    ASSERT_EQ(trackerToConditionMap.size(), 6);
-    const vector<int>& matcher1Conditions = trackerToConditionMap[matcher1Index];
-    EXPECT_THAT(matcher1Conditions, UnorderedElementsAre(simple1Index, combination1Index,
-                                                         combination2Index, combination4Index));
-    const vector<int>& matcher2Conditions = trackerToConditionMap[matcher2Index];
-    EXPECT_THAT(matcher2Conditions, UnorderedElementsAre(simple1Index, combination1Index,
-                                                         combination2Index, combination4Index));
-    const vector<int>& matcher3Conditions = trackerToConditionMap[matcher3Index];
-    EXPECT_THAT(matcher3Conditions, UnorderedElementsAre(simple2Index, combination1Index));
-    const vector<int>& matcher4Conditions = trackerToConditionMap[matcher4Index];
-    EXPECT_THAT(matcher4Conditions, UnorderedElementsAre(simple2Index, combination1Index));
-    const vector<int>& matcher5Conditions = trackerToConditionMap[matcher5Index];
-    EXPECT_THAT(matcher5Conditions, UnorderedElementsAre(simple3Index, combination2Index));
-    const vector<int>& matcher6Conditions = trackerToConditionMap[matcher6Index];
-    EXPECT_THAT(matcher6Conditions, UnorderedElementsAre(simple3Index, combination2Index));
-
-    // Verify the conditionCache. Specifically, simple1 is false and combination4 is true.
-    ASSERT_EQ(conditionCache.size(), 6);
-    EXPECT_EQ(conditionCache[simple1Index], ConditionState::kFalse);
-    EXPECT_EQ(conditionCache[simple2Index], ConditionState::kUnknown);
-    EXPECT_EQ(conditionCache[simple3Index], ConditionState::kUnknown);
-    EXPECT_EQ(conditionCache[combination1Index], ConditionState::kUnknown);
-    EXPECT_EQ(conditionCache[combination2Index], ConditionState::kUnknown);
-    EXPECT_EQ(conditionCache[combination4Index], ConditionState::kTrue);
-
-    // Verify tracker indices/ids are correct.
-    EXPECT_EQ(newConditionTrackers[simple1Index]->getConditionId(), simple1Id);
-    EXPECT_EQ(newConditionTrackers[simple1Index]->mIndex, simple1Index);
-    EXPECT_TRUE(newConditionTrackers[simple1Index]->IsSimpleCondition());
-    EXPECT_EQ(newConditionTrackers[simple2Index]->getConditionId(), simple2Id);
-    EXPECT_EQ(newConditionTrackers[simple2Index]->mIndex, simple2Index);
-    EXPECT_TRUE(newConditionTrackers[simple2Index]->IsSimpleCondition());
-    EXPECT_EQ(newConditionTrackers[simple3Index]->getConditionId(), simple3Id);
-    EXPECT_EQ(newConditionTrackers[simple3Index]->mIndex, simple3Index);
-    EXPECT_TRUE(newConditionTrackers[simple3Index]->IsSimpleCondition());
-    EXPECT_EQ(newConditionTrackers[combination1Index]->getConditionId(), combination1Id);
-    EXPECT_EQ(newConditionTrackers[combination1Index]->mIndex, combination1Index);
-    EXPECT_FALSE(newConditionTrackers[combination1Index]->IsSimpleCondition());
-    EXPECT_EQ(newConditionTrackers[combination2Index]->getConditionId(), combination2Id);
-    EXPECT_EQ(newConditionTrackers[combination2Index]->mIndex, combination2Index);
-    EXPECT_FALSE(newConditionTrackers[combination2Index]->IsSimpleCondition());
-    EXPECT_EQ(newConditionTrackers[combination4Index]->getConditionId(), combination4Id);
-    EXPECT_EQ(newConditionTrackers[combination4Index]->mIndex, combination4Index);
-    EXPECT_FALSE(newConditionTrackers[combination4Index]->IsSimpleCondition());
-
-    // Verify preserved trackers have indices updated.
-    SimpleConditionTracker* simpleTracker1 =
-            static_cast<SimpleConditionTracker*>(newConditionTrackers[simple1Index].get());
-    EXPECT_EQ(simpleTracker1->mStartLogMatcherIndex, matcher1Index);
-    EXPECT_EQ(simpleTracker1->mStopLogMatcherIndex, matcher2Index);
-    EXPECT_EQ(simpleTracker1->mStopAllLogMatcherIndex, -1);
-
-    SimpleConditionTracker* simpleTracker2 =
-            static_cast<SimpleConditionTracker*>(newConditionTrackers[simple2Index].get());
-    EXPECT_EQ(simpleTracker2->mStartLogMatcherIndex, matcher3Index);
-    EXPECT_EQ(simpleTracker2->mStopLogMatcherIndex, matcher4Index);
-    EXPECT_EQ(simpleTracker2->mStopAllLogMatcherIndex, -1);
-
-    CombinationConditionTracker* combinationTracker1 = static_cast<CombinationConditionTracker*>(
-            newConditionTrackers[combination1Index].get());
-    EXPECT_THAT(combinationTracker1->mChildren, UnorderedElementsAre(simple1Index, simple2Index));
-    EXPECT_THAT(combinationTracker1->mUnSlicedChildren,
-                UnorderedElementsAre(simple1Index, simple2Index));
-    EXPECT_THAT(combinationTracker1->mSlicedChildren, IsEmpty());
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateStates) {
-    StatsdConfig config;
-    // Add states.
-    // Will be replaced because we add a state map.
-    State state1 = CreateScreenState();
-    int64_t state1Id = state1.id();
-    *config.add_state() = state1;
-
-    // Will be preserved.
-    State state2 = CreateUidProcessState();
-    int64_t state2Id = state2.id();
-    *config.add_state() = state2;
-
-    // Will be replaced since the atom changes from overlay to screen.
-    State state3 = CreateOverlayState();
-    int64_t state3Id = state3.id();
-    *config.add_state() = state3;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Change definitions of state1 and state3.
-    int64_t screenOnId = 0x4321, screenOffId = 0x1234;
-    *state1.mutable_map() = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId);
-    state3.set_atom_id(util::SCREEN_STATE_CHANGED);
-
-    StatsdConfig newConfig;
-    *newConfig.add_state() = state3;
-    *newConfig.add_state() = state1;
-    *newConfig.add_state() = state2;
-
-    unordered_map<int64_t, int> stateAtomIdMap;
-    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
-    map<int64_t, uint64_t> newStateProtoHashes;
-    set<int64_t> replacedStates;
-    EXPECT_TRUE(updateStates(newConfig, oldStateHashes, stateAtomIdMap, allStateGroupMaps,
-                             newStateProtoHashes, replacedStates));
-    EXPECT_THAT(replacedStates, ContainerEq(set({state1Id, state3Id})));
-
-    unordered_map<int64_t, int> expectedStateAtomIdMap = {
-            {state1Id, util::SCREEN_STATE_CHANGED},
-            {state2Id, util::UID_PROCESS_STATE_CHANGED},
-            {state3Id, util::SCREEN_STATE_CHANGED}};
-    EXPECT_THAT(stateAtomIdMap, ContainerEq(expectedStateAtomIdMap));
-
-    unordered_map<int64_t, unordered_map<int, int64_t>> expectedStateGroupMaps = {
-            {state1Id,
-             {{android::view::DisplayStateEnum::DISPLAY_STATE_OFF, screenOffId},
-              {android::view::DisplayStateEnum::DISPLAY_STATE_ON, screenOnId}}}};
-    EXPECT_THAT(allStateGroupMaps, ContainerEq(expectedStateGroupMaps));
-}
-
-TEST_F(ConfigUpdateTest, TestEventMetricPreserve) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    EventMetric* metric = config.add_event_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap,
-                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-                                                 /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestEventMetricActivationAdded) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    EventMetric* metric = config.add_event_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    // Add a metric activation, which should change the proto, causing replacement.
-    MetricActivation* activation = config.add_metric_activation();
-    activation->set_metric_id(12345);
-    EventActivation* eventActivation = activation->add_event_activation();
-    eventActivation->set_atom_matcher_id(startMatcher.id());
-    eventActivation->set_ttl_seconds(5);
-
-    unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap,
-                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-                                                 /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestEventMetricWhatChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    EventMetric* metric = config.add_event_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestEventMetricConditionChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    EventMetric* metric = config.add_event_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestMetricConditionLinkDepsChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    Predicate linkPredicate = CreateScreenIsOffPredicate();
-    *config.add_predicate() = linkPredicate;
-
-    EventMetric* metric = config.add_event_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-    // Doesn't make sense as a real metric definition, but suffices as a separate predicate
-    // From the one in the condition.
-    MetricConditionLink* link = metric->add_links();
-    link->set_condition(linkPredicate.id());
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{linkPredicate.id()},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestEventMetricActivationDepsChange) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    EventMetric* metric = config.add_event_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-
-    MetricActivation* activation = config.add_metric_activation();
-    activation->set_metric_id(12345);
-    EventActivation* eventActivation = activation->add_event_activation();
-    eventActivation->set_atom_matcher_id(startMatcher.id());
-    eventActivation->set_ttl_seconds(5);
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {startMatcher.id()}, /*replacedConditions=*/{},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestCountMetricPreserve) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-    State sliceState = CreateScreenState();
-    *config.add_state() = sliceState;
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-    metric->add_slice_by_state(sliceState.id());
-    metric->set_bucket(ONE_HOUR);
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap,
-                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-                                                 /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestCountMetricDefinitionChange) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-    metric->set_bucket(ONE_HOUR);
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    // Change bucket size, which should change the proto, causing replacement.
-    metric->set_bucket(TEN_MINUTES);
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap,
-                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-                                                 /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestCountMetricWhatChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-    metric->set_bucket(ONE_HOUR);
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestCountMetricConditionChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->set_condition(predicate.id());
-    metric->set_bucket(ONE_HOUR);
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestCountMetricStateChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    State sliceState = CreateScreenState();
-    *config.add_state() = sliceState;
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(12345);
-    metric->set_what(whatMatcher.id());
-    metric->add_slice_by_state(sliceState.id());
-    metric->set_bucket(ONE_HOUR);
-
-    // Create an initial config.
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-            /*replacedStates=*/{sliceState.id()}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestGaugeMetricPreserve) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    *config.add_gauge_metric() = createGaugeMetric(
-            "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, predicate.id(), nullopt);
-
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap,
-                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-                                                 /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestGaugeMetricDefinitionChange) {
-    StatsdConfig config;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    *config.add_gauge_metric() = createGaugeMetric(
-            "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Change split bucket on app upgrade, which should change the proto, causing replacement.
-    config.mutable_gauge_metric(0)->set_split_bucket_for_app_upgrade(false);
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap,
-                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-                                                 /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestGaugeMetricWhatChanged) {
-    StatsdConfig config;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    *config.add_gauge_metric() = createGaugeMetric(
-            "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
-
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestGaugeMetricConditionChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    *config.add_gauge_metric() = createGaugeMetric(
-            "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, predicate.id(), nullopt);
-
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestGaugeMetricTriggerEventChanged) {
-    StatsdConfig config;
-    AtomMatcher triggerEvent = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = triggerEvent;
-    AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    *config.add_gauge_metric() = createGaugeMetric(
-            "GAUGE1", whatMatcher.id(), GaugeMetric::FIRST_N_SAMPLES, nullopt, triggerEvent.id());
-
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {triggerEvent.id()}, /*replacedConditions=*/{},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestDurationMetricPreserve) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-
-    Predicate what = CreateScreenIsOnPredicate();
-    *config.add_predicate() = what;
-    Predicate condition = CreateScreenIsOffPredicate();
-    *config.add_predicate() = condition;
-
-    State sliceState = CreateScreenState();
-    *config.add_state() = sliceState;
-
-    *config.add_duration_metric() =
-            createDurationMetric("DURATION1", what.id(), condition.id(), {sliceState.id()});
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap,
-                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-                                                 /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestDurationMetricDefinitionChange) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-
-    Predicate what = CreateScreenIsOnPredicate();
-    *config.add_predicate() = what;
-
-    *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {});
-    EXPECT_TRUE(initConfig(config));
-
-    config.mutable_duration_metric(0)->set_aggregation_type(DurationMetric::MAX_SPARSE);
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap, /*replacedMatchers*/ {},
-                                                 /*replacedConditions=*/{}, /*replacedStates=*/{},
-                                                 metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestDurationMetricWhatChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-
-    Predicate what = CreateScreenIsOnPredicate();
-    *config.add_predicate() = what;
-
-    *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {});
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{what.id()},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestDurationMetricConditionChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-
-    Predicate what = CreateScreenIsOnPredicate();
-    *config.add_predicate() = what;
-    Predicate condition = CreateScreenIsOffPredicate();
-    *config.add_predicate() = condition;
-
-    *config.add_duration_metric() = createDurationMetric("DURATION", what.id(), condition.id(), {});
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{condition.id()},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestDurationMetricStateChange) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-
-    Predicate what = CreateScreenIsOnPredicate();
-    *config.add_predicate() = what;
-
-    State sliceState = CreateScreenState();
-    *config.add_state() = sliceState;
-
-    *config.add_duration_metric() =
-            createDurationMetric("DURATION1", what.id(), nullopt, {sliceState.id()});
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-            /*replacedStates=*/{sliceState.id()}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestValueMetricPreserve) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-    State sliceState = CreateScreenState();
-    *config.add_state() = sliceState;
-
-    *config.add_value_metric() =
-            createValueMetric("VALUE1", whatMatcher, predicate.id(), {sliceState.id()});
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap,
-                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-                                                 /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestValueMetricDefinitionChange) {
-    StatsdConfig config;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, nullopt, {});
-    EXPECT_TRUE(initConfig(config));
-
-    // Change skip zero diff output, which should change the proto, causing replacement.
-    config.mutable_value_metric(0)->set_skip_zero_diff_output(true);
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
-                                                 metricToActivationMap,
-                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-                                                 /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestValueMetricWhatChanged) {
-    StatsdConfig config;
-    AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, nullopt, {});
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestValueMetricConditionChanged) {
-    StatsdConfig config;
-    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = startMatcher;
-    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = stopMatcher;
-    AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    Predicate predicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = predicate;
-
-    *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, predicate.id(), {});
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
-            /*replacedStates=*/{}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestValueMetricStateChanged) {
-    StatsdConfig config;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    State sliceState = CreateScreenState();
-    *config.add_state() = sliceState;
-
-    *config.add_value_metric() =
-            createValueMetric("VALUE1", whatMatcher, nullopt, {sliceState.id()});
-    EXPECT_TRUE(initConfig(config));
-
-    unordered_map<int64_t, int> metricToActivationMap;
-    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
-    EXPECT_TRUE(determineAllMetricUpdateStatuses(
-            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
-            /*replacedMatchers*/ {}, /*replacedConditions=*/{},
-            /*replacedStates=*/{sliceState.id()}, metricsToUpdate));
-    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) {
-    StatsdConfig config;
-
-    // Add atom matchers/predicates. These are mostly needed for initStatsdConfig
-    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
-    int64_t matcher2Id = matcher2.id();
-    *config.add_atom_matcher() = matcher2;
-
-    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
-    int64_t matcher4Id = matcher4.id();
-    *config.add_atom_matcher() = matcher4;
-
-    AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
-    int64_t matcher5Id = matcher5.id();
-    *config.add_atom_matcher() = matcher5;
-
-    Predicate predicate1 = CreateScreenIsOnPredicate();
-    int64_t predicate1Id = predicate1.id();
-    *config.add_predicate() = predicate1;
-
-    Predicate predicate2 = CreateScheduledJobPredicate();
-    int64_t predicate2Id = predicate2.id();
-    *config.add_predicate() = predicate2;
-
-    // Add a few event metrics.
-    // Will be preserved.
-    EventMetric event1 = createEventMetric("EVENT1", matcher1Id, predicate2Id);
-    int64_t event1Id = event1.id();
-    *config.add_event_metric() = event1;
-
-    // Will be replaced.
-    EventMetric event2 = createEventMetric("EVENT2", matcher2Id, nullopt);
-    int64_t event2Id = event2.id();
-    *config.add_event_metric() = event2;
-
-    // Will be replaced.
-    EventMetric event3 = createEventMetric("EVENT3", matcher3Id, nullopt);
-    int64_t event3Id = event3.id();
-    *config.add_event_metric() = event3;
-
-    MetricActivation event3Activation;
-    event3Activation.set_metric_id(event3Id);
-    EventActivation* eventActivation = event3Activation.add_event_activation();
-    eventActivation->set_atom_matcher_id(matcher5Id);
-    eventActivation->set_ttl_seconds(5);
-    *config.add_metric_activation() = event3Activation;
-
-    // Will be replaced.
-    EventMetric event4 = createEventMetric("EVENT4", matcher4Id, predicate1Id);
-    int64_t event4Id = event4.id();
-    *config.add_event_metric() = event4;
-
-    // Will be deleted.
-    EventMetric event5 = createEventMetric("EVENT5", matcher5Id, nullopt);
-    int64_t event5Id = event5.id();
-    *config.add_event_metric() = event5;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
-    sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
-    EXPECT_EQ(oldConditionWizard->getStrongCount(), oldMetricProducers.size() + 1);
-
-    // Add a condition to event2, causing it to be replaced.
-    event2.set_condition(predicate1Id);
-
-    // Mark matcher 5 as replaced. Causes event3 to be replaced.
-    set<int64_t> replacedMatchers;
-    replacedMatchers.insert(matcher5Id);
-
-    // Mark predicate 1 as replaced. Causes event4 to be replaced.
-    set<int64_t> replacedConditions;
-    replacedConditions.insert(predicate1Id);
-
-    // Fake that predicate 2 is true.
-    ASSERT_EQ(oldMetricProducers[0]->getMetricId(), event1Id);
-    oldMetricProducers[0]->onConditionChanged(true, /*timestamp=*/0);
-    EXPECT_EQ(oldMetricProducers[0]->mCondition, ConditionState::kTrue);
-
-    // New event metric. Should have an initial condition of true since it depends on predicate2.
-    EventMetric event6 = createEventMetric("EVENT6", matcher3Id, predicate2Id);
-    int64_t event6Id = event6.id();
-    MetricActivation event6Activation;
-    event6Activation.set_metric_id(event6Id);
-    eventActivation = event6Activation.add_event_activation();
-    eventActivation->set_atom_matcher_id(matcher5Id);
-    eventActivation->set_ttl_seconds(20);
-
-    // Map the matchers and predicates in reverse order to force the indices to change.
-    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    const int matcher5Index = 0;
-    newAtomMatchingTrackerMap[matcher5Id] = 0;
-    const int matcher4Index = 1;
-    newAtomMatchingTrackerMap[matcher4Id] = 1;
-    const int matcher3Index = 2;
-    newAtomMatchingTrackerMap[matcher3Id] = 2;
-    const int matcher2Index = 3;
-    newAtomMatchingTrackerMap[matcher2Id] = 3;
-    const int matcher1Index = 4;
-    newAtomMatchingTrackerMap[matcher1Id] = 4;
-    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
-    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
-                      newAtomMatchingTrackers.begin());
-
-    std::unordered_map<int64_t, int> newConditionTrackerMap;
-    const int predicate2Index = 0;
-    newConditionTrackerMap[predicate2Id] = 0;
-    const int predicate1Index = 1;
-    newConditionTrackerMap[predicate1Id] = 1;
-    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<ConditionTracker>> newConditionTrackers(2);
-    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
-                      newConditionTrackers.begin());
-    // Fake that predicate2 is true.
-    vector<ConditionState> conditionCache = {ConditionState::kTrue, ConditionState::kUnknown};
-
-    StatsdConfig newConfig;
-    *newConfig.add_event_metric() = event6;
-    const int event6Index = 0;
-    *newConfig.add_event_metric() = event3;
-    const int event3Index = 1;
-    *newConfig.add_event_metric() = event1;
-    const int event1Index = 2;
-    *newConfig.add_event_metric() = event4;
-    const int event4Index = 3;
-    *newConfig.add_event_metric() = event2;
-    const int event2Index = 4;
-    *newConfig.add_metric_activation() = event3Activation;
-    *newConfig.add_metric_activation() = event6Activation;
-
-    // Output data structures to validate.
-    unordered_map<int64_t, int> newMetricProducerMap;
-    vector<sp<MetricProducer>> newMetricProducers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    set<int64_t> noReportMetricIds;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
-    vector<int> metricsWithActivation;
-    set<int64_t> replacedMetrics;
-    EXPECT_TRUE(updateMetrics(
-            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
-            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
-            newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
-            newConditionTrackers, conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
-            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
-            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
-            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-            metricsWithActivation, replacedMetrics));
-
-    unordered_map<int64_t, int> expectedMetricProducerMap = {
-            {event1Id, event1Index}, {event2Id, event2Index}, {event3Id, event3Index},
-            {event4Id, event4Index}, {event6Id, event6Index},
-    };
-    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
-    EXPECT_EQ(replacedMetrics, set<int64_t>({event2Id, event3Id, event4Id}));
-
-    // Make sure preserved metrics are the same.
-    ASSERT_EQ(newMetricProducers.size(), 5);
-    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(event1Id)],
-              newMetricProducers[newMetricProducerMap.at(event1Id)]);
-
-    // Make sure replaced metrics are different.
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event2Id)],
-              newMetricProducers[newMetricProducerMap.at(event2Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event3Id)],
-              newMetricProducers[newMetricProducerMap.at(event3Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event4Id)],
-              newMetricProducers[newMetricProducerMap.at(event4Id)]);
-
-    // Verify the conditionToMetricMap.
-    ASSERT_EQ(conditionToMetricMap.size(), 2);
-    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
-    EXPECT_THAT(condition1Metrics, UnorderedElementsAre(event2Index, event4Index));
-    const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
-    EXPECT_THAT(condition2Metrics, UnorderedElementsAre(event1Index, event6Index));
-
-    // Verify the trackerToMetricMap.
-    ASSERT_EQ(trackerToMetricMap.size(), 4);
-    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
-    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(event1Index));
-    const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
-    EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(event2Index));
-    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
-    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(event3Index, event6Index));
-    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
-    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(event4Index));
-
-    // Verify event activation/deactivation maps.
-    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 1);
-    EXPECT_THAT(activationAtomTrackerToMetricMap[matcher5Index],
-                UnorderedElementsAre(event3Index, event6Index));
-    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(metricsWithActivation.size(), 2);
-    EXPECT_THAT(metricsWithActivation, UnorderedElementsAre(event3Index, event6Index));
-
-    // Verify tracker indices/ids/conditions are correct.
-    EXPECT_EQ(newMetricProducers[event1Index]->getMetricId(), event1Id);
-    EXPECT_EQ(newMetricProducers[event1Index]->mConditionTrackerIndex, predicate2Index);
-    EXPECT_EQ(newMetricProducers[event1Index]->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(newMetricProducers[event2Index]->getMetricId(), event2Id);
-    EXPECT_EQ(newMetricProducers[event2Index]->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(newMetricProducers[event2Index]->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(newMetricProducers[event3Index]->getMetricId(), event3Id);
-    EXPECT_EQ(newMetricProducers[event3Index]->mConditionTrackerIndex, -1);
-    EXPECT_EQ(newMetricProducers[event3Index]->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(newMetricProducers[event4Index]->getMetricId(), event4Id);
-    EXPECT_EQ(newMetricProducers[event4Index]->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(newMetricProducers[event4Index]->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(newMetricProducers[event6Index]->getMetricId(), event6Id);
-    EXPECT_EQ(newMetricProducers[event6Index]->mConditionTrackerIndex, predicate2Index);
-    EXPECT_EQ(newMetricProducers[event6Index]->mCondition, ConditionState::kTrue);
-
-    sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
-    EXPECT_NE(newConditionWizard, oldConditionWizard);
-    EXPECT_EQ(newConditionWizard->getStrongCount(), newMetricProducers.size() + 1);
-    oldMetricProducers.clear();
-    // Only reference to the old wizard should be the one in the test.
-    EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateCountMetrics) {
-    StatsdConfig config;
-
-    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
-    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
-    int64_t matcher2Id = matcher2.id();
-    *config.add_atom_matcher() = matcher2;
-
-    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
-    int64_t matcher4Id = matcher4.id();
-    *config.add_atom_matcher() = matcher4;
-
-    AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
-    int64_t matcher5Id = matcher5.id();
-    *config.add_atom_matcher() = matcher5;
-
-    Predicate predicate1 = CreateScreenIsOnPredicate();
-    int64_t predicate1Id = predicate1.id();
-    *config.add_predicate() = predicate1;
-
-    State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
-    int64_t state1Id = state1.id();
-    *config.add_state() = state1;
-
-    State state2 = CreateScreenState();
-    int64_t state2Id = state2.id();
-    *config.add_state() = state2;
-
-    // Add a few count metrics.
-    // Will be preserved.
-    CountMetric count1 = createCountMetric("COUNT1", matcher1Id, predicate1Id, {state1Id});
-    int64_t count1Id = count1.id();
-    *config.add_count_metric() = count1;
-
-    // Will be replaced.
-    CountMetric count2 = createCountMetric("COUNT2", matcher2Id, nullopt, {});
-    int64_t count2Id = count2.id();
-    *config.add_count_metric() = count2;
-
-    // Will be replaced.
-    CountMetric count3 = createCountMetric("COUNT3", matcher3Id, nullopt, {});
-    int64_t count3Id = count3.id();
-    *config.add_count_metric() = count3;
-
-    // Will be replaced.
-    CountMetric count4 = createCountMetric("COUNT4", matcher4Id, nullopt, {state2Id});
-    int64_t count4Id = count4.id();
-    *config.add_count_metric() = count4;
-
-    // Will be deleted.
-    CountMetric count5 = createCountMetric("COUNT5", matcher5Id, nullopt, {});
-    int64_t count5Id = count5.id();
-    *config.add_count_metric() = count5;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Change bucket size of count2, causing it to be replaced.
-    count2.set_bucket(ONE_HOUR);
-
-    // Mark matcher 3 as replaced. Causes count3 to be replaced.
-    set<int64_t> replacedMatchers;
-    replacedMatchers.insert(matcher3Id);
-
-    // Mark state 2 as replaced and change the state to be about a different atom.
-    // Causes count4 to be replaced.
-    set<int64_t> replacedStates;
-    replacedStates.insert(state2Id);
-    state2.set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);
-
-    // Fake that predicate 1 is true for count metric 1.
-    ASSERT_EQ(oldMetricProducers[0]->getMetricId(), count1Id);
-    oldMetricProducers[0]->onConditionChanged(true, /*timestamp=*/0);
-    EXPECT_EQ(oldMetricProducers[0]->mCondition, ConditionState::kTrue);
-
-    EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 1);
-    // Tell the StateManager that the screen is on.
-    unique_ptr<LogEvent> event =
-            CreateScreenStateChangedEvent(0, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    StateManager::getInstance().onLogEvent(*event);
-
-    // New count metric. Should have an initial condition of true since it depends on predicate1.
-    CountMetric count6 = createCountMetric("EVENT6", matcher2Id, predicate1Id, {state1Id});
-    int64_t count6Id = count6.id();
-
-    // Map the matchers and predicates in reverse order to force the indices to change.
-    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    const int matcher5Index = 0;
-    newAtomMatchingTrackerMap[matcher5Id] = 0;
-    const int matcher4Index = 1;
-    newAtomMatchingTrackerMap[matcher4Id] = 1;
-    const int matcher3Index = 2;
-    newAtomMatchingTrackerMap[matcher3Id] = 2;
-    const int matcher2Index = 3;
-    newAtomMatchingTrackerMap[matcher2Id] = 3;
-    const int matcher1Index = 4;
-    newAtomMatchingTrackerMap[matcher1Id] = 4;
-    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
-    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
-                      newAtomMatchingTrackers.begin());
-
-    std::unordered_map<int64_t, int> newConditionTrackerMap;
-    const int predicate1Index = 0;
-    newConditionTrackerMap[predicate1Id] = 0;
-    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<ConditionTracker>> newConditionTrackers(1);
-    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
-                      newConditionTrackers.begin());
-    // Fake that predicate1 is true for all new metrics.
-    vector<ConditionState> conditionCache = {ConditionState::kTrue};
-
-    StatsdConfig newConfig;
-    *newConfig.add_count_metric() = count6;
-    const int count6Index = 0;
-    *newConfig.add_count_metric() = count3;
-    const int count3Index = 1;
-    *newConfig.add_count_metric() = count1;
-    const int count1Index = 2;
-    *newConfig.add_count_metric() = count4;
-    const int count4Index = 3;
-    *newConfig.add_count_metric() = count2;
-    const int count2Index = 4;
-
-    *newConfig.add_state() = state1;
-    *newConfig.add_state() = state2;
-
-    unordered_map<int64_t, int> stateAtomIdMap;
-    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
-    map<int64_t, uint64_t> stateProtoHashes;
-    EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes));
-    EXPECT_EQ(stateAtomIdMap[state2Id], util::BATTERY_SAVER_MODE_STATE_CHANGED);
-
-    // Output data structures to validate.
-    unordered_map<int64_t, int> newMetricProducerMap;
-    vector<sp<MetricProducer>> newMetricProducers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    set<int64_t> noReportMetricIds;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
-    vector<int> metricsWithActivation;
-    set<int64_t> replacedMetrics;
-    EXPECT_TRUE(updateMetrics(
-            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
-            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
-            newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{},
-            newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
-            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers,
-            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
-            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-            metricsWithActivation, replacedMetrics));
-
-    unordered_map<int64_t, int> expectedMetricProducerMap = {
-            {count1Id, count1Index}, {count2Id, count2Index}, {count3Id, count3Index},
-            {count4Id, count4Index}, {count6Id, count6Index},
-    };
-    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
-    EXPECT_EQ(replacedMetrics, set<int64_t>({count2Id, count3Id, count4Id}));
-
-    // Make sure preserved metrics are the same.
-    ASSERT_EQ(newMetricProducers.size(), 5);
-    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(count1Id)],
-              newMetricProducers[newMetricProducerMap.at(count1Id)]);
-
-    // Make sure replaced metrics are different.
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count2Id)],
-              newMetricProducers[newMetricProducerMap.at(count2Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count3Id)],
-              newMetricProducers[newMetricProducerMap.at(count3Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count4Id)],
-              newMetricProducers[newMetricProducerMap.at(count4Id)]);
-
-    // Verify the conditionToMetricMap.
-    ASSERT_EQ(conditionToMetricMap.size(), 1);
-    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
-    EXPECT_THAT(condition1Metrics, UnorderedElementsAre(count1Index, count6Index));
-
-    // Verify the trackerToMetricMap.
-    ASSERT_EQ(trackerToMetricMap.size(), 4);
-    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
-    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(count1Index));
-    const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
-    EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(count2Index, count6Index));
-    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
-    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(count3Index));
-    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
-    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(count4Index));
-
-    // Verify event activation/deactivation maps.
-    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(metricsWithActivation.size(), 0);
-
-    // Verify tracker indices/ids/conditions/states are correct.
-    EXPECT_EQ(newMetricProducers[count1Index]->getMetricId(), count1Id);
-    EXPECT_EQ(newMetricProducers[count1Index]->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(newMetricProducers[count1Index]->mCondition, ConditionState::kTrue);
-    EXPECT_THAT(newMetricProducers[count1Index]->getSlicedStateAtoms(),
-                UnorderedElementsAre(util::SCREEN_STATE_CHANGED));
-    EXPECT_EQ(newMetricProducers[count2Index]->getMetricId(), count2Id);
-    EXPECT_EQ(newMetricProducers[count2Index]->mConditionTrackerIndex, -1);
-    EXPECT_EQ(newMetricProducers[count2Index]->mCondition, ConditionState::kTrue);
-    EXPECT_TRUE(newMetricProducers[count2Index]->getSlicedStateAtoms().empty());
-    EXPECT_EQ(newMetricProducers[count3Index]->getMetricId(), count3Id);
-    EXPECT_EQ(newMetricProducers[count3Index]->mConditionTrackerIndex, -1);
-    EXPECT_EQ(newMetricProducers[count3Index]->mCondition, ConditionState::kTrue);
-    EXPECT_TRUE(newMetricProducers[count3Index]->getSlicedStateAtoms().empty());
-    EXPECT_EQ(newMetricProducers[count4Index]->getMetricId(), count4Id);
-    EXPECT_EQ(newMetricProducers[count4Index]->mConditionTrackerIndex, -1);
-    EXPECT_EQ(newMetricProducers[count4Index]->mCondition, ConditionState::kTrue);
-    EXPECT_THAT(newMetricProducers[count4Index]->getSlicedStateAtoms(),
-                UnorderedElementsAre(util::BATTERY_SAVER_MODE_STATE_CHANGED));
-    EXPECT_EQ(newMetricProducers[count6Index]->getMetricId(), count6Id);
-    EXPECT_EQ(newMetricProducers[count6Index]->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(newMetricProducers[count6Index]->mCondition, ConditionState::kTrue);
-    EXPECT_THAT(newMetricProducers[count6Index]->getSlicedStateAtoms(),
-                UnorderedElementsAre(util::SCREEN_STATE_CHANGED));
-
-    oldMetricProducers.clear();
-    // Ensure that the screen state StateTracker did not get deleted and replaced.
-    EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 2);
-    FieldValue screenState;
-    StateManager::getInstance().getStateValue(util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY,
-                                              &screenState);
-    EXPECT_EQ(screenState.mValue.int_value, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateGaugeMetrics) {
-    StatsdConfig config;
-
-    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
-    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
-    int64_t matcher2Id = matcher2.id();
-    *config.add_atom_matcher() = matcher2;
-
-    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    AtomMatcher matcher4 = CreateTemperatureAtomMatcher();
-    int64_t matcher4Id = matcher4.id();
-    *config.add_atom_matcher() = matcher4;
-
-    AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
-    int64_t matcher5Id = matcher5.id();
-    *config.add_atom_matcher() = matcher5;
-
-    Predicate predicate1 = CreateScreenIsOnPredicate();
-    int64_t predicate1Id = predicate1.id();
-    *config.add_predicate() = predicate1;
-
-    // Add a few gauge metrics.
-    // Will be preserved.
-    GaugeMetric gauge1 = createGaugeMetric("GAUGE1", matcher4Id, GaugeMetric::FIRST_N_SAMPLES,
-                                           predicate1Id, matcher1Id);
-    int64_t gauge1Id = gauge1.id();
-    *config.add_gauge_metric() = gauge1;
-
-    // Will be replaced.
-    GaugeMetric gauge2 =
-            createGaugeMetric("GAUGE2", matcher1Id, GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
-    int64_t gauge2Id = gauge2.id();
-    *config.add_gauge_metric() = gauge2;
-
-    // Will be replaced.
-    GaugeMetric gauge3 = createGaugeMetric("GAUGE3", matcher5Id, GaugeMetric::FIRST_N_SAMPLES,
-                                           nullopt, matcher3Id);
-    int64_t gauge3Id = gauge3.id();
-    *config.add_gauge_metric() = gauge3;
-
-    // Will be replaced.
-    GaugeMetric gauge4 = createGaugeMetric("GAUGE4", matcher3Id, GaugeMetric::RANDOM_ONE_SAMPLE,
-                                           predicate1Id, nullopt);
-    int64_t gauge4Id = gauge4.id();
-    *config.add_gauge_metric() = gauge4;
-
-    // Will be deleted.
-    GaugeMetric gauge5 =
-            createGaugeMetric("GAUGE5", matcher2Id, GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, {});
-    int64_t gauge5Id = gauge5.id();
-    *config.add_gauge_metric() = gauge5;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
-    sp<EventMatcherWizard> oldMatcherWizard =
-            static_cast<GaugeMetricProducer*>(oldMetricProducers[0].get())->mEventMatcherWizard;
-    EXPECT_EQ(oldMatcherWizard->getStrongCount(), 6);
-
-    // Change gauge2, causing it to be replaced.
-    gauge2.set_max_num_gauge_atoms_per_bucket(50);
-
-    // Mark matcher 3 as replaced. Causes gauge3 and gauge4 to be replaced.
-    set<int64_t> replacedMatchers = {matcher3Id};
-
-    // New gauge metric.
-    GaugeMetric gauge6 = createGaugeMetric("GAUGE6", matcher5Id, GaugeMetric::FIRST_N_SAMPLES,
-                                           predicate1Id, matcher3Id);
-    int64_t gauge6Id = gauge6.id();
-
-    // Map the matchers and predicates in reverse order to force the indices to change.
-    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    const int matcher5Index = 0;
-    newAtomMatchingTrackerMap[matcher5Id] = 0;
-    const int matcher4Index = 1;
-    newAtomMatchingTrackerMap[matcher4Id] = 1;
-    const int matcher3Index = 2;
-    newAtomMatchingTrackerMap[matcher3Id] = 2;
-    const int matcher2Index = 3;
-    newAtomMatchingTrackerMap[matcher2Id] = 3;
-    const int matcher1Index = 4;
-    newAtomMatchingTrackerMap[matcher1Id] = 4;
-    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
-    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
-                      newAtomMatchingTrackers.begin());
-
-    std::unordered_map<int64_t, int> newConditionTrackerMap;
-    const int predicate1Index = 0;
-    newConditionTrackerMap[predicate1Id] = 0;
-    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<ConditionTracker>> newConditionTrackers(1);
-    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
-                      newConditionTrackers.begin());
-    // Say that predicate1 is unknown since the initial condition never changed.
-    vector<ConditionState> conditionCache = {ConditionState::kUnknown};
-
-    StatsdConfig newConfig;
-    *newConfig.add_gauge_metric() = gauge6;
-    const int gauge6Index = 0;
-    *newConfig.add_gauge_metric() = gauge3;
-    const int gauge3Index = 1;
-    *newConfig.add_gauge_metric() = gauge1;
-    const int gauge1Index = 2;
-    *newConfig.add_gauge_metric() = gauge4;
-    const int gauge4Index = 3;
-    *newConfig.add_gauge_metric() = gauge2;
-    const int gauge2Index = 4;
-
-    // Output data structures to validate.
-    unordered_map<int64_t, int> newMetricProducerMap;
-    vector<sp<MetricProducer>> newMetricProducers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    set<int64_t> noReportMetricIds;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
-    vector<int> metricsWithActivation;
-    set<int64_t> replacedMetrics;
-    EXPECT_TRUE(updateMetrics(
-            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
-            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
-            newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{},
-            newConditionTrackers, conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
-            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
-            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
-            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-            metricsWithActivation, replacedMetrics));
-
-    unordered_map<int64_t, int> expectedMetricProducerMap = {
-            {gauge1Id, gauge1Index}, {gauge2Id, gauge2Index}, {gauge3Id, gauge3Index},
-            {gauge4Id, gauge4Index}, {gauge6Id, gauge6Index},
-    };
-    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
-    EXPECT_EQ(replacedMetrics, set<int64_t>({gauge2Id, gauge3Id, gauge4Id}));
-
-    // Make sure preserved metrics are the same.
-    ASSERT_EQ(newMetricProducers.size(), 5);
-    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(gauge1Id)],
-              newMetricProducers[newMetricProducerMap.at(gauge1Id)]);
-
-    // Make sure replaced metrics are different.
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge2Id)],
-              newMetricProducers[newMetricProducerMap.at(gauge2Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge3Id)],
-              newMetricProducers[newMetricProducerMap.at(gauge3Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge4Id)],
-              newMetricProducers[newMetricProducerMap.at(gauge4Id)]);
-
-    // Verify the conditionToMetricMap.
-    ASSERT_EQ(conditionToMetricMap.size(), 1);
-    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
-    EXPECT_THAT(condition1Metrics, UnorderedElementsAre(gauge1Index, gauge4Index, gauge6Index));
-
-    // Verify the trackerToMetricMap.
-    ASSERT_EQ(trackerToMetricMap.size(), 4);
-    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
-    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(gauge1Index, gauge2Index));
-    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
-    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(gauge3Index, gauge4Index, gauge6Index));
-    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
-    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(gauge1Index));
-    const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
-    EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(gauge3Index, gauge6Index));
-
-    // Verify event activation/deactivation maps.
-    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(metricsWithActivation.size(), 0);
-
-    // Verify tracker indices/ids/conditions/states are correct.
-    GaugeMetricProducer* gaugeProducer1 =
-            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge1Index].get());
-    EXPECT_EQ(gaugeProducer1->getMetricId(), gauge1Id);
-    EXPECT_EQ(gaugeProducer1->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(gaugeProducer1->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(gaugeProducer1->mWhatMatcherIndex, matcher4Index);
-    GaugeMetricProducer* gaugeProducer2 =
-            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge2Index].get());
-    EXPECT_EQ(gaugeProducer2->getMetricId(), gauge2Id);
-    EXPECT_EQ(gaugeProducer2->mConditionTrackerIndex, -1);
-    EXPECT_EQ(gaugeProducer2->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(gaugeProducer2->mWhatMatcherIndex, matcher1Index);
-    GaugeMetricProducer* gaugeProducer3 =
-            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge3Index].get());
-    EXPECT_EQ(gaugeProducer3->getMetricId(), gauge3Id);
-    EXPECT_EQ(gaugeProducer3->mConditionTrackerIndex, -1);
-    EXPECT_EQ(gaugeProducer3->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(gaugeProducer3->mWhatMatcherIndex, matcher5Index);
-    GaugeMetricProducer* gaugeProducer4 =
-            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge4Index].get());
-    EXPECT_EQ(gaugeProducer4->getMetricId(), gauge4Id);
-    EXPECT_EQ(gaugeProducer4->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(gaugeProducer4->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(gaugeProducer4->mWhatMatcherIndex, matcher3Index);
-    GaugeMetricProducer* gaugeProducer6 =
-            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge6Index].get());
-    EXPECT_EQ(gaugeProducer6->getMetricId(), gauge6Id);
-    EXPECT_EQ(gaugeProducer6->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(gaugeProducer6->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(gaugeProducer6->mWhatMatcherIndex, matcher5Index);
-
-    sp<EventMatcherWizard> newMatcherWizard = gaugeProducer1->mEventMatcherWizard;
-    EXPECT_NE(newMatcherWizard, oldMatcherWizard);
-    EXPECT_EQ(newMatcherWizard->getStrongCount(), 6);
-    oldMetricProducers.clear();
-    // Only reference to the old wizard should be the one in the test.
-    EXPECT_EQ(oldMatcherWizard->getStrongCount(), 1);
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateDurationMetrics) {
-    StatsdConfig config;
-    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
-    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
-    int64_t matcher2Id = matcher2.id();
-    *config.add_atom_matcher() = matcher2;
-
-    AtomMatcher matcher3 = CreateAcquireWakelockAtomMatcher();
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    AtomMatcher matcher4 = CreateReleaseWakelockAtomMatcher();
-    int64_t matcher4Id = matcher4.id();
-    *config.add_atom_matcher() = matcher4;
-
-    AtomMatcher matcher5 = CreateMoveToForegroundAtomMatcher();
-    int64_t matcher5Id = matcher5.id();
-    *config.add_atom_matcher() = matcher5;
-
-    AtomMatcher matcher6 = CreateMoveToBackgroundAtomMatcher();
-    int64_t matcher6Id = matcher6.id();
-    *config.add_atom_matcher() = matcher6;
-
-    AtomMatcher matcher7 = CreateBatteryStateNoneMatcher();
-    int64_t matcher7Id = matcher7.id();
-    *config.add_atom_matcher() = matcher7;
-
-    AtomMatcher matcher8 = CreateBatteryStateUsbMatcher();
-    int64_t matcher8Id = matcher8.id();
-    *config.add_atom_matcher() = matcher8;
-
-    Predicate predicate1 = CreateScreenIsOnPredicate();
-    int64_t predicate1Id = predicate1.id();
-    *config.add_predicate() = predicate1;
-
-    Predicate predicate2 = CreateScreenIsOffPredicate();
-    int64_t predicate2Id = predicate2.id();
-    *config.add_predicate() = predicate2;
-
-    Predicate predicate3 = CreateDeviceUnpluggedPredicate();
-    int64_t predicate3Id = predicate3.id();
-    *config.add_predicate() = predicate3;
-
-    Predicate predicate4 = CreateIsInBackgroundPredicate();
-    *predicate4.mutable_simple_predicate()->mutable_dimensions() =
-            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1});
-    int64_t predicate4Id = predicate4.id();
-    *config.add_predicate() = predicate4;
-
-    Predicate predicate5 = CreateHoldingWakelockPredicate();
-    *predicate5.mutable_simple_predicate()->mutable_dimensions() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    predicate5.mutable_simple_predicate()->set_stop_all(matcher7Id);
-    int64_t predicate5Id = predicate5.id();
-    *config.add_predicate() = predicate5;
-
-    State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
-    int64_t state1Id = state1.id();
-    *config.add_state() = state1;
-
-    State state2 = CreateScreenState();
-    int64_t state2Id = state2.id();
-    *config.add_state() = state2;
-
-    // Add a few duration metrics.
-    // Will be preserved.
-    DurationMetric duration1 =
-            createDurationMetric("DURATION1", predicate5Id, predicate4Id, {state2Id});
-    *duration1.mutable_dimensions_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    MetricConditionLink* link = duration1.add_links();
-    link->set_condition(predicate4Id);
-    *link->mutable_fields_in_what() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    *link->mutable_fields_in_condition() =
-            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
-    int64_t duration1Id = duration1.id();
-    *config.add_duration_metric() = duration1;
-
-    // Will be replaced.
-    DurationMetric duration2 = createDurationMetric("DURATION2", predicate1Id, nullopt, {});
-    int64_t duration2Id = duration2.id();
-    *config.add_duration_metric() = duration2;
-
-    // Will be replaced.
-    DurationMetric duration3 = createDurationMetric("DURATION3", predicate3Id, nullopt, {state1Id});
-    int64_t duration3Id = duration3.id();
-    *config.add_duration_metric() = duration3;
-
-    // Will be replaced.
-    DurationMetric duration4 = createDurationMetric("DURATION4", predicate3Id, predicate2Id, {});
-    int64_t duration4Id = duration4.id();
-    *config.add_duration_metric() = duration4;
-
-    // Will be deleted.
-    DurationMetric duration5 = createDurationMetric("DURATION5", predicate2Id, nullopt, {});
-    int64_t duration5Id = duration5.id();
-    *config.add_duration_metric() = duration5;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Make some sliced conditions true.
-    int uid1 = 10;
-    int uid2 = 11;
-    vector<MatchingState> matchingStates(8, MatchingState::kNotMatched);
-    matchingStates[2] = kMatched;
-    vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
-    vector<bool> changedCache(5, false);
-    unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(timeBaseNs + 3, {uid1}, {"tag"}, "wl1");
-    oldConditionTrackers[4]->evaluateCondition(*event.get(), matchingStates, oldConditionTrackers,
-                                               conditionCache, changedCache);
-    EXPECT_TRUE(oldConditionTrackers[4]->isSliced());
-    EXPECT_TRUE(changedCache[4]);
-    EXPECT_EQ(conditionCache[4], ConditionState::kTrue);
-    oldMetricProducers[0]->onMatchedLogEvent(2, *event.get());
-
-    fill(conditionCache.begin(), conditionCache.end(), ConditionState::kNotEvaluated);
-    fill(changedCache.begin(), changedCache.end(), false);
-    event = CreateAcquireWakelockEvent(timeBaseNs + 3, {uid2}, {"tag"}, "wl2");
-    oldConditionTrackers[4]->evaluateCondition(*event.get(), matchingStates, oldConditionTrackers,
-                                               conditionCache, changedCache);
-    EXPECT_TRUE(changedCache[4]);
-    EXPECT_EQ(conditionCache[4], ConditionState::kTrue);
-    oldMetricProducers[0]->onMatchedLogEvent(2, *event.get());
-
-    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
-    // The duration trackers have a pointer to the wizard, and 2 trackers were created above.
-    sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
-    EXPECT_EQ(oldConditionWizard->getStrongCount(), 8);
-
-    // Replace predicate1, predicate3, and state1. Causes duration2/3/4 to be replaced.
-    set<int64_t> replacedConditions({predicate1Id, predicate2Id});
-    set<int64_t> replacedStates({state1Id});
-
-    // New duration metric.
-    DurationMetric duration6 = createDurationMetric("DURATION6", predicate4Id, predicate5Id, {});
-    *duration6.mutable_dimensions_in_what() =
-            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
-    link = duration6.add_links();
-    link->set_condition(predicate5Id);
-    *link->mutable_fields_in_what() =
-            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
-    *link->mutable_fields_in_condition() =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    int64_t duration6Id = duration6.id();
-
-    // Map the matchers and predicates in reverse order to force the indices to change.
-    const int matcher8Index = 0, matcher7Index = 1, matcher6Index = 2, matcher5Index = 3,
-              matcher4Index = 4, matcher3Index = 5, matcher2Index = 6, matcher1Index = 7;
-    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap({{matcher8Id, matcher8Index},
-                                                                {matcher7Id, matcher7Index},
-                                                                {matcher6Id, matcher6Index},
-                                                                {matcher5Id, matcher5Index},
-                                                                {matcher4Id, matcher4Index},
-                                                                {matcher3Id, matcher3Index},
-                                                                {matcher2Id, matcher2Index},
-                                                                {matcher1Id, matcher1Index}});
-    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(8);
-    reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
-                 newAtomMatchingTrackers.begin());
-
-    const int predicate5Index = 0, predicate4Index = 1, predicate3Index = 2, predicate2Index = 3,
-              predicate1Index = 4;
-    std::unordered_map<int64_t, int> newConditionTrackerMap({
-            {predicate5Id, predicate5Index},
-            {predicate4Id, predicate4Index},
-            {predicate3Id, predicate3Index},
-            {predicate2Id, predicate2Index},
-            {predicate1Id, predicate1Index},
-    });
-    // Use the existing conditionTrackers and reinitialize them to get the initial condition cache.
-    vector<sp<ConditionTracker>> newConditionTrackers(5);
-    reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
-                 newConditionTrackers.begin());
-    vector<Predicate> conditionProtos(5);
-    reverse_copy(config.predicate().begin(), config.predicate().end(), conditionProtos.begin());
-    for (int i = 0; i < newConditionTrackers.size(); i++) {
-        EXPECT_TRUE(newConditionTrackers[i]->onConfigUpdated(
-                conditionProtos, i, newConditionTrackers, newAtomMatchingTrackerMap,
-                newConditionTrackerMap));
-    }
-    vector<bool> cycleTracker(5, false);
-    fill(conditionCache.begin(), conditionCache.end(), ConditionState::kNotEvaluated);
-    for (int i = 0; i < newConditionTrackers.size(); i++) {
-        EXPECT_TRUE(newConditionTrackers[i]->init(conditionProtos, newConditionTrackers,
-                                                  newConditionTrackerMap, cycleTracker,
-                                                  conditionCache));
-    }
-    // Predicate5 should be true since 2 uids have wakelocks
-    EXPECT_EQ(conditionCache, vector({kTrue, kUnknown, kUnknown, kUnknown, kUnknown}));
-
-    StatsdConfig newConfig;
-    *newConfig.add_duration_metric() = duration6;
-    const int duration6Index = 0;
-    *newConfig.add_duration_metric() = duration3;
-    const int duration3Index = 1;
-    *newConfig.add_duration_metric() = duration1;
-    const int duration1Index = 2;
-    *newConfig.add_duration_metric() = duration4;
-    const int duration4Index = 3;
-    *newConfig.add_duration_metric() = duration2;
-    const int duration2Index = 4;
-
-    for (const Predicate& predicate : conditionProtos) {
-        *newConfig.add_predicate() = predicate;
-    }
-    *newConfig.add_state() = state1;
-    *newConfig.add_state() = state2;
-    unordered_map<int64_t, int> stateAtomIdMap;
-    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
-    map<int64_t, uint64_t> stateProtoHashes;
-    EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes));
-
-    // Output data structures to validate.
-    unordered_map<int64_t, int> newMetricProducerMap;
-    vector<sp<MetricProducer>> newMetricProducers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    set<int64_t> noReportMetricIds;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
-    vector<int> metricsWithActivation;
-    set<int64_t> replacedMetrics;
-    EXPECT_TRUE(updateMetrics(
-            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
-            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
-            newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
-            newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
-            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers,
-            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
-            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-            metricsWithActivation, replacedMetrics));
-
-    unordered_map<int64_t, int> expectedMetricProducerMap = {
-            {duration1Id, duration1Index}, {duration2Id, duration2Index},
-            {duration3Id, duration3Index}, {duration4Id, duration4Index},
-            {duration6Id, duration6Index},
-    };
-    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
-    EXPECT_EQ(replacedMetrics, set<int64_t>({duration2Id, duration3Id, duration4Id}));
-    // Make sure preserved metrics are the same.
-    ASSERT_EQ(newMetricProducers.size(), 5);
-    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(duration1Id)],
-              newMetricProducers[newMetricProducerMap.at(duration1Id)]);
-
-    // Make sure replaced metrics are different.
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration2Id)],
-              newMetricProducers[newMetricProducerMap.at(duration2Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration3Id)],
-              newMetricProducers[newMetricProducerMap.at(duration3Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration4Id)],
-              newMetricProducers[newMetricProducerMap.at(duration4Id)]);
-
-    // Verify the conditionToMetricMap. Note that the "what" is not in this map.
-    ASSERT_EQ(conditionToMetricMap.size(), 3);
-    const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
-    EXPECT_THAT(condition2Metrics, UnorderedElementsAre(duration4Index));
-    const vector<int>& condition4Metrics = conditionToMetricMap[predicate4Index];
-    EXPECT_THAT(condition4Metrics, UnorderedElementsAre(duration1Index));
-    const vector<int>& condition5Metrics = conditionToMetricMap[predicate5Index];
-    EXPECT_THAT(condition5Metrics, UnorderedElementsAre(duration6Index));
-
-    // Verify the trackerToMetricMap. The start/stop/stopall indices from the "what" should be here.
-    ASSERT_EQ(trackerToMetricMap.size(), 8);
-    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
-    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(duration2Index));
-    const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
-    EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(duration2Index));
-    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
-    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(duration1Index));
-    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
-    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(duration1Index));
-    const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
-    EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(duration6Index));
-    const vector<int>& matcher6Metrics = trackerToMetricMap[matcher6Index];
-    EXPECT_THAT(matcher6Metrics, UnorderedElementsAre(duration6Index));
-    const vector<int>& matcher7Metrics = trackerToMetricMap[matcher7Index];
-    EXPECT_THAT(matcher7Metrics,
-                UnorderedElementsAre(duration1Index, duration3Index, duration4Index));
-    const vector<int>& matcher8Metrics = trackerToMetricMap[matcher8Index];
-    EXPECT_THAT(matcher8Metrics, UnorderedElementsAre(duration3Index, duration4Index));
-
-    // Verify event activation/deactivation maps.
-    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(metricsWithActivation.size(), 0);
-
-    // Verify tracker indices/ids/conditions are correct.
-    DurationMetricProducer* durationProducer1 =
-            static_cast<DurationMetricProducer*>(newMetricProducers[duration1Index].get());
-    EXPECT_EQ(durationProducer1->getMetricId(), duration1Id);
-    EXPECT_EQ(durationProducer1->mConditionTrackerIndex, predicate4Index);
-    EXPECT_EQ(durationProducer1->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(durationProducer1->mStartIndex, matcher3Index);
-    EXPECT_EQ(durationProducer1->mStopIndex, matcher4Index);
-    EXPECT_EQ(durationProducer1->mStopAllIndex, matcher7Index);
-    EXPECT_EQ(durationProducer1->mCurrentSlicedDurationTrackerMap.size(), 2);
-    for (const auto& durationTrackerIt : durationProducer1->mCurrentSlicedDurationTrackerMap) {
-        EXPECT_EQ(durationTrackerIt.second->mConditionTrackerIndex, predicate4Index);
-    }
-    DurationMetricProducer* durationProducer2 =
-            static_cast<DurationMetricProducer*>(newMetricProducers[duration2Index].get());
-    EXPECT_EQ(durationProducer2->getMetricId(), duration2Id);
-    EXPECT_EQ(durationProducer2->mConditionTrackerIndex, -1);
-    EXPECT_EQ(durationProducer2->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(durationProducer2->mStartIndex, matcher1Index);
-    EXPECT_EQ(durationProducer2->mStopIndex, matcher2Index);
-    EXPECT_EQ(durationProducer2->mStopAllIndex, -1);
-    DurationMetricProducer* durationProducer3 =
-            static_cast<DurationMetricProducer*>(newMetricProducers[duration3Index].get());
-    EXPECT_EQ(durationProducer3->getMetricId(), duration3Id);
-    EXPECT_EQ(durationProducer3->mConditionTrackerIndex, -1);
-    EXPECT_EQ(durationProducer3->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(durationProducer3->mStartIndex, matcher7Index);
-    EXPECT_EQ(durationProducer3->mStopIndex, matcher8Index);
-    EXPECT_EQ(durationProducer3->mStopAllIndex, -1);
-    DurationMetricProducer* durationProducer4 =
-            static_cast<DurationMetricProducer*>(newMetricProducers[duration4Index].get());
-    EXPECT_EQ(durationProducer4->getMetricId(), duration4Id);
-    EXPECT_EQ(durationProducer4->mConditionTrackerIndex, predicate2Index);
-    EXPECT_EQ(durationProducer4->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(durationProducer4->mStartIndex, matcher7Index);
-    EXPECT_EQ(durationProducer4->mStopIndex, matcher8Index);
-    EXPECT_EQ(durationProducer4->mStopAllIndex, -1);
-    DurationMetricProducer* durationProducer6 =
-            static_cast<DurationMetricProducer*>(newMetricProducers[duration6Index].get());
-    EXPECT_EQ(durationProducer6->getMetricId(), duration6Id);
-    EXPECT_EQ(durationProducer6->mConditionTrackerIndex, predicate5Index);
-    // TODO(b/167491517): should this be unknown since the condition is sliced?
-    EXPECT_EQ(durationProducer6->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(durationProducer6->mStartIndex, matcher6Index);
-    EXPECT_EQ(durationProducer6->mStopIndex, matcher5Index);
-    EXPECT_EQ(durationProducer6->mStopAllIndex, -1);
-
-    sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
-    EXPECT_NE(newConditionWizard, oldConditionWizard);
-    EXPECT_EQ(newConditionWizard->getStrongCount(), 8);
-    oldMetricProducers.clear();
-    // Only reference to the old wizard should be the one in the test.
-    EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateValueMetrics) {
-    StatsdConfig config;
-
-    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
-    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
-    int64_t matcher2Id = matcher2.id();
-    *config.add_atom_matcher() = matcher2;
-
-    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    AtomMatcher matcher4 = CreateTemperatureAtomMatcher();
-    int64_t matcher4Id = matcher4.id();
-    *config.add_atom_matcher() = matcher4;
-
-    AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
-    int64_t matcher5Id = matcher5.id();
-    *config.add_atom_matcher() = matcher5;
-
-    Predicate predicate1 = CreateScreenIsOnPredicate();
-    int64_t predicate1Id = predicate1.id();
-    *config.add_predicate() = predicate1;
-
-    Predicate predicate2 = CreateScreenIsOffPredicate();
-    int64_t predicate2Id = predicate2.id();
-    *config.add_predicate() = predicate2;
-
-    State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
-    int64_t state1Id = state1.id();
-    *config.add_state() = state1;
-
-    State state2 = CreateScreenState();
-    int64_t state2Id = state2.id();
-    *config.add_state() = state2;
-
-    // Add a few value metrics.
-    // Note that these will not work as "real" metrics since the value field is always 2.
-    // Will be preserved.
-    ValueMetric value1 = createValueMetric("VALUE1", matcher4, predicate1Id, {state1Id});
-    int64_t value1Id = value1.id();
-    *config.add_value_metric() = value1;
-
-    // Will be replaced - definition change.
-    ValueMetric value2 = createValueMetric("VALUE2", matcher1, nullopt, {});
-    int64_t value2Id = value2.id();
-    *config.add_value_metric() = value2;
-
-    // Will be replaced - condition change.
-    ValueMetric value3 = createValueMetric("VALUE3", matcher5, predicate2Id, {});
-    int64_t value3Id = value3.id();
-    *config.add_value_metric() = value3;
-
-    // Will be replaced - state change.
-    ValueMetric value4 = createValueMetric("VALUE4", matcher3, nullopt, {state2Id});
-    int64_t value4Id = value4.id();
-    *config.add_value_metric() = value4;
-
-    // Will be deleted.
-    ValueMetric value5 = createValueMetric("VALUE5", matcher2, nullopt, {});
-    int64_t value5Id = value5.id();
-    *config.add_value_metric() = value5;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
-    sp<EventMatcherWizard> oldMatcherWizard =
-            static_cast<ValueMetricProducer*>(oldMetricProducers[0].get())->mEventMatcherWizard;
-    EXPECT_EQ(oldMatcherWizard->getStrongCount(), 6);
-
-    // Change value2, causing it to be replaced.
-    value2.set_aggregation_type(ValueMetric::AVG);
-
-    // Mark predicate 2 as replaced. Causes value3 to be replaced.
-    set<int64_t> replacedConditions = {predicate2Id};
-
-    // Mark state 2 as replaced. Causes value4 to be replaced.
-    set<int64_t> replacedStates = {state2Id};
-
-    // New value metric.
-    ValueMetric value6 = createValueMetric("VALUE6", matcher5, predicate1Id, {state1Id});
-    int64_t value6Id = value6.id();
-
-    // Map the matchers and predicates in reverse order to force the indices to change.
-    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    const int matcher5Index = 0;
-    newAtomMatchingTrackerMap[matcher5Id] = 0;
-    const int matcher4Index = 1;
-    newAtomMatchingTrackerMap[matcher4Id] = 1;
-    const int matcher3Index = 2;
-    newAtomMatchingTrackerMap[matcher3Id] = 2;
-    const int matcher2Index = 3;
-    newAtomMatchingTrackerMap[matcher2Id] = 3;
-    const int matcher1Index = 4;
-    newAtomMatchingTrackerMap[matcher1Id] = 4;
-    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
-    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
-                      newAtomMatchingTrackers.begin());
-
-    std::unordered_map<int64_t, int> newConditionTrackerMap;
-    const int predicate2Index = 0;
-    newConditionTrackerMap[predicate2Id] = 0;
-    const int predicate1Index = 1;
-    newConditionTrackerMap[predicate1Id] = 1;
-    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<ConditionTracker>> newConditionTrackers(2);
-    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
-                      newConditionTrackers.begin());
-    // Say that predicate1 & predicate2 is unknown since the initial condition never changed.
-    vector<ConditionState> conditionCache = {ConditionState::kUnknown, ConditionState::kUnknown};
-
-    StatsdConfig newConfig;
-    *newConfig.add_value_metric() = value6;
-    const int value6Index = 0;
-    *newConfig.add_value_metric() = value3;
-    const int value3Index = 1;
-    *newConfig.add_value_metric() = value1;
-    const int value1Index = 2;
-    *newConfig.add_value_metric() = value4;
-    const int value4Index = 3;
-    *newConfig.add_value_metric() = value2;
-    const int value2Index = 4;
-
-    *newConfig.add_state() = state1;
-    *newConfig.add_state() = state2;
-
-    unordered_map<int64_t, int> stateAtomIdMap;
-    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
-    map<int64_t, uint64_t> stateProtoHashes;
-    EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes));
-
-    // Output data structures to validate.
-    unordered_map<int64_t, int> newMetricProducerMap;
-    vector<sp<MetricProducer>> newMetricProducers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    set<int64_t> noReportMetricIds;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
-    vector<int> metricsWithActivation;
-    set<int64_t> replacedMetrics;
-    EXPECT_TRUE(updateMetrics(
-            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
-            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
-            newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
-            newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
-            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers,
-            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
-            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-            metricsWithActivation, replacedMetrics));
-
-    unordered_map<int64_t, int> expectedMetricProducerMap = {
-            {value1Id, value1Index}, {value2Id, value2Index}, {value3Id, value3Index},
-            {value4Id, value4Index}, {value6Id, value6Index},
-    };
-    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
-    EXPECT_EQ(replacedMetrics, set<int64_t>({value2Id, value3Id, value4Id}));
-
-    // Make sure preserved metrics are the same.
-    ASSERT_EQ(newMetricProducers.size(), 5);
-    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(value1Id)],
-              newMetricProducers[newMetricProducerMap.at(value1Id)]);
-
-    // Make sure replaced metrics are different.
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value2Id)],
-              newMetricProducers[newMetricProducerMap.at(value2Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value3Id)],
-              newMetricProducers[newMetricProducerMap.at(value3Id)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value4Id)],
-              newMetricProducers[newMetricProducerMap.at(value4Id)]);
-
-    // Verify the conditionToMetricMap.
-    ASSERT_EQ(conditionToMetricMap.size(), 2);
-    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
-    EXPECT_THAT(condition1Metrics, UnorderedElementsAre(value1Index, value6Index));
-    const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
-    EXPECT_THAT(condition2Metrics, UnorderedElementsAre(value3Index));
-
-    // Verify the trackerToMetricMap.
-    ASSERT_EQ(trackerToMetricMap.size(), 4);
-    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
-    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(value2Index));
-    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
-    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(value4Index));
-    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
-    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(value1Index));
-    const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
-    EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(value3Index, value6Index));
-
-    // Verify event activation/deactivation maps.
-    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(metricsWithActivation.size(), 0);
-
-    // Verify tracker indices/ids/conditions/states are correct.
-    ValueMetricProducer* valueProducer1 =
-            static_cast<ValueMetricProducer*>(newMetricProducers[value1Index].get());
-    EXPECT_EQ(valueProducer1->getMetricId(), value1Id);
-    EXPECT_EQ(valueProducer1->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(valueProducer1->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(valueProducer1->mWhatMatcherIndex, matcher4Index);
-    ValueMetricProducer* valueProducer2 =
-            static_cast<ValueMetricProducer*>(newMetricProducers[value2Index].get());
-    EXPECT_EQ(valueProducer2->getMetricId(), value2Id);
-    EXPECT_EQ(valueProducer2->mConditionTrackerIndex, -1);
-    EXPECT_EQ(valueProducer2->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(valueProducer2->mWhatMatcherIndex, matcher1Index);
-    ValueMetricProducer* valueProducer3 =
-            static_cast<ValueMetricProducer*>(newMetricProducers[value3Index].get());
-    EXPECT_EQ(valueProducer3->getMetricId(), value3Id);
-    EXPECT_EQ(valueProducer3->mConditionTrackerIndex, predicate2Index);
-    EXPECT_EQ(valueProducer3->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(valueProducer3->mWhatMatcherIndex, matcher5Index);
-    ValueMetricProducer* valueProducer4 =
-            static_cast<ValueMetricProducer*>(newMetricProducers[value4Index].get());
-    EXPECT_EQ(valueProducer4->getMetricId(), value4Id);
-    EXPECT_EQ(valueProducer4->mConditionTrackerIndex, -1);
-    EXPECT_EQ(valueProducer4->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(valueProducer4->mWhatMatcherIndex, matcher3Index);
-    ValueMetricProducer* valueProducer6 =
-            static_cast<ValueMetricProducer*>(newMetricProducers[value6Index].get());
-    EXPECT_EQ(valueProducer6->getMetricId(), value6Id);
-    EXPECT_EQ(valueProducer6->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(valueProducer6->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(valueProducer6->mWhatMatcherIndex, matcher5Index);
-
-    sp<EventMatcherWizard> newMatcherWizard = valueProducer1->mEventMatcherWizard;
-    EXPECT_NE(newMatcherWizard, oldMatcherWizard);
-    EXPECT_EQ(newMatcherWizard->getStrongCount(), 6);
-    oldMetricProducers.clear();
-    // Only reference to the old wizard should be the one in the test.
-    EXPECT_EQ(oldMatcherWizard->getStrongCount(), 1);
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateMetricActivations) {
-    StatsdConfig config;
-    // Add atom matchers
-    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
-    int64_t matcher2Id = matcher2.id();
-    *config.add_atom_matcher() = matcher2;
-
-    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
-    int64_t matcher4Id = matcher4.id();
-    *config.add_atom_matcher() = matcher4;
-
-    // Add an event metric with multiple activations.
-    EventMetric event1 = createEventMetric("EVENT1", matcher1Id, nullopt);
-    int64_t event1Id = event1.id();
-    *config.add_event_metric() = event1;
-
-    int64_t matcher2TtlSec = 2, matcher3TtlSec = 3, matcher4TtlSec = 4;
-    MetricActivation metricActivation;
-    metricActivation.set_metric_id(event1Id);
-    EventActivation* activation = metricActivation.add_event_activation();
-    activation->set_atom_matcher_id(matcher2Id);
-    activation->set_ttl_seconds(matcher2TtlSec);
-    activation->set_activation_type(ACTIVATE_IMMEDIATELY);
-    activation->set_deactivation_atom_matcher_id(matcher1Id);
-    activation = metricActivation.add_event_activation();
-    activation->set_atom_matcher_id(matcher3Id);
-    activation->set_ttl_seconds(matcher3TtlSec);
-    activation->set_activation_type(ACTIVATE_ON_BOOT);
-    activation->set_deactivation_atom_matcher_id(matcher1Id);
-    activation = metricActivation.add_event_activation();
-    activation->set_atom_matcher_id(matcher4Id);
-    activation->set_ttl_seconds(matcher4TtlSec);
-    activation->set_activation_type(ACTIVATE_IMMEDIATELY);
-    activation->set_deactivation_atom_matcher_id(matcher2Id);
-    *config.add_metric_activation() = metricActivation;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Activate some of the event activations.
-    ASSERT_EQ(oldMetricProducers[0]->getMetricId(), event1Id);
-    int64_t matcher2StartNs = 12345;
-    oldMetricProducers[0]->activate(oldAtomMatchingTrackerMap[matcher2Id], matcher2StartNs);
-    int64_t matcher3StartNs = 23456;
-    oldMetricProducers[0]->activate(oldAtomMatchingTrackerMap[matcher3Id], matcher3StartNs);
-    EXPECT_TRUE(oldMetricProducers[0]->isActive());
-
-    // Map the matchers and predicates in reverse order to force the indices to change.
-    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    const int matcher4Index = 0;
-    newAtomMatchingTrackerMap[matcher4Id] = 0;
-    const int matcher3Index = 1;
-    newAtomMatchingTrackerMap[matcher3Id] = 1;
-    const int matcher2Index = 2;
-    newAtomMatchingTrackerMap[matcher2Id] = 2;
-    const int matcher1Index = 3;
-    newAtomMatchingTrackerMap[matcher1Id] = 3;
-    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(4);
-    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
-                      newAtomMatchingTrackers.begin());
-    set<int64_t> replacedMatchers;
-
-    unordered_map<int64_t, int> newConditionTrackerMap;
-    vector<sp<ConditionTracker>> newConditionTrackers;
-    set<int64_t> replacedConditions;
-    vector<ConditionState> conditionCache;
-    unordered_map<int64_t, int> newMetricProducerMap;
-    vector<sp<MetricProducer>> newMetricProducers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    set<int64_t> noReportMetricIds;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
-    vector<int> metricsWithActivation;
-    set<int64_t> replacedMetrics;
-    EXPECT_TRUE(updateMetrics(
-            key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
-            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
-            newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
-            newConditionTrackers, conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
-            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
-            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
-            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-            metricsWithActivation, replacedMetrics));
-
-    // Verify event activation/deactivation maps.
-    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 3);
-    EXPECT_THAT(activationAtomTrackerToMetricMap[matcher2Index], UnorderedElementsAre(0));
-    EXPECT_THAT(activationAtomTrackerToMetricMap[matcher3Index], UnorderedElementsAre(0));
-    EXPECT_THAT(activationAtomTrackerToMetricMap[matcher4Index], UnorderedElementsAre(0));
-    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 2);
-    EXPECT_THAT(deactivationAtomTrackerToMetricMap[matcher1Index], UnorderedElementsAre(0, 0));
-    EXPECT_THAT(deactivationAtomTrackerToMetricMap[matcher2Index], UnorderedElementsAre(0));
-    ASSERT_EQ(metricsWithActivation.size(), 1);
-    EXPECT_THAT(metricsWithActivation, UnorderedElementsAre(0));
-
-    // Verify mEventActivation and mEventDeactivation map of the producer.
-    sp<MetricProducer> producer = newMetricProducers[0];
-    EXPECT_TRUE(producer->isActive());
-    ASSERT_EQ(producer->mEventActivationMap.size(), 3);
-    shared_ptr<Activation> matcher2Activation = producer->mEventActivationMap[matcher2Index];
-    EXPECT_EQ(matcher2Activation->ttl_ns, matcher2TtlSec * NS_PER_SEC);
-    EXPECT_EQ(matcher2Activation->activationType, ACTIVATE_IMMEDIATELY);
-    EXPECT_EQ(matcher2Activation->state, kActive);
-    EXPECT_EQ(matcher2Activation->start_ns, matcher2StartNs);
-    shared_ptr<Activation> matcher3Activation = producer->mEventActivationMap[matcher3Index];
-    EXPECT_EQ(matcher3Activation->ttl_ns, matcher3TtlSec * NS_PER_SEC);
-    EXPECT_EQ(matcher3Activation->activationType, ACTIVATE_ON_BOOT);
-    EXPECT_EQ(matcher3Activation->state, kActiveOnBoot);
-    shared_ptr<Activation> matcher4Activation = producer->mEventActivationMap[matcher4Index];
-    EXPECT_EQ(matcher4Activation->ttl_ns, matcher4TtlSec * NS_PER_SEC);
-    EXPECT_EQ(matcher4Activation->activationType, ACTIVATE_IMMEDIATELY);
-    EXPECT_EQ(matcher4Activation->state, kNotActive);
-
-    ASSERT_EQ(producer->mEventDeactivationMap.size(), 2);
-    EXPECT_THAT(producer->mEventDeactivationMap[matcher1Index],
-                UnorderedElementsAre(matcher2Activation, matcher3Activation));
-    EXPECT_THAT(producer->mEventDeactivationMap[matcher2Index],
-                UnorderedElementsAre(matcher4Activation));
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) {
-    StatsdConfig config;
-    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig
-    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
-    int64_t matcher1Id = matcher1.id();
-    *config.add_atom_matcher() = matcher1;
-
-    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
-    int64_t matcher2Id = matcher2.id();
-    *config.add_atom_matcher() = matcher2;
-
-    AtomMatcher matcher3 = CreateTemperatureAtomMatcher();
-    int64_t matcher3Id = matcher3.id();
-    *config.add_atom_matcher() = matcher3;
-
-    Predicate predicate1 = CreateScreenIsOnPredicate();
-    int64_t predicate1Id = predicate1.id();
-    *config.add_predicate() = predicate1;
-
-    // Add a few count metrics.
-    // Will be preserved.
-    CountMetric countMetric = createCountMetric("COUNT1", matcher1Id, predicate1Id, {});
-    int64_t countMetricId = countMetric.id();
-    *config.add_count_metric() = countMetric;
-
-    // Will be replaced since matcher2 is replaced.
-    EventMetric eventMetric = createEventMetric("EVENT1", matcher2Id, nullopt);
-    int64_t eventMetricId = eventMetric.id();
-    *config.add_event_metric() = eventMetric;
-
-    // Will be replaced because the definition changes - a predicate is added.
-    GaugeMetric gaugeMetric = createGaugeMetric("GAUGE1", matcher3Id,
-                                                GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
-    int64_t gaugeMetricId = gaugeMetric.id();
-    *config.add_gauge_metric() = gaugeMetric;
-
-    // Preserved.
-    ValueMetric valueMetric = createValueMetric("VALUE1", matcher3, predicate1Id, {});
-    int64_t valueMetricId = valueMetric.id();
-    *config.add_value_metric() = valueMetric;
-
-    // Preserved.
-    DurationMetric durationMetric = createDurationMetric("DURATION1", predicate1Id, nullopt, {});
-    int64_t durationMetricId = durationMetric.id();
-    *config.add_duration_metric() = durationMetric;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
-    sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
-    EXPECT_EQ(oldConditionWizard->getStrongCount(), 6);
-
-    // Mark matcher 2 as replaced. Causes eventMetric to be replaced.
-    set<int64_t> replacedMatchers;
-    replacedMatchers.insert(matcher2Id);
-
-    // Add predicate1 as a predicate on gaugeMetric, causing it to be replaced.
-    gaugeMetric.set_condition(predicate1Id);
-
-    // Map the matchers and predicates in reverse order to force the indices to change.
-    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
-    const int matcher3Index = 0;
-    newAtomMatchingTrackerMap[matcher3Id] = 0;
-    const int matcher2Index = 1;
-    newAtomMatchingTrackerMap[matcher2Id] = 1;
-    const int matcher1Index = 2;
-    newAtomMatchingTrackerMap[matcher1Id] = 2;
-    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(3);
-    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
-                      newAtomMatchingTrackers.begin());
-
-    std::unordered_map<int64_t, int> newConditionTrackerMap;
-    const int predicate1Index = 0;
-    newConditionTrackerMap[predicate1Id] = 0;
-    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
-    vector<sp<ConditionTracker>> newConditionTrackers(1);
-    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
-                      newConditionTrackers.begin());
-    vector<ConditionState> conditionCache = {ConditionState::kUnknown};
-
-    // The order matters. we parse in the order of: count, duration, event, value, gauge.
-    StatsdConfig newConfig;
-    *newConfig.add_count_metric() = countMetric;
-    const int countMetricIndex = 0;
-    *newConfig.add_duration_metric() = durationMetric;
-    const int durationMetricIndex = 1;
-    *newConfig.add_event_metric() = eventMetric;
-    const int eventMetricIndex = 2;
-    *newConfig.add_value_metric() = valueMetric;
-    const int valueMetricIndex = 3;
-    *newConfig.add_gauge_metric() = gaugeMetric;
-    const int gaugeMetricIndex = 4;
-
-    // Add the predicate since duration metric needs it.
-    *newConfig.add_predicate() = predicate1;
-
-    // Output data structures to validate.
-    unordered_map<int64_t, int> newMetricProducerMap;
-    vector<sp<MetricProducer>> newMetricProducers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    set<int64_t> noReportMetricIds;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
-    vector<int> metricsWithActivation;
-    set<int64_t> replacedMetrics;
-    EXPECT_TRUE(updateMetrics(
-            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
-            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
-            newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{},
-            newConditionTrackers, conditionCache, /*stateAtomIdMap*/ {}, /*allStateGroupMaps=*/{},
-            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
-            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
-            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-            metricsWithActivation, replacedMetrics));
-
-    unordered_map<int64_t, int> expectedMetricProducerMap = {
-            {countMetricId, countMetricIndex}, {durationMetricId, durationMetricIndex},
-            {eventMetricId, eventMetricIndex}, {valueMetricId, valueMetricIndex},
-            {gaugeMetricId, gaugeMetricIndex},
-    };
-    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
-
-    EXPECT_EQ(replacedMetrics, set<int64_t>({eventMetricId, gaugeMetricId}));
-
-    // Make sure preserved metrics are the same.
-    ASSERT_EQ(newMetricProducers.size(), 5);
-    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(countMetricId)],
-              newMetricProducers[newMetricProducerMap.at(countMetricId)]);
-    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(durationMetricId)],
-              newMetricProducers[newMetricProducerMap.at(durationMetricId)]);
-    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(valueMetricId)],
-              newMetricProducers[newMetricProducerMap.at(valueMetricId)]);
-
-    // Make sure replaced metrics are different.
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(eventMetricId)],
-              newMetricProducers[newMetricProducerMap.at(eventMetricId)]);
-    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gaugeMetricId)],
-              newMetricProducers[newMetricProducerMap.at(gaugeMetricId)]);
-
-    // Verify the conditionToMetricMap.
-    ASSERT_EQ(conditionToMetricMap.size(), 1);
-    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
-    EXPECT_THAT(condition1Metrics,
-                UnorderedElementsAre(countMetricIndex, gaugeMetricIndex, valueMetricIndex));
-
-    // Verify the trackerToMetricMap.
-    ASSERT_EQ(trackerToMetricMap.size(), 3);
-    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
-    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(countMetricIndex, durationMetricIndex));
-    const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
-    EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(eventMetricIndex, durationMetricIndex));
-    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
-    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(gaugeMetricIndex, valueMetricIndex));
-
-    // Verify event activation/deactivation maps.
-    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
-    ASSERT_EQ(metricsWithActivation.size(), 0);
-
-    // Verify tracker indices/ids/conditions are correct.
-    EXPECT_EQ(newMetricProducers[countMetricIndex]->getMetricId(), countMetricId);
-    EXPECT_EQ(newMetricProducers[countMetricIndex]->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(newMetricProducers[countMetricIndex]->mCondition, ConditionState::kUnknown);
-    EXPECT_EQ(newMetricProducers[durationMetricIndex]->getMetricId(), durationMetricId);
-    EXPECT_EQ(newMetricProducers[durationMetricIndex]->mConditionTrackerIndex, -1);
-    EXPECT_EQ(newMetricProducers[durationMetricIndex]->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(newMetricProducers[eventMetricIndex]->getMetricId(), eventMetricId);
-    EXPECT_EQ(newMetricProducers[eventMetricIndex]->mConditionTrackerIndex, -1);
-    EXPECT_EQ(newMetricProducers[eventMetricIndex]->mCondition, ConditionState::kTrue);
-    EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->getMetricId(), gaugeMetricId);
-    EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->mConditionTrackerIndex, predicate1Index);
-    EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->mCondition, ConditionState::kUnknown);
-
-    sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
-    EXPECT_NE(newConditionWizard, oldConditionWizard);
-    EXPECT_EQ(newConditionWizard->getStrongCount(), 6);
-    oldMetricProducers.clear();
-    // Only reference to the old wizard should be the one in the test.
-    EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
-}
-
-TEST_F(ConfigUpdateTest, TestAlertPreserve) {
-    StatsdConfig config;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
-
-    Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
-    *config.add_alert() = alert;
-    EXPECT_TRUE(initConfig(config));
-
-    UpdateStatus updateStatus = UPDATE_UNKNOWN;
-    EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
-                                           /*replacedMetrics*/ {}, updateStatus));
-    EXPECT_EQ(updateStatus, UPDATE_PRESERVE);
-}
-
-TEST_F(ConfigUpdateTest, TestAlertMetricChanged) {
-    StatsdConfig config;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    CountMetric metric = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
-    *config.add_count_metric() = metric;
-
-    Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
-    *config.add_alert() = alert;
-    EXPECT_TRUE(initConfig(config));
-
-    UpdateStatus updateStatus = UPDATE_UNKNOWN;
-    EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
-                                           /*replacedMetrics*/ {metric.id()}, updateStatus));
-    EXPECT_EQ(updateStatus, UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestAlertDefinitionChanged) {
-    StatsdConfig config;
-    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
-    *config.add_atom_matcher() = whatMatcher;
-
-    *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
-
-    Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
-    *config.add_alert() = alert;
-    EXPECT_TRUE(initConfig(config));
-
-    alert.set_num_buckets(2);
-
-    UpdateStatus updateStatus = UPDATE_UNKNOWN;
-    EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
-                                           /*replacedMetrics*/ {}, updateStatus));
-    EXPECT_EQ(updateStatus, UPDATE_REPLACE);
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateAlerts) {
-    StatsdConfig config;
-    // Add atom matchers/predicates/metrics. These are mostly needed for initStatsdConfig
-    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
-    *config.add_predicate() = CreateScreenIsOnPredicate();
-
-    CountMetric countMetric = createCountMetric("COUNT1", config.atom_matcher(0).id(), nullopt, {});
-    int64_t countMetricId = countMetric.id();
-    *config.add_count_metric() = countMetric;
-
-    DurationMetric durationMetric =
-            createDurationMetric("DURATION1", config.predicate(0).id(), nullopt, {});
-    int64_t durationMetricId = durationMetric.id();
-    *config.add_duration_metric() = durationMetric;
-
-    // Add alerts.
-    // Preserved.
-    Alert alert1 = createAlert("Alert1", durationMetricId, /*buckets*/ 1, /*triggerSum*/ 5000);
-    int64_t alert1Id = alert1.id();
-    *config.add_alert() = alert1;
-
-    // Replaced.
-    Alert alert2 = createAlert("Alert2", countMetricId, /*buckets*/ 1, /*triggerSum*/ 2);
-    int64_t alert2Id = alert2.id();
-    *config.add_alert() = alert2;
-
-    // Replaced.
-    Alert alert3 = createAlert("Alert3", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 5000);
-    int64_t alert3Id = alert3.id();
-    *config.add_alert() = alert3;
-
-    // Add Subscriptions.
-    Subscription subscription1 = createSubscription("S1", Subscription::ALERT, alert1Id);
-    *config.add_subscription() = subscription1;
-    Subscription subscription2 = createSubscription("S2", Subscription::ALERT, alert1Id);
-    *config.add_subscription() = subscription2;
-    Subscription subscription3 = createSubscription("S3", Subscription::ALERT, alert2Id);
-    *config.add_subscription() = subscription3;
-
-    EXPECT_TRUE(initConfig(config));
-
-    // Add a duration tracker to the duration metric to ensure durationTrackers are updated
-    // with the proper anomalyTrackers.
-    unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
-            timeBaseNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    oldMetricProducers[1]->onMatchedLogEvent(0, *event.get());
-
-    // Change the count metric. Causes alert2 to be replaced.
-    config.mutable_count_metric(0)->set_bucket(ONE_DAY);
-    // Change num buckets on alert3, causing replacement.
-    alert3.set_num_buckets(5);
-
-    // New alert.
-    Alert alert4 = createAlert("Alert4", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 10000);
-    int64_t alert4Id = alert4.id();
-
-    // Move subscription2 to be on alert2 and make a new subscription.
-    subscription2.set_rule_id(alert2Id);
-    Subscription subscription4 = createSubscription("S4", Subscription::ALERT, alert2Id);
-
-    // Create the new config. Modify the old one to avoid adding the matchers/predicates.
-    // Add alerts in different order so the map is changed.
-    config.clear_alert();
-    *config.add_alert() = alert4;
-    const int alert4Index = 0;
-    *config.add_alert() = alert3;
-    const int alert3Index = 1;
-    *config.add_alert() = alert1;
-    const int alert1Index = 2;
-    *config.add_alert() = alert2;
-    const int alert2Index = 3;
-
-    // Subscription3 is removed.
-    config.clear_subscription();
-    *config.add_subscription() = subscription4;
-    *config.add_subscription() = subscription2;
-    *config.add_subscription() = subscription1;
-
-    // Output data structures from update metrics. Don't care about the outputs besides
-    // replacedMetrics, but need to do this so that the metrics clear their anomaly trackers.
-    unordered_map<int64_t, int> newMetricProducerMap;
-    vector<sp<MetricProducer>> newMetricProducers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    set<int64_t> noReportMetricIds;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
-    vector<int> metricsWithActivation;
-    set<int64_t> replacedMetrics;
-    EXPECT_TRUE(updateMetrics(
-            key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
-            oldAtomMatchingTrackerMap, oldAtomMatchingTrackerMap, /*replacedMatchers*/ {},
-            oldAtomMatchingTrackers, oldConditionTrackerMap, /*replacedConditions=*/{},
-            oldConditionTrackers, {ConditionState::kUnknown}, /*stateAtomIdMap*/ {},
-            /*allStateGroupMaps=*/{},
-            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
-            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
-            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
-            metricsWithActivation, replacedMetrics));
-
-    EXPECT_EQ(replacedMetrics, set<int64_t>({countMetricId}));
-
-    unordered_map<int64_t, int> newAlertTrackerMap;
-    vector<sp<AnomalyTracker>> newAnomalyTrackers;
-    EXPECT_TRUE(updateAlerts(config, newMetricProducerMap, replacedMetrics, oldAlertTrackerMap,
-                             oldAnomalyTrackers, anomalyAlarmMonitor, newMetricProducers,
-                             newAlertTrackerMap, newAnomalyTrackers));
-
-    unordered_map<int64_t, int> expectedAlertMap = {
-            {alert1Id, alert1Index},
-            {alert2Id, alert2Index},
-            {alert3Id, alert3Index},
-            {alert4Id, alert4Index},
-    };
-    EXPECT_THAT(newAlertTrackerMap, ContainerEq(expectedAlertMap));
-
-    // Make sure preserved alerts are the same.
-    ASSERT_EQ(newAnomalyTrackers.size(), 4);
-    EXPECT_EQ(oldAnomalyTrackers[oldAlertTrackerMap.at(alert1Id)],
-              newAnomalyTrackers[newAlertTrackerMap.at(alert1Id)]);
-
-    // Make sure replaced alerts are different.
-    EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert2Id)],
-              newAnomalyTrackers[newAlertTrackerMap.at(alert2Id)]);
-    EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert3Id)],
-              newAnomalyTrackers[newAlertTrackerMap.at(alert3Id)]);
-
-    // Verify the alerts have the correct anomaly trackers.
-    ASSERT_EQ(newMetricProducers.size(), 2);
-    EXPECT_THAT(newMetricProducers[0]->mAnomalyTrackers,
-                UnorderedElementsAre(newAnomalyTrackers[alert2Index]));
-    // For durationMetric, make sure the duration trackers get the updated anomalyTrackers.
-    DurationMetricProducer* durationProducer =
-            static_cast<DurationMetricProducer*>(newMetricProducers[1].get());
-    EXPECT_THAT(
-            durationProducer->mAnomalyTrackers,
-            UnorderedElementsAre(newAnomalyTrackers[alert1Index], newAnomalyTrackers[alert3Index],
-                                 newAnomalyTrackers[alert4Index]));
-    ASSERT_EQ(durationProducer->mCurrentSlicedDurationTrackerMap.size(), 1);
-    for (const auto& durationTrackerIt : durationProducer->mCurrentSlicedDurationTrackerMap) {
-        EXPECT_EQ(durationTrackerIt.second->mAnomalyTrackers, durationProducer->mAnomalyTrackers);
-    }
-
-    // Verify alerts have the correct subscriptions. Use subscription id as proxy for equivalency.
-    vector<int64_t> alert1Subscriptions;
-    for (const Subscription& subscription : newAnomalyTrackers[alert1Index]->mSubscriptions) {
-        alert1Subscriptions.push_back(subscription.id());
-    }
-    EXPECT_THAT(alert1Subscriptions, UnorderedElementsAre(subscription1.id()));
-    vector<int64_t> alert2Subscriptions;
-    for (const Subscription& subscription : newAnomalyTrackers[alert2Index]->mSubscriptions) {
-        alert2Subscriptions.push_back(subscription.id());
-    }
-    EXPECT_THAT(alert2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription4.id()));
-    EXPECT_THAT(newAnomalyTrackers[alert3Index]->mSubscriptions, IsEmpty());
-    EXPECT_THAT(newAnomalyTrackers[alert4Index]->mSubscriptions, IsEmpty());
-}
-
-TEST_F(ConfigUpdateTest, TestUpdateAlarms) {
-    StatsdConfig config;
-    // Add alarms.
-    Alarm alarm1 = createAlarm("Alarm1", /*offset*/ 1 * MS_PER_SEC, /*period*/ 50 * MS_PER_SEC);
-    int64_t alarm1Id = alarm1.id();
-    *config.add_alarm() = alarm1;
-
-    Alarm alarm2 = createAlarm("Alarm2", /*offset*/ 1 * MS_PER_SEC, /*period*/ 2000 * MS_PER_SEC);
-    int64_t alarm2Id = alarm2.id();
-    *config.add_alarm() = alarm2;
-
-    Alarm alarm3 = createAlarm("Alarm3", /*offset*/ 10 * MS_PER_SEC, /*period*/ 5000 * MS_PER_SEC);
-    int64_t alarm3Id = alarm3.id();
-    *config.add_alarm() = alarm3;
-
-    // Add Subscriptions.
-    Subscription subscription1 = createSubscription("S1", Subscription::ALARM, alarm1Id);
-    *config.add_subscription() = subscription1;
-    Subscription subscription2 = createSubscription("S2", Subscription::ALARM, alarm1Id);
-    *config.add_subscription() = subscription2;
-    Subscription subscription3 = createSubscription("S3", Subscription::ALARM, alarm2Id);
-    *config.add_subscription() = subscription3;
-
-    EXPECT_TRUE(initConfig(config));
-
-    ASSERT_EQ(oldAlarmTrackers.size(), 3);
-    // Config is created at statsd start time, so just add the offsets.
-    EXPECT_EQ(oldAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
-    EXPECT_EQ(oldAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
-    EXPECT_EQ(oldAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);
-
-    // Change alarm2/alarm3.
-    config.mutable_alarm(1)->set_offset_millis(5 * MS_PER_SEC);
-    config.mutable_alarm(2)->set_period_millis(10000 * MS_PER_SEC);
-
-    // Move subscription2 to be on alarm2 and make a new subscription.
-    config.mutable_subscription(1)->set_rule_id(alarm2Id);
-    Subscription subscription4 = createSubscription("S4", Subscription::ALARM, alarm1Id);
-    *config.add_subscription() = subscription4;
-
-    // Update time is 2 seconds after the base time.
-    int64_t currentTimeNs = timeBaseNs + 2 * NS_PER_SEC;
-    vector<sp<AlarmTracker>> newAlarmTrackers;
-    EXPECT_TRUE(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
-                           newAlarmTrackers));
-
-    ASSERT_EQ(newAlarmTrackers.size(), 3);
-    // Config is updated 2 seconds after statsd start
-    // The offset has passed for alarm1, but not for alarms 2/3.
-    EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 50);
-    EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5);
-    EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);
-
-    // Verify alarms have the correct subscriptions. Use subscription id as proxy for equivalency.
-    vector<int64_t> alarm1Subscriptions;
-    for (const Subscription& subscription : newAlarmTrackers[0]->mSubscriptions) {
-        alarm1Subscriptions.push_back(subscription.id());
-    }
-    EXPECT_THAT(alarm1Subscriptions, UnorderedElementsAre(subscription1.id(), subscription4.id()));
-    vector<int64_t> alarm2Subscriptions;
-    for (const Subscription& subscription : newAlarmTrackers[1]->mSubscriptions) {
-        alarm2Subscriptions.push_back(subscription.id());
-    }
-    EXPECT_THAT(alarm2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription3.id()));
-    EXPECT_THAT(newAlarmTrackers[2]->mSubscriptions, IsEmpty());
-
-    // Verify the alarm monitor is updated accordingly once the old alarms are removed.
-    // Alarm2 fires the earliest.
-    oldAlarmTrackers.clear();
-    EXPECT_EQ(periodicAlarmMonitor->getRegisteredAlarmTimeSec(), timeBaseNs / NS_PER_SEC + 5);
-
-    // Do another update 60 seconds after config creation time, after the offsets of each alarm.
-    currentTimeNs = timeBaseNs + 60 * NS_PER_SEC;
-    newAlarmTrackers.clear();
-    EXPECT_TRUE(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
-                           newAlarmTrackers));
-
-    ASSERT_EQ(newAlarmTrackers.size(), 3);
-    // Config is updated one minute after statsd start.
-    // Two periods have passed for alarm 1, one has passed for alarms2/3.
-    EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 2 * 50);
-    EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5 + 2000);
-    EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10 + 10000);
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
deleted file mode 100644
index 9ab7e47..0000000
--- a/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
+++ /dev/null
@@ -1,928 +0,0 @@
-// Copyright (C) 2020 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.
-
-#include "src/metrics/parsing_utils/metrics_manager_util.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-#include <stdio.h>
-
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "src/condition/ConditionTracker.h"
-#include "src/matchers/AtomMatchingTracker.h"
-#include "src/metrics/CountMetricProducer.h"
-#include "src/metrics/DurationMetricProducer.h"
-#include "src/metrics/GaugeMetricProducer.h"
-#include "src/metrics/MetricProducer.h"
-#include "src/metrics/ValueMetricProducer.h"
-#include "src/state/StateManager.h"
-#include "tests/metrics/metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-using namespace testing;
-using android::sp;
-using android::os::statsd::Predicate;
-using std::map;
-using std::set;
-using std::unordered_map;
-using std::vector;
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-namespace {
-const ConfigKey kConfigKey(0, 12345);
-const long kAlertId = 3;
-
-const long timeBaseSec = 1000;
-
-StatsdConfig buildGoodConfig() {
-    StatsdConfig config;
-    config.set_id(12345);
-
-    AtomMatcher* eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
-    SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
-    simpleAtomMatcher->add_field_value_matcher()->set_field(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
-            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
-    eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
-
-    simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
-    simpleAtomMatcher->add_field_value_matcher()->set_field(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
-
-    eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
-    AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_matcher(StringToId("SCREEN_IS_ON"));
-    combination->add_matcher(StringToId("SCREEN_IS_OFF"));
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(3);
-    metric->set_what(StringToId("SCREEN_IS_ON"));
-    metric->set_bucket(ONE_MINUTE);
-    metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
-    metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
-    config.add_no_report_metric(3);
-
-    auto alert = config.add_alert();
-    alert->set_id(kAlertId);
-    alert->set_metric_id(3);
-    alert->set_num_buckets(10);
-    alert->set_refractory_period_secs(100);
-    alert->set_trigger_if_sum_gt(100);
-    return config;
-}
-
-StatsdConfig buildCircleMatchers() {
-    StatsdConfig config;
-    config.set_id(12345);
-
-    AtomMatcher* eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
-    SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
-    simpleAtomMatcher->add_field_value_matcher()->set_field(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
-            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
-    eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
-    AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_matcher(StringToId("SCREEN_IS_ON"));
-    // Circle dependency
-    combination->add_matcher(StringToId("SCREEN_ON_OR_OFF"));
-
-    return config;
-}
-
-StatsdConfig buildAlertWithUnknownMetric() {
-    StatsdConfig config;
-    config.set_id(12345);
-
-    AtomMatcher* eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(3);
-    metric->set_what(StringToId("SCREEN_IS_ON"));
-    metric->set_bucket(ONE_MINUTE);
-    metric->mutable_dimensions_in_what()->set_field(2 /*SCREEN_STATE_CHANGE*/);
-    metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
-    auto alert = config.add_alert();
-    alert->set_id(3);
-    alert->set_metric_id(2);
-    alert->set_num_buckets(10);
-    alert->set_refractory_period_secs(100);
-    alert->set_trigger_if_sum_gt(100);
-    return config;
-}
-
-StatsdConfig buildMissingMatchers() {
-    StatsdConfig config;
-    config.set_id(12345);
-
-    AtomMatcher* eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
-    SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
-    simpleAtomMatcher->add_field_value_matcher()->set_field(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
-            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
-    eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_ON_OR_OFF"));
-
-    AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_matcher(StringToId("SCREEN_IS_ON"));
-    // undefined matcher
-    combination->add_matcher(StringToId("ABC"));
-
-    return config;
-}
-
-StatsdConfig buildMissingPredicate() {
-    StatsdConfig config;
-    config.set_id(12345);
-
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(3);
-    metric->set_what(StringToId("SCREEN_EVENT"));
-    metric->set_bucket(ONE_MINUTE);
-    metric->set_condition(StringToId("SOME_CONDITION"));
-
-    AtomMatcher* eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_EVENT"));
-
-    SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2);
-
-    return config;
-}
-
-StatsdConfig buildDimensionMetricsWithMultiTags() {
-    StatsdConfig config;
-    config.set_id(12345);
-
-    AtomMatcher* eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("BATTERY_VERY_LOW"));
-    SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2);
-
-    eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("BATTERY_VERY_VERY_LOW"));
-    simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(3);
-
-    eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("BATTERY_LOW"));
-
-    AtomMatcher_Combination* combination = eventMatcher->mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_matcher(StringToId("BATTERY_VERY_LOW"));
-    combination->add_matcher(StringToId("BATTERY_VERY_VERY_LOW"));
-
-    // Count process state changes, slice by uid, while SCREEN_IS_OFF
-    CountMetric* metric = config.add_count_metric();
-    metric->set_id(3);
-    metric->set_what(StringToId("BATTERY_LOW"));
-    metric->set_bucket(ONE_MINUTE);
-    // This case is interesting. We want to dimension across two atoms.
-    metric->mutable_dimensions_in_what()->add_child()->set_field(1);
-
-    auto alert = config.add_alert();
-    alert->set_id(kAlertId);
-    alert->set_metric_id(3);
-    alert->set_num_buckets(10);
-    alert->set_refractory_period_secs(100);
-    alert->set_trigger_if_sum_gt(100);
-    return config;
-}
-
-StatsdConfig buildCirclePredicates() {
-    StatsdConfig config;
-    config.set_id(12345);
-
-    AtomMatcher* eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_IS_ON"));
-
-    SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
-    simpleAtomMatcher->add_field_value_matcher()->set_field(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
-            2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
-
-    eventMatcher = config.add_atom_matcher();
-    eventMatcher->set_id(StringToId("SCREEN_IS_OFF"));
-
-    simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(2 /*SCREEN_STATE_CHANGE*/);
-    simpleAtomMatcher->add_field_value_matcher()->set_field(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/);
-
-    auto condition = config.add_predicate();
-    condition->set_id(StringToId("SCREEN_IS_ON"));
-    SimplePredicate* simplePredicate = condition->mutable_simple_predicate();
-    simplePredicate->set_start(StringToId("SCREEN_IS_ON"));
-    simplePredicate->set_stop(StringToId("SCREEN_IS_OFF"));
-
-    condition = config.add_predicate();
-    condition->set_id(StringToId("SCREEN_IS_EITHER_ON_OFF"));
-
-    Predicate_Combination* combination = condition->mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_predicate(StringToId("SCREEN_IS_ON"));
-    combination->add_predicate(StringToId("SCREEN_IS_EITHER_ON_OFF"));
-
-    return config;
-}
-
-StatsdConfig buildConfigWithDifferentPredicates() {
-    StatsdConfig config;
-    config.set_id(12345);
-
-    auto pulledAtomMatcher =
-            CreateSimpleAtomMatcher("SUBSYSTEM_SLEEP", util::SUBSYSTEM_SLEEP_STATE);
-    *config.add_atom_matcher() = pulledAtomMatcher;
-    auto screenOnAtomMatcher = CreateScreenTurnedOnAtomMatcher();
-    *config.add_atom_matcher() = screenOnAtomMatcher;
-    auto screenOffAtomMatcher = CreateScreenTurnedOffAtomMatcher();
-    *config.add_atom_matcher() = screenOffAtomMatcher;
-    auto batteryNoneAtomMatcher = CreateBatteryStateNoneMatcher();
-    *config.add_atom_matcher() = batteryNoneAtomMatcher;
-    auto batteryUsbAtomMatcher = CreateBatteryStateUsbMatcher();
-    *config.add_atom_matcher() = batteryUsbAtomMatcher;
-
-    // Simple condition with InitialValue set to default (unknown).
-    auto screenOnUnknownPredicate = CreateScreenIsOnPredicate();
-    *config.add_predicate() = screenOnUnknownPredicate;
-
-    // Simple condition with InitialValue set to false.
-    auto screenOnFalsePredicate = config.add_predicate();
-    screenOnFalsePredicate->set_id(StringToId("ScreenIsOnInitialFalse"));
-    SimplePredicate* simpleScreenOnFalsePredicate =
-            screenOnFalsePredicate->mutable_simple_predicate();
-    simpleScreenOnFalsePredicate->set_start(screenOnAtomMatcher.id());
-    simpleScreenOnFalsePredicate->set_stop(screenOffAtomMatcher.id());
-    simpleScreenOnFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
-
-    // Simple condition with InitialValue set to false.
-    auto onBatteryFalsePredicate = config.add_predicate();
-    onBatteryFalsePredicate->set_id(StringToId("OnBatteryInitialFalse"));
-    SimplePredicate* simpleOnBatteryFalsePredicate =
-            onBatteryFalsePredicate->mutable_simple_predicate();
-    simpleOnBatteryFalsePredicate->set_start(batteryNoneAtomMatcher.id());
-    simpleOnBatteryFalsePredicate->set_stop(batteryUsbAtomMatcher.id());
-    simpleOnBatteryFalsePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
-
-    // Combination condition with both simple condition InitialValues set to false.
-    auto screenOnFalseOnBatteryFalsePredicate = config.add_predicate();
-    screenOnFalseOnBatteryFalsePredicate->set_id(StringToId("ScreenOnFalseOnBatteryFalse"));
-    screenOnFalseOnBatteryFalsePredicate->mutable_combination()->set_operation(
-            LogicalOperation::AND);
-    addPredicateToPredicateCombination(*screenOnFalsePredicate,
-                                       screenOnFalseOnBatteryFalsePredicate);
-    addPredicateToPredicateCombination(*onBatteryFalsePredicate,
-                                       screenOnFalseOnBatteryFalsePredicate);
-
-    // Combination condition with one simple condition InitialValue set to unknown and one set to
-    // false.
-    auto screenOnUnknownOnBatteryFalsePredicate = config.add_predicate();
-    screenOnUnknownOnBatteryFalsePredicate->set_id(StringToId("ScreenOnUnknowneOnBatteryFalse"));
-    screenOnUnknownOnBatteryFalsePredicate->mutable_combination()->set_operation(
-            LogicalOperation::AND);
-    addPredicateToPredicateCombination(screenOnUnknownPredicate,
-                                       screenOnUnknownOnBatteryFalsePredicate);
-    addPredicateToPredicateCombination(*onBatteryFalsePredicate,
-                                       screenOnUnknownOnBatteryFalsePredicate);
-
-    // Simple condition metric with initial value false.
-    ValueMetric* metric1 = config.add_value_metric();
-    metric1->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialFalse"));
-    metric1->set_what(pulledAtomMatcher.id());
-    *metric1->mutable_value_field() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
-    metric1->set_bucket(FIVE_MINUTES);
-    metric1->set_condition(screenOnFalsePredicate->id());
-
-    // Simple condition metric with initial value unknown.
-    ValueMetric* metric2 = config.add_value_metric();
-    metric2->set_id(StringToId("ValueSubsystemSleepWhileScreenOnInitialUnknown"));
-    metric2->set_what(pulledAtomMatcher.id());
-    *metric2->mutable_value_field() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
-    metric2->set_bucket(FIVE_MINUTES);
-    metric2->set_condition(screenOnUnknownPredicate.id());
-
-    // Combination condition metric with initial values false and false.
-    ValueMetric* metric3 = config.add_value_metric();
-    metric3->set_id(StringToId("ValueSubsystemSleepWhileScreenOnFalseDeviceUnpluggedFalse"));
-    metric3->set_what(pulledAtomMatcher.id());
-    *metric3->mutable_value_field() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
-    metric3->set_bucket(FIVE_MINUTES);
-    metric3->set_condition(screenOnFalseOnBatteryFalsePredicate->id());
-
-    // Combination condition metric with initial values unknown and false.
-    ValueMetric* metric4 = config.add_value_metric();
-    metric4->set_id(StringToId("ValueSubsystemSleepWhileScreenOnUnknownDeviceUnpluggedFalse"));
-    metric4->set_what(pulledAtomMatcher.id());
-    *metric4->mutable_value_field() =
-            CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
-    metric4->set_bucket(FIVE_MINUTES);
-    metric4->set_condition(screenOnUnknownOnBatteryFalsePredicate->id());
-
-    return config;
-}
-}  // anonymous namespace
-
-TEST(MetricsManagerTest, TestInitialConditions) {
-    sp<UidMap> uidMap = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    StatsdConfig config = buildConfigWithDifferentPredicates();
-    set<int> allTagIds;
-    vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
-    unordered_map<int64_t, int> atomMatchingTrackerMap;
-    vector<sp<ConditionTracker>> allConditionTrackers;
-    unordered_map<int64_t, int> conditionTrackerMap;
-    vector<sp<MetricProducer>> allMetricProducers;
-    unordered_map<int64_t, int> metricProducerMap;
-    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    std::vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, std::vector<int>> conditionToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
-    unordered_map<int64_t, int> alertTrackerMap;
-    vector<int> metricsWithActivation;
-    map<int64_t, uint64_t> stateProtoHashes;
-    std::set<int64_t> noReportMetricIds;
-
-    EXPECT_TRUE(initStatsdConfig(
-            kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
-            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
-            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
-            trackerToConditionMap, activationAtomTrackerToMetricMap,
-            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
-            stateProtoHashes, noReportMetricIds));
-    ASSERT_EQ(4u, allMetricProducers.size());
-    ASSERT_EQ(5u, allConditionTrackers.size());
-
-    ConditionKey queryKey;
-    vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
-
-    allConditionTrackers[3]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
-    allConditionTrackers[4]->isConditionMet(queryKey, allConditionTrackers, false, conditionCache);
-    EXPECT_EQ(ConditionState::kUnknown, conditionCache[0]);
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[1]);
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[2]);
-    EXPECT_EQ(ConditionState::kFalse, conditionCache[3]);
-    EXPECT_EQ(ConditionState::kUnknown, conditionCache[4]);
-
-    EXPECT_EQ(ConditionState::kFalse, allMetricProducers[0]->mCondition);
-    EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
-    EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
-    EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
-}
-
-TEST(MetricsManagerTest, TestGoodConfig) {
-    sp<UidMap> uidMap = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    StatsdConfig config = buildGoodConfig();
-    set<int> allTagIds;
-    vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
-    unordered_map<int64_t, int> atomMatchingTrackerMap;
-    vector<sp<ConditionTracker>> allConditionTrackers;
-    unordered_map<int64_t, int> conditionTrackerMap;
-    vector<sp<MetricProducer>> allMetricProducers;
-    unordered_map<int64_t, int> metricProducerMap;
-    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    std::vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, std::vector<int>> conditionToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
-    unordered_map<int64_t, int> alertTrackerMap;
-    vector<int> metricsWithActivation;
-    map<int64_t, uint64_t> stateProtoHashes;
-    std::set<int64_t> noReportMetricIds;
-
-    EXPECT_TRUE(initStatsdConfig(
-            kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
-            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
-            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
-            trackerToConditionMap, activationAtomTrackerToMetricMap,
-            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
-            stateProtoHashes, noReportMetricIds));
-    ASSERT_EQ(1u, allMetricProducers.size());
-    EXPECT_THAT(metricProducerMap, UnorderedElementsAre(Pair(config.count_metric(0).id(), 0)));
-    ASSERT_EQ(1u, allAnomalyTrackers.size());
-    ASSERT_EQ(1u, noReportMetricIds.size());
-    ASSERT_EQ(1u, alertTrackerMap.size());
-    EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
-    EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
-}
-
-TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
-    sp<UidMap> uidMap = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    StatsdConfig config = buildDimensionMetricsWithMultiTags();
-    set<int> allTagIds;
-    vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
-    unordered_map<int64_t, int> atomMatchingTrackerMap;
-    vector<sp<ConditionTracker>> allConditionTrackers;
-    unordered_map<int64_t, int> conditionTrackerMap;
-    vector<sp<MetricProducer>> allMetricProducers;
-    unordered_map<int64_t, int> metricProducerMap;
-    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    std::vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, std::vector<int>> conditionToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
-    unordered_map<int64_t, int> alertTrackerMap;
-    vector<int> metricsWithActivation;
-    map<int64_t, uint64_t> stateProtoHashes;
-    std::set<int64_t> noReportMetricIds;
-
-    EXPECT_FALSE(initStatsdConfig(
-            kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
-            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
-            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
-            trackerToConditionMap, activationAtomTrackerToMetricMap,
-            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
-            stateProtoHashes, noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
-    sp<UidMap> uidMap = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    StatsdConfig config = buildCircleMatchers();
-    set<int> allTagIds;
-    vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
-    unordered_map<int64_t, int> atomMatchingTrackerMap;
-    vector<sp<ConditionTracker>> allConditionTrackers;
-    unordered_map<int64_t, int> conditionTrackerMap;
-    vector<sp<MetricProducer>> allMetricProducers;
-    unordered_map<int64_t, int> metricProducerMap;
-    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    std::vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, std::vector<int>> conditionToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
-    unordered_map<int64_t, int> alertTrackerMap;
-    vector<int> metricsWithActivation;
-    map<int64_t, uint64_t> stateProtoHashes;
-    std::set<int64_t> noReportMetricIds;
-
-    EXPECT_FALSE(initStatsdConfig(
-            kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
-            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
-            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
-            trackerToConditionMap, activationAtomTrackerToMetricMap,
-            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
-            stateProtoHashes, noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestMissingMatchers) {
-    sp<UidMap> uidMap = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    StatsdConfig config = buildMissingMatchers();
-    set<int> allTagIds;
-    vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
-    unordered_map<int64_t, int> atomMatchingTrackerMap;
-    vector<sp<ConditionTracker>> allConditionTrackers;
-    unordered_map<int64_t, int> conditionTrackerMap;
-    vector<sp<MetricProducer>> allMetricProducers;
-    unordered_map<int64_t, int> metricProducerMap;
-    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    std::vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, std::vector<int>> conditionToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
-    unordered_map<int64_t, int> alertTrackerMap;
-    vector<int> metricsWithActivation;
-    map<int64_t, uint64_t> stateProtoHashes;
-    std::set<int64_t> noReportMetricIds;
-    EXPECT_FALSE(initStatsdConfig(
-            kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
-            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
-            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
-            trackerToConditionMap, activationAtomTrackerToMetricMap,
-            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
-            stateProtoHashes, noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestMissingPredicate) {
-    sp<UidMap> uidMap = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    StatsdConfig config = buildMissingPredicate();
-    set<int> allTagIds;
-    vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
-    unordered_map<int64_t, int> atomMatchingTrackerMap;
-    vector<sp<ConditionTracker>> allConditionTrackers;
-    unordered_map<int64_t, int> conditionTrackerMap;
-    vector<sp<MetricProducer>> allMetricProducers;
-    unordered_map<int64_t, int> metricProducerMap;
-    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    std::vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, std::vector<int>> conditionToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
-    unordered_map<int64_t, int> alertTrackerMap;
-    vector<int> metricsWithActivation;
-    map<int64_t, uint64_t> stateProtoHashes;
-    std::set<int64_t> noReportMetricIds;
-    EXPECT_FALSE(initStatsdConfig(
-            kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
-            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
-            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
-            trackerToConditionMap, activationAtomTrackerToMetricMap,
-            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
-            stateProtoHashes, noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestCirclePredicateDependency) {
-    sp<UidMap> uidMap = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    StatsdConfig config = buildCirclePredicates();
-    set<int> allTagIds;
-    vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
-    unordered_map<int64_t, int> atomMatchingTrackerMap;
-    vector<sp<ConditionTracker>> allConditionTrackers;
-    unordered_map<int64_t, int> conditionTrackerMap;
-    vector<sp<MetricProducer>> allMetricProducers;
-    unordered_map<int64_t, int> metricProducerMap;
-    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    std::vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, std::vector<int>> conditionToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
-    unordered_map<int64_t, int> alertTrackerMap;
-    vector<int> metricsWithActivation;
-    map<int64_t, uint64_t> stateProtoHashes;
-    std::set<int64_t> noReportMetricIds;
-
-    EXPECT_FALSE(initStatsdConfig(
-            kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
-            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
-            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
-            trackerToConditionMap, activationAtomTrackerToMetricMap,
-            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
-            stateProtoHashes, noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
-    sp<UidMap> uidMap = new UidMap();
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    StatsdConfig config = buildAlertWithUnknownMetric();
-    set<int> allTagIds;
-    vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
-    unordered_map<int64_t, int> atomMatchingTrackerMap;
-    vector<sp<ConditionTracker>> allConditionTrackers;
-    unordered_map<int64_t, int> conditionTrackerMap;
-    vector<sp<MetricProducer>> allMetricProducers;
-    unordered_map<int64_t, int> metricProducerMap;
-    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    std::vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, std::vector<int>> conditionToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToMetricMap;
-    unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
-    unordered_map<int64_t, int> alertTrackerMap;
-    vector<int> metricsWithActivation;
-    map<int64_t, uint64_t> stateProtoHashes;
-    std::set<int64_t> noReportMetricIds;
-
-    EXPECT_FALSE(initStatsdConfig(
-            kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
-            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
-            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
-            trackerToConditionMap, activationAtomTrackerToMetricMap,
-            deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
-            stateProtoHashes, noReportMetricIds));
-}
-
-TEST(MetricsManagerTest, TestCreateAtomMatchingTrackerInvalidMatcher) {
-    sp<UidMap> uidMap = new UidMap();
-    AtomMatcher matcher;
-    // Matcher has no contents_case (simple/combination), so it is invalid.
-    matcher.set_id(21);
-    EXPECT_EQ(createAtomMatchingTracker(matcher, 0, uidMap), nullptr);
-}
-
-TEST(MetricsManagerTest, TestCreateAtomMatchingTrackerSimple) {
-    int index = 1;
-    int64_t id = 123;
-    sp<UidMap> uidMap = new UidMap();
-    AtomMatcher matcher;
-    matcher.set_id(id);
-    SimpleAtomMatcher* simpleAtomMatcher = matcher.mutable_simple_atom_matcher();
-    simpleAtomMatcher->set_atom_id(util::SCREEN_STATE_CHANGED);
-    simpleAtomMatcher->add_field_value_matcher()->set_field(
-            1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
-    simpleAtomMatcher->mutable_field_value_matcher(0)->set_eq_int(
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
-    sp<AtomMatchingTracker> tracker = createAtomMatchingTracker(matcher, index, uidMap);
-    EXPECT_NE(tracker, nullptr);
-
-    EXPECT_TRUE(tracker->mInitialized);
-    EXPECT_EQ(tracker->getId(), id);
-    EXPECT_EQ(tracker->mIndex, index);
-    const set<int>& atomIds = tracker->getAtomIds();
-    ASSERT_EQ(atomIds.size(), 1);
-    EXPECT_EQ(atomIds.count(util::SCREEN_STATE_CHANGED), 1);
-}
-
-TEST(MetricsManagerTest, TestCreateAtomMatchingTrackerCombination) {
-    int index = 1;
-    int64_t id = 123;
-    sp<UidMap> uidMap = new UidMap();
-    AtomMatcher matcher;
-    matcher.set_id(id);
-    AtomMatcher_Combination* combination = matcher.mutable_combination();
-    combination->set_operation(LogicalOperation::OR);
-    combination->add_matcher(123);
-    combination->add_matcher(223);
-
-    sp<AtomMatchingTracker> tracker = createAtomMatchingTracker(matcher, index, uidMap);
-    EXPECT_NE(tracker, nullptr);
-
-    // Combination matchers need to be initialized first.
-    EXPECT_FALSE(tracker->mInitialized);
-    EXPECT_EQ(tracker->getId(), id);
-    EXPECT_EQ(tracker->mIndex, index);
-    const set<int>& atomIds = tracker->getAtomIds();
-    ASSERT_EQ(atomIds.size(), 0);
-}
-
-TEST(MetricsManagerTest, TestCreateConditionTrackerInvalid) {
-    const ConfigKey key(123, 456);
-    // Predicate has no contents_case (simple/combination), so it is invalid.
-    Predicate predicate;
-    predicate.set_id(21);
-    unordered_map<int64_t, int> atomTrackerMap;
-    EXPECT_EQ(createConditionTracker(key, predicate, 0, atomTrackerMap), nullptr);
-}
-
-TEST(MetricsManagerTest, TestCreateConditionTrackerSimple) {
-    int index = 1;
-    int64_t id = 987;
-    const ConfigKey key(123, 456);
-
-    int startMatcherIndex = 2, stopMatcherIndex = 0, stopAllMatcherIndex = 1;
-    int64_t startMatcherId = 246, stopMatcherId = 153, stopAllMatcherId = 975;
-
-    Predicate predicate;
-    predicate.set_id(id);
-    SimplePredicate* simplePredicate = predicate.mutable_simple_predicate();
-    simplePredicate->set_start(startMatcherId);
-    simplePredicate->set_stop(stopMatcherId);
-    simplePredicate->set_stop_all(stopAllMatcherId);
-
-    unordered_map<int64_t, int> atomTrackerMap;
-    atomTrackerMap[startMatcherId] = startMatcherIndex;
-    atomTrackerMap[stopMatcherId] = stopMatcherIndex;
-    atomTrackerMap[stopAllMatcherId] = stopAllMatcherIndex;
-
-    sp<ConditionTracker> tracker = createConditionTracker(key, predicate, index, atomTrackerMap);
-    EXPECT_EQ(tracker->getConditionId(), id);
-    EXPECT_EQ(tracker->isSliced(), false);
-    EXPECT_TRUE(tracker->IsSimpleCondition());
-    const set<int>& interestedMatchers = tracker->getAtomMatchingTrackerIndex();
-    ASSERT_EQ(interestedMatchers.size(), 3);
-    ASSERT_EQ(interestedMatchers.count(startMatcherIndex), 1);
-    ASSERT_EQ(interestedMatchers.count(stopMatcherIndex), 1);
-    ASSERT_EQ(interestedMatchers.count(stopAllMatcherIndex), 1);
-}
-
-TEST(MetricsManagerTest, TestCreateConditionTrackerCombination) {
-    int index = 1;
-    int64_t id = 987;
-    const ConfigKey key(123, 456);
-
-    Predicate predicate;
-    predicate.set_id(id);
-    Predicate_Combination* combinationPredicate = predicate.mutable_combination();
-    combinationPredicate->set_operation(LogicalOperation::AND);
-    combinationPredicate->add_predicate(888);
-    combinationPredicate->add_predicate(777);
-
-    // Combination conditions must be initialized to set most state.
-    unordered_map<int64_t, int> atomTrackerMap;
-    sp<ConditionTracker> tracker = createConditionTracker(key, predicate, index, atomTrackerMap);
-    EXPECT_EQ(tracker->getConditionId(), id);
-    EXPECT_FALSE(tracker->IsSimpleCondition());
-}
-
-TEST(MetricsManagerTest, TestCreateAnomalyTrackerInvalidMetric) {
-    Alert alert;
-    alert.set_id(123);
-    alert.set_metric_id(1);
-    alert.set_trigger_if_sum_gt(1);
-    alert.set_num_buckets(1);
-
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    vector<sp<MetricProducer>> metricProducers;
-    // Pass in empty metric producers, causing an error.
-    EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, {}, metricProducers), nullopt);
-}
-
-TEST(MetricsManagerTest, TestCreateAnomalyTrackerNoThreshold) {
-    int64_t metricId = 1;
-    Alert alert;
-    alert.set_id(123);
-    alert.set_metric_id(metricId);
-    alert.set_num_buckets(1);
-
-    CountMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
-            kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, {{1, 0}}, metricProducers), nullopt);
-}
-
-TEST(MetricsManagerTest, TestCreateAnomalyTrackerMissingBuckets) {
-    int64_t metricId = 1;
-    Alert alert;
-    alert.set_id(123);
-    alert.set_metric_id(metricId);
-    alert.set_trigger_if_sum_gt(1);
-
-    CountMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
-            kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, {{1, 0}}, metricProducers), nullopt);
-}
-
-TEST(MetricsManagerTest, TestCreateAnomalyTrackerGood) {
-    int64_t metricId = 1;
-    Alert alert;
-    alert.set_id(123);
-    alert.set_metric_id(metricId);
-    alert.set_trigger_if_sum_gt(1);
-    alert.set_num_buckets(1);
-
-    CountMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
-            kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    EXPECT_NE(createAnomalyTracker(alert, anomalyAlarmMonitor, {{1, 0}}, metricProducers), nullopt);
-}
-
-TEST(MetricsManagerTest, TestCreateAnomalyTrackerDurationTooLong) {
-    int64_t metricId = 1;
-    Alert alert;
-    alert.set_id(123);
-    alert.set_metric_id(metricId);
-    // Impossible for alert to fire since the time is bigger than bucketSize * numBuckets
-    alert.set_trigger_if_sum_gt(MillisToNano(TimeUnitToBucketSizeInMillis(ONE_MINUTE)) + 1);
-    alert.set_num_buckets(1);
-
-    DurationMetric metric;
-    metric.set_id(metricId);
-    metric.set_bucket(ONE_MINUTE);
-    metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
-    FieldMatcher dimensions;
-    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
-    vector<sp<MetricProducer>> metricProducers({new DurationMetricProducer(
-            kConfigKey, metric, -1 /*no condition*/, {}, -1 /* what index not needed*/,
-            1 /* start index */, 2 /* stop index */, 3 /* stop_all index */, false /*nesting*/,
-            wizard, 0x0123456789, dimensions, 0, 0)});
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, {{1, 0}}, metricProducers), nullopt);
-}
-
-TEST(MetricsManagerTest, TestCreateDurationProducerDimensionsInWhatInvalid) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");
-    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
-    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
-
-    Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
-    // The predicate is dimensioning by first attribution node by uid.
-    FieldMatcher dimensions =
-            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
-    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
-    *config.add_predicate() = holdingWakelockPredicate;
-
-    DurationMetric* durationMetric = config.add_duration_metric();
-    durationMetric->set_id(StringToId("WakelockDuration"));
-    durationMetric->set_what(holdingWakelockPredicate.id());
-    durationMetric->set_aggregation_type(DurationMetric::SUM);
-    // The metric is dimensioning by first attribution node by uid AND tag.
-    // Invalid since the predicate only dimensions by uid.
-    *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidAndOtherDimensions(
-            util::WAKELOCK_STATE_CHANGED, {Position::FIRST}, {3 /* tag */});
-    durationMetric->set_bucket(FIVE_MINUTES);
-
-    ConfigKey key(123, 987);
-    uint64_t timeNs = 456;
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-    sp<UidMap> uidMap;
-    sp<MetricsManager> metricsManager =
-            new MetricsManager(key, config, timeNs, timeNs, uidMap, pullerManager,
-                               anomalyAlarmMonitor, periodicAlarmMonitor);
-    EXPECT_FALSE(metricsManager->isConfigValid());
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
deleted file mode 100644
index 1ba8593..0000000
--- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright (C) 2018 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.
-
-#include "src/shell/ShellSubscriber.h"
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <vector>
-
-#include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
-#include "frameworks/base/cmds/statsd/src/shell/shell_data.pb.h"
-#include "frameworks/proto_logging/stats/atoms.pb.h"
-#include "stats_event.h"
-#include "tests/metrics/metrics_test_helper.h"
-#include "tests/statsd_test_util.h"
-
-using namespace android::os::statsd;
-using android::sp;
-using std::vector;
-using testing::_;
-using testing::Invoke;
-using testing::NaggyMock;
-using testing::StrictMock;
-
-#ifdef __ANDROID__
-
-void runShellTest(ShellSubscription config, sp<MockUidMap> uidMap,
-                  sp<MockStatsPullerManager> pullerManager,
-                  const vector<std::shared_ptr<LogEvent>>& pushedEvents,
-                  const ShellData& expectedData) {
-    // set up 2 pipes for read/write config and data
-    int fds_config[2];
-    ASSERT_EQ(0, pipe(fds_config));
-
-    int fds_data[2];
-    ASSERT_EQ(0, pipe(fds_data));
-
-    size_t bufferSize = config.ByteSize();
-    // write the config to pipe, first write size of the config
-    write(fds_config[1], &bufferSize, sizeof(bufferSize));
-    // then write config itself
-    vector<uint8_t> buffer(bufferSize);
-    config.SerializeToArray(&buffer[0], bufferSize);
-    write(fds_config[1], buffer.data(), bufferSize);
-    close(fds_config[1]);
-
-    sp<ShellSubscriber> shellClient = new ShellSubscriber(uidMap, pullerManager);
-
-    // mimic a binder thread that a shell subscriber runs on. it would block.
-    std::thread reader([&shellClient, &fds_config, &fds_data] {
-        shellClient->startNewSubscription(fds_config[0], fds_data[1], /*timeoutSec=*/-1);
-    });
-    reader.detach();
-
-    // let the shell subscriber to receive the config from pipe.
-    std::this_thread::sleep_for(100ms);
-
-    if (pushedEvents.size() > 0) {
-        // send a log event that matches the config.
-        std::thread log_reader([&shellClient, &pushedEvents] {
-            for (const auto& event : pushedEvents) {
-                shellClient->onLogEvent(*event);
-            }
-        });
-
-        log_reader.detach();
-
-        if (log_reader.joinable()) {
-            log_reader.join();
-        }
-    }
-
-    // wait for the data to be written.
-    std::this_thread::sleep_for(100ms);
-
-    // Because we might receive heartbeats from statsd, consisting of data sizes
-    // of 0, encapsulate reads within a while loop.
-    bool readAtom = false;
-    while (!readAtom) {
-        // Read the atom size.
-        size_t dataSize = 0;
-        read(fds_data[0], &dataSize, sizeof(dataSize));
-        if (dataSize == 0) continue;
-        EXPECT_EQ(expectedData.ByteSize(), int(dataSize));
-
-        // Read that much data in proto binary format.
-        vector<uint8_t> dataBuffer(dataSize);
-        EXPECT_EQ((int)dataSize, read(fds_data[0], dataBuffer.data(), dataSize));
-
-        // Make sure the received bytes can be parsed to an atom.
-        ShellData receivedAtom;
-        EXPECT_TRUE(receivedAtom.ParseFromArray(dataBuffer.data(), dataSize) != 0);
-
-        // Serialize the expected atom to byte array and compare to make sure
-        // they are the same.
-        vector<uint8_t> expectedAtomBuffer(expectedData.ByteSize());
-        expectedData.SerializeToArray(expectedAtomBuffer.data(), expectedData.ByteSize());
-        EXPECT_EQ(expectedAtomBuffer, dataBuffer);
-
-        readAtom = true;
-    }
-
-    close(fds_data[0]);
-    if (reader.joinable()) {
-        reader.join();
-    }
-}
-
-TEST(ShellSubscriberTest, testPushedSubscription) {
-    sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    vector<std::shared_ptr<LogEvent>> pushedList;
-
-    // Create the LogEvent from an AStatsEvent
-    std::unique_ptr<LogEvent> logEvent = CreateScreenStateChangedEvent(
-            1000 /*timestamp*/, ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    pushedList.push_back(std::move(logEvent));
-
-    // create a simple config to get screen events
-    ShellSubscription config;
-    config.add_pushed()->set_atom_id(29);
-
-    // this is the expected screen event atom.
-    ShellData shellData;
-    shellData.add_atom()->mutable_screen_state_changed()->set_state(
-            ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
-    runShellTest(config, uidMap, pullerManager, pushedList, shellData);
-}
-
-namespace {
-
-int kUid1 = 1000;
-int kUid2 = 2000;
-
-int kCpuTime1 = 100;
-int kCpuTime2 = 200;
-
-ShellData getExpectedShellData() {
-    ShellData shellData;
-    auto* atom1 = shellData.add_atom()->mutable_cpu_active_time();
-    atom1->set_uid(kUid1);
-    atom1->set_time_millis(kCpuTime1);
-
-    auto* atom2 = shellData.add_atom()->mutable_cpu_active_time();
-    atom2->set_uid(kUid2);
-    atom2->set_time_millis(kCpuTime2);
-
-    return shellData;
-}
-
-ShellSubscription getPulledConfig() {
-    ShellSubscription config;
-    auto* pull_config = config.add_pulled();
-    pull_config->mutable_matcher()->set_atom_id(10016);
-    pull_config->set_freq_millis(2000);
-    return config;
-}
-
-shared_ptr<LogEvent> makeCpuActiveTimeAtom(int32_t uid, int64_t timeMillis) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, 10016);
-    AStatsEvent_overwriteTimestamp(statsEvent, 1111L);
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_writeInt64(statsEvent, timeMillis);
-
-    std::shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-}  // namespace
-
-TEST(ShellSubscriberTest, testPulledSubscription) {
-    sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
-
-    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    const vector<int32_t> uids = {AID_SYSTEM};
-    EXPECT_CALL(*pullerManager, Pull(10016, uids, _, _))
-            .WillRepeatedly(Invoke([](int tagId, const vector<int32_t>&, const int64_t,
-                                      vector<std::shared_ptr<LogEvent>>* data) {
-                data->clear();
-                data->push_back(makeCpuActiveTimeAtom(/*uid=*/kUid1, /*timeMillis=*/kCpuTime1));
-                data->push_back(makeCpuActiveTimeAtom(/*uid=*/kUid2, /*timeMillis=*/kCpuTime2));
-                return true;
-            }));
-    runShellTest(getPulledConfig(), uidMap, pullerManager, vector<std::shared_ptr<LogEvent>>(),
-                 getExpectedShellData());
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp
deleted file mode 100644
index 6516c15..0000000
--- a/cmds/statsd/tests/state/StateTracker_test.cpp
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Copyright (C) 2019, 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.
- */
-#include "state/StateTracker.h"
-
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-
-#include "state/StateListener.h"
-#include "state/StateManager.h"
-#include "state/StateTracker.h"
-#include "stats_event.h"
-#include "tests/statsd_test_util.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-const int32_t timestampNs = 1000;
-
-/**
- * Mock StateListener class for testing.
- * Stores primary key and state pairs.
- */
-class TestStateListener : public virtual StateListener {
-public:
-    TestStateListener(){};
-
-    virtual ~TestStateListener(){};
-
-    struct Update {
-        Update(const HashableDimensionKey& key, int state) : mKey(key), mState(state){};
-        HashableDimensionKey mKey;
-        int mState;
-    };
-
-    std::vector<Update> updates;
-
-    void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
-                        const HashableDimensionKey& primaryKey, const FieldValue& oldState,
-                        const FieldValue& newState) {
-        updates.emplace_back(primaryKey, newState.mValue.int_value);
-    }
-};
-
-int getStateInt(StateManager& mgr, int atomId, const HashableDimensionKey& queryKey) {
-    FieldValue output;
-    mgr.getStateValue(atomId, queryKey, &output);
-    return output.mValue.int_value;
-}
-
-// START: build event functions.
-// Incorrect event - missing fields
-std::unique_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName,
-                                                     int state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, 1000);
-
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_writeString(statsEvent, packageName.c_str());
-    // Missing field 3 - using_alert_window.
-    AStatsEvent_writeInt32(statsEvent, state);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-// Incorrect event - exclusive state has wrong type
-std::unique_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, 1000);
-
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_writeString(statsEvent, packageName.c_str());
-    AStatsEvent_writeInt32(statsEvent, true);       // using_alert_window
-    AStatsEvent_writeString(statsEvent, "string");  // exclusive state: string instead of int
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-// END: build event functions.
-
-TEST(StateListenerTest, TestStateListenerWeakPointer) {
-    sp<TestStateListener> listener = new TestStateListener();
-    wp<TestStateListener> wListener = listener;
-    listener = nullptr;  // let go of listener
-    EXPECT_TRUE(wListener.promote() == nullptr);
-}
-
-TEST(StateManagerTest, TestStateManagerGetInstance) {
-    sp<TestStateListener> listener1 = new TestStateListener();
-    StateManager& mgr = StateManager::getInstance();
-    mgr.clear();
-
-    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-    EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
-}
-
-TEST(StateManagerTest, TestOnLogEvent) {
-    sp<MockUidMap> uidMap = makeMockUidMapForPackage("com.android.systemui", {10111});
-    sp<TestStateListener> listener1 = new TestStateListener();
-    StateManager mgr;
-    mgr.updateLogSources(uidMap);
-    // Add StateTracker by registering a listener.
-    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-
-    // log event using AID_ROOT
-    std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
-            timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    mgr.onLogEvent(*event);
-
-    // check StateTracker was updated by querying for state
-    HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-              getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-
-    // log event using mocked uid
-    event = CreateScreenStateChangedEvent(
-            timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_OFF, 10111);
-    mgr.onLogEvent(*event);
-
-    // check StateTracker was updated by querying for state
-    queryKey = DEFAULT_DIMENSION_KEY;
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
-              getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-
-    // log event using non-whitelisted uid
-    event = CreateScreenStateChangedEvent(timestampNs,
-                                          android::view::DisplayStateEnum::DISPLAY_STATE_ON, 10112);
-    mgr.onLogEvent(*event);
-
-    // check StateTracker was NOT updated by querying for state
-    queryKey = DEFAULT_DIMENSION_KEY;
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF,
-              getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-
-    // log event using AID_SYSTEM
-    event = CreateScreenStateChangedEvent(
-            timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON, AID_SYSTEM);
-    mgr.onLogEvent(*event);
-
-    // check StateTracker was updated by querying for state
-    queryKey = DEFAULT_DIMENSION_KEY;
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-              getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-}
-
-/**
- * Test registering listeners to StateTrackers
- *
- * - StateManager will create a new StateTracker if it doesn't already exist
- * and then register the listener to the StateTracker.
- * - If a listener is already registered to a StateTracker, it is not added again.
- * - StateTrackers are only created for atoms that are state atoms.
- */
-TEST(StateTrackerTest, TestRegisterListener) {
-    sp<TestStateListener> listener1 = new TestStateListener();
-    sp<TestStateListener> listener2 = new TestStateListener();
-    StateManager mgr;
-
-    // Register listener to non-existing StateTracker
-    EXPECT_EQ(0, mgr.getStateTrackersCount());
-    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-    EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
-    // Register listener to existing StateTracker
-    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
-    EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
-    // Register already registered listener to existing StateTracker
-    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
-    EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
-    // Register listener to non-state atom
-    mgr.registerListener(util::BATTERY_LEVEL_CHANGED, listener2);
-    EXPECT_EQ(2, mgr.getStateTrackersCount());
-}
-
-/**
- * Test unregistering listeners from StateTrackers
- *
- * - StateManager will unregister listeners from a StateTracker only if the
- * StateTracker exists and the listener is registered to the StateTracker.
- * - Once all listeners are removed from a StateTracker, the StateTracker
- * is also removed.
- */
-TEST(StateTrackerTest, TestUnregisterListener) {
-    sp<TestStateListener> listener1 = new TestStateListener();
-    sp<TestStateListener> listener2 = new TestStateListener();
-    StateManager mgr;
-
-    // Unregister listener from non-existing StateTracker
-    EXPECT_EQ(0, mgr.getStateTrackersCount());
-    mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener1);
-    EXPECT_EQ(0, mgr.getStateTrackersCount());
-    EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
-    // Unregister non-registered listener from existing StateTracker
-    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-    EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-    mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener2);
-    EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
-    // Unregister second-to-last listener from StateTracker
-    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2);
-    mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener1);
-    EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-
-    // Unregister last listener from StateTracker
-    mgr.unregisterListener(util::SCREEN_STATE_CHANGED, listener2);
-    EXPECT_EQ(0, mgr.getStateTrackersCount());
-    EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED));
-}
-
-/**
- * Test a binary state atom with nested counting.
- *
- * To go from an "ON" state to an "OFF" state with nested counting, we must see
- * an equal number of "OFF" events as "ON" events.
- * For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state.
- * ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state.
- */
-TEST(StateTrackerTest, TestStateChangeNested) {
-    sp<TestStateListener> listener = new TestStateListener();
-    StateManager mgr;
-    mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener);
-
-    std::vector<int> attributionUids1 = {1000};
-    std::vector<string> attributionTags1 = {"tag"};
-
-    std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(timestampNs, attributionUids1,
-                                                                  attributionTags1, "wakelockName");
-    mgr.onLogEvent(*event1);
-    ASSERT_EQ(1, listener->updates.size());
-    EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
-    EXPECT_EQ(1, listener->updates[0].mState);
-    listener->updates.clear();
-
-    std::unique_ptr<LogEvent> event2 = CreateAcquireWakelockEvent(
-            timestampNs + 1000, attributionUids1, attributionTags1, "wakelockName");
-    mgr.onLogEvent(*event2);
-    ASSERT_EQ(0, listener->updates.size());
-
-    std::unique_ptr<LogEvent> event3 = CreateReleaseWakelockEvent(
-            timestampNs + 2000, attributionUids1, attributionTags1, "wakelockName");
-    mgr.onLogEvent(*event3);
-    ASSERT_EQ(0, listener->updates.size());
-
-    std::unique_ptr<LogEvent> event4 = CreateReleaseWakelockEvent(
-            timestampNs + 3000, attributionUids1, attributionTags1, "wakelockName");
-    mgr.onLogEvent(*event4);
-    ASSERT_EQ(1, listener->updates.size());
-    EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
-    EXPECT_EQ(0, listener->updates[0].mState);
-}
-
-/**
- * Test a state atom with a reset state.
- *
- * If the reset state value is seen, every state in the map is set to the default
- * state and every listener is notified.
- */
-TEST(StateTrackerTest, TestStateChangeReset) {
-    sp<TestStateListener> listener = new TestStateListener();
-    StateManager mgr;
-    mgr.registerListener(util::BLE_SCAN_STATE_CHANGED, listener);
-
-    std::vector<int> attributionUids1 = {1000};
-    std::vector<string> attributionTags1 = {"tag1"};
-    std::vector<int> attributionUids2 = {2000};
-
-    std::unique_ptr<LogEvent> event1 =
-            CreateBleScanStateChangedEvent(timestampNs, attributionUids1, attributionTags1,
-                                           BleScanStateChanged::ON, false, false, false);
-    mgr.onLogEvent(*event1);
-    ASSERT_EQ(1, listener->updates.size());
-    EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
-    EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
-    FieldValue stateFieldValue;
-    mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, listener->updates[0].mKey, &stateFieldValue);
-    EXPECT_EQ(BleScanStateChanged::ON, stateFieldValue.mValue.int_value);
-    listener->updates.clear();
-
-    std::unique_ptr<LogEvent> event2 =
-            CreateBleScanStateChangedEvent(timestampNs + 1000, attributionUids2, attributionTags1,
-                                           BleScanStateChanged::ON, false, false, false);
-    mgr.onLogEvent(*event2);
-    ASSERT_EQ(1, listener->updates.size());
-    EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
-    EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
-    mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, listener->updates[0].mKey, &stateFieldValue);
-    EXPECT_EQ(BleScanStateChanged::ON, stateFieldValue.mValue.int_value);
-    listener->updates.clear();
-
-    std::unique_ptr<LogEvent> event3 =
-            CreateBleScanStateChangedEvent(timestampNs + 2000, attributionUids2, attributionTags1,
-                                           BleScanStateChanged::RESET, false, false, false);
-    mgr.onLogEvent(*event3);
-    ASSERT_EQ(2, listener->updates.size());
-    for (const TestStateListener::Update& update : listener->updates) {
-        EXPECT_EQ(BleScanStateChanged::OFF, update.mState);
-
-        mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, update.mKey, &stateFieldValue);
-        EXPECT_EQ(BleScanStateChanged::OFF, stateFieldValue.mValue.int_value);
-    }
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
- * updates listener for states without primary keys.
- */
-TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) {
-    sp<TestStateListener> listener1 = new TestStateListener();
-    StateManager mgr;
-    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-
-    // log event
-    std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
-            timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    mgr.onLogEvent(*event);
-
-    // check listener was updated
-    ASSERT_EQ(1, listener1->updates.size());
-    EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey);
-    EXPECT_EQ(2, listener1->updates[0].mState);
-
-    // check StateTracker was updated by querying for state
-    HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY;
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-              getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey));
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
- * updates listener for states with one primary key.
- */
-TEST(StateTrackerTest, TestStateChangeOnePrimaryField) {
-    sp<TestStateListener> listener1 = new TestStateListener();
-    StateManager mgr;
-    mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener1);
-
-    // log event
-    std::unique_ptr<LogEvent> event = CreateUidProcessStateChangedEvent(
-            timestampNs, 1000 /*uid*/, android::app::ProcessStateEnum::PROCESS_STATE_TOP);
-    mgr.onLogEvent(*event);
-
-    // check listener was updated
-    ASSERT_EQ(1, listener1->updates.size());
-    EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
-    EXPECT_EQ(1002, listener1->updates[0].mState);
-
-    // check StateTracker was updated by querying for state
-    HashableDimensionKey queryKey;
-    getUidProcessKey(1000 /* uid */, &queryKey);
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
-              getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey));
-}
-
-TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) {
-    sp<TestStateListener> listener1 = new TestStateListener();
-    StateManager mgr;
-    mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener1);
-
-    // Log event.
-    std::vector<int> attributionUids = {1001};
-    std::vector<string> attributionTags = {"tag1"};
-
-    std::unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(timestampNs, attributionUids,
-                                                                 attributionTags, "wakelockName");
-    mgr.onLogEvent(*event);
-    EXPECT_EQ(1, mgr.getStateTrackersCount());
-    EXPECT_EQ(1, mgr.getListenersCount(util::WAKELOCK_STATE_CHANGED));
-
-    // Check listener was updated.
-    ASSERT_EQ(1, listener1->updates.size());
-    ASSERT_EQ(3, listener1->updates[0].mKey.getValues().size());
-    EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
-    EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value);
-    EXPECT_EQ("wakelockName", listener1->updates[0].mKey.getValues()[2].mValue.str_value);
-    EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState);
-
-    // Check StateTracker was updated by querying for state.
-    HashableDimensionKey queryKey;
-    getPartialWakelockKey(1001 /* uid */, "wakelockName", &queryKey);
-    EXPECT_EQ(WakelockStateChanged::ACQUIRE,
-              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey));
-
-    // No state stored for this query key.
-    HashableDimensionKey queryKey2;
-    getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2);
-    EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/,
-              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey2));
-
-    // Partial query fails.
-    HashableDimensionKey queryKey3;
-    getPartialWakelockKey(1001 /* uid */, &queryKey3);
-    EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/,
-              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey3));
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged correctly
- * updates listener for states with multiple primary keys.
- */
-TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) {
-    sp<TestStateListener> listener1 = new TestStateListener();
-    StateManager mgr;
-    mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
-
-    // log event
-    std::unique_ptr<LogEvent> event = CreateOverlayStateChangedEvent(
-            timestampNs, 1000 /* uid */, "package1", true /*using_alert_window*/,
-            OverlayStateChanged::ENTERED);
-    mgr.onLogEvent(*event);
-
-    // check listener was updated
-    ASSERT_EQ(1, listener1->updates.size());
-    EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
-    EXPECT_EQ(1, listener1->updates[0].mState);
-
-    // check StateTracker was updated by querying for state
-    HashableDimensionKey queryKey;
-    getOverlayKey(1000 /* uid */, "package1", &queryKey);
-    EXPECT_EQ(OverlayStateChanged::ENTERED,
-              getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey));
-}
-
-/**
- * Test StateManager's onLogEvent and StateListener's onStateChanged
- * when there is an error extracting state from log event. Listener is not
- * updated of state change.
- */
-TEST(StateTrackerTest, TestStateChangeEventError) {
-    sp<TestStateListener> listener1 = new TestStateListener();
-    StateManager mgr;
-    mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1);
-
-    // log event
-    std::shared_ptr<LogEvent> event1 =
-            buildIncorrectOverlayEvent(1000 /* uid */, "package1", 1 /* state */);
-    std::shared_ptr<LogEvent> event2 = buildOverlayEventBadStateType(1001 /* uid */, "package2");
-
-    // check listener was updated
-    mgr.onLogEvent(*event1);
-    ASSERT_EQ(0, listener1->updates.size());
-    mgr.onLogEvent(*event2);
-    ASSERT_EQ(0, listener1->updates.size());
-}
-
-TEST(StateTrackerTest, TestStateQuery) {
-    sp<TestStateListener> listener1 = new TestStateListener();
-    sp<TestStateListener> listener2 = new TestStateListener();
-    sp<TestStateListener> listener3 = new TestStateListener();
-    sp<TestStateListener> listener4 = new TestStateListener();
-    StateManager mgr;
-    mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1);
-    mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener2);
-    mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener3);
-    mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener4);
-
-    std::unique_ptr<LogEvent> event1 = CreateUidProcessStateChangedEvent(
-            timestampNs, 1000 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_TOP);  //  state value: 1002
-    std::unique_ptr<LogEvent> event2 = CreateUidProcessStateChangedEvent(
-            timestampNs + 1000, 1001 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE);  //  state value:
-                                                                                //  1003
-    std::unique_ptr<LogEvent> event3 = CreateUidProcessStateChangedEvent(
-            timestampNs + 2000, 1002 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_PERSISTENT);  //  state value: 1000
-    std::unique_ptr<LogEvent> event4 = CreateUidProcessStateChangedEvent(
-            timestampNs + 3000, 1001 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_TOP);  //  state value: 1002
-    std::unique_ptr<LogEvent> event5 = CreateScreenStateChangedEvent(
-            timestampNs + 4000, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    std::unique_ptr<LogEvent> event6 = CreateOverlayStateChangedEvent(
-            timestampNs + 5000, 1000 /*uid*/, "package1", true /*using_alert_window*/,
-            OverlayStateChanged::ENTERED);
-    std::unique_ptr<LogEvent> event7 = CreateOverlayStateChangedEvent(
-            timestampNs + 6000, 1000 /*uid*/, "package2", true /*using_alert_window*/,
-            OverlayStateChanged::EXITED);
-
-    std::vector<int> attributionUids = {1005};
-    std::vector<string> attributionTags = {"tag"};
-
-    std::unique_ptr<LogEvent> event8 = CreateAcquireWakelockEvent(
-            timestampNs + 7000, attributionUids, attributionTags, "wakelock1");
-    std::unique_ptr<LogEvent> event9 = CreateReleaseWakelockEvent(
-            timestampNs + 8000, attributionUids, attributionTags, "wakelock2");
-
-    mgr.onLogEvent(*event1);
-    mgr.onLogEvent(*event2);
-    mgr.onLogEvent(*event3);
-    mgr.onLogEvent(*event5);
-    mgr.onLogEvent(*event5);
-    mgr.onLogEvent(*event6);
-    mgr.onLogEvent(*event7);
-    mgr.onLogEvent(*event8);
-    mgr.onLogEvent(*event9);
-
-    // Query for UidProcessState of uid 1001
-    HashableDimensionKey queryKey1;
-    getUidProcessKey(1001, &queryKey1);
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
-              getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
-
-    // Query for UidProcessState of uid 1004 - not in state map
-    HashableDimensionKey queryKey2;
-    getUidProcessKey(1004, &queryKey2);
-    EXPECT_EQ(-1, getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED,
-                              queryKey2));  // default state
-
-    // Query for UidProcessState of uid 1001 - after change in state
-    mgr.onLogEvent(*event4);
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP,
-              getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1));
-
-    // Query for ScreenState
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON,
-              getStateInt(mgr, util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY));
-
-    // Query for OverlayState of uid 1000, package name "package2"
-    HashableDimensionKey queryKey3;
-    getOverlayKey(1000, "package2", &queryKey3);
-    EXPECT_EQ(OverlayStateChanged::EXITED,
-              getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey3));
-
-    // Query for WakelockState of uid 1005, tag 2
-    HashableDimensionKey queryKey4;
-    getPartialWakelockKey(1005, "wakelock2", &queryKey4);
-    EXPECT_EQ(WakelockStateChanged::RELEASE,
-              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey4));
-
-    // Query for WakelockState of uid 1005, tag 1
-    HashableDimensionKey queryKey5;
-    getPartialWakelockKey(1005, "wakelock1", &queryKey5);
-    EXPECT_EQ(WakelockStateChanged::ACQUIRE,
-              getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey5));
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
deleted file mode 100644
index 153b696..0000000
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ /dev/null
@@ -1,1424 +0,0 @@
-// Copyright (C) 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.
-
-#include "statsd_test_util.h"
-
-#include <aidl/android/util/StatsEventParcel.h>
-
-#include "matchers/SimpleAtomMatchingTracker.h"
-#include "stats_event.h"
-
-using aidl::android::util::StatsEventParcel;
-using std::shared_ptr;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsLogReport outputStreamToProto(ProtoOutputStream* proto) {
-    vector<uint8_t> bytes;
-    bytes.resize(proto->size());
-    size_t pos = 0;
-    sp<ProtoReader> reader = proto->data();
-
-    while (reader->readBuffer() != NULL) {
-        size_t toRead = reader->currentToRead();
-        std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
-        pos += toRead;
-        reader->move(toRead);
-    }
-
-    StatsLogReport report;
-    report.ParseFromArray(bytes.data(), bytes.size());
-    return report;
-}
-
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(atomId);
-    return atom_matcher;
-}
-
-AtomMatcher CreateTemperatureAtomMatcher() {
-    return CreateSimpleAtomMatcher("TemperatureMatcher", util::TEMPERATURE);
-}
-
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher(const string& name,
-                                                      ScheduledJobStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::SCHEDULED_JOB_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(3);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateStartScheduledJobAtomMatcher() {
-    return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobStart",
-                                                     ScheduledJobStateChanged::STARTED);
-}
-
-AtomMatcher CreateFinishScheduledJobAtomMatcher() {
-    return CreateScheduledJobStateChangedAtomMatcher("ScheduledJobFinish",
-                                                     ScheduledJobStateChanged::FINISHED);
-}
-
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher() {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId("ScreenBrightnessChanged"));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::SCREEN_BRIGHTNESS_CHANGED);
-    return atom_matcher;
-}
-
-AtomMatcher CreateUidProcessStateChangedAtomMatcher() {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId("UidProcessStateChanged"));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::UID_PROCESS_STATE_CHANGED);
-    return atom_matcher;
-}
-
-AtomMatcher CreateWakelockStateChangedAtomMatcher(const string& name,
-                                                  WakelockStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::WAKELOCK_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(4);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateAcquireWakelockAtomMatcher() {
-    return CreateWakelockStateChangedAtomMatcher("AcquireWakelock", WakelockStateChanged::ACQUIRE);
-}
-
-AtomMatcher CreateReleaseWakelockAtomMatcher() {
-    return CreateWakelockStateChangedAtomMatcher("ReleaseWakelock", WakelockStateChanged::RELEASE);
-}
-
-AtomMatcher CreateBatterySaverModeStateChangedAtomMatcher(
-    const string& name, BatterySaverModeStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(1);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateBatterySaverModeStartAtomMatcher() {
-    return CreateBatterySaverModeStateChangedAtomMatcher(
-        "BatterySaverModeStart", BatterySaverModeStateChanged::ON);
-}
-
-
-AtomMatcher CreateBatterySaverModeStopAtomMatcher() {
-    return CreateBatterySaverModeStateChangedAtomMatcher(
-        "BatterySaverModeStop", BatterySaverModeStateChanged::OFF);
-}
-
-AtomMatcher CreateBatteryStateChangedAtomMatcher(const string& name,
-                                                 BatteryPluggedStateEnum state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::PLUGGED_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(1);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateBatteryStateNoneMatcher() {
-    return CreateBatteryStateChangedAtomMatcher("BatteryPluggedNone",
-                                                BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
-}
-
-AtomMatcher CreateBatteryStateUsbMatcher() {
-    return CreateBatteryStateChangedAtomMatcher("BatteryPluggedUsb",
-                                                BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
-}
-
-AtomMatcher CreateScreenStateChangedAtomMatcher(
-    const string& name, android::view::DisplayStateEnum state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::SCREEN_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(1);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateScreenTurnedOnAtomMatcher() {
-    return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn",
-            android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-}
-
-AtomMatcher CreateScreenTurnedOffAtomMatcher() {
-    return CreateScreenStateChangedAtomMatcher("ScreenTurnedOff",
-            ::android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-}
-
-AtomMatcher CreateSyncStateChangedAtomMatcher(
-    const string& name, SyncStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::SYNC_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(3);  // State field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateSyncStartAtomMatcher() {
-    return CreateSyncStateChangedAtomMatcher("SyncStart", SyncStateChanged::ON);
-}
-
-AtomMatcher CreateSyncEndAtomMatcher() {
-    return CreateSyncStateChangedAtomMatcher("SyncEnd", SyncStateChanged::OFF);
-}
-
-AtomMatcher CreateActivityForegroundStateChangedAtomMatcher(
-    const string& name, ActivityForegroundStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(4);  // Activity field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateMoveToBackgroundAtomMatcher() {
-    return CreateActivityForegroundStateChangedAtomMatcher(
-        "Background", ActivityForegroundStateChanged::BACKGROUND);
-}
-
-AtomMatcher CreateMoveToForegroundAtomMatcher() {
-    return CreateActivityForegroundStateChangedAtomMatcher(
-        "Foreground", ActivityForegroundStateChanged::FOREGROUND);
-}
-
-AtomMatcher CreateProcessLifeCycleStateChangedAtomMatcher(
-    const string& name, ProcessLifeCycleStateChanged::State state) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(3);  // Process state field.
-    field_value_matcher->set_eq_int(state);
-    return atom_matcher;
-}
-
-AtomMatcher CreateProcessCrashAtomMatcher() {
-    return CreateProcessLifeCycleStateChangedAtomMatcher(
-        "Crashed", ProcessLifeCycleStateChanged::CRASHED);
-}
-
-Predicate CreateScheduledJobPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("ScheduledJobRunningPredicate"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("ScheduledJobStart"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("ScheduledJobFinish"));
-    return predicate;
-}
-
-Predicate CreateBatterySaverModePredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("BatterySaverIsOn"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("BatterySaverModeStart"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("BatterySaverModeStop"));
-    return predicate;
-}
-
-Predicate CreateDeviceUnpluggedPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("DeviceUnplugged"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("BatteryPluggedNone"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("BatteryPluggedUsb"));
-    return predicate;
-}
-
-Predicate CreateScreenIsOnPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("ScreenIsOn"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOn"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOff"));
-    return predicate;
-}
-
-Predicate CreateScreenIsOffPredicate() {
-    Predicate predicate;
-    predicate.set_id(1111123);
-    predicate.mutable_simple_predicate()->set_start(StringToId("ScreenTurnedOff"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("ScreenTurnedOn"));
-    return predicate;
-}
-
-Predicate CreateHoldingWakelockPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("HoldingWakelock"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("AcquireWakelock"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("ReleaseWakelock"));
-    return predicate;
-}
-
-Predicate CreateIsSyncingPredicate() {
-    Predicate predicate;
-    predicate.set_id(33333333333333);
-    predicate.mutable_simple_predicate()->set_start(StringToId("SyncStart"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("SyncEnd"));
-    return predicate;
-}
-
-Predicate CreateIsInBackgroundPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("IsInBackground"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("Background"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("Foreground"));
-    return predicate;
-}
-
-State CreateScreenState() {
-    State state;
-    state.set_id(StringToId("ScreenState"));
-    state.set_atom_id(util::SCREEN_STATE_CHANGED);
-    return state;
-}
-
-State CreateUidProcessState() {
-    State state;
-    state.set_id(StringToId("UidProcessState"));
-    state.set_atom_id(util::UID_PROCESS_STATE_CHANGED);
-    return state;
-}
-
-State CreateOverlayState() {
-    State state;
-    state.set_id(StringToId("OverlayState"));
-    state.set_atom_id(util::OVERLAY_STATE_CHANGED);
-    return state;
-}
-
-State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId) {
-    State state;
-    state.set_id(StringToId("ScreenStateOnOff"));
-    state.set_atom_id(util::SCREEN_STATE_CHANGED);
-
-    auto map = CreateScreenStateOnOffMap(screenOnId, screenOffId);
-    *state.mutable_map() = map;
-
-    return state;
-}
-
-State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
-    State state;
-    state.set_id(StringToId("ScreenStateSimpleOnOff"));
-    state.set_atom_id(util::SCREEN_STATE_CHANGED);
-
-    auto map = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId);
-    *state.mutable_map() = map;
-
-    return state;
-}
-
-StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId) {
-    StateMap_StateGroup group;
-    group.set_group_id(screenOnId);
-    group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_VR);
-    group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND);
-    return group;
-}
-
-StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId) {
-    StateMap_StateGroup group;
-    group.set_group_id(screenOffId);
-    group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE);
-    group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND);
-    return group;
-}
-
-StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId) {
-    StateMap_StateGroup group;
-    group.set_group_id(screenOnId);
-    group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-    return group;
-}
-
-StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId) {
-    StateMap_StateGroup group;
-    group.set_group_id(screenOffId);
-    group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
-    return group;
-}
-
-StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId) {
-    StateMap map;
-    *map.add_group() = CreateScreenStateOnGroup(screenOnId);
-    *map.add_group() = CreateScreenStateOffGroup(screenOffId);
-    return map;
-}
-
-StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) {
-    StateMap map;
-    *map.add_group() = CreateScreenStateSimpleOnGroup(screenOnId);
-    *map.add_group() = CreateScreenStateSimpleOffGroup(screenOffId);
-    return map;
-}
-
-void addPredicateToPredicateCombination(const Predicate& predicate,
-                                        Predicate* combinationPredicate) {
-    combinationPredicate->mutable_combination()->add_predicate(predicate.id());
-}
-
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
-                                            const std::vector<Position>& positions) {
-    FieldMatcher dimensions;
-    dimensions.set_field(atomId);
-    for (const auto position : positions) {
-        auto child = dimensions.add_child();
-        child->set_field(1);
-        child->set_position(position);
-        child->add_child()->set_field(1);
-    }
-    return dimensions;
-}
-
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
-                                                 const std::vector<Position>& positions) {
-    FieldMatcher dimensions;
-    dimensions.set_field(atomId);
-    for (const auto position : positions) {
-        auto child = dimensions.add_child();
-        child->set_field(1);
-        child->set_position(position);
-        child->add_child()->set_field(1);
-        child->add_child()->set_field(2);
-    }
-    return dimensions;
-}
-
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) {
-    FieldMatcher dimensions;
-    dimensions.set_field(atomId);
-    for (const int field : fields) {
-        dimensions.add_child()->set_field(field);
-    }
-    return dimensions;
-}
-
-FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
-                                                    const std::vector<Position>& positions,
-                                                    const std::vector<int>& fields) {
-    FieldMatcher dimensions = CreateAttributionUidDimensions(atomId, positions);
-
-    for (const int field : fields) {
-        dimensions.add_child()->set_field(field);
-    }
-    return dimensions;
-}
-
-// START: get primary key functions
-void getUidProcessKey(int uid, HashableDimensionKey* key) {
-    int pos1[] = {1, 0, 0};
-    Field field1(27 /* atom id */, pos1, 0 /* depth */);
-    Value value1((int32_t)uid);
-
-    key->addValue(FieldValue(field1, value1));
-}
-
-void getOverlayKey(int uid, string packageName, HashableDimensionKey* key) {
-    int pos1[] = {1, 0, 0};
-    int pos2[] = {2, 0, 0};
-
-    Field field1(59 /* atom id */, pos1, 0 /* depth */);
-    Field field2(59 /* atom id */, pos2, 0 /* depth */);
-
-    Value value1((int32_t)uid);
-    Value value2(packageName);
-
-    key->addValue(FieldValue(field1, value1));
-    key->addValue(FieldValue(field2, value2));
-}
-
-void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key) {
-    int pos1[] = {1, 1, 1};
-    int pos3[] = {2, 0, 0};
-    int pos4[] = {3, 0, 0};
-
-    Field field1(10 /* atom id */, pos1, 2 /* depth */);
-
-    Field field3(10 /* atom id */, pos3, 0 /* depth */);
-    Field field4(10 /* atom id */, pos4, 0 /* depth */);
-
-    Value value1((int32_t)uid);
-    Value value3((int32_t)1 /*partial*/);
-    Value value4(tag);
-
-    key->addValue(FieldValue(field1, value1));
-    key->addValue(FieldValue(field3, value3));
-    key->addValue(FieldValue(field4, value4));
-}
-
-void getPartialWakelockKey(int uid, HashableDimensionKey* key) {
-    int pos1[] = {1, 1, 1};
-    int pos3[] = {2, 0, 0};
-
-    Field field1(10 /* atom id */, pos1, 2 /* depth */);
-    Field field3(10 /* atom id */, pos3, 0 /* depth */);
-
-    Value value1((int32_t)uid);
-    Value value3((int32_t)1 /*partial*/);
-
-    key->addValue(FieldValue(field1, value1));
-    key->addValue(FieldValue(field3, value3));
-}
-// END: get primary key functions
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
-                      const vector<string>& attributionTags) {
-    vector<const char*> cTags(attributionTags.size());
-    for (int i = 0; i < cTags.size(); i++) {
-        cTags[i] = attributionTags[i].c_str();
-    }
-
-    AStatsEvent_writeAttributionChain(statsEvent,
-                                      reinterpret_cast<const uint32_t*>(attributionUids.data()),
-                                      cTags.data(), attributionUids.size());
-}
-
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) {
-    AStatsEvent_build(statsEvent);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    logEvent->parseBuffer(buf, size);
-
-    AStatsEvent_release(statsEvent);
-}
-
-void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
-                            int32_t value2) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
-    AStatsEvent_writeInt32(statsEvent, value1);
-    AStatsEvent_writeInt32(statsEvent, value2);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
-                                            int32_t value2) {
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    CreateTwoValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2);
-    return logEvent;
-}
-
-void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
-                              int32_t value2, int32_t value3) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
-    AStatsEvent_writeInt32(statsEvent, value1);
-    AStatsEvent_writeInt32(statsEvent, value2);
-    AStatsEvent_writeInt32(statsEvent, value3);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
-                                              int32_t value2, int32_t value3) {
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    CreateThreeValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2, value3);
-    return logEvent;
-}
-
-void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
-                                 int32_t value) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
-    AStatsEvent_writeInt32(statsEvent, value);
-    AStatsEvent_writeInt32(statsEvent, value);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) {
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    CreateRepeatedValueLogEvent(logEvent.get(), atomId, eventTimeNs, value);
-    return logEvent;
-}
-
-void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) {
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    CreateNoValuesLogEvent(logEvent.get(), atomId, eventTimeNs);
-    return logEvent;
-}
-
-shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
-                                     int data2) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_writeInt32(statsEvent, data1);
-    AStatsEvent_writeInt32(statsEvent, data2);
-
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
-                                             const vector<int>& uids, const vector<string>& tags,
-                                             int data1, int data2) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-
-    writeAttribution(statsEvent, uids, tags);
-    AStatsEvent_writeInt32(statsEvent, data1);
-    AStatsEvent_writeInt32(statsEvent, data2);
-
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids) {
-    sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
-    EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(ReturnArg<0>());
-    for (const int isolatedUid : isolatedUids) {
-        EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)).WillRepeatedly(Return(hostUid));
-    }
-
-    return uidMap;
-}
-
-sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids) {
-    sp<MockUidMap> uidMap = new StrictMock<MockUidMap>();
-    EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber());
-    EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids));
-
-    return uidMap;
-}
-
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
-                                                        const android::view::DisplayStateEnum state,
-                                                        int loggerUid) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-    AStatsEvent_writeInt32(statsEvent, state);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(loggerUid, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-    AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-    AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs, const BatteryPluggedStateEnum state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-    AStatsEvent_writeInt32(statsEvent, state);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::SCREEN_BRIGHTNESS_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-    AStatsEvent_writeInt32(statsEvent, level);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent(
-        const vector<int>& attributionUids, const vector<string>& attributionTags,
-        const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_writeString(statsEvent, jobName.c_str());
-    AStatsEvent_writeInt32(statsEvent, state);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
-                                                       const vector<int>& attributionUids,
-                                                       const vector<string>& attributionTags,
-                                                       const string& jobName) {
-    return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
-                                               ScheduledJobStateChanged::STARTED, timestampNs);
-}
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
-                                                        const vector<int>& attributionUids,
-                                                        const vector<string>& attributionTags,
-                                                        const string& jobName) {
-    return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName,
-                                               ScheduledJobStateChanged::FINISHED, timestampNs);
-}
-
-std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
-                                                          const vector<int>& attributionUids,
-                                                          const vector<string>& attributionTags,
-                                                          const string& wakelockName,
-                                                          const WakelockStateChanged::State state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::WAKELOCK_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
-    AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-    AStatsEvent_writeString(statsEvent, wakelockName.c_str());
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-    AStatsEvent_writeInt32(statsEvent, state);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, true);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs,
-                                                     const vector<int>& attributionUids,
-                                                     const vector<string>& attributionTags,
-                                                     const string& wakelockName) {
-    return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
-                                           wakelockName, WakelockStateChanged::ACQUIRE);
-}
-
-std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs,
-                                                     const vector<int>& attributionUids,
-                                                     const vector<string>& attributionTags,
-                                                     const string& wakelockName) {
-    return CreateWakelockStateChangedEvent(timestampNs, attributionUids, attributionTags,
-                                           wakelockName, WakelockStateChanged::RELEASE);
-}
-
-std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent(
-        uint64_t timestampNs, const int uid, const ActivityForegroundStateChanged::State state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::ACTIVITY_FOREGROUND_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_writeString(statsEvent, "pkg_name");
-    AStatsEvent_writeString(statsEvent, "class_name");
-    AStatsEvent_writeInt32(statsEvent, state);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid) {
-    return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
-                                                     ActivityForegroundStateChanged::BACKGROUND);
-}
-
-std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid) {
-    return CreateActivityForegroundStateChangedEvent(timestampNs, uid,
-                                                     ActivityForegroundStateChanged::FOREGROUND);
-}
-
-std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs,
-                                                      const vector<int>& attributionUids,
-                                                      const vector<string>& attributionTags,
-                                                      const string& name,
-                                                      const SyncStateChanged::State state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_writeString(statsEvent, name.c_str());
-    AStatsEvent_writeInt32(statsEvent, state);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs,
-                                               const vector<int>& attributionUids,
-                                               const vector<string>& attributionTags,
-                                               const string& name) {
-    return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
-                                       SyncStateChanged::ON);
-}
-
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs,
-                                             const vector<int>& attributionUids,
-                                             const vector<string>& attributionTags,
-                                             const string& name) {
-    return CreateSyncStateChangedEvent(timestampNs, attributionUids, attributionTags, name,
-                                       SyncStateChanged::OFF);
-}
-
-std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent(
-        uint64_t timestampNs, const int uid, const ProcessLifeCycleStateChanged::State state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_writeString(statsEvent, "");
-    AStatsEvent_writeInt32(statsEvent, state);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid) {
-    return CreateProcessLifeCycleStateChangedEvent(timestampNs, uid,
-                                                   ProcessLifeCycleStateChanged::CRASHED);
-}
-
-std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::APP_CRASH_OCCURRED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_writeString(statsEvent, "eventType");
-    AStatsEvent_writeString(statsEvent, "processName");
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
-                                                        int isolatedUid, bool is_create) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::ISOLATED_UID_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    AStatsEvent_writeInt32(statsEvent, hostUid);
-    AStatsEvent_writeInt32(statsEvent, isolatedUid);
-    AStatsEvent_writeInt32(statsEvent, is_create);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
-        uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::UID_PROCESS_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-    AStatsEvent_writeInt32(statsEvent, state);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
-                                                         const vector<int>& attributionUids,
-                                                         const vector<string>& attributionTags,
-                                                         const BleScanStateChanged::State state,
-                                                         const bool filtered, const bool firstMatch,
-                                                         const bool opportunistic) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
-    AStatsEvent_writeInt32(statsEvent, state);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, true);
-    if (state == util::BLE_SCAN_STATE_CHANGED__STATE__RESET) {
-        AStatsEvent_addInt32Annotation(statsEvent, ANNOTATION_ID_TRIGGER_STATE_RESET,
-                                       util::BLE_SCAN_STATE_CHANGED__STATE__OFF);
-    }
-    AStatsEvent_writeBool(statsEvent, filtered);  // filtered
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-    AStatsEvent_writeBool(statsEvent, firstMatch);  // first match
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-    AStatsEvent_writeBool(statsEvent, opportunistic);  // opportunistic
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
-                                                         const string& packageName,
-                                                         const bool usingAlertWindow,
-                                                         const OverlayStateChanged::State state) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-    AStatsEvent_writeString(statsEvent, packageName.c_str());
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true);
-    AStatsEvent_writeBool(statsEvent, usingAlertWindow);
-    AStatsEvent_writeInt32(statsEvent, state);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true);
-    AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false);
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
-sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
-                                              const StatsdConfig& config, const ConfigKey& key,
-                                              const shared_ptr<IPullAtomCallback>& puller,
-                                              const int32_t atomTag, const sp<UidMap> uidMap) {
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    if (puller != nullptr) {
-        pullerManager->RegisterPullAtomCallback(/*uid=*/0, atomTag, NS_PER_SEC, NS_PER_SEC * 10, {},
-                                                puller);
-    }
-    sp<AlarmMonitor> anomalyAlarmMonitor =
-        new AlarmMonitor(1,
-                         [](const shared_ptr<IStatsCompanionService>&, int64_t){},
-                         [](const shared_ptr<IStatsCompanionService>&){});
-    sp<AlarmMonitor> periodicAlarmMonitor =
-        new AlarmMonitor(1,
-                         [](const shared_ptr<IStatsCompanionService>&, int64_t){},
-                         [](const shared_ptr<IStatsCompanionService>&){});
-    sp<StatsLogProcessor> processor =
-            new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-                                  timeBaseNs, [](const ConfigKey&) { return true; },
-                                  [](const int&, const vector<int64_t>&) {return true;});
-    processor->OnConfigUpdated(currentTimeNs, key, config);
-    return processor;
-}
-
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events) {
-  std::sort(events->begin(), events->end(),
-            [](const std::unique_ptr<LogEvent>& a, const std::unique_ptr<LogEvent>& b) {
-              return a->GetElapsedTimestampNs() < b->GetElapsedTimestampNs();
-            });
-}
-
-int64_t StringToId(const string& str) {
-    return static_cast<int64_t>(std::hash<std::string>()(str));
-}
-
-sp<EventMatcherWizard> createEventMatcherWizard(
-        int tagId, int matcherIndex, const vector<FieldValueMatcher>& fieldValueMatchers) {
-    sp<UidMap> uidMap = new UidMap();
-    SimpleAtomMatcher atomMatcher;
-    atomMatcher.set_atom_id(tagId);
-    for (const FieldValueMatcher& fvm : fieldValueMatchers) {
-        *atomMatcher.add_field_value_matcher() = fvm;
-    }
-    uint64_t matcherHash = 0x12345678;
-    int64_t matcherId = 678;
-    return new EventMatcherWizard({new SimpleAtomMatchingTracker(
-            matcherId, matcherIndex, matcherHash, atomMatcher, uidMap)});
-}
-
-void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
-                                                   const int uid, const string& tag) {
-    EXPECT_EQ(value.field(), atomId);
-    ASSERT_EQ(value.value_tuple().dimensions_value_size(), 2);
-    // Attribution field.
-    EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
-    // Uid field.
-    ASSERT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 1);
-    EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
-    EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
-              uid);
-    // Tag field.
-    EXPECT_EQ(value.value_tuple().dimensions_value(1).field(), 3);
-    EXPECT_EQ(value.value_tuple().dimensions_value(1).value_str(), tag);
-}
-
-void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
-    EXPECT_EQ(value.field(), atomId);
-    ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
-    // Attribution field.
-    EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
-    // Uid only.
-    EXPECT_EQ(value.value_tuple().dimensions_value(0)
-        .value_tuple().dimensions_value_size(), 1);
-    EXPECT_EQ(value.value_tuple().dimensions_value(0)
-        .value_tuple().dimensions_value(0).field(), 1);
-    EXPECT_EQ(value.value_tuple().dimensions_value(0)
-        .value_tuple().dimensions_value(0).value_int(), uid);
-}
-
-void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
-    EXPECT_EQ(value.field(), atomId);
-    ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
-    // Attribution field.
-    EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
-    EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
-        .value_tuple().dimensions_value(0).field(), 1);
-    EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
-        .value_tuple().dimensions_value(0).value_int(), uid);
-}
-
-void ValidateAttributionUidAndTagDimension(
-    const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
-    EXPECT_EQ(value.field(), atomId);
-    ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
-    // Attribution field.
-    EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
-    // Uid only.
-    EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
-        .value_tuple().dimensions_value_size());
-    EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx)
-        .value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(uid, value.value_tuple().dimensions_value(node_idx)
-        .value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(2, value.value_tuple().dimensions_value(node_idx)
-        .value_tuple().dimensions_value(1).field());
-    EXPECT_EQ(tag, value.value_tuple().dimensions_value(node_idx)
-        .value_tuple().dimensions_value(1).value_str());
-}
-
-void ValidateAttributionUidAndTagDimension(
-    const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
-    EXPECT_EQ(value.field(), atomId);
-    ASSERT_EQ(1, value.value_tuple().dimensions_value_size());
-    // Attribution field.
-    EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
-    // Uid only.
-    EXPECT_EQ(value.value_tuple().dimensions_value(0)
-        .value_tuple().dimensions_value_size(), 2);
-    EXPECT_EQ(value.value_tuple().dimensions_value(0)
-        .value_tuple().dimensions_value(0).field(), 1);
-    EXPECT_EQ(value.value_tuple().dimensions_value(0)
-        .value_tuple().dimensions_value(0).value_int(), uid);
-    EXPECT_EQ(value.value_tuple().dimensions_value(0)
-        .value_tuple().dimensions_value(1).field(), 2);
-    EXPECT_EQ(value.value_tuple().dimensions_value(0)
-        .value_tuple().dimensions_value(1).value_str(), tag);
-}
-
-void ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue>& stateValues,
-                        int atomId, int64_t value) {
-    ASSERT_EQ(stateValues.size(), 1);
-    ASSERT_EQ(stateValues[0].atom_id(), atomId);
-    switch (stateValues[0].contents_case()) {
-        case StateValue::ContentsCase::kValue:
-            EXPECT_EQ(stateValues[0].value(), (int32_t)value);
-            break;
-        case StateValue::ContentsCase::kGroupId:
-            EXPECT_EQ(stateValues[0].group_id(), value);
-            break;
-        default:
-            FAIL() << "State value should have either a value or a group id";
-    }
-}
-bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
-    if (s1.field() != s2.field()) {
-        return false;
-    }
-    if (s1.value_case() != s2.value_case()) {
-        return false;
-    }
-    switch (s1.value_case()) {
-        case DimensionsValue::ValueCase::kValueStr:
-            return (s1.value_str() == s2.value_str());
-        case DimensionsValue::ValueCase::kValueInt:
-            return s1.value_int() == s2.value_int();
-        case DimensionsValue::ValueCase::kValueLong:
-            return s1.value_long() == s2.value_long();
-        case DimensionsValue::ValueCase::kValueBool:
-            return s1.value_bool() == s2.value_bool();
-        case DimensionsValue::ValueCase::kValueFloat:
-            return s1.value_float() == s2.value_float();
-        case DimensionsValue::ValueCase::kValueTuple: {
-            if (s1.value_tuple().dimensions_value_size() !=
-                s2.value_tuple().dimensions_value_size()) {
-                return false;
-            }
-            bool allMatched = true;
-            for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
-                allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
-                                       s2.value_tuple().dimensions_value(i));
-            }
-            return allMatched;
-        }
-        case DimensionsValue::ValueCase::VALUE_NOT_SET:
-        default:
-            return true;
-    }
-}
-
-bool LessThan(const google::protobuf::RepeatedPtrField<StateValue>& s1,
-              const google::protobuf::RepeatedPtrField<StateValue>& s2) {
-    if (s1.size() != s2.size()) {
-        return s1.size() < s2.size();
-    }
-    for (int i = 0; i < s1.size(); i++) {
-        const StateValue& state1 = s1[i];
-        const StateValue& state2 = s2[i];
-        if (state1.atom_id() != state2.atom_id()) {
-            return state1.atom_id() < state2.atom_id();
-        }
-        if (state1.value() != state2.value()) {
-            return state1.value() < state2.value();
-        }
-        if (state1.group_id() != state2.group_id()) {
-            return state1.group_id() < state2.group_id();
-        }
-    }
-    return false;
-}
-
-bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
-    if (s1.field() != s2.field()) {
-        return s1.field() < s2.field();
-    }
-    if (s1.value_case() != s2.value_case()) {
-        return s1.value_case() < s2.value_case();
-    }
-    switch (s1.value_case()) {
-        case DimensionsValue::ValueCase::kValueStr:
-            return s1.value_str() < s2.value_str();
-        case DimensionsValue::ValueCase::kValueInt:
-            return s1.value_int() < s2.value_int();
-        case DimensionsValue::ValueCase::kValueLong:
-            return s1.value_long() < s2.value_long();
-        case DimensionsValue::ValueCase::kValueBool:
-            return (int)s1.value_bool() < (int)s2.value_bool();
-        case DimensionsValue::ValueCase::kValueFloat:
-            return s1.value_float() < s2.value_float();
-        case DimensionsValue::ValueCase::kValueTuple: {
-            if (s1.value_tuple().dimensions_value_size() !=
-                s2.value_tuple().dimensions_value_size()) {
-                return s1.value_tuple().dimensions_value_size() <
-                       s2.value_tuple().dimensions_value_size();
-            }
-            for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
-                if (EqualsTo(s1.value_tuple().dimensions_value(i),
-                             s2.value_tuple().dimensions_value(i))) {
-                    continue;
-                } else {
-                    return LessThan(s1.value_tuple().dimensions_value(i),
-                                    s2.value_tuple().dimensions_value(i));
-                }
-            }
-            return false;
-        }
-        case DimensionsValue::ValueCase::VALUE_NOT_SET:
-        default:
-            return false;
-    }
-}
-
-bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2) {
-    if (LessThan(s1.dimInWhat, s2.dimInWhat)) {
-        return true;
-    } else if (LessThan(s2.dimInWhat, s1.dimInWhat)) {
-        return false;
-    }
-
-    return LessThan(s1.stateValues, s2.stateValues);
-}
-
-void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
-                               DimensionsValue* dimension) {
-    if (dimension->has_value_str_hash()) {
-        auto it = str_map.find((uint64_t)(dimension->value_str_hash()));
-        if (it != str_map.end()) {
-            dimension->clear_value_str_hash();
-            dimension->set_value_str(it->second);
-        } else {
-            ALOGE("Can not find the string hash: %llu",
-                (unsigned long long)dimension->value_str_hash());
-        }
-    } else if (dimension->has_value_tuple()) {
-        auto value_tuple = dimension->mutable_value_tuple();
-        for (int i = 0; i < value_tuple->dimensions_value_size(); ++i) {
-            backfillStringInDimension(str_map, value_tuple->mutable_dimensions_value(i));
-        }
-    }
-}
-
-void backfillStringInReport(ConfigMetricsReport *config_report) {
-    std::map<uint64_t, string> str_map;
-    for (const auto& str : config_report->strings()) {
-        uint64_t hash = Hash64(str);
-        if (str_map.find(hash) != str_map.end()) {
-            ALOGE("String hash conflicts: %s %s", str.c_str(), str_map[hash].c_str());
-        }
-        str_map[hash] = str;
-    }
-    for (int i = 0; i < config_report->metrics_size(); ++i) {
-        auto metric_report = config_report->mutable_metrics(i);
-        if (metric_report->has_count_metrics()) {
-            backfillStringInDimension(str_map, metric_report->mutable_count_metrics());
-        } else if (metric_report->has_duration_metrics()) {
-            backfillStringInDimension(str_map, metric_report->mutable_duration_metrics());
-        } else if (metric_report->has_gauge_metrics()) {
-            backfillStringInDimension(str_map, metric_report->mutable_gauge_metrics());
-        } else if (metric_report->has_value_metrics()) {
-            backfillStringInDimension(str_map, metric_report->mutable_value_metrics());
-        }
-    }
-    // Backfill the package names.
-    for (int i = 0 ; i < config_report->uid_map().snapshots_size(); ++i) {
-        auto snapshot = config_report->mutable_uid_map()->mutable_snapshots(i);
-        for (int j = 0 ; j < snapshot->package_info_size(); ++j) {
-            auto package_info = snapshot->mutable_package_info(j);
-            if (package_info->has_name_hash()) {
-                auto it = str_map.find((uint64_t)(package_info->name_hash()));
-                if (it != str_map.end()) {
-                    package_info->clear_name_hash();
-                    package_info->set_name(it->second);
-                } else {
-                    ALOGE("Can not find the string package name hash: %llu",
-                        (unsigned long long)package_info->name_hash());
-                }
-
-            }
-        }
-    }
-    // Backfill the app name in app changes.
-    for (int i = 0 ; i < config_report->uid_map().changes_size(); ++i) {
-        auto change = config_report->mutable_uid_map()->mutable_changes(i);
-        if (change->has_app_hash()) {
-            auto it = str_map.find((uint64_t)(change->app_hash()));
-            if (it != str_map.end()) {
-                change->clear_app_hash();
-                change->set_app(it->second);
-            } else {
-                ALOGE("Can not find the string change app name hash: %llu",
-                    (unsigned long long)change->app_hash());
-            }
-        }
-    }
-}
-
-void backfillStringInReport(ConfigMetricsReportList *config_report_list) {
-    for (int i = 0; i < config_report_list->reports_size(); ++i) {
-        backfillStringInReport(config_report_list->mutable_reports(i));
-    }
-}
-
-bool backfillDimensionPath(const DimensionsValue& path,
-                           const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
-                           int* leafIndex,
-                           DimensionsValue* dimension) {
-    dimension->set_field(path.field());
-    if (path.has_value_tuple()) {
-        for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
-            if (!backfillDimensionPath(
-                path.value_tuple().dimensions_value(i), leafValues, leafIndex,
-                dimension->mutable_value_tuple()->add_dimensions_value())) {
-                return false;
-            }
-        }
-    } else {
-        if (*leafIndex < 0 || *leafIndex >= leafValues.size()) {
-            return false;
-        }
-        dimension->MergeFrom(leafValues.Get(*leafIndex));
-        (*leafIndex)++;
-    }
-    return true;
-}
-
-bool backfillDimensionPath(const DimensionsValue& path,
-                           const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
-                           DimensionsValue* dimension) {
-    int leafIndex = 0;
-    return backfillDimensionPath(path, leafValues, &leafIndex, dimension);
-}
-
-void backfillDimensionPath(ConfigMetricsReportList *config_report_list) {
-    for (int i = 0; i < config_report_list->reports_size(); ++i) {
-        auto report = config_report_list->mutable_reports(i);
-        for (int j = 0; j < report->metrics_size(); ++j) {
-            auto metric_report = report->mutable_metrics(j);
-            if (metric_report->has_dimensions_path_in_what() ||
-                metric_report->has_dimensions_path_in_condition()) {
-                auto whatPath = metric_report->dimensions_path_in_what();
-                auto conditionPath = metric_report->dimensions_path_in_condition();
-                if (metric_report->has_count_metrics()) {
-                    backfillDimensionPath(whatPath, conditionPath,
-                                          metric_report->mutable_count_metrics());
-                } else if (metric_report->has_duration_metrics()) {
-                    backfillDimensionPath(whatPath, conditionPath,
-                                          metric_report->mutable_duration_metrics());
-                } else if (metric_report->has_gauge_metrics()) {
-                    backfillDimensionPath(whatPath, conditionPath,
-                                          metric_report->mutable_gauge_metrics());
-                } else if (metric_report->has_value_metrics()) {
-                    backfillDimensionPath(whatPath, conditionPath,
-                                          metric_report->mutable_value_metrics());
-                }
-                metric_report->clear_dimensions_path_in_what();
-                metric_report->clear_dimensions_path_in_condition();
-            }
-        }
-    }
-}
-
-void backfillStartEndTimestamp(StatsLogReport *report) {
-    const int64_t timeBaseNs = report->time_base_elapsed_nano_seconds();
-    const int64_t bucketSizeNs = report->bucket_size_nano_seconds();
-    if (report->has_count_metrics()) {
-        backfillStartEndTimestampForMetrics(
-            timeBaseNs, bucketSizeNs, report->mutable_count_metrics());
-    } else if (report->has_duration_metrics()) {
-        backfillStartEndTimestampForMetrics(
-            timeBaseNs, bucketSizeNs, report->mutable_duration_metrics());
-    } else if (report->has_gauge_metrics()) {
-        backfillStartEndTimestampForMetrics(
-            timeBaseNs, bucketSizeNs, report->mutable_gauge_metrics());
-        if (report->gauge_metrics().skipped_size() > 0) {
-            backfillStartEndTimestampForSkippedBuckets(
-                timeBaseNs, report->mutable_gauge_metrics());
-        }
-    } else if (report->has_value_metrics()) {
-        backfillStartEndTimestampForMetrics(
-            timeBaseNs, bucketSizeNs, report->mutable_value_metrics());
-        if (report->value_metrics().skipped_size() > 0) {
-            backfillStartEndTimestampForSkippedBuckets(
-                timeBaseNs, report->mutable_value_metrics());
-        }
-    }
-}
-
-void backfillStartEndTimestamp(ConfigMetricsReport *config_report) {
-    for (int j = 0; j < config_report->metrics_size(); ++j) {
-        backfillStartEndTimestamp(config_report->mutable_metrics(j));
-    }
-}
-
-void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list) {
-    for (int i = 0; i < config_report_list->reports_size(); ++i) {
-        backfillStartEndTimestamp(config_report_list->mutable_reports(i));
-    }
-}
-
-Status FakeSubsystemSleepCallback::onPullAtom(int atomTag,
-        const shared_ptr<IPullAtomResultReceiver>& resultReceiver) {
-    // Convert stats_events into StatsEventParcels.
-    std::vector<StatsEventParcel> parcels;
-    for (int i = 1; i < 3; i++) {
-        AStatsEvent* event = AStatsEvent_obtain();
-        AStatsEvent_setAtomId(event, atomTag);
-        std::string subsystemName = "subsystem_name_";
-        subsystemName = subsystemName + std::to_string(i);
-        AStatsEvent_writeString(event, subsystemName.c_str());
-        AStatsEvent_writeString(event, "subsystem_subname foo");
-        AStatsEvent_writeInt64(event, /*count= */ i);
-        AStatsEvent_writeInt64(event, /*time_millis= */ i * 100);
-        AStatsEvent_build(event);
-        size_t size;
-        uint8_t* buffer = AStatsEvent_getBuffer(event, &size);
-
-        StatsEventParcel p;
-        // vector.assign() creates a copy, but this is inevitable unless
-        // stats_event.h/c uses a vector as opposed to a buffer.
-        p.buffer.assign(buffer, buffer + size);
-        parcels.push_back(std::move(p));
-        AStatsEvent_release(event);
-    }
-    resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
-    return Status::ok();
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
deleted file mode 100644
index c514912..0000000
--- a/cmds/statsd/tests/statsd_test_util.h
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright (C) 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.
-
-#pragma once
-
-#include <aidl/android/os/BnPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomCallback.h>
-#include <aidl/android/os/IPullAtomResultReceiver.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "src/StatsLogProcessor.h"
-#include "src/hash.h"
-#include "src/logd/LogEvent.h"
-#include "src/matchers/EventMatcherWizard.h"
-#include "src/packages/UidMap.h"
-#include "src/stats_log_util.h"
-#include "stats_event.h"
-#include "statslog_statsdtest.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using ::aidl::android::os::BnPullAtomCallback;
-using ::aidl::android::os::IPullAtomCallback;
-using ::aidl::android::os::IPullAtomResultReceiver;
-using android::util::ProtoReader;
-using google::protobuf::RepeatedPtrField;
-using Status = ::ndk::ScopedAStatus;
-
-const int SCREEN_STATE_ATOM_ID = util::SCREEN_STATE_CHANGED;
-const int UID_PROCESS_STATE_ATOM_ID = util::UID_PROCESS_STATE_CHANGED;
-
-enum BucketSplitEvent { APP_UPGRADE, BOOT_COMPLETE };
-
-class MockUidMap : public UidMap {
-public:
-    MOCK_METHOD(int, getHostUidOrSelf, (int uid), (const));
-    MOCK_METHOD(std::set<int32_t>, getAppUid, (const string& package), (const));
-};
-
-// Converts a ProtoOutputStream to a StatsLogReport proto.
-StatsLogReport outputStreamToProto(ProtoOutputStream* proto);
-
-// Create AtomMatcher proto to simply match a specific atom type.
-AtomMatcher CreateSimpleAtomMatcher(const string& name, int atomId);
-
-// Create AtomMatcher proto for temperature atom.
-AtomMatcher CreateTemperatureAtomMatcher();
-
-// Create AtomMatcher proto for scheduled job state changed.
-AtomMatcher CreateScheduledJobStateChangedAtomMatcher();
-
-// Create AtomMatcher proto for starting a scheduled job.
-AtomMatcher CreateStartScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for a scheduled job is done.
-AtomMatcher CreateFinishScheduledJobAtomMatcher();
-
-// Create AtomMatcher proto for screen brightness state changed.
-AtomMatcher CreateScreenBrightnessChangedAtomMatcher();
-
-// Create AtomMatcher proto for starting battery save mode.
-AtomMatcher CreateBatterySaverModeStartAtomMatcher();
-
-// Create AtomMatcher proto for stopping battery save mode.
-AtomMatcher CreateBatterySaverModeStopAtomMatcher();
-
-// Create AtomMatcher proto for battery state none mode.
-AtomMatcher CreateBatteryStateNoneMatcher();
-
-// Create AtomMatcher proto for battery state usb mode.
-AtomMatcher CreateBatteryStateUsbMatcher();
-
-// Create AtomMatcher proto for process state changed.
-AtomMatcher CreateUidProcessStateChangedAtomMatcher();
-
-// Create AtomMatcher proto for acquiring wakelock.
-AtomMatcher CreateAcquireWakelockAtomMatcher();
-
-// Create AtomMatcher proto for releasing wakelock.
-AtomMatcher CreateReleaseWakelockAtomMatcher() ;
-
-// Create AtomMatcher proto for screen turned on.
-AtomMatcher CreateScreenTurnedOnAtomMatcher();
-
-// Create AtomMatcher proto for screen turned off.
-AtomMatcher CreateScreenTurnedOffAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned on.
-AtomMatcher CreateSyncStartAtomMatcher();
-
-// Create AtomMatcher proto for app sync turned off.
-AtomMatcher CreateSyncEndAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to background.
-AtomMatcher CreateMoveToBackgroundAtomMatcher();
-
-// Create AtomMatcher proto for app sync moves to foreground.
-AtomMatcher CreateMoveToForegroundAtomMatcher();
-
-// Create AtomMatcher proto for process crashes
-AtomMatcher CreateProcessCrashAtomMatcher() ;
-
-// Create Predicate proto for screen is on.
-Predicate CreateScreenIsOnPredicate();
-
-// Create Predicate proto for screen is off.
-Predicate CreateScreenIsOffPredicate();
-
-// Create Predicate proto for a running scheduled job.
-Predicate CreateScheduledJobPredicate();
-
-// Create Predicate proto for battery saver mode.
-Predicate CreateBatterySaverModePredicate();
-
-// Create Predicate proto for device unplogged mode.
-Predicate CreateDeviceUnpluggedPredicate();
-
-// Create Predicate proto for holding wakelock.
-Predicate CreateHoldingWakelockPredicate();
-
-// Create a Predicate proto for app syncing.
-Predicate CreateIsSyncingPredicate();
-
-// Create a Predicate proto for app is in background.
-Predicate CreateIsInBackgroundPredicate();
-
-// Create State proto for screen state atom.
-State CreateScreenState();
-
-// Create State proto for uid process state atom.
-State CreateUidProcessState();
-
-// Create State proto for overlay state atom.
-State CreateOverlayState();
-
-// Create State proto for screen state atom with on/off map.
-State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Create State proto for screen state atom with simple on/off map.
-State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Create StateGroup proto for ScreenState ON group
-StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId);
-
-// Create StateGroup proto for ScreenState OFF group
-StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId);
-
-// Create StateGroup proto for simple ScreenState ON group
-StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId);
-
-// Create StateGroup proto for simple ScreenState OFF group
-StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId);
-
-// Create StateMap proto for ScreenState ON/OFF map
-StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Create StateMap proto for simple ScreenState ON/OFF map
-StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId);
-
-// Add a predicate to the predicate combination.
-void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination);
-
-// Create dimensions from primitive fields.
-FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields);
-
-// Create dimensions by attribution uid and tag.
-FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
-                                                  const std::vector<Position>& positions);
-
-// Create dimensions by attribution uid only.
-FieldMatcher CreateAttributionUidDimensions(const int atomId,
-                                            const std::vector<Position>& positions);
-
-FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
-                                                    const std::vector<Position>& positions,
-                                                    const std::vector<int>& fields);
-
-// START: get primary key functions
-// These functions take in atom field information and create FieldValues which are stored in the
-// given HashableDimensionKey.
-void getUidProcessKey(int uid, HashableDimensionKey* key);
-
-void getOverlayKey(int uid, string packageName, HashableDimensionKey* key);
-
-void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey* key);
-
-void getPartialWakelockKey(int uid, HashableDimensionKey* key);
-// END: get primary key functions
-
-void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids,
-                      const vector<string>& attributionTags);
-
-// Builds statsEvent to get buffer that is parsed into logEvent then releases statsEvent.
-void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent);
-
-shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
-                                            int32_t value2);
-
-void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
-                            int32_t value2);
-
-shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1,
-                                              int32_t value2, int32_t value3);
-
-void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1,
-                              int32_t value2, int32_t value3);
-
-// The repeated value log event helpers create a log event with two int fields, both
-// set to the same value. This is useful for testing metrics that are only interested
-// in the value of the second field but still need the first field to be populated.
-std::shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs,
-                                                      int32_t value);
-
-void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs,
-                                 int32_t value);
-
-std::shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs);
-
-void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs);
-
-std::shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
-                                          int data2);
-
-std::shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
-                                                  const vector<int>& uids,
-                                                  const vector<string>& tags, int data1, int data2);
-
-sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids);
-
-sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids);
-
-// Create log event for screen state changed.
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
-                                                        const android::view::DisplayStateEnum state,
-                                                        int loggerUid = 0);
-
-// Create log event for screen brightness state changed.
-std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level);
-
-// Create log event when scheduled job starts.
-std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs,
-                                                       const vector<int>& attributionUids,
-                                                       const vector<string>& attributionTags,
-                                                       const string& jobName);
-
-// Create log event when scheduled job finishes.
-std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs,
-                                                        const vector<int>& attributionUids,
-                                                        const vector<string>& attributionTags,
-                                                        const string& jobName);
-
-// Create log event when battery saver starts.
-std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs);
-// Create log event when battery saver stops.
-std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs);
-
-// Create log event when battery state changes.
-std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestampNs, const BatteryPluggedStateEnum state);
-
-// Create log event for app moving to background.
-std::unique_ptr<LogEvent> CreateMoveToBackgroundEvent(uint64_t timestampNs, const int uid);
-
-// Create log event for app moving to foreground.
-std::unique_ptr<LogEvent> CreateMoveToForegroundEvent(uint64_t timestampNs, const int uid);
-
-// Create log event when the app sync starts.
-std::unique_ptr<LogEvent> CreateSyncStartEvent(uint64_t timestampNs, const vector<int>& uids,
-                                               const vector<string>& tags, const string& name);
-
-// Create log event when the app sync ends.
-std::unique_ptr<LogEvent> CreateSyncEndEvent(uint64_t timestampNs, const vector<int>& uids,
-                                             const vector<string>& tags, const string& name);
-
-// Create log event when the app sync ends.
-std::unique_ptr<LogEvent> CreateAppCrashEvent(uint64_t timestampNs, const int uid);
-
-// Create log event for an app crash.
-std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, const int uid);
-
-// Create log event for acquiring wakelock.
-std::unique_ptr<LogEvent> CreateAcquireWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
-                                                     const vector<string>& tags,
-                                                     const string& wakelockName);
-
-// Create log event for releasing wakelock.
-std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(uint64_t timestampNs, const vector<int>& uids,
-                                                     const vector<string>& tags,
-                                                     const string& wakelockName);
-
-// Create log event for releasing wakelock.
-std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, int hostUid,
-                                                        int isolatedUid, bool is_create);
-
-// Create log event for uid process state change.
-std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent(
-        uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state);
-
-std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs,
-                                                         const vector<int>& attributionUids,
-                                                         const vector<string>& attributionTags,
-                                                         const BleScanStateChanged::State state,
-                                                         const bool filtered, const bool firstMatch,
-                                                         const bool opportunistic);
-
-std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid,
-                                                         const string& packageName,
-                                                         const bool usingAlertWindow,
-                                                         const OverlayStateChanged::State state);
-
-// Create a statsd log event processor upon the start time in seconds, config and key.
-sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
-                                              const StatsdConfig& config, const ConfigKey& key,
-                                              const shared_ptr<IPullAtomCallback>& puller = nullptr,
-                                              const int32_t atomTag = 0 /*for puller only*/,
-                                              const sp<UidMap> = new UidMap());
-
-// Util function to sort the log events by timestamp.
-void sortLogEventsByTimestamp(std::vector<std::unique_ptr<LogEvent>> *events);
-
-int64_t StringToId(const string& str);
-
-sp<EventMatcherWizard> createEventMatcherWizard(
-        int tagId, int matcherIndex, const std::vector<FieldValueMatcher>& fieldValueMatchers = {});
-
-void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
-                                                   const int uid, const string& tag);
-void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid);
-void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid);
-void ValidateAttributionUidAndTagDimension(
-    const DimensionsValue& value, int atomId, int uid, const std::string& tag);
-void ValidateAttributionUidAndTagDimension(
-    const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag);
-void ValidateStateValue(const google::protobuf::RepeatedPtrField<StateValue>& stateValues,
-                        int atomId, int64_t value);
-
-struct DimensionsPair {
-    DimensionsPair(DimensionsValue m1, google::protobuf::RepeatedPtrField<StateValue> m2)
-        : dimInWhat(m1), stateValues(m2){};
-
-    DimensionsValue dimInWhat;
-    google::protobuf::RepeatedPtrField<StateValue> stateValues;
-};
-
-bool LessThan(const StateValue& s1, const StateValue& s2);
-bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2);
-bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2);
-
-
-void backfillStartEndTimestamp(ConfigMetricsReport *config_report);
-void backfillStartEndTimestamp(ConfigMetricsReportList *config_report_list);
-
-void backfillStringInReport(ConfigMetricsReportList *config_report_list);
-void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
-                               DimensionsValue* dimension);
-
-template <typename T>
-void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
-                               T* metrics) {
-    for (int i = 0; i < metrics->data_size(); ++i) {
-        auto data = metrics->mutable_data(i);
-        if (data->has_dimensions_in_what()) {
-            backfillStringInDimension(str_map, data->mutable_dimensions_in_what());
-        }
-        if (data->has_dimensions_in_condition()) {
-            backfillStringInDimension(str_map, data->mutable_dimensions_in_condition());
-        }
-    }
-}
-
-void backfillDimensionPath(ConfigMetricsReportList* config_report_list);
-
-bool backfillDimensionPath(const DimensionsValue& path,
-                           const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
-                           DimensionsValue* dimension);
-
-class FakeSubsystemSleepCallback : public BnPullAtomCallback {
-public:
-    Status onPullAtom(int atomTag,
-                      const shared_ptr<IPullAtomResultReceiver>& resultReceiver) override;
-};
-
-template <typename T>
-void backfillDimensionPath(const DimensionsValue& whatPath,
-                           const DimensionsValue& conditionPath,
-                           T* metricData) {
-    for (int i = 0; i < metricData->data_size(); ++i) {
-        auto data = metricData->mutable_data(i);
-        if (data->dimension_leaf_values_in_what_size() > 0) {
-            backfillDimensionPath(whatPath, data->dimension_leaf_values_in_what(),
-                                  data->mutable_dimensions_in_what());
-            data->clear_dimension_leaf_values_in_what();
-        }
-        if (data->dimension_leaf_values_in_condition_size() > 0) {
-            backfillDimensionPath(conditionPath, data->dimension_leaf_values_in_condition(),
-                                  data->mutable_dimensions_in_condition());
-            data->clear_dimension_leaf_values_in_condition();
-        }
-    }
-}
-
-struct DimensionCompare {
-    bool operator()(const DimensionsPair& s1, const DimensionsPair& s2) const {
-        return LessThan(s1, s2);
-    }
-};
-
-template <typename T>
-void sortMetricDataByDimensionsValue(const T& metricData, T* sortedMetricData) {
-    std::map<DimensionsPair, int, DimensionCompare> dimensionIndexMap;
-    for (int i = 0; i < metricData.data_size(); ++i) {
-        dimensionIndexMap.insert(
-                std::make_pair(DimensionsPair(metricData.data(i).dimensions_in_what(),
-                                              metricData.data(i).slice_by_state()),
-                               i));
-    }
-    for (const auto& itr : dimensionIndexMap) {
-        *sortedMetricData->add_data() = metricData.data(itr.second);
-    }
-}
-
-template <typename T>
-void backfillStartEndTimestampForFullBucket(
-    const int64_t timeBaseNs, const int64_t bucketSizeNs, T* bucket) {
-    bucket->set_start_bucket_elapsed_nanos(timeBaseNs + bucketSizeNs * bucket->bucket_num());
-    bucket->set_end_bucket_elapsed_nanos(
-        timeBaseNs + bucketSizeNs * bucket->bucket_num() + bucketSizeNs);
-    bucket->clear_bucket_num();
-}
-
-template <typename T>
-void backfillStartEndTimestampForPartialBucket(const int64_t timeBaseNs, T* bucket) {
-    if (bucket->has_start_bucket_elapsed_millis()) {
-        bucket->set_start_bucket_elapsed_nanos(
-            MillisToNano(bucket->start_bucket_elapsed_millis()));
-        bucket->clear_start_bucket_elapsed_millis();
-    }
-    if (bucket->has_end_bucket_elapsed_millis()) {
-        bucket->set_end_bucket_elapsed_nanos(
-            MillisToNano(bucket->end_bucket_elapsed_millis()));
-        bucket->clear_end_bucket_elapsed_millis();
-    }
-}
-
-template <typename T>
-void backfillStartEndTimestampForMetrics(const int64_t timeBaseNs, const int64_t bucketSizeNs,
-                                         T* metrics) {
-    for (int i = 0; i < metrics->data_size(); ++i) {
-        auto data = metrics->mutable_data(i);
-        for (int j = 0; j < data->bucket_info_size(); ++j) {
-            auto bucket = data->mutable_bucket_info(j);
-            if (bucket->has_bucket_num()) {
-                backfillStartEndTimestampForFullBucket(timeBaseNs, bucketSizeNs, bucket);
-            } else {
-                backfillStartEndTimestampForPartialBucket(timeBaseNs, bucket);
-            }
-        }
-    }
-}
-
-template <typename T>
-void backfillStartEndTimestampForSkippedBuckets(const int64_t timeBaseNs, T* metrics) {
-    for (int i = 0; i < metrics->skipped_size(); ++i) {
-        backfillStartEndTimestampForPartialBucket(timeBaseNs, metrics->mutable_skipped(i));
-    }
-}
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/tests/storage/StorageManager_test.cpp b/cmds/statsd/tests/storage/StorageManager_test.cpp
deleted file mode 100644
index 74eafbf..0000000
--- a/cmds/statsd/tests/storage/StorageManager_test.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (C) 2019 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.
-
-#include <android-base/unique_fd.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <stdio.h>
-#include "src/storage/StorageManager.h"
-
-#ifdef __ANDROID__
-
-namespace android {
-namespace os {
-namespace statsd {
-
-using namespace testing;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-using testing::Contains;
-
-TEST(StorageManagerTest, TrainInfoReadWriteTest) {
-    InstallTrainInfo trainInfo;
-    trainInfo.trainVersionCode = 12345;
-    trainInfo.trainName = "This is a train name #)$(&&$";
-    trainInfo.status = 1;
-    const char* expIds = "test_ids";
-    trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds));
-
-    bool result;
-
-    result = StorageManager::writeTrainInfo(trainInfo);
-
-    EXPECT_TRUE(result);
-
-    InstallTrainInfo trainInfoResult;
-    result = StorageManager::readTrainInfo(trainInfo.trainName, trainInfoResult);
-    EXPECT_TRUE(result);
-
-    EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
-    ASSERT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
-    EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
-    EXPECT_EQ(trainInfo.status, trainInfoResult.status);
-    ASSERT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
-    EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
-}
-
-TEST(StorageManagerTest, TrainInfoReadWriteTrainNameSizeOneTest) {
-    InstallTrainInfo trainInfo;
-    trainInfo.trainVersionCode = 12345;
-    trainInfo.trainName = "{";
-    trainInfo.status = 1;
-    const char* expIds = "test_ids";
-    trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds));
-
-    bool result;
-
-    result = StorageManager::writeTrainInfo(trainInfo);
-
-    EXPECT_TRUE(result);
-
-    InstallTrainInfo trainInfoResult;
-    result = StorageManager::readTrainInfo(trainInfo.trainName, trainInfoResult);
-    EXPECT_TRUE(result);
-
-    EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
-    ASSERT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
-    EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
-    EXPECT_EQ(trainInfo.status, trainInfoResult.status);
-    ASSERT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
-    EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
-}
-
-TEST(StorageManagerTest, SortFileTest) {
-    vector<StorageManager::FileInfo> list;
-    // assume now sec is 500
-    list.emplace_back("200_5000_123454", false, 20, 300);
-    list.emplace_back("300_2000_123454_history", true, 30, 200);
-    list.emplace_back("400_100009_123454_history", true, 40, 100);
-    list.emplace_back("100_2000_123454", false, 50, 400);
-
-    StorageManager::sortFiles(&list);
-    EXPECT_EQ("200_5000_123454", list[0].mFileName);
-    EXPECT_EQ("100_2000_123454", list[1].mFileName);
-    EXPECT_EQ("400_100009_123454_history", list[2].mFileName);
-    EXPECT_EQ("300_2000_123454_history", list[3].mFileName);
-}
-
-const string testDir = "/data/misc/stats-data/";
-const string file1 = testDir + "2557169347_1066_1";
-const string file2 = testDir + "2557169349_1066_1";
-const string file1_history = file1 + "_history";
-const string file2_history = file2 + "_history";
-
-bool prepareLocalHistoryTestFiles() {
-    android::base::unique_fd fd(TEMP_FAILURE_RETRY(
-            open(file1.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
-    if (fd != -1) {
-        dprintf(fd, "content");
-    } else {
-        return false;
-    }
-
-    android::base::unique_fd fd2(TEMP_FAILURE_RETRY(
-            open(file2.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
-    if (fd2 != -1) {
-        dprintf(fd2, "content");
-    } else {
-        return false;
-    }
-    return true;
-}
-
-void clearLocalHistoryTestFiles() {
-    TEMP_FAILURE_RETRY(remove(file1.c_str()));
-    TEMP_FAILURE_RETRY(remove(file2.c_str()));
-    TEMP_FAILURE_RETRY(remove(file1_history.c_str()));
-    TEMP_FAILURE_RETRY(remove(file2_history.c_str()));
-}
-
-bool fileExist(string name) {
-    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(name.c_str(), O_RDONLY | O_CLOEXEC)));
-    return fd != -1;
-}
-
-/* The following AppendConfigReportTests test the 4 combinations of [whether erase data] [whether
- * the caller is adb] */
-TEST(StorageManagerTest, AppendConfigReportTest1) {
-    EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
-    ProtoOutputStream out;
-    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
-                                              false /*isAdb?*/);
-
-    EXPECT_FALSE(fileExist(file1));
-    EXPECT_FALSE(fileExist(file2));
-
-    EXPECT_TRUE(fileExist(file1_history));
-    EXPECT_TRUE(fileExist(file2_history));
-    clearLocalHistoryTestFiles();
-}
-
-TEST(StorageManagerTest, AppendConfigReportTest2) {
-    EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
-    ProtoOutputStream out;
-    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
-                                              false /*isAdb?*/);
-
-    EXPECT_FALSE(fileExist(file1));
-    EXPECT_FALSE(fileExist(file2));
-    EXPECT_FALSE(fileExist(file1_history));
-    EXPECT_FALSE(fileExist(file2_history));
-
-    clearLocalHistoryTestFiles();
-}
-
-TEST(StorageManagerTest, AppendConfigReportTest3) {
-    EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
-    ProtoOutputStream out;
-    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
-                                              true /*isAdb?*/);
-
-    EXPECT_TRUE(fileExist(file1));
-    EXPECT_TRUE(fileExist(file2));
-    EXPECT_FALSE(fileExist(file1_history));
-    EXPECT_FALSE(fileExist(file2_history));
-
-    clearLocalHistoryTestFiles();
-}
-
-TEST(StorageManagerTest, AppendConfigReportTest4) {
-    EXPECT_TRUE(prepareLocalHistoryTestFiles());
-
-    ProtoOutputStream out;
-    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
-                                              true /*isAdb?*/);
-
-    EXPECT_FALSE(fileExist(file1));
-    EXPECT_FALSE(fileExist(file2));
-    EXPECT_FALSE(fileExist(file1_history));
-    EXPECT_FALSE(fileExist(file2_history));
-
-    clearLocalHistoryTestFiles();
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp b/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp
deleted file mode 100644
index 32cecd3..0000000
--- a/cmds/statsd/tests/utils/MultiConditionTrigger_test.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-#include "utils/MultiConditionTrigger.h"
-
-#include <gtest/gtest.h>
-
-#include <chrono>
-#include <set>
-#include <thread>
-#include <vector>
-
-#ifdef __ANDROID__
-
-using namespace std;
-using std::this_thread::sleep_for;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-TEST(MultiConditionTrigger, TestMultipleConditions) {
-    int numConditions = 5;
-    string t1 = "t1", t2 = "t2", t3 = "t3", t4 = "t4", t5 = "t5";
-    set<string> conditionNames = {t1, t2, t3, t4, t5};
-
-    mutex lock;
-    condition_variable cv;
-    bool triggerCalled = false;
-
-    // Mark done as true and notify in the done.
-    MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled] {
-        {
-            lock_guard lg(lock);
-            triggerCalled = true;
-        }
-        cv.notify_all();
-    });
-
-    vector<thread> threads;
-    vector<int> done(numConditions, 0);
-
-    int i = 0;
-    for (const string& conditionName : conditionNames) {
-        threads.emplace_back([&done, &conditionName, &trigger, i] {
-            sleep_for(chrono::milliseconds(3));
-            done[i] = 1;
-            trigger.markComplete(conditionName);
-        });
-        i++;
-    }
-
-    unique_lock<mutex> unique_lk(lock);
-    cv.wait(unique_lk, [&triggerCalled] {
-        return triggerCalled;
-    });
-
-    for (i = 0; i < numConditions; i++) {
-        EXPECT_EQ(done[i], 1);
-    }
-
-    for (i = 0; i < numConditions; i++) {
-        threads[i].join();
-    }
-}
-
-TEST(MultiConditionTrigger, TestNoConditions) {
-    mutex lock;
-    condition_variable cv;
-    bool triggerCalled = false;
-
-    MultiConditionTrigger trigger({}, [&lock, &cv, &triggerCalled] {
-        {
-            lock_guard lg(lock);
-            triggerCalled = true;
-        }
-        cv.notify_all();
-    });
-
-    unique_lock<mutex> unique_lk(lock);
-    cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
-    EXPECT_TRUE(triggerCalled);
-    // Ensure that trigger occurs immediately if no events need to be completed.
-}
-
-TEST(MultiConditionTrigger, TestMarkCompleteCalledBySameCondition) {
-    string t1 = "t1", t2 = "t2";
-    set<string> conditionNames = {t1, t2};
-
-    mutex lock;
-    condition_variable cv;
-    bool triggerCalled = false;
-
-    MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled] {
-        {
-            lock_guard lg(lock);
-            triggerCalled = true;
-        }
-        cv.notify_all();
-    });
-
-    trigger.markComplete(t1);
-    trigger.markComplete(t1);
-
-    // Ensure that the trigger still hasn't fired.
-    {
-        lock_guard lg(lock);
-        EXPECT_FALSE(triggerCalled);
-    }
-
-    trigger.markComplete(t2);
-    unique_lock<mutex> unique_lk(lock);
-    cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
-    EXPECT_TRUE(triggerCalled);
-}
-
-TEST(MultiConditionTrigger, TestTriggerOnlyCalledOnce) {
-    string t1 = "t1";
-    set<string> conditionNames = {t1};
-
-    mutex lock;
-    condition_variable cv;
-    bool triggerCalled = false;
-    int triggerCount = 0;
-
-    MultiConditionTrigger trigger(conditionNames, [&lock, &cv, &triggerCalled, &triggerCount] {
-        {
-            lock_guard lg(lock);
-            triggerCount++;
-            triggerCalled = true;
-        }
-        cv.notify_all();
-    });
-
-    trigger.markComplete(t1);
-
-    // Ensure that the trigger fired.
-    {
-        unique_lock<mutex> unique_lk(lock);
-        cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
-        EXPECT_TRUE(triggerCalled);
-        EXPECT_EQ(triggerCount, 1);
-        triggerCalled = false;
-    }
-
-    trigger.markComplete(t1);
-
-    // Ensure that the trigger does not fire again.
-    {
-        unique_lock<mutex> unique_lk(lock);
-        cv.wait_for(unique_lk, chrono::milliseconds(5), [&triggerCalled] { return triggerCalled; });
-        EXPECT_FALSE(triggerCalled);
-        EXPECT_EQ(triggerCount, 1);
-    }
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
diff --git a/cmds/statsd/tools/localtools/Android.bp b/cmds/statsd/tools/localtools/Android.bp
deleted file mode 100644
index 69a43a8..0000000
--- a/cmds/statsd/tools/localtools/Android.bp
+++ /dev/null
@@ -1,46 +0,0 @@
-java_binary_host {
-    name: "statsd_localdrive",
-    manifest: "localdrive_manifest.txt",
-    srcs: [
-        "src/com/android/statsd/shelltools/localdrive/*.java",
-        "src/com/android/statsd/shelltools/Utils.java",
-    ],
-    static_libs: [
-        "platformprotos",
-        "guava",
-    ],
-}
-
-java_library_host {
-    name: "statsd_testdrive_lib",
-    srcs: [
-        "src/com/android/statsd/shelltools/testdrive/*.java",
-        "src/com/android/statsd/shelltools/Utils.java",
-    ],
-    static_libs: [
-        "platformprotos",
-        "guava",
-    ],
-}
-
-
-java_binary_host {
-    name: "statsd_testdrive",
-    manifest: "testdrive_manifest.txt",
-    static_libs: [
-        "statsd_testdrive_lib",
-    ],
-}
-
-java_test_host {
-    name: "statsd_testdrive_test",
-    test_suites: ["general-tests"],
-    srcs: ["test/com/android/statsd/shelltools/testdrive/*.java"],
-    static_libs: [
-        "statsd_testdrive_lib",
-        "junit",
-        "platformprotos",
-        "guava",
-    ],
-}
-
diff --git a/cmds/statsd/tools/localtools/TEST_MAPPING b/cmds/statsd/tools/localtools/TEST_MAPPING
deleted file mode 100644
index 7c8a3db..0000000
--- a/cmds/statsd/tools/localtools/TEST_MAPPING
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "statsd_testdrive_test",
-      "host": true
-    }
-  ]
-}
diff --git a/cmds/statsd/tools/localtools/localdrive_manifest.txt b/cmds/statsd/tools/localtools/localdrive_manifest.txt
deleted file mode 100644
index 035cea1..0000000
--- a/cmds/statsd/tools/localtools/localdrive_manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-class: com.android.statsd.shelltools.localdrive.LocalDrive
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java
deleted file mode 100644
index 6a74480..0000000
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/Utils.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.statsd.shelltools;
-
-import com.android.os.StatsLog.ConfigMetricsReportList;
-
-import com.google.common.io.Files;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Formatter;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Utilities for local use of statsd.
- */
-public class Utils {
-
-    public static final String CMD_DUMP_REPORT = "cmd stats dump-report";
-    public static final String CMD_LOG_APP_BREADCRUMB = "cmd stats log-app-breadcrumb";
-    public static final String CMD_REMOVE_CONFIG = "cmd stats config remove";
-    public static final String CMD_UPDATE_CONFIG = "cmd stats config update";
-
-    public static final String SHELL_UID = "2000"; // Use shell, even if rooted.
-
-    /**
-     * Runs adb shell command with output directed to outputFile if non-null.
-     */
-    public static void runCommand(File outputFile, Logger logger, String... commands)
-            throws IOException, InterruptedException {
-        ProcessBuilder pb = new ProcessBuilder(commands);
-        if (outputFile != null && outputFile.exists() && outputFile.canWrite()) {
-            pb.redirectOutput(outputFile);
-        }
-        Process process = pb.start();
-
-        // Capture any errors
-        StringBuilder err = new StringBuilder();
-        BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
-        for (String line = br.readLine(); line != null; line = br.readLine()) {
-            err.append(line).append('\n');
-        }
-        logger.severe(err.toString());
-
-        // Check result
-        if (process.waitFor() == 0) {
-            logger.fine("Adb command successful.");
-        } else {
-            logger.severe("Abnormal adb shell termination for: " + String.join(",", commands));
-            throw new RuntimeException("Error running adb command: " + err.toString());
-        }
-    }
-
-    /**
-     * Dumps the report from the device and converts it to a ConfigMetricsReportList.
-     * Erases the data if clearData is true.
-     * @param configId id of the config
-     * @param clearData whether to erase the report data from statsd after getting the report.
-     * @param useShellUid Pulls data for the {@link SHELL_UID} instead of the caller's uid.
-     * @param logger Logger to log error messages
-     * @return
-     * @throws IOException
-     * @throws InterruptedException
-     */
-    public static ConfigMetricsReportList getReportList(long configId, boolean clearData,
-            boolean useShellUid, Logger logger, String deviceSerial)
-            throws IOException, InterruptedException {
-        try {
-            File outputFile = File.createTempFile("statsdret", ".bin");
-            outputFile.deleteOnExit();
-            runCommand(
-                    outputFile,
-                    logger,
-                    "adb",
-                    "-s",
-                    deviceSerial,
-                    "shell",
-                    CMD_DUMP_REPORT,
-                    useShellUid ? SHELL_UID : "",
-                    String.valueOf(configId),
-                    clearData ? "" : "--keep_data",
-                    "--include_current_bucket",
-                    "--proto");
-            ConfigMetricsReportList reportList =
-                    ConfigMetricsReportList.parseFrom(new FileInputStream(outputFile));
-            return reportList;
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            logger.severe("Failed to fetch and parse the statsd output report. "
-                            + "Perhaps there is not a valid statsd config for the requested "
-                            + (useShellUid ? ("uid=" + SHELL_UID + ", ") : "")
-                            + "configId=" + configId
-                            + ".");
-            throw (e);
-        }
-    }
-
-    /**
-     * Logs an AppBreadcrumbReported atom.
-     * @param label which label to log for the app breadcrumb atom.
-     * @param state which state to log for the app breadcrumb atom.
-     * @param logger Logger to log error messages
-     *
-     * @throws IOException
-     * @throws InterruptedException
-     */
-    public static void logAppBreadcrumb(int label, int state, Logger logger, String deviceSerial)
-            throws IOException, InterruptedException {
-        runCommand(
-                null,
-                logger,
-                "adb",
-                "-s",
-                deviceSerial,
-                "shell",
-                CMD_LOG_APP_BREADCRUMB,
-                String.valueOf(label),
-                String.valueOf(state));
-    }
-    public static void setUpLogger(Logger logger, boolean debug) {
-        ConsoleHandler handler = new ConsoleHandler();
-        handler.setFormatter(new LocalToolsFormatter());
-        logger.setUseParentHandlers(false);
-        if (debug) {
-            handler.setLevel(Level.ALL);
-            logger.setLevel(Level.ALL);
-        }
-        logger.addHandler(handler);
-    }
-
-    /**
-     * Attempt to determine whether tool will work with this statsd, i.e. whether statsd is
-     * minCodename or higher.
-     * Algorithm: true if (sdk >= minSdk) || (sdk == minSdk-1 && codeName.startsWith(minCodeName))
-     * If all else fails, assume it will work (letting future commands deal with any errors).
-     */
-    public static boolean isAcceptableStatsd(Logger logger, int minSdk, String minCodename,
-            String deviceSerial) {
-        BufferedReader in = null;
-        try {
-            File outFileSdk = File.createTempFile("shelltools_sdk", "tmp");
-            outFileSdk.deleteOnExit();
-            runCommand(outFileSdk, logger,
-                    "adb", "-s", deviceSerial, "shell", "getprop", "ro.build.version.sdk");
-            in = new BufferedReader(new InputStreamReader(new FileInputStream(outFileSdk)));
-            // If NullPointerException/NumberFormatException/etc., just catch and return true.
-            int sdk = Integer.parseInt(in.readLine().trim());
-            if (sdk >= minSdk) {
-                return true;
-            } else if (sdk == minSdk - 1) { // Could be minSdk-1, or could be minSdk development.
-                in.close();
-                File outFileCode = File.createTempFile("shelltools_codename", "tmp");
-                outFileCode.deleteOnExit();
-                runCommand(outFileCode, logger,
-                        "adb", "-s", deviceSerial, "shell", "getprop", "ro.build.version.codename");
-                in = new BufferedReader(new InputStreamReader(new FileInputStream(outFileCode)));
-                return in.readLine().startsWith(minCodename);
-            } else {
-                return false;
-            }
-        } catch (Exception e) {
-            logger.fine("Could not determine whether statsd version is compatibile "
-                    + "with tool: " + e.toString());
-        } finally {
-            try {
-                if (in != null) {
-                    in.close();
-                }
-            } catch (IOException e) {
-                logger.fine("Could not close temporary file: " + e.toString());
-            }
-        }
-        // Could not determine whether statsd is acceptable version.
-        // Just assume it is; if it isn't, we'll just get future errors via adb and deal with them.
-        return true;
-    }
-
-    public static class LocalToolsFormatter extends Formatter {
-        public String format(LogRecord record) {
-            return record.getMessage() + "\n";
-        }
-    }
-
-    /**
-     * Parse the result of "adb devices" to return the list of connected devices.
-     * @param logger Logger to log error messages
-     * @return List of the serial numbers of the connected devices.
-     */
-    public static List<String> getDeviceSerials(Logger logger) {
-        try {
-            ArrayList<String> devices = new ArrayList<>();
-            File outFile = File.createTempFile("device_serial", "tmp");
-            outFile.deleteOnExit();
-            Utils.runCommand(outFile, logger, "adb", "devices");
-            List<String> outputLines = Files.readLines(outFile, Charset.defaultCharset());
-            Pattern regex = Pattern.compile("^(.*)\tdevice$");
-            for (String line : outputLines) {
-                Matcher m = regex.matcher(line);
-                if (m.find()) {
-                    devices.add(m.group(1));
-                }
-            }
-            return devices;
-        } catch (Exception ex) {
-            logger.log(Level.SEVERE, "Failed to list connected devices: " + ex.getMessage());
-        }
-        return null;
-    }
-
-    /**
-     * Returns ANDROID_SERIAL environment variable, or null if that is undefined or unavailable.
-     * @param logger Destination of error messages.
-     * @return String value of ANDROID_SERIAL environment variable, or null.
-     */
-    public static String getDefaultDevice(Logger logger) {
-        try {
-            return System.getenv("ANDROID_SERIAL");
-        } catch (Exception ex) {
-            logger.log(Level.SEVERE, "Failed to check ANDROID_SERIAL environment variable.",
-                    ex);
-        }
-        return null;
-    }
-
-    /**
-     * Returns the device to use if one can be deduced, or null.
-     * @param device Command-line specified device, or null.
-     * @param connectedDevices List of all connected devices.
-     * @param defaultDevice Environment-variable specified device, or null.
-     * @param logger Destination of error messages.
-     * @return Device to use, or null.
-     */
-    public static String chooseDevice(String device, List<String> connectedDevices,
-            String defaultDevice, Logger logger) {
-        if (connectedDevices == null || connectedDevices.isEmpty()) {
-            logger.severe("No connected device.");
-            return null;
-        }
-        if (device != null) {
-            if (connectedDevices.contains(device)) {
-                return device;
-            }
-            logger.severe("Device not connected: " + device);
-            return null;
-        }
-        if (connectedDevices.size() == 1) {
-            return connectedDevices.get(0);
-        }
-        if (defaultDevice != null) {
-            if (connectedDevices.contains(defaultDevice)) {
-                return defaultDevice;
-            } else {
-                logger.severe("ANDROID_SERIAL device is not connected: " + defaultDevice);
-                return null;
-            }
-        }
-        logger.severe("More than one device is connected. Choose one"
-                + " with -s DEVICE_SERIAL or environment variable ANDROID_SERIAL.");
-        return null;
-    }
-}
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java
deleted file mode 100644
index ec3c7df..0000000
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/localdrive/LocalDrive.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.statsd.shelltools.localdrive;
-
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.statsd.shelltools.Utils;
-
-import com.google.common.io.Files;
-import com.google.protobuf.TextFormat;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.List;
-import java.util.logging.Logger;
-
-/**
- * Tool for using statsd locally. Can upload a config and get the data. Handles
- * both binary and human-readable protos.
- * To make: make statsd_localdrive
- * To run: statsd_localdrive     (i.e.  ./out/host/linux-x86/bin/statsd_localdrive)
- */
-public class LocalDrive {
-    private static final boolean DEBUG = false;
-
-    public static final int MIN_SDK = 29;
-    public static final String MIN_CODENAME = "Q";
-
-    public static final long DEFAULT_CONFIG_ID = 56789;
-
-    public static final String BINARY_FLAG = "--binary";
-    public static final String CLEAR_DATA = "--clear";
-    public static final String NO_UID_MAP_FLAG = "--no-uid-map";
-
-    public static final String HELP_STRING =
-        "Usage:\n\n" +
-
-        "statsd_localdrive [-s DEVICE_SERIAL] upload CONFIG_FILE [CONFIG_ID] [--binary]\n" +
-        "  Uploads the given statsd config file (in binary or human-readable-text format).\n" +
-        "  If a config with this id already exists, removes it first.\n" +
-        "    CONFIG_FILE    Location of config file on host.\n" +
-        "    CONFIG_ID      Long ID to associate with this config. If absent, uses "
-                                                                + DEFAULT_CONFIG_ID + ".\n" +
-        "    --binary       Config is in binary format; otherwise, assumed human-readable text.\n" +
-        // Similar to: adb shell cmd stats config update SHELL_UID CONFIG_ID
-        "\n" +
-
-        "statsd_localdrive [-s DEVICE_SERIAL] update CONFIG_FILE [CONFIG_ID] [--binary]\n" +
-        "  Same as upload, but does not remove the old config first (if it already exists).\n" +
-        // Similar to: adb shell cmd stats config update SHELL_UID CONFIG_ID
-        "\n" +
-
-        "statsd_localdrive [-s DEVICE_SERIAL] get-data [CONFIG_ID] [--clear] [--binary] [--no-uid-map]\n" +
-        "  Prints the output statslog data (in binary or human-readable-text format).\n" +
-        "    CONFIG_ID      Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
-        "    --binary       Output should be in binary, instead of default human-readable text.\n" +
-        "                       Binary output can be redirected as usual (e.g. > FILENAME).\n" +
-        "    --no-uid-map   Do not include the uid-map (the very lengthy uid<-->pkgName map).\n" +
-        "    --clear        Erase the data from statsd afterwards. Does not remove the config.\n" +
-        // Similar to: adb shell cmd stats dump-report SHELL_UID CONFIG_ID [--keep_data]
-        //                                                      --include_current_bucket --proto
-        "\n" +
-
-        "statsd_localdrive [-s DEVICE_SERIAL] remove [CONFIG_ID]\n" +
-        "  Removes the config.\n" +
-        "    CONFIG_ID      Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
-        // Equivalent to: adb shell cmd stats config remove SHELL_UID CONFIG_ID
-        "\n" +
-
-        "statsd_localdrive [-s DEVICE_SERIAL] clear [CONFIG_ID]\n" +
-        "  Clears the data associated with the config.\n" +
-        "    CONFIG_ID      Long ID of the config. If absent, uses " + DEFAULT_CONFIG_ID + ".\n" +
-        // Similar to: adb shell cmd stats dump-report SHELL_UID CONFIG_ID
-        //                                                      --include_current_bucket --proto
-        "";
-
-
-    private static final Logger sLogger = Logger.getLogger(LocalDrive.class.getName());
-
-    /** Usage: make statsd_localdrive && statsd_localdrive */
-    public static void main(String[] args) {
-        Utils.setUpLogger(sLogger, DEBUG);
-        if (args.length == 0) {
-            printHelp();
-            return;
-        }
-
-        int remainingArgsLength = args.length;
-        String deviceSerial = null;
-        if (args[0].equals("-s")) {
-            if (args.length == 1) {
-                printHelp();
-            }
-            deviceSerial = args[1];
-            remainingArgsLength -= 2;
-        }
-
-        List<String> connectedDevices = Utils.getDeviceSerials(sLogger);
-        deviceSerial = Utils.chooseDevice(deviceSerial, connectedDevices,
-                Utils.getDefaultDevice(sLogger), sLogger);
-        if (deviceSerial == null) {
-            return;
-        }
-
-        if (!Utils.isAcceptableStatsd(sLogger, MIN_SDK, MIN_CODENAME, deviceSerial)) {
-            sLogger.severe("LocalDrive only works with statsd versions for Android "
-                    + MIN_CODENAME + " or higher.");
-            return;
-        }
-
-        int idx = args.length - remainingArgsLength;
-        if (remainingArgsLength > 0) {
-            switch (args[idx]) {
-                case "clear":
-                    cmdClear(args, idx, deviceSerial);
-                    return;
-                case "get-data":
-                    cmdGetData(args, idx, deviceSerial);
-                    return;
-                case "remove":
-                    cmdRemove(args, idx);
-                    return;
-                case "update":
-                    cmdUpdate(args, idx, deviceSerial);
-                    return;
-                case "upload":
-                    cmdUpload(args, idx, deviceSerial);
-                    return;
-            }
-        }
-        printHelp();
-    }
-
-    private static void printHelp() {
-        sLogger.info(HELP_STRING);
-    }
-
-    // upload CONFIG_FILE [CONFIG_ID] [--binary]
-    private static boolean cmdUpload(String[] args, int idx, String deviceSerial) {
-        return updateConfig(args, idx, true, deviceSerial);
-    }
-
-    // update CONFIG_FILE [CONFIG_ID] [--binary]
-    private static boolean cmdUpdate(String[] args, int idx, String deviceSerial) {
-        return updateConfig(args, idx, false, deviceSerial);
-    }
-
-    private static boolean updateConfig(String[] args, int idx, boolean removeOldConfig,
-            String deviceSerial) {
-        int argCount = args.length - 1 - idx; // Used up one for upload/update.
-
-        // Get CONFIG_FILE
-        if (argCount < 1) {
-            sLogger.severe("No config file provided.");
-            printHelp();
-            return false;
-        }
-        final String origConfigLocation = args[idx + 1];
-        if (!new File(origConfigLocation).exists()) {
-            sLogger.severe("Error - Cannot find the provided config file: " + origConfigLocation);
-            return false;
-        }
-        argCount--;
-
-        // Get --binary
-        boolean binary = contains(args, idx + 2, BINARY_FLAG);
-        if (binary) argCount --;
-
-        // Get CONFIG_ID
-        long configId;
-        try {
-            configId = getConfigId(argCount < 1, args, idx + 2);
-        } catch (NumberFormatException e) {
-            sLogger.severe("Invalid config id provided.");
-            printHelp();
-            return false;
-        }
-        sLogger.fine(String.format("updateConfig with %s %d %b %b",
-                origConfigLocation, configId, binary, removeOldConfig));
-
-        // Remove the old config.
-        if (removeOldConfig) {
-            try {
-                Utils.runCommand(null, sLogger, "adb", "shell", Utils.CMD_REMOVE_CONFIG,
-                        Utils.SHELL_UID, String.valueOf(configId));
-                Utils.getReportList(configId, true /* clearData */, true /* SHELL_UID */, sLogger,
-                        deviceSerial);
-            } catch (InterruptedException | IOException e) {
-                sLogger.severe("Failed to remove config: " + e.getMessage());
-                return false;
-            }
-        }
-
-        // Upload the config.
-        String configLocation;
-        if (binary) {
-            configLocation = origConfigLocation;
-        } else {
-            StatsdConfig.Builder builder = StatsdConfig.newBuilder();
-            try {
-                TextFormat.merge(new FileReader(origConfigLocation), builder);
-            } catch (IOException e) {
-                sLogger.severe("Failed to read config file " + origConfigLocation + ": "
-                        + e.getMessage());
-                return false;
-            }
-
-            try {
-                File tempConfigFile = File.createTempFile("statsdconfig", ".config");
-                tempConfigFile.deleteOnExit();
-                Files.write(builder.build().toByteArray(), tempConfigFile);
-                configLocation = tempConfigFile.getAbsolutePath();
-            } catch (IOException e) {
-                sLogger.severe("Failed to write temp config file: " + e.getMessage());
-                return false;
-            }
-        }
-        String remotePath = "/data/local/tmp/statsdconfig.config";
-        try {
-            Utils.runCommand(null, sLogger, "adb", "push", configLocation, remotePath);
-            Utils.runCommand(null, sLogger, "adb", "shell", "cat", remotePath, "|",
-                    Utils.CMD_UPDATE_CONFIG, Utils.SHELL_UID, String.valueOf(configId));
-        } catch (InterruptedException | IOException e) {
-            sLogger.severe("Failed to update config: " + e.getMessage());
-            return false;
-        }
-        return true;
-    }
-
-    // get-data [CONFIG_ID] [--clear] [--binary] [--no-uid-map]
-    private static boolean cmdGetData(String[] args, int idx, String deviceSerial) {
-        boolean binary = contains(args, idx + 1, BINARY_FLAG);
-        boolean noUidMap = contains(args, idx + 1, NO_UID_MAP_FLAG);
-        boolean clearData = contains(args, idx + 1, CLEAR_DATA);
-
-        // Get CONFIG_ID
-        int argCount = args.length - 1 - idx; // Used up one for get-data.
-        if (binary) argCount--;
-        if (noUidMap) argCount--;
-        if (clearData) argCount--;
-        long configId;
-        try {
-            configId = getConfigId(argCount < 1, args, idx + 1);
-        } catch (NumberFormatException e) {
-            sLogger.severe("Invalid config id provided.");
-            printHelp();
-            return false;
-        }
-        sLogger.fine(String.format("cmdGetData with %d %b %b %b",
-                configId, clearData, binary, noUidMap));
-
-        // Get the StatsLog
-        // Even if the args request no modifications, we still parse it to make sure it's valid.
-        ConfigMetricsReportList reportList;
-        try {
-            reportList = Utils.getReportList(configId, clearData, true /* SHELL_UID */, sLogger,
-                    deviceSerial);
-        } catch (IOException | InterruptedException e) {
-            sLogger.severe("Failed to get report list: " + e.getMessage());
-            return false;
-        }
-        if (noUidMap) {
-            ConfigMetricsReportList.Builder builder
-                    = ConfigMetricsReportList.newBuilder(reportList);
-            // Clear the reports, then add them back without their UidMap.
-            builder.clearReports();
-            for (ConfigMetricsReport report : reportList.getReportsList()) {
-                builder.addReports(ConfigMetricsReport.newBuilder(report).clearUidMap());
-            }
-            reportList = builder.build();
-        }
-
-        if (!binary) {
-            sLogger.info(reportList.toString());
-        } else {
-            try {
-                System.out.write(reportList.toByteArray());
-            } catch (IOException e) {
-                sLogger.severe("Failed to output binary statslog proto: "
-                        + e.getMessage());
-                return false;
-            }
-        }
-        return true;
-    }
-
-    // clear [CONFIG_ID]
-    private static boolean cmdClear(String[] args, int idx, String deviceSerial) {
-        // Get CONFIG_ID
-        long configId;
-        try {
-            configId = getConfigId(false, args, idx + 1);
-        } catch (NumberFormatException e) {
-            sLogger.severe("Invalid config id provided.");
-            printHelp();
-            return false;
-        }
-        sLogger.fine(String.format("cmdClear with %d", configId));
-
-        try {
-            Utils.getReportList(configId, true /* clearData */, true /* SHELL_UID */, sLogger,
-                    deviceSerial);
-        } catch (IOException | InterruptedException e) {
-            sLogger.severe("Failed to get report list: " + e.getMessage());
-            return false;
-        }
-        return true;
-    }
-
-    // remove [CONFIG_ID]
-    private static boolean cmdRemove(String[] args, int idx) {
-        // Get CONFIG_ID
-        long configId;
-        try {
-            configId = getConfigId(false, args, idx + 1);
-        } catch (NumberFormatException e) {
-            sLogger.severe("Invalid config id provided.");
-            printHelp();
-            return false;
-        }
-        sLogger.fine(String.format("cmdRemove with %d", configId));
-
-        try {
-            Utils.runCommand(null, sLogger, "adb", "shell", Utils.CMD_REMOVE_CONFIG,
-                    Utils.SHELL_UID, String.valueOf(configId));
-        } catch (InterruptedException | IOException e) {
-            sLogger.severe("Failed to remove config: " + e.getMessage());
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Searches through the array to see if it contains (precisely) the given value, starting
-     * at the given firstIdx.
-     */
-    private static boolean contains(String[] array, int firstIdx, String value) {
-        if (value == null) return false;
-        if (firstIdx < 0) return false;
-        for (int i = firstIdx; i < array.length; i++) {
-            if (value.equals(array[i])) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Gets the config id from args[idx], or returns DEFAULT_CONFIG_ID if args[idx] does not exist.
-     * If justUseDefault, overrides and just uses DEFAULT_CONFIG_ID instead.
-     */
-    private static long getConfigId(boolean justUseDefault, String[] args, int idx)
-            throws NumberFormatException {
-        if (justUseDefault || args.length <= idx || idx < 0) {
-            return DEFAULT_CONFIG_ID;
-        }
-        try {
-            return Long.valueOf(args[idx]);
-        } catch (NumberFormatException e) {
-            sLogger.severe("Bad config id provided: " + args[idx]);
-            throw e;
-        }
-    }
-}
diff --git a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java b/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
deleted file mode 100644
index 51bcad1..0000000
--- a/cmds/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.statsd.shelltools.testdrive;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.EventMetric;
-import com.android.internal.os.StatsdConfigProto.FieldFilter;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.PullAtomPackages;
-import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import com.android.os.AtomsProto.Atom;
-import com.android.os.StatsLog;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.statsd.shelltools.Utils;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.io.Files;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class TestDrive {
-
-    private static final int METRIC_ID_BASE = 1111;
-    private static final long ATOM_MATCHER_ID_BASE = 1234567;
-    private static final long APP_BREADCRUMB_MATCHER_ID = 1111111;
-    private static final int PULL_ATOM_START = 10000;
-    private static final int MAX_PLATFORM_ATOM_TAG = 100000;
-    private static final int VENDOR_PULLED_ATOM_START_TAG = 150000;
-    private static final long CONFIG_ID = 54321;
-    private static final String[] ALLOWED_LOG_SOURCES = {
-            "AID_GRAPHICS",
-            "AID_INCIDENTD",
-            "AID_STATSD",
-            "AID_RADIO",
-            "com.android.systemui",
-            "com.android.vending",
-            "AID_SYSTEM",
-            "AID_ROOT",
-            "AID_BLUETOOTH",
-            "AID_LMKD",
-            "com.android.managedprovisioning",
-            "AID_MEDIA",
-            "AID_NETWORK_STACK",
-            "com.google.android.providers.media.module",
-    };
-    private static final String[] DEFAULT_PULL_SOURCES = {
-            "AID_SYSTEM",
-            "AID_RADIO"
-    };
-    private static final Logger LOGGER = Logger.getLogger(TestDrive.class.getName());
-
-    @VisibleForTesting
-    String mDeviceSerial = null;
-    @VisibleForTesting
-    Dumper mDumper = new BasicDumper();
-
-    public static void main(String[] args) {
-        final Configuration configuration = new Configuration();
-        final TestDrive testDrive = new TestDrive();
-        Utils.setUpLogger(LOGGER, false);
-
-        if (!testDrive.processArgs(configuration, args,
-                Utils.getDeviceSerials(LOGGER), Utils.getDefaultDevice(LOGGER))) {
-            return;
-        }
-
-        final ConfigMetricsReportList reports = testDrive.testDriveAndGetReports(
-                configuration.createConfig(), configuration.hasPulledAtoms(),
-                configuration.hasPushedAtoms());
-        if (reports != null) {
-            configuration.dumpMetrics(reports, testDrive.mDumper);
-        }
-    }
-
-    boolean processArgs(Configuration configuration, String[] args, List<String> connectedDevices,
-            String defaultDevice) {
-        if (args.length < 1) {
-            LOGGER.severe("Usage: ./test_drive [-one] "
-                    + "[-p additional_allowed_package] "
-                    + "[-s DEVICE_SERIAL_NUMBER] "
-                    + "<atomId1> <atomId2> ... <atomIdN>");
-            return false;
-        }
-
-        int first_arg = 0;
-        // Consume all flags, which must precede all atoms
-        for (; first_arg < args.length; ++first_arg) {
-            String arg = args[first_arg];
-            int remaining_args = args.length - first_arg;
-            if (remaining_args >= 2 && arg.equals("-one")) {
-                LOGGER.info("Creating one event metric to catch all pushed atoms.");
-                configuration.mOnePushedAtomEvent = true;
-            } else if (remaining_args >= 2 && arg.equals("-terse")) {
-                LOGGER.info("Terse output format.");
-                mDumper = new TerseDumper();
-            } else if (remaining_args >= 3 && arg.equals("-p")) {
-                configuration.mAdditionalAllowedPackage = args[++first_arg];
-            } else if (remaining_args >= 3 && arg.equals("-s")) {
-                mDeviceSerial = args[++first_arg];
-            } else {
-                break;  // Found the atom list
-            }
-        }
-
-        mDeviceSerial = Utils.chooseDevice(mDeviceSerial, connectedDevices, defaultDevice, LOGGER);
-        if (mDeviceSerial == null) {
-            return false;
-        }
-
-        for ( ; first_arg < args.length; ++first_arg) {
-            String atom = args[first_arg];
-            try {
-                configuration.addAtom(Integer.valueOf(atom));
-            } catch (NumberFormatException e) {
-                LOGGER.severe("Bad atom id provided: " + atom);
-            }
-        }
-
-        return configuration.hasPulledAtoms() || configuration.hasPushedAtoms();
-    }
-
-    private ConfigMetricsReportList testDriveAndGetReports(StatsdConfig config,
-            boolean hasPulledAtoms, boolean hasPushedAtoms) {
-        if (config == null) {
-            LOGGER.severe("Failed to create valid config.");
-            return null;
-        }
-
-        String remoteConfigPath = null;
-        try {
-            remoteConfigPath = pushConfig(config, mDeviceSerial);
-            LOGGER.info("Pushed the following config to statsd on device '" + mDeviceSerial
-                    + "':");
-            LOGGER.info(config.toString());
-            if (hasPushedAtoms) {
-                LOGGER.info("Now please play with the device to trigger the event.");
-            }
-            if (!hasPulledAtoms) {
-                LOGGER.info(
-                        "All events should be dumped after 1 min ...");
-                Thread.sleep(60_000);
-            } else {
-                LOGGER.info("All events should be dumped after 1.5 minutes ...");
-                Thread.sleep(15_000);
-                Utils.logAppBreadcrumb(0, 0, LOGGER, mDeviceSerial);
-                Thread.sleep(75_000);
-            }
-            return Utils.getReportList(CONFIG_ID, true, false, LOGGER,
-                    mDeviceSerial);
-        } catch (Exception e) {
-            LOGGER.log(Level.SEVERE, "Failed to test drive: " + e.getMessage(), e);
-        } finally {
-            removeConfig(mDeviceSerial);
-            if (remoteConfigPath != null) {
-                try {
-                    Utils.runCommand(null, LOGGER,
-                            "adb", "-s", mDeviceSerial, "shell", "rm",
-                            remoteConfigPath);
-                } catch (Exception e) {
-                    LOGGER.log(Level.WARNING,
-                            "Unable to remove remote config file: " + remoteConfigPath, e);
-                }
-            }
-        }
-        return null;
-    }
-
-    static class Configuration {
-        boolean mOnePushedAtomEvent = false;
-        @VisibleForTesting
-        Set<Integer> mPushedAtoms = new TreeSet<>();
-        @VisibleForTesting
-        Set<Integer> mPulledAtoms = new TreeSet<>();
-        @VisibleForTesting
-        String mAdditionalAllowedPackage = null;
-        private final Set<Long> mTrackedMetrics = new HashSet<>();
-
-        private void dumpMetrics(ConfigMetricsReportList reportList, Dumper dumper) {
-            // We may get multiple reports. Take the last one.
-            ConfigMetricsReport report = reportList.getReports(reportList.getReportsCount() - 1);
-            for (StatsLogReport statsLog : report.getMetricsList()) {
-                if (isTrackedMetric(statsLog.getMetricId())) {
-                    dumper.dump(statsLog);
-                }
-            }
-        }
-
-        boolean isTrackedMetric(long metricId) {
-            return mTrackedMetrics.contains(metricId);
-        }
-
-        static boolean isPulledAtom(int atomId) {
-            return atomId >= PULL_ATOM_START && atomId <= MAX_PLATFORM_ATOM_TAG
-                    || atomId >= VENDOR_PULLED_ATOM_START_TAG;
-        }
-
-        void addAtom(Integer atom) {
-            if (Atom.getDescriptor().findFieldByNumber(atom) == null) {
-                LOGGER.severe("No such atom found: " + atom);
-                return;
-            }
-            if (isPulledAtom(atom)) {
-                mPulledAtoms.add(atom);
-            } else {
-                mPushedAtoms.add(atom);
-            }
-        }
-
-        private boolean hasPulledAtoms() {
-            return !mPulledAtoms.isEmpty();
-        }
-
-        private boolean hasPushedAtoms() {
-            return !mPushedAtoms.isEmpty();
-        }
-
-        StatsdConfig createConfig() {
-            long metricId = METRIC_ID_BASE;
-            long atomMatcherId = ATOM_MATCHER_ID_BASE;
-
-            StatsdConfig.Builder builder = baseBuilder();
-
-            if (hasPulledAtoms()) {
-                builder.addAtomMatcher(
-                        createAtomMatcher(
-                                Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
-                                APP_BREADCRUMB_MATCHER_ID));
-            }
-
-            for (int atomId : mPulledAtoms) {
-                builder.addAtomMatcher(createAtomMatcher(atomId, atomMatcherId));
-                GaugeMetric.Builder gaugeMetricBuilder = GaugeMetric.newBuilder();
-                gaugeMetricBuilder
-                        .setId(metricId)
-                        .setWhat(atomMatcherId)
-                        .setTriggerEvent(APP_BREADCRUMB_MATCHER_ID)
-                        .setGaugeFieldsFilter(FieldFilter.newBuilder().setIncludeAll(true).build())
-                        .setBucket(TimeUnit.ONE_MINUTE)
-                        .setSamplingType(GaugeMetric.SamplingType.FIRST_N_SAMPLES)
-                        .setMaxNumGaugeAtomsPerBucket(100);
-                builder.addGaugeMetric(gaugeMetricBuilder.build());
-                atomMatcherId++;
-                mTrackedMetrics.add(metricId++);
-            }
-
-            // A simple atom matcher for each pushed atom.
-            List<AtomMatcher> simpleAtomMatchers = new ArrayList<>();
-            for (int atomId : mPushedAtoms) {
-                final AtomMatcher atomMatcher = createAtomMatcher(atomId, atomMatcherId++);
-                simpleAtomMatchers.add(atomMatcher);
-                builder.addAtomMatcher(atomMatcher);
-            }
-
-            if (mOnePushedAtomEvent) {
-                // Create a union event metric, using an matcher that matches all pulled atoms.
-                AtomMatcher unionAtomMatcher = createUnionMatcher(simpleAtomMatchers,
-                        atomMatcherId);
-                builder.addAtomMatcher(unionAtomMatcher);
-                EventMetric.Builder eventMetricBuilder = EventMetric.newBuilder();
-                eventMetricBuilder.setId(metricId).setWhat(unionAtomMatcher.getId());
-                builder.addEventMetric(eventMetricBuilder.build());
-                mTrackedMetrics.add(metricId++);
-            } else {
-                // Create multiple event metrics, one per pulled atom.
-                for (AtomMatcher atomMatcher : simpleAtomMatchers) {
-                    EventMetric.Builder eventMetricBuilder = EventMetric.newBuilder();
-                    eventMetricBuilder
-                            .setId(metricId)
-                            .setWhat(atomMatcher.getId());
-                    builder.addEventMetric(eventMetricBuilder.build());
-                    mTrackedMetrics.add(metricId++);
-                }
-            }
-
-            return builder.build();
-        }
-
-        private static AtomMatcher createAtomMatcher(int atomId, long matcherId) {
-            AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder();
-            atomMatcherBuilder
-                    .setId(matcherId)
-                    .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder().setAtomId(atomId));
-            return atomMatcherBuilder.build();
-        }
-
-        private AtomMatcher createUnionMatcher(List<AtomMatcher> simpleAtomMatchers,
-                long atomMatcherId) {
-            AtomMatcher.Combination.Builder combinationBuilder =
-                    AtomMatcher.Combination.newBuilder();
-            combinationBuilder.setOperation(StatsdConfigProto.LogicalOperation.OR);
-            for (AtomMatcher matcher : simpleAtomMatchers) {
-                combinationBuilder.addMatcher(matcher.getId());
-            }
-            AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder();
-            atomMatcherBuilder.setId(atomMatcherId).setCombination(combinationBuilder.build());
-            return atomMatcherBuilder.build();
-        }
-
-        private StatsdConfig.Builder baseBuilder() {
-            ArrayList<String> allowedSources = new ArrayList<>();
-            Collections.addAll(allowedSources, ALLOWED_LOG_SOURCES);
-            if (mAdditionalAllowedPackage != null) {
-                allowedSources.add(mAdditionalAllowedPackage);
-            }
-            return StatsdConfig.newBuilder()
-                    .addAllAllowedLogSource(allowedSources)
-                    .addAllDefaultPullPackages(Arrays.asList(DEFAULT_PULL_SOURCES))
-                    .addPullAtomPackages(PullAtomPackages.newBuilder()
-                            .setAtomId(Atom.GPU_STATS_GLOBAL_INFO_FIELD_NUMBER)
-                            .addPackages("AID_GPU_SERVICE"))
-                    .addPullAtomPackages(PullAtomPackages.newBuilder()
-                            .setAtomId(Atom.GPU_STATS_APP_INFO_FIELD_NUMBER)
-                            .addPackages("AID_GPU_SERVICE"))
-                    .addPullAtomPackages(PullAtomPackages.newBuilder()
-                            .setAtomId(Atom.TRAIN_INFO_FIELD_NUMBER)
-                            .addPackages("AID_STATSD"))
-                    .addPullAtomPackages(PullAtomPackages.newBuilder()
-                            .setAtomId(Atom.GENERAL_EXTERNAL_STORAGE_ACCESS_STATS_FIELD_NUMBER)
-                            .addPackages("com.google.android.providers.media.module"))
-                    .setHashStringsInMetricReport(false);
-        }
-    }
-
-    interface Dumper {
-        void dump(StatsLogReport report);
-    }
-
-    static class BasicDumper implements Dumper {
-        @Override
-        public void dump(StatsLogReport report) {
-            System.out.println(report.toString());
-        }
-    }
-
-    static class TerseDumper extends BasicDumper {
-        @Override
-        public void dump(StatsLogReport report) {
-            if (report.hasGaugeMetrics()) {
-                dumpGaugeMetrics(report);
-            }
-            if (report.hasEventMetrics()) {
-                dumpEventMetrics(report);
-            }
-        }
-        void dumpEventMetrics(StatsLogReport report) {
-            final List<StatsLog.EventMetricData> data = report.getEventMetrics().getDataList();
-            if (data.isEmpty()) {
-                return;
-            }
-            long firstTimestampNanos = data.get(0).getElapsedTimestampNanos();
-            for (StatsLog.EventMetricData event : data) {
-                final double deltaSec = (event.getElapsedTimestampNanos() - firstTimestampNanos)
-                        / 1e9;
-                System.out.println(
-                        String.format("+%.3fs: %s", deltaSec, event.getAtom().toString()));
-            }
-        }
-        void dumpGaugeMetrics(StatsLogReport report) {
-            final List<StatsLog.GaugeMetricData> data = report.getGaugeMetrics().getDataList();
-            if (data.isEmpty()) {
-                return;
-            }
-            for (StatsLog.GaugeMetricData gauge : data) {
-                System.out.println(gauge.toString());
-            }
-        }
-    }
-
-    private static String pushConfig(StatsdConfig config, String deviceSerial)
-            throws IOException, InterruptedException {
-        File configFile = File.createTempFile("statsdconfig", ".config");
-        configFile.deleteOnExit();
-        Files.write(config.toByteArray(), configFile);
-        String remotePath = "/data/local/tmp/" + configFile.getName();
-        Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial,
-                "push", configFile.getAbsolutePath(), remotePath);
-        Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial,
-                "shell", "cat", remotePath, "|", Utils.CMD_UPDATE_CONFIG,
-                String.valueOf(CONFIG_ID));
-        return remotePath;
-    }
-
-    private static void removeConfig(String deviceSerial) {
-        try {
-            Utils.runCommand(null, LOGGER, "adb", "-s", deviceSerial,
-                    "shell", Utils.CMD_REMOVE_CONFIG, String.valueOf(CONFIG_ID));
-        } catch (Exception e) {
-            LOGGER.severe("Failed to remove config: " + e.getMessage());
-        }
-    }
-}
diff --git a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java
deleted file mode 100644
index b1cc60f..0000000
--- a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/ConfigurationTest.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2020 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 com.android.statsd.shelltools.testdrive;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import com.android.internal.os.StatsdConfigProto;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.os.AtomsProto;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for {@link TestDrive}
- */
-public class ConfigurationTest {
-
-    private StatsdConfigProto.AtomMatcher findAndRemoveAtomMatcherById(
-            List<StatsdConfigProto.AtomMatcher> atomMatchers, long id) {
-        int numMatches = 0;
-        StatsdConfigProto.AtomMatcher match = null;
-        for (StatsdConfigProto.AtomMatcher atomMatcher : atomMatchers) {
-            if (id == atomMatcher.getId()) {
-                ++numMatches;
-                match = atomMatcher;
-            }
-        }
-        if (numMatches == 1) {
-            atomMatchers.remove(match);
-            return match;
-        }
-        return null;  // Too many, or not found
-    }
-
-    private final TestDrive.Configuration mConfiguration = new TestDrive.Configuration();
-
-    @Test
-    public void testOnePushed() {
-        final int atom = 90;
-        assertFalse(TestDrive.Configuration.isPulledAtom(atom));
-        mConfiguration.addAtom(atom);
-        StatsdConfig config = mConfiguration.createConfig();
-
-        //event_metric {
-        //  id: 1111
-        //  what: 1234567
-        //}
-        //atom_matcher {
-        //  id: 1234567
-        //  simple_atom_matcher {
-        //    atom_id: 90
-        //  }
-        //}
-
-        assertEquals(1, config.getEventMetricCount());
-        assertEquals(0, config.getGaugeMetricCount());
-
-        assertTrue(mConfiguration.isTrackedMetric(config.getEventMetric(0).getId()));
-
-        final List<StatsdConfigProto.AtomMatcher> atomMatchers =
-                new ArrayList<>(config.getAtomMatcherList());
-        assertEquals(atom,
-                findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(0).getWhat())
-                        .getSimpleAtomMatcher().getAtomId());
-        assertEquals(0, atomMatchers.size());
-    }
-
-    @Test
-    public void testOnePulled() {
-        final int atom = 10022;
-        assertTrue(TestDrive.Configuration.isPulledAtom(atom));
-        mConfiguration.addAtom(atom);
-        StatsdConfig config = mConfiguration.createConfig();
-
-        //gauge_metric {
-        //  id: 1111
-        //  what: 1234567
-        //  gauge_fields_filter {
-        //    include_all: true
-        //  }
-        //  bucket: ONE_MINUTE
-        //  sampling_type: FIRST_N_SAMPLES
-        //  max_num_gauge_atoms_per_bucket: 100
-        //  trigger_event: 1111111
-        //}
-        //atom_matcher {
-        //  id: 1111111
-        //  simple_atom_matcher {
-        //    atom_id: 47
-        //  }
-        //}
-        //atom_matcher {
-        //  id: 1234567
-        //  simple_atom_matcher {
-        //    atom_id: 10022
-        //  }
-        //}
-
-        assertEquals(0, config.getEventMetricCount());
-        assertEquals(1, config.getGaugeMetricCount());
-
-        assertTrue(mConfiguration.isTrackedMetric(config.getGaugeMetric(0).getId()));
-
-        final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0);
-        assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll());
-
-        final List<StatsdConfigProto.AtomMatcher> atomMatchers =
-                new ArrayList<>(config.getAtomMatcherList());
-        assertEquals(atom,
-                findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat())
-                        .getSimpleAtomMatcher().getAtomId());
-        assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
-                findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent())
-                        .getSimpleAtomMatcher().getAtomId());
-        assertEquals(0, atomMatchers.size());
-    }
-
-    @Test
-    public void testOnePulledTwoPushed() {
-        final int pulledAtom = 10022;
-        assertTrue(TestDrive.Configuration.isPulledAtom(pulledAtom));
-        mConfiguration.addAtom(pulledAtom);
-
-        Integer[] pushedAtoms = new Integer[]{244, 245};
-        for (int atom : pushedAtoms) {
-            assertFalse(TestDrive.Configuration.isPulledAtom(atom));
-            mConfiguration.addAtom(atom);
-        }
-        StatsdConfig config = mConfiguration.createConfig();
-
-        //  event_metric {
-        //    id: 1111
-        //    what: 1234567
-        //  }
-        //  event_metric {
-        //    id: 1112
-        //    what: 1234568
-        //  }
-        //  gauge_metric {
-        //    id: 1114
-        //    what: 1234570
-        //    gauge_fields_filter {
-        //      include_all: true
-        //    }
-        //    bucket: ONE_MINUTE
-        //    sampling_type: FIRST_N_SAMPLES
-        //    max_num_gauge_atoms_per_bucket: 100
-        //    trigger_event: 1111111
-        //  }
-        //  atom_matcher {
-        //    id: 1111111
-        //    simple_atom_matcher {
-        //      atom_id: 47
-        //    }
-        //  }
-        //  atom_matcher {
-        //    id: 1234567
-        //    simple_atom_matcher {
-        //      atom_id: 244
-        //    }
-        //  }
-        //  atom_matcher {
-        //    id: 1234568
-        //    simple_atom_matcher {
-        //      atom_id: 245
-        //    }
-        //  }
-        //  atom_matcher {
-        //    id: 1234570
-        //    simple_atom_matcher {
-        //      atom_id: 10022
-        //    }
-        //  }
-
-        assertEquals(2, config.getEventMetricCount());
-        assertEquals(1, config.getGaugeMetricCount());
-
-        final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0);
-        assertTrue(mConfiguration.isTrackedMetric(gaugeMetric.getId()));
-        assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll());
-        for (StatsdConfigProto.EventMetric eventMetric : config.getEventMetricList()) {
-            assertTrue(mConfiguration.isTrackedMetric(eventMetric.getId()));
-        }
-
-        final List<StatsdConfigProto.AtomMatcher> atomMatchers =
-                new ArrayList<>(config.getAtomMatcherList());
-
-        assertEquals(pulledAtom, findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat())
-                .getSimpleAtomMatcher().getAtomId());
-        assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
-                findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent())
-                        .getSimpleAtomMatcher().getAtomId());
-
-        Integer[] actualAtoms = new Integer[]{
-                findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(0).getWhat())
-                        .getSimpleAtomMatcher().getAtomId(),
-                findAndRemoveAtomMatcherById(atomMatchers, config.getEventMetric(1).getWhat())
-                        .getSimpleAtomMatcher().getAtomId()};
-        Arrays.sort(actualAtoms);
-        assertArrayEquals(pushedAtoms, actualAtoms);
-
-        assertEquals(0, atomMatchers.size());
-    }
-
-    @Test
-    public void testOnePulledTwoPushedTogether() {
-        mConfiguration.mOnePushedAtomEvent = true;  // Use one event grabbing all pushed atoms
-
-        final int pulledAtom = 10022;
-        assertTrue(TestDrive.Configuration.isPulledAtom(pulledAtom));
-        mConfiguration.addAtom(pulledAtom);
-
-        Integer[] pushedAtoms = new Integer[]{244, 245};
-        for (int atom : pushedAtoms) {
-            assertFalse(TestDrive.Configuration.isPulledAtom(atom));
-            mConfiguration.addAtom(atom);
-        }
-        StatsdConfig config = mConfiguration.createConfig();
-
-        //    event_metric {
-        //      id: 1112
-        //      what: 1234570
-        //    }
-        //    gauge_metric {
-        //      id: 1111
-        //      what: 1234567
-        //      gauge_fields_filter {
-        //        include_all: true
-        //      }
-        //      bucket: ONE_MINUTE
-        //      sampling_type: FIRST_N_SAMPLES
-        //      max_num_gauge_atoms_per_bucket: 100
-        //      trigger_event: 1111111
-        //    }
-        //    atom_matcher {
-        //      id: 1111111
-        //      simple_atom_matcher {
-        //        atom_id: 47
-        //      }
-        //    }
-        //    atom_matcher {
-        //      id: 1234567
-        //      simple_atom_matcher {
-        //        atom_id: 10022
-        //      }
-        //    }
-        //    atom_matcher {
-        //      id: 1234568
-        //      simple_atom_matcher {
-        //        atom_id: 244
-        //      }
-        //    }
-        //    atom_matcher {
-        //      id: 1234569
-        //      simple_atom_matcher {
-        //        atom_id: 245
-        //      }
-        //    }
-        //    atom_matcher {
-        //      id: 1234570
-        //      combination {
-        //        operation: OR
-        //        matcher: 1234568
-        //        matcher: 1234569
-        //      }
-        //    }
-
-        assertEquals(1, config.getEventMetricCount());
-        assertEquals(1, config.getGaugeMetricCount());
-
-        final StatsdConfigProto.GaugeMetric gaugeMetric = config.getGaugeMetric(0);
-        assertTrue(mConfiguration.isTrackedMetric(gaugeMetric.getId()));
-        assertTrue(gaugeMetric.getGaugeFieldsFilter().getIncludeAll());
-
-        StatsdConfigProto.EventMetric eventMetric = config.getEventMetric(0);
-        assertTrue(mConfiguration.isTrackedMetric(eventMetric.getId()));
-
-        final List<StatsdConfigProto.AtomMatcher> atomMatchers =
-                new ArrayList<>(config.getAtomMatcherList());
-
-        assertEquals(pulledAtom, findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getWhat())
-                .getSimpleAtomMatcher().getAtomId());
-        assertEquals(AtomsProto.Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER,
-                findAndRemoveAtomMatcherById(atomMatchers, gaugeMetric.getTriggerEvent())
-                        .getSimpleAtomMatcher().getAtomId());
-
-        StatsdConfigProto.AtomMatcher unionMatcher = findAndRemoveAtomMatcherById(atomMatchers,
-                eventMetric.getWhat());
-        assertNotNull(unionMatcher.getCombination());
-        assertEquals(2, unionMatcher.getCombination().getMatcherCount());
-
-        Integer[] actualAtoms = new Integer[]{
-              findAndRemoveAtomMatcherById(atomMatchers,
-                      unionMatcher.getCombination().getMatcher(0))
-                      .getSimpleAtomMatcher().getAtomId(),
-                findAndRemoveAtomMatcherById(atomMatchers,
-                        unionMatcher.getCombination().getMatcher(1))
-                        .getSimpleAtomMatcher().getAtomId()};
-        Arrays.sort(actualAtoms);
-        assertArrayEquals(pushedAtoms, actualAtoms);
-
-        assertEquals(0, atomMatchers.size());
-    }
-}
diff --git a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java b/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java
deleted file mode 100644
index 363fac0..0000000
--- a/cmds/statsd/tools/localtools/test/com/android/statsd/shelltools/testdrive/TestDriveTest.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2020 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 com.android.statsd.shelltools.testdrive;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Tests for {@link TestDrive}
- */
-@RunWith(Parameterized.class)
-public class TestDriveTest {
-    /**
-     * Expected results of a single iteration of the paramerized test.
-     */
-    static class Expect {
-        public boolean success;
-        public Integer[] atoms;
-        public boolean onePushedAtomEvent = false;
-        public String extraPackage = null;
-        public String target;
-        public boolean terse = false;
-
-        static Expect success(Integer... atoms) {
-            return new Expect(true, atoms,
-                    TARGET);
-        }
-        Expect(boolean success, Integer[] atoms, String target) {
-            this.success = success;
-            this.atoms = atoms;
-            this.target = target;
-        }
-        static final Expect FAILURE = new Expect(false, null, null);
-        Expect onePushedAtomEvent() {
-            this.onePushedAtomEvent = true;
-            return this;
-        }
-        Expect extraPackage() {
-            this.extraPackage = TestDriveTest.PACKAGE;
-            return this;
-        }
-        Expect terse() {
-            this.terse = true;
-            return this;
-        }
-    }
-
-    @Parameterized.Parameter(0)
-    public String[] mArgs;
-
-    @Parameterized.Parameter(1)
-    public List<String> mConnectedDevices;
-
-    @Parameterized.Parameter(2)
-    public String mDefaultDevice;
-
-    @Parameterized.Parameter(3)
-    public Expect mExpect;
-
-    private static final String TARGET = "target";
-    private static final List<String> TARGET_AND_OTHER = Arrays.asList("otherDevice",
-            TARGET);
-    private static final List<String> TWO_OTHER_DEVICES = Arrays.asList(
-            "other1", "other2");
-    private static final List<String> TARGET_ONLY = Collections.singletonList(TARGET);
-    private static final List<String> NOT_TARGET = Collections.singletonList("other");
-    private static final List<String> NO_DEVICES = Collections.emptyList();
-    private static final String PACKAGE = "extraPackage";
-
-    @Parameterized.Parameters
-    public static Collection<Object[]> data() {
-        return Arrays.asList(
-                new Object[]{new String[]{}, null, null,
-                        Expect.FAILURE},  // Usage explanation
-                new Object[]{new String[]{"244", "245"}, null, null,
-                        Expect.FAILURE},  // Failure looking up connected devices
-                new Object[]{new String[]{"244", "245"}, NO_DEVICES, null,
-                        Expect.FAILURE},  // No connected devices
-                new Object[]{new String[]{"-s", TARGET, "244", "245"}, NOT_TARGET, null,
-                        Expect.FAILURE},  // Wrong device connected
-                new Object[]{new String[]{"244", "245"}, TWO_OTHER_DEVICES, null,
-                        Expect.FAILURE},  // Wrong devices connected
-                new Object[]{new String[]{"244", "245"}, TARGET_ONLY, null,
-                        Expect.success(244, 245)},  // If only one device connected, guess that one
-                new Object[]{new String[]{"244", "not_an_atom"}, TARGET_ONLY, null,
-                        Expect.success(244)},  // Ignore non-atoms
-                new Object[]{new String[]{"not_an_atom"}, TARGET_ONLY, null,
-                        Expect.FAILURE},  // Require at least one atom
-                new Object[]{new String[]{"244", "245"}, TWO_OTHER_DEVICES, TARGET,
-                        Expect.FAILURE},  // ANDROID_SERIAL specifies non-connected target
-                new Object[]{new String[]{"244", "245"}, TARGET_AND_OTHER, TARGET,
-                        Expect.success(244, 245)},  // ANDROID_SERIAL specifies a valid target
-                new Object[]{new String[]{"244", "245"}, TARGET_AND_OTHER, null,
-                        Expect.FAILURE},  // Two connected devices, no indication of which to use
-                new Object[]{new String[]{"-one", "244", "245"}, TARGET_ONLY, null,
-                        Expect.success(244, 245).onePushedAtomEvent()},
-                new Object[]{new String[]{"-terse", "-one", "244", "245"}, TARGET_ONLY, null,
-                        Expect.success(244, 245).onePushedAtomEvent().terse()},
-                new Object[]{new String[]{"-one", "-terse", "244", "245"}, TARGET_ONLY, null,
-                        Expect.success(244, 245).onePushedAtomEvent().terse()},
-                new Object[]{new String[]{"-p", PACKAGE, "244", "245"}, TARGET_ONLY, null,
-                        Expect.success(244, 245).extraPackage()},
-                new Object[]{new String[]{"-p", PACKAGE, "-one", "244", "245"}, TARGET_ONLY, null,
-                        Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
-                new Object[]{new String[]{"-one", "-p", PACKAGE, "244", "245"}, TARGET_ONLY, null,
-                        Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
-                new Object[]{new String[]{"-s", TARGET, "-one", "-p", PACKAGE, "244", "245"},
-                        TARGET_AND_OTHER, null,
-                        Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
-                new Object[]{new String[]{"-one", "-s", TARGET, "-p", PACKAGE, "244", "245"},
-                        TARGET_AND_OTHER, null,
-                        Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
-                new Object[]{new String[]{"-one", "-p", PACKAGE, "-s", TARGET, "244", "245"},
-                        TARGET_AND_OTHER, null,
-                        Expect.success(244, 245).extraPackage().onePushedAtomEvent()},
-                new Object[]{new String[]{"-terse", "-one", "-p", PACKAGE, "-s", TARGET,
-                        "244", "245"},
-                        TARGET_AND_OTHER, null,
-                        Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()},
-                new Object[]{new String[]{"-one", "-terse", "-p", PACKAGE, "-s", TARGET,
-                        "244", "245"},
-                        TARGET_AND_OTHER, null,
-                        Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()},
-                new Object[]{new String[]{"-one", "-p", PACKAGE, "-terse", "-s", TARGET,
-                        "244", "245"},
-                        TARGET_AND_OTHER, null,
-                        Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()},
-                new Object[]{new String[]{"-one", "-p", PACKAGE, "-s", TARGET, "-terse",
-                        "244", "245"},
-                        TARGET_AND_OTHER, null,
-                        Expect.success(244, 245).extraPackage().onePushedAtomEvent().terse()}
-        );
-    }
-
-    private final TestDrive.Configuration mConfiguration = new TestDrive.Configuration();
-    private final TestDrive mTestDrive = new TestDrive();
-
-    private static Integer[] collectAtoms(TestDrive.Configuration configuration) {
-        Integer[] result = new Integer[configuration.mPulledAtoms.size()
-                + configuration.mPushedAtoms.size()];
-        int result_index = 0;
-        for (Integer atom : configuration.mPushedAtoms) {
-            result[result_index++] = atom;
-        }
-        for (Integer atom : configuration.mPulledAtoms) {
-            result[result_index++] = atom;
-        }
-        Arrays.sort(result);
-        return result;
-    }
-
-    @Test
-    public void testProcessArgs() {
-        boolean result = mTestDrive.processArgs(mConfiguration, mArgs, mConnectedDevices,
-                mDefaultDevice);
-        if (mExpect.success) {
-            assertTrue(result);
-            assertArrayEquals(mExpect.atoms, collectAtoms(mConfiguration));
-            assertEquals(mExpect.onePushedAtomEvent, mConfiguration.mOnePushedAtomEvent);
-            assertEquals(mExpect.target, mTestDrive.mDeviceSerial);
-            if (mExpect.terse) {
-                assertEquals(TestDrive.TerseDumper.class, mTestDrive.mDumper.getClass());
-            } else {
-                assertEquals(TestDrive.BasicDumper.class, mTestDrive.mDumper.getClass());
-            }
-        } else {
-            assertFalse(result);
-        }
-    }
-}
diff --git a/cmds/statsd/tools/localtools/testdrive_manifest.txt b/cmds/statsd/tools/localtools/testdrive_manifest.txt
deleted file mode 100644
index 625ebfa..0000000
--- a/cmds/statsd/tools/localtools/testdrive_manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-class: com.android.statsd.shelltools.testdrive.TestDrive
diff --git a/cmds/telecom/OWNERS b/cmds/telecom/OWNERS
new file mode 100644
index 0000000..2f813e6
--- /dev/null
+++ b/cmds/telecom/OWNERS
@@ -0,0 +1 @@
+include /telecomm/OWNERS
diff --git a/cmds/uinput/OWNERS b/cmds/uinput/OWNERS
new file mode 100644
index 0000000..d701f23
--- /dev/null
+++ b/cmds/uinput/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/hardware/input/OWNERS
diff --git a/cmds/wm/OWNERS b/cmds/wm/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/cmds/wm/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/config/OWNERS b/config/OWNERS
index 3d4924d..d59c6f2 100644
--- a/config/OWNERS
+++ b/config/OWNERS
@@ -1,4 +1,7 @@
+include /ZYGOTE_OWNERS
+
 # compat-team@ for changes to hiddenapi files
+
 per-file hiddenapi-* = andreionea@google.com, mathewi@google.com, satayev@google.com
 
 # Escalations:
diff --git a/core/api/OWNERS b/core/api/OWNERS
new file mode 100644
index 0000000..0b95c51
--- /dev/null
+++ b/core/api/OWNERS
@@ -0,0 +1,2 @@
+# API changes are managed via Prolog rules, not OWNERS
+*
diff --git a/core/api/current.txt b/core/api/current.txt
index ed92c29..8a6430f 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -2883,6 +2883,7 @@
     method protected void onServiceConnected();
     method public void onSystemActionsChanged();
     method public final boolean performGlobalAction(int);
+    method public void setAccessibilityFocusAppearance(int, @ColorInt int);
     method public void setGestureDetectionPassthroughRegion(int, @NonNull android.graphics.Region);
     method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
     method public void setTouchExplorationPassthroughRegion(int, @NonNull android.graphics.Region);
@@ -7150,6 +7151,7 @@
     field @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY) public static final String EXTRA_PASSWORD_COMPLEXITY = "android.app.extra.PASSWORD_COMPLEXITY";
     field public static final String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE = "android.app.extra.PROVISIONING_ACCOUNT_TO_MIGRATE";
     field public static final String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
+    field public static final String EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES = "android.app.extra.PROVISIONING_ALLOWED_PROVISIONING_MODES";
     field public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME";
     field public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE = "android.app.extra.PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE";
     field public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
@@ -7254,6 +7256,7 @@
     field public static final int PRIVATE_DNS_SET_NO_ERROR = 0; // 0x0
     field public static final int PROVISIONING_MODE_FULLY_MANAGED_DEVICE = 1; // 0x1
     field public static final int PROVISIONING_MODE_MANAGED_PROFILE = 2; // 0x2
+    field public static final int PROVISIONING_MODE_MANAGED_PROFILE_ON_PERSONAL_DEVICE = 3; // 0x3
     field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
     field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
     field public static final int SKIP_SETUP_WIZARD = 1; // 0x1
@@ -7686,6 +7689,7 @@
     method public long getTriggerContentMaxDelay();
     method public long getTriggerContentUpdateDelay();
     method @Nullable public android.app.job.JobInfo.TriggerContentUri[] getTriggerContentUris();
+    method public boolean isForegroundJob();
     method public boolean isImportantWhileForeground();
     method public boolean isPeriodic();
     method public boolean isPersisted();
@@ -7717,7 +7721,8 @@
     method public android.app.job.JobInfo.Builder setClipData(@Nullable android.content.ClipData, int);
     method public android.app.job.JobInfo.Builder setEstimatedNetworkBytes(long, long);
     method public android.app.job.JobInfo.Builder setExtras(@NonNull android.os.PersistableBundle);
-    method public android.app.job.JobInfo.Builder setImportantWhileForeground(boolean);
+    method @NonNull public android.app.job.JobInfo.Builder setForeground(boolean);
+    method @Deprecated public android.app.job.JobInfo.Builder setImportantWhileForeground(boolean);
     method public android.app.job.JobInfo.Builder setMinimumLatency(long);
     method public android.app.job.JobInfo.Builder setOverrideDeadline(long);
     method public android.app.job.JobInfo.Builder setPeriodic(long);
@@ -7757,6 +7762,7 @@
     method @NonNull public android.os.Bundle getTransientExtras();
     method @Nullable public String[] getTriggeredContentAuthorities();
     method @Nullable public android.net.Uri[] getTriggeredContentUris();
+    method public boolean isForegroundJob();
     method public boolean isOverrideDeadlineExpired();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.job.JobParameters> CREATOR;
@@ -34856,6 +34862,27 @@
     method public void onCancel();
   }
 
+  public abstract class CombinedVibrationEffect implements android.os.Parcelable {
+    method @NonNull public static android.os.CombinedVibrationEffect createSynced(@NonNull android.os.VibrationEffect);
+    method public int describeContents();
+    method @NonNull public static android.os.CombinedVibrationEffect.SequentialCombination startSequential();
+    method @NonNull public static android.os.CombinedVibrationEffect.SyncedCombination startSynced();
+    field @NonNull public static final android.os.Parcelable.Creator<android.os.CombinedVibrationEffect> CREATOR;
+  }
+
+  public static final class CombinedVibrationEffect.SequentialCombination {
+    method @NonNull public android.os.CombinedVibrationEffect.SequentialCombination addNext(int, @NonNull android.os.VibrationEffect);
+    method @NonNull public android.os.CombinedVibrationEffect.SequentialCombination addNext(int, @NonNull android.os.VibrationEffect, int);
+    method @NonNull public android.os.CombinedVibrationEffect.SequentialCombination addNext(@NonNull android.os.CombinedVibrationEffect);
+    method @NonNull public android.os.CombinedVibrationEffect.SequentialCombination addNext(@NonNull android.os.CombinedVibrationEffect, int);
+    method @NonNull public android.os.CombinedVibrationEffect combine();
+  }
+
+  public static final class CombinedVibrationEffect.SyncedCombination {
+    method @NonNull public android.os.CombinedVibrationEffect.SyncedCombination addVibrator(int, @NonNull android.os.VibrationEffect);
+    method @NonNull public android.os.CombinedVibrationEffect combine();
+  }
+
   public class ConditionVariable {
     ctor public ConditionVariable();
     ctor public ConditionVariable(boolean);
@@ -36082,6 +36109,13 @@
     field public static final int VIBRATION_EFFECT_SUPPORT_YES = 1; // 0x1
   }
 
+  public abstract class VibratorManager {
+    method @NonNull public abstract android.os.Vibrator getDefaultVibrator();
+    method @NonNull public abstract android.os.Vibrator getVibrator(int);
+    method @NonNull public abstract int[] getVibratorIds();
+    method public abstract void vibrate(@NonNull android.os.CombinedVibrationEffect);
+  }
+
   public class WorkSource implements android.os.Parcelable {
     ctor public WorkSource();
     ctor public WorkSource(android.os.WorkSource);
@@ -38699,6 +38733,25 @@
     field public static final String UNGROUPED_WITH_PHONES = "summ_phones";
   }
 
+  public static final class ContactsContract.SimAccount implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public String getAccountName();
+    method @NonNull public String getAccountType();
+    method public int getEfType();
+    method public int getSimSlotIndex();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int ADN_EF_TYPE = 1; // 0x1
+    field @NonNull public static final android.os.Parcelable.Creator<android.provider.ContactsContract.SimAccount> CREATOR;
+    field public static final int FDN_EF_TYPE = 3; // 0x3
+    field public static final int SDN_EF_TYPE = 2; // 0x2
+    field public static final int UNKNOWN_EF_TYPE = 0; // 0x0
+  }
+
+  public static final class ContactsContract.SimContacts {
+    method @NonNull public static java.util.List<android.provider.ContactsContract.SimAccount> getSimAccounts(@NonNull android.content.ContentResolver);
+    field public static final String ACTION_SIM_ACCOUNTS_CHANGED = "android.provider.action.SIM_ACCOUNTS_CHANGED";
+  }
+
   protected static interface ContactsContract.StatusColumns {
     field public static final int AVAILABLE = 5; // 0x5
     field public static final int AWAY = 2; // 0x2
@@ -42438,6 +42491,7 @@
     method public CharSequence getImportanceExplanation();
     method public String getKey();
     method public long getLastAudiblyAlertedMillis();
+    method public int getLockscreenVisibilityOverride();
     method public String getOverrideGroupKey();
     method public int getRank();
     method @NonNull public java.util.List<android.app.Notification.Action> getSmartActions();
@@ -42451,6 +42505,7 @@
     field public static final int USER_SENTIMENT_NEGATIVE = -1; // 0xffffffff
     field public static final int USER_SENTIMENT_NEUTRAL = 0; // 0x0
     field public static final int USER_SENTIMENT_POSITIVE = 1; // 0x1
+    field public static final int VISIBILITY_NO_OVERRIDE = -1000; // 0xfffffc18
   }
 
   public static class NotificationListenerService.RankingMap implements android.os.Parcelable {
@@ -44838,14 +44893,19 @@
     field public static final String EXTRA_DEFAULT_CALL_SCREENING_APP_COMPONENT_NAME = "android.telecom.extra.DEFAULT_CALL_SCREENING_APP_COMPONENT_NAME";
     field public static final String EXTRA_DISCONNECT_CAUSE = "android.telecom.extra.DISCONNECT_CAUSE";
     field public static final String EXTRA_HANDLE = "android.telecom.extra.HANDLE";
+    field public static final String EXTRA_HAS_PICTURE = "android.telecom.extra.HAS_PICTURE";
     field public static final String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
     field public static final String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
+    field public static final String EXTRA_INCOMING_PICTURE = "android.telecom.extra.INCOMING_PICTURE";
     field public static final String EXTRA_INCOMING_VIDEO_STATE = "android.telecom.extra.INCOMING_VIDEO_STATE";
     field public static final String EXTRA_IS_DEFAULT_CALL_SCREENING_APP = "android.telecom.extra.IS_DEFAULT_CALL_SCREENING_APP";
+    field public static final String EXTRA_LOCATION = "android.telecom.extra.LOCATION";
     field public static final String EXTRA_NOTIFICATION_COUNT = "android.telecom.extra.NOTIFICATION_COUNT";
     field public static final String EXTRA_NOTIFICATION_PHONE_NUMBER = "android.telecom.extra.NOTIFICATION_PHONE_NUMBER";
     field public static final String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
+    field public static final String EXTRA_OUTGOING_PICTURE = "android.telecom.extra.OUTGOING_PICTURE";
     field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
+    field public static final String EXTRA_PRIORITY = "android.telecom.extra.PRIORITY";
     field public static final String EXTRA_START_CALL_WITH_RTT = "android.telecom.extra.START_CALL_WITH_RTT";
     field public static final String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
     field public static final String EXTRA_START_CALL_WITH_VIDEO_STATE = "android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
@@ -44861,6 +44921,8 @@
     field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
     field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
     field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
+    field public static final int PRIORITY_NORMAL = 0; // 0x0
+    field public static final int PRIORITY_URGENT = 1; // 0x1
   }
 
   public class VideoProfile implements android.os.Parcelable {
@@ -46250,6 +46312,12 @@
     field public static final int SCAN_TYPE_PERIODIC = 1; // 0x1
   }
 
+  public final class PhoneCapability implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneCapability> CREATOR;
+  }
+
   public class PhoneNumberFormattingTextWatcher implements android.text.TextWatcher {
     ctor public PhoneNumberFormattingTextWatcher();
     ctor public PhoneNumberFormattingTextWatcher(String);
@@ -46318,10 +46386,10 @@
 
   public class PhoneStateListener {
     ctor public PhoneStateListener();
-    ctor public PhoneStateListener(@NonNull java.util.concurrent.Executor);
+    ctor @Deprecated public PhoneStateListener(@NonNull java.util.concurrent.Executor);
     method public void onActiveDataSubscriptionIdChanged(int);
     method public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo);
-    method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onCallDisconnectCauseChanged(int, int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallDisconnectCauseChanged(int, int);
     method public void onCallForwardingIndicatorChanged(boolean);
     method public void onCallStateChanged(int, String);
     method public void onCellInfoChanged(java.util.List<android.telephony.CellInfo>);
@@ -46329,36 +46397,140 @@
     method public void onDataActivity(int);
     method public void onDataConnectionStateChanged(int);
     method public void onDataConnectionStateChanged(int, int);
-    method @RequiresPermission("android.permission.READ_PHONE_STATE") public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
     method public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
-    method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
     method public void onMessageWaitingIndicatorChanged(boolean);
-    method @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
     method public void onRegistrationFailed(@NonNull android.telephony.CellIdentity, @NonNull String, int, int, int);
     method public void onServiceStateChanged(android.telephony.ServiceState);
     method @Deprecated public void onSignalStrengthChanged(int);
     method public void onSignalStrengthsChanged(android.telephony.SignalStrength);
     method public void onUserMobileDataStateChanged(boolean);
-    field public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_BARRING_INFO = -2147483648; // 0x80000000
-    field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000
-    field public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8
-    field public static final int LISTEN_CALL_STATE = 32; // 0x20
-    field public static final int LISTEN_CELL_INFO = 1024; // 0x400
-    field public static final int LISTEN_CELL_LOCATION = 16; // 0x10
-    field public static final int LISTEN_DATA_ACTIVITY = 128; // 0x80
-    field public static final int LISTEN_DATA_CONNECTION_STATE = 64; // 0x40
-    field public static final int LISTEN_DISPLAY_INFO_CHANGED = 1048576; // 0x100000
-    field public static final int LISTEN_EMERGENCY_NUMBER_LIST = 16777216; // 0x1000000
-    field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 134217728; // 0x8000000
-    field public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4
+    field @Deprecated public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_BARRING_INFO = -2147483648; // 0x80000000
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000
+    field @Deprecated public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8
+    field @Deprecated public static final int LISTEN_CALL_STATE = 32; // 0x20
+    field @Deprecated public static final int LISTEN_CELL_INFO = 1024; // 0x400
+    field @Deprecated public static final int LISTEN_CELL_LOCATION = 16; // 0x10
+    field @Deprecated public static final int LISTEN_DATA_ACTIVITY = 128; // 0x80
+    field @Deprecated public static final int LISTEN_DATA_CONNECTION_STATE = 64; // 0x40
+    field @Deprecated public static final int LISTEN_DISPLAY_INFO_CHANGED = 1048576; // 0x100000
+    field @Deprecated public static final int LISTEN_EMERGENCY_NUMBER_LIST = 16777216; // 0x1000000
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 134217728; // 0x8000000
+    field @Deprecated public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4
     field public static final int LISTEN_NONE = 0; // 0x0
-    field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 1073741824; // 0x40000000
-    field public static final int LISTEN_SERVICE_STATE = 1; // 0x1
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 1073741824; // 0x40000000
+    field @Deprecated public static final int LISTEN_SERVICE_STATE = 1; // 0x1
     field @Deprecated public static final int LISTEN_SIGNAL_STRENGTH = 2; // 0x2
-    field public static final int LISTEN_SIGNAL_STRENGTHS = 256; // 0x100
-    field public static final int LISTEN_USER_MOBILE_DATA_STATE = 524288; // 0x80000
+    field @Deprecated public static final int LISTEN_SIGNAL_STRENGTHS = 256; // 0x100
+    field @Deprecated public static final int LISTEN_USER_MOBILE_DATA_STATE = 524288; // 0x80000
+  }
+
+  public static interface PhoneStateListener.ActiveDataSubscriptionIdChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onActiveDataSubscriptionIdChanged(int);
+  }
+
+  public static interface PhoneStateListener.AlwaysReportedSignalStrengthChangedListener {
+    method @RequiresPermission("android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH") public void onSignalStrengthsChanged(@NonNull android.telephony.SignalStrength);
+  }
+
+  public static interface PhoneStateListener.BarringInfoChangedListener {
+    method @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo);
+  }
+
+  public static interface PhoneStateListener.CallDisconnectCauseChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallDisconnectCauseChanged(int, int);
+  }
+
+  public static interface PhoneStateListener.CallForwardingIndicatorChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onCallForwardingIndicatorChanged(boolean);
+  }
+
+  public static interface PhoneStateListener.CallStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public void onCallStateChanged(int, @Nullable String);
+  }
+
+  public static interface PhoneStateListener.CarrierNetworkChangeListener {
+    method public void onCarrierNetworkChange(boolean);
+  }
+
+  public static interface PhoneStateListener.CellInfoChangedListener {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void onCellInfoChanged(@NonNull java.util.List<android.telephony.CellInfo>);
+  }
+
+  public static interface PhoneStateListener.CellLocationChangedListener {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void onCellLocationChanged(@NonNull android.telephony.CellLocation);
+  }
+
+  public static interface PhoneStateListener.DataActivationStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataActivationStateChanged(int);
+  }
+
+  public static interface PhoneStateListener.DataActivityListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataActivity(int);
+  }
+
+  public static interface PhoneStateListener.DataConnectionStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataConnectionStateChanged(int, int);
+  }
+
+  public static interface PhoneStateListener.DisplayInfoChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo);
+  }
+
+  public static interface PhoneStateListener.EmergencyNumberListChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onEmergencyNumberListChanged(@NonNull java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
+  }
+
+  public static interface PhoneStateListener.ImsCallDisconnectCauseChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo);
+  }
+
+  public static interface PhoneStateListener.MessageWaitingIndicatorChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onMessageWaitingIndicatorChanged(boolean);
+  }
+
+  public static interface PhoneStateListener.PhoneCapabilityChangedListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onPhoneCapabilityChanged(@NonNull android.telephony.PhoneCapability);
+  }
+
+  public static interface PhoneStateListener.PreciseDataConnectionStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
+  }
+
+  public static interface PhoneStateListener.RegistrationFailedListener {
+    method @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void onRegistrationFailed(@NonNull android.telephony.CellIdentity, @NonNull String, int, int, int);
+  }
+
+  public static interface PhoneStateListener.ServiceStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onServiceStateChanged(@NonNull android.telephony.ServiceState);
+  }
+
+  public static interface PhoneStateListener.SignalStrengthsChangedListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onSignalStrengthsChanged(@NonNull android.telephony.SignalStrength);
+  }
+
+  public static interface PhoneStateListener.UserMobileDataStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onUserMobileDataStateChanged(boolean);
+  }
+
+  public final class PhysicalChannelConfig implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getCellBandwidthDownlink();
+    method public int getChannelNumber();
+    method public int getConnectionStatus();
+    method public int getNetworkType();
+    method @IntRange(from=0, to=1007) public int getPhysicalCellId();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int CHANNEL_NUMBER_UNKNOWN = -1; // 0xffffffff
+    field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1
+    field public static final int CONNECTION_SECONDARY_SERVING = 2; // 0x2
+    field public static final int CONNECTION_UNKNOWN = -1; // 0xffffffff
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhysicalChannelConfig> CREATOR;
+    field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff
   }
 
   public final class PreciseDataConnectionState implements android.os.Parcelable {
@@ -46870,7 +47042,8 @@
     method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
     method public boolean isWorldPhone();
     method @Deprecated public void listen(android.telephony.PhoneStateListener, int);
-    method public void listen(long, @NonNull android.telephony.PhoneStateListener);
+    method @Deprecated public void listen(long, @NonNull android.telephony.PhoneStateListener);
+    method public void registerPhoneStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.PhoneStateListener);
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
     method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback);
     method public void sendDialerSpecialCode(String);
@@ -46892,6 +47065,7 @@
     method @Deprecated public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
     method @Deprecated public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void switchMultiSimConfig(int);
+    method public void unregisterPhoneStateListener(@NonNull android.telephony.PhoneStateListener);
     method public void updateAvailableNetworks(@NonNull java.util.List<android.telephony.AvailableNetworkInfo>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
     field public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE = "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE";
     field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "android.telephony.action.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
@@ -47638,6 +47812,7 @@
     field public static final int CODE_WIFI_LOST = 1407; // 0x57f
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsReasonInfo> CREATOR;
     field public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; // 0x3
+    field public static final int EXTRA_CODE_CALL_RETRY_EMERGENCY = 4; // 0x4
     field public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; // 0x1
     field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2
   }
@@ -50871,7 +51046,7 @@
     method public int getFlags();
     method @Nullable public android.net.Uri getLinkUri();
     method public int getSource();
-    method @NonNull public java.util.Map<java.lang.Boolean,android.view.ContentInfo> partition(@NonNull java.util.function.Predicate<android.content.ClipData.Item>);
+    method @NonNull public android.util.Pair<android.view.ContentInfo,android.view.ContentInfo> partition(@NonNull java.util.function.Predicate<android.content.ClipData.Item>);
     field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
     field public static final int SOURCE_APP = 0; // 0x0
     field public static final int SOURCE_AUTOFILL = 4; // 0x4
@@ -51190,6 +51365,7 @@
     method public int getSources();
     method public int getVendorId();
     method public android.os.Vibrator getVibrator();
+    method @NonNull public android.os.VibratorManager getVibratorManager();
     method public boolean[] hasKeys(int...);
     method public boolean hasMicrophone();
     method public boolean isEnabled();
@@ -54589,6 +54765,8 @@
     method public void addAccessibilityStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, @Nullable android.os.Handler);
     method public boolean addTouchExplorationStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
     method public void addTouchExplorationStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener, @Nullable android.os.Handler);
+    method @ColorInt public int getAccessibilityFocusColor();
+    method public int getAccessibilityFocusStrokeWidth();
     method @Deprecated public java.util.List<android.content.pm.ServiceInfo> getAccessibilityServiceList();
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int);
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
@@ -56542,6 +56720,7 @@
     method @Nullable public String getId();
     method public int getSelectionEndIndex();
     method public int getSelectionStartIndex();
+    method @Nullable public android.view.textclassifier.TextClassification getTextClassification();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.view.textclassifier.TextSelection> CREATOR;
   }
@@ -56552,6 +56731,7 @@
     method @NonNull public android.view.textclassifier.TextSelection.Builder setEntityType(@NonNull String, @FloatRange(from=0.0, to=1.0) float);
     method @NonNull public android.view.textclassifier.TextSelection.Builder setExtras(@Nullable android.os.Bundle);
     method @NonNull public android.view.textclassifier.TextSelection.Builder setId(@Nullable String);
+    method @NonNull public android.view.textclassifier.TextSelection.Builder setTextClassification(@Nullable android.view.textclassifier.TextClassification);
   }
 
   public static final class TextSelection.Request implements android.os.Parcelable {
@@ -56562,6 +56742,7 @@
     method @NonNull public android.os.Bundle getExtras();
     method @IntRange(from=0) public int getStartIndex();
     method @NonNull public CharSequence getText();
+    method public boolean shouldIncludeTextClassification();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.view.textclassifier.TextSelection.Request> CREATOR;
   }
@@ -56571,6 +56752,7 @@
     method @NonNull public android.view.textclassifier.TextSelection.Request build();
     method @NonNull public android.view.textclassifier.TextSelection.Request.Builder setDefaultLocales(@Nullable android.os.LocaleList);
     method @NonNull public android.view.textclassifier.TextSelection.Request.Builder setExtras(@Nullable android.os.Bundle);
+    method @NonNull public android.view.textclassifier.TextSelection.Request.Builder setIncludeTextClassification(boolean);
   }
 
 }
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 8eb1b5f..66d29d3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -607,7 +607,10 @@
     method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
     method public void setDontSendToRestrictedApps(boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long);
+    method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(int, long);
     method public android.os.Bundle toBundle();
+    field public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0; // 0x0
+    field public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1; // 0x1
   }
 
   public class DownloadManager {
@@ -878,11 +881,13 @@
     field public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI";
     field public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL";
     field public static final String EXTRA_PROVISIONING_ORGANIZATION_NAME = "android.app.extra.PROVISIONING_ORGANIZATION_NAME";
+    field public static final String EXTRA_PROVISIONING_SUPPORTED_MODES = "android.app.extra.PROVISIONING_SUPPORTED_MODES";
     field public static final String EXTRA_PROVISIONING_SUPPORT_URL = "android.app.extra.PROVISIONING_SUPPORT_URL";
     field public static final String EXTRA_PROVISIONING_TRIGGER = "android.app.extra.PROVISIONING_TRIGGER";
     field public static final String EXTRA_RESTRICTION = "android.app.extra.RESTRICTION";
     field public static final int PROVISIONING_TRIGGER_CLOUD_ENROLLMENT = 1; // 0x1
-    field public static final int PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER = 3; // 0x3
+    field public static final int PROVISIONING_TRIGGER_MANAGED_ACCOUNT = 4; // 0x4
+    field @Deprecated public static final int PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER = 3; // 0x3
     field public static final int PROVISIONING_TRIGGER_QR_CODE = 2; // 0x2
     field public static final int PROVISIONING_TRIGGER_UNSPECIFIED = 0; // 0x0
     field public static final int STATE_USER_PROFILE_COMPLETE = 4; // 0x4
@@ -891,6 +896,9 @@
     field public static final int STATE_USER_SETUP_FINALIZED = 3; // 0x3
     field public static final int STATE_USER_SETUP_INCOMPLETE = 1; // 0x1
     field public static final int STATE_USER_UNMANAGED = 0; // 0x0
+    field public static final int SUPPORTED_MODES_ORGANIZATION_AND_PERSONALLY_OWNED = 3; // 0x3
+    field public static final int SUPPORTED_MODES_ORGANIZATION_OWNED = 1; // 0x1
+    field public static final int SUPPORTED_MODES_PERSONALLY_OWNED = 2; // 0x2
   }
 
   public final class SystemUpdatePolicy implements android.os.Parcelable {
@@ -4111,6 +4119,22 @@
     method @Deprecated public void onStatusChanged(int);
   }
 
+  public final class LastLocationRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public boolean isHiddenFromAppOps();
+    method public boolean isLocationSettingsIgnored();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.location.LastLocationRequest> CREATOR;
+  }
+
+  public static final class LastLocationRequest.Builder {
+    ctor public LastLocationRequest.Builder();
+    ctor public LastLocationRequest.Builder(@NonNull android.location.LastLocationRequest);
+    method @NonNull public android.location.LastLocationRequest build();
+    method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_APP_OPS_STATS) public android.location.LastLocationRequest.Builder setHiddenFromAppOps(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LastLocationRequest.Builder setLocationSettingsIgnored(boolean);
+  }
+
   public class Location implements android.os.Parcelable {
     method public boolean isComplete();
     method public void makeComplete();
@@ -4123,6 +4147,7 @@
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void getCurrentLocation(@NonNull android.location.LocationRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.location.Location>);
     method @Nullable public String getExtraLocationControllerPackage();
     method @Deprecated public int getGnssBatchSize();
+    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.location.Location getLastKnownLocation(@NonNull String, @NonNull android.location.LastLocationRequest);
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void injectGnssMeasurementCorrections(@NonNull android.location.GnssMeasurementCorrections);
     method public boolean isExtraLocationControllerPackageEnabled();
     method public boolean isLocationEnabledForUser(@NonNull android.os.UserHandle);
@@ -4345,6 +4370,7 @@
     field public static final int PLAYER_STATE_STARTED = 2; // 0x2
     field public static final int PLAYER_STATE_STOPPED = 4; // 0x4
     field public static final int PLAYER_STATE_UNKNOWN = -1; // 0xffffffff
+    field public static final int PLAYER_TYPE_AAUDIO = 13; // 0xd
     field public static final int PLAYER_TYPE_JAM_AUDIOTRACK = 1; // 0x1
     field public static final int PLAYER_TYPE_JAM_MEDIAPLAYER = 2; // 0x2
     field public static final int PLAYER_TYPE_JAM_SOUNDPOOL = 3; // 0x3
@@ -4991,6 +5017,7 @@
   public class Descrambler implements java.lang.AutoCloseable {
     method public int addPid(int, int, @Nullable android.media.tv.tuner.filter.Filter);
     method public void close();
+    method public static boolean isValidKeyToken(@NonNull byte[]);
     method public int removePid(int, int, @Nullable android.media.tv.tuner.filter.Filter);
     method public int setKeyToken(@NonNull byte[]);
     field public static final int PID_TYPE_MMTP = 2; // 0x2
@@ -5065,7 +5092,6 @@
     field public static final int INVALID_FIRST_MACROBLOCK_IN_SLICE = -1; // 0xffffffff
     field public static final int INVALID_FRONTEND_ID = -1; // 0xffffffff
     field public static final int INVALID_FRONTEND_SETTING_FREQUENCY = -1; // 0xffffffff
-    field @NonNull public static final byte[] INVALID_KEYTOKEN;
     field public static final int INVALID_LTS_ID = -1; // 0xffffffff
     field public static final int INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = -1; // 0xffffffff
     field public static final int INVALID_STREAM_ID = 65535; // 0xffff
@@ -5081,6 +5107,7 @@
     field public static final int SCAN_TYPE_AUTO = 1; // 0x1
     field public static final int SCAN_TYPE_BLIND = 2; // 0x2
     field public static final int SCAN_TYPE_UNDEFINED = 0; // 0x0
+    field @NonNull public static final byte[] VOID_KEYTOKEN;
   }
 
   public static interface Tuner.OnResourceLostListener {
@@ -5885,8 +5912,8 @@
 
   public class DvbsFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
     method @NonNull public static android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder builder();
+    method public boolean canHandleDiseqcRxMessage();
     method @Nullable public android.media.tv.tuner.frontend.DvbsCodeRate getCodeRate();
-    method public boolean getCouldHandleDiseqcRxMessage();
     method public int getInputStreamId();
     method public int getModulation();
     method public int getPilot();
@@ -5938,8 +5965,8 @@
 
   public static class DvbsFrontendSettings.Builder {
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings build();
+    method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setCanHandleDiseqcRxMessage(boolean);
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setCodeRate(@Nullable android.media.tv.tuner.frontend.DvbsCodeRate);
-    method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setCouldHandleDiseqcRxMessage(boolean);
     method @IntRange(from=1) @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setFrequency(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setInputStreamId(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbsFrontendSettings.Builder setModulation(int);
@@ -7813,7 +7840,7 @@
     method @Nullable public <T extends android.os.Parcelable> T getParcelable(@NonNull Class<T>);
     method public int getStability();
     method public void readFromParcel(@NonNull android.os.Parcel);
-    method public boolean setParcelable(@Nullable android.os.Parcelable);
+    method public void setParcelable(@Nullable android.os.Parcelable);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.os.ParcelableHolder> CREATOR;
   }
@@ -8383,6 +8410,11 @@
     field @Deprecated public static final String STATE = "state";
   }
 
+  public static final class ContactsContract.SimContacts {
+    method @RequiresPermission("android.contacts.permission.MANAGE_SIM_ACCOUNTS") public static void addSimAccount(@NonNull android.content.ContentResolver, @NonNull String, @NonNull String, int, int);
+    method @RequiresPermission("android.contacts.permission.MANAGE_SIM_ACCOUNTS") public static void removeSimAccounts(@NonNull android.content.ContentResolver, int);
+  }
+
   public final class DeviceConfig {
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener);
     method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static boolean getBoolean(@NonNull String, @NonNull String, boolean);
@@ -8401,6 +8433,7 @@
     field public static final String NAMESPACE_APP_COMPAT = "app_compat";
     field public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service";
     field public static final String NAMESPACE_AUTOFILL = "autofill";
+    field public static final String NAMESPACE_BATTERY_SAVER = "battery_saver";
     field public static final String NAMESPACE_BIOMETRICS = "biometrics";
     field public static final String NAMESPACE_BLOBSTORE = "blobstore";
     field public static final String NAMESPACE_BLUETOOTH = "bluetooth";
@@ -9088,6 +9121,26 @@
     method @NonNull @WorkerThread public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
   }
 
+  public final class CarrierMessagingServiceWrapper {
+    ctor public CarrierMessagingServiceWrapper();
+    method public boolean bindToCarrierMessagingService(@NonNull android.content.Context, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull Runnable);
+    method public void disposeConnection(@NonNull android.content.Context);
+    method public void downloadMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void receiveSms(@NonNull android.service.carrier.MessagePdu, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void sendDataSms(@NonNull byte[], int, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void sendMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void sendMultipartTextSms(@NonNull java.util.List<java.lang.String>, int, @NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void sendTextSms(@NonNull String, int, @NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+  }
+
+  public static interface CarrierMessagingServiceWrapper.CarrierMessagingCallback {
+    method public default void onDownloadMmsComplete(int);
+    method public default void onReceiveSmsComplete(int);
+    method public default void onSendMmsComplete(int, @Nullable byte[]);
+    method public default void onSendMultipartSmsComplete(int, @Nullable int[]);
+    method public default void onSendSmsComplete(int, int);
+  }
+
 }
 
 package android.service.contentcapture {
@@ -10402,35 +10455,87 @@
     method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
     method @Deprecated public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
     method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int);
-    method public void onPhysicalChannelConfigurationChanged(@NonNull java.util.List<android.telephony.PhysicalChannelConfig>);
-    method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
     method public void onRadioPowerStateChanged(int);
     method public void onSrvccStateChanged(int);
     method public void onVoiceActivationStateChanged(int);
-    field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
-    field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
-    field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
-    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final long LISTEN_PHYSICAL_CHANNEL_CONFIGURATION = 4294967296L; // 0x100000000L
-    field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
-    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
-    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
-    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
+    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23; // 0x17
+    field @RequiresPermission("android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH") public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10; // 0xa
+    field @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static final int EVENT_BARRING_INFO_CHANGED = 32; // 0x20
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27; // 0x1b
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26; // 0x1a
+    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4; // 0x4
+    field @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public static final int EVENT_CALL_STATE_CHANGED = 6; // 0x6
+    field public static final int EVENT_CARRIER_NETWORK_CHANGED = 17; // 0x11
+    field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_INFO_CHANGED = 11; // 0xb
+    field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_LOCATION_CHANGED = 5; // 0x5
+    field public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19; // 0x13
+    field public static final int EVENT_DATA_ACTIVITY_CHANGED = 8; // 0x8
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14; // 0xe
+    field public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7; // 0x7
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_DATA_ENABLED_CHANGED = 34; // 0x22
+    field public static final int EVENT_DISPLAY_INFO_CHANGED = 21; // 0x15
+    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; // 0x19
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; // 0x1c
+    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3; // 0x3
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_OEM_HOOK_RAW = 15; // 0xf
+    field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29; // 0x1d
+    field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30; // 0x1e
+    field public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22; // 0x16
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33; // 0x21
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12; // 0xc
+    field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13; // 0xd
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24; // 0x18
+    field @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static final int EVENT_REGISTRATION_FAILURE = 31; // 0x1f
+    field public static final int EVENT_SERVICE_STATE_CHANGED = 1; // 0x1
+    field public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9; // 0x9
+    field public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2; // 0x2
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_SRVCC_STATE_CHANGED = 16; // 0x10
+    field public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20; // 0x14
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18; // 0x12
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
+    field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
   }
 
-  public final class PhysicalChannelConfig implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getCellBandwidthDownlink();
-    method public int getChannelNumber();
-    method public int getConnectionStatus();
-    method public int getNetworkType();
-    method @IntRange(from=0, to=1007) public int getPhysicalCellId();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field public static final int CHANNEL_NUMBER_UNKNOWN = -1; // 0xffffffff
-    field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1
-    field public static final int CONNECTION_SECONDARY_SERVING = 2; // 0x2
-    field public static final int CONNECTION_UNKNOWN = -1; // 0xffffffff
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhysicalChannelConfig> CREATOR;
-    field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff
+  public static interface PhoneStateListener.CallAttributesChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes);
+  }
+
+  public static interface PhoneStateListener.DataEnabledChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onDataEnabledChanged(boolean, int);
+  }
+
+  public static interface PhoneStateListener.OutgoingEmergencyCallListener {
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int);
+  }
+
+  public static interface PhoneStateListener.OutgoingEmergencySmsListener {
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int);
+  }
+
+  public static interface PhoneStateListener.PhysicalChannelConfigChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPhysicalChannelConfigChanged(@NonNull java.util.List<android.telephony.PhysicalChannelConfig>);
+  }
+
+  public static interface PhoneStateListener.PreciseCallStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
+  }
+
+  public static interface PhoneStateListener.RadioPowerStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onRadioPowerStateChanged(int);
+  }
+
+  public static interface PhoneStateListener.SrvccStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onSrvccStateChanged(int);
+  }
+
+  public static interface PhoneStateListener.VoiceActivationStateChangedListener {
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onVoiceActivationStateChanged(int);
   }
 
   public final class PinResult implements android.os.Parcelable {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 51edd03..ffb31c9 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -272,6 +272,7 @@
     method public void allowAssistantAdjustment(String);
     method public void disallowAssistantAdjustment(String);
     method public android.content.ComponentName getEffectsSuppressor();
+    method public boolean isNotificationPolicyAccessGrantedForPackage(@NonNull String);
     method public boolean matchesCallFilter(android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) public void setNotificationListenerAccessGranted(@NonNull android.content.ComponentName, boolean, boolean);
     method public void updateNotificationChannel(@NonNull String, int, @NonNull android.app.NotificationChannel);
@@ -372,8 +373,15 @@
     method public java.util.List<java.lang.String> getOwnerInstalledCaCerts(@NonNull android.os.UserHandle);
     method public boolean isCurrentInputMethodSetByOwner();
     method public boolean isFactoryResetProtectionPolicySupported();
+    method @NonNull public static String operationToString(int);
+    method @RequiresPermission("android.permission.MANAGE_DEVICE_ADMINS") public void setNextOperationSafety(int, boolean);
     field public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED = "android.app.action.DATA_SHARING_RESTRICTION_APPLIED";
+    field public static final int OPERATION_CREATE_AND_MANAGE_USER = 5; // 0x5
     field public static final int OPERATION_LOCK_NOW = 1; // 0x1
+    field public static final int OPERATION_REMOVE_USER = 6; // 0x6
+    field public static final int OPERATION_START_USER_IN_BACKGROUND = 3; // 0x3
+    field public static final int OPERATION_STOP_USER = 4; // 0x4
+    field public static final int OPERATION_SWITCH_USER = 2; // 0x2
   }
 
   public static final class SecurityLog.SecurityEvent implements android.os.Parcelable {
@@ -987,9 +995,9 @@
   }
 
   public class AudioSystem {
-    method public static float getMasterBalance();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS) public static float getMasterBalance();
     method public static final int getNumStreamTypes();
-    method public static int setMasterBalance(float);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS) public static int setMasterBalance(float);
     field public static final int DEVICE_ROLE_DISABLED = 2; // 0x2
     field public static final int DEVICE_ROLE_NONE = 0; // 0x0
     field public static final int DEVICE_ROLE_PREFERRED = 1; // 0x1
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 0ad9e44..8e50184 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -18,6 +18,7 @@
 
 import android.accessibilityservice.GestureDescription.MotionEventGenerator;
 import android.annotation.CallbackExecutor;
+import android.annotation.ColorInt;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -2118,6 +2119,27 @@
     }
 
     /**
+     * Sets the strokeWidth and color of the accessibility focus rectangle.
+     *
+     * @param strokeWidth The stroke width of the rectangle in pixels.
+     *                    Setting this value to zero results in no focus rectangle being drawn.
+     * @param color The color of the rectangle.
+     */
+    public void setAccessibilityFocusAppearance(int strokeWidth, @ColorInt int color) {
+        IAccessibilityServiceConnection connection =
+                AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+        if (connection != null) {
+            try {
+                connection.setFocusAppearance(strokeWidth, color);
+            } catch (RemoteException re) {
+                Log.w(LOG_TAG, "Error while setting the strokeWidth and color of the "
+                        + "accessibility focus rectangle", re);
+                re.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
      * Implement to return the implementation of the internal accessibility
      * service interface.
      */
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 0b3b9b2..ab21dc9 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -115,4 +115,6 @@
     void setGestureDetectionPassthroughRegion(int displayId, in Region region);
 
     void setTouchExplorationPassthroughRegion(int displayId, in Region region);
+
+    void setFocusAppearance(int strokeWidth, int color);
 }
diff --git a/core/java/android/animation/OWNERS b/core/java/android/animation/OWNERS
new file mode 100644
index 0000000..822a35c
--- /dev/null
+++ b/core/java/android/animation/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 47085
+
+romainguy@google.com
+tianliu@google.com
+alanv@google.com
+adamp@google.com
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 5ee5597..f92768a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -963,8 +963,8 @@
          * @hide
          */
         @Override
-        public void toggleFreeformWindowingMode() throws RemoteException {
-            ActivityTaskManager.getService().toggleFreeformWindowingMode(mToken);
+        public void toggleFreeformWindowingMode() {
+            ActivityClient.getInstance().toggleFreeformWindowingMode(mToken);
         }
 
         /**
@@ -981,11 +981,8 @@
 
         @Override
         public boolean isTaskRoot() {
-            try {
-                return ActivityTaskManager.getService().getTaskForActivity(mToken, true) >= 0;
-            } catch (RemoteException e) {
-                return false;
-            }
+            return ActivityClient.getInstance().getTaskForActivity(
+                    mToken, true /* onlyRoot */) >= 0;
         }
 
         /**
@@ -2052,12 +2049,8 @@
      * {@link #isVoiceInteractionRoot()} return {@code false} in this case.
      */
     public boolean isVoiceInteractionRoot() {
-        try {
-            return mVoiceInteractor != null
-                    && ActivityTaskManager.getService().isRootVoiceInteraction(mToken);
-        } catch (RemoteException e) {
-        }
-        return false;
+        return mVoiceInteractor != null
+                && ActivityClient.getInstance().isRootVoiceInteraction(mToken);
     }
 
     /**
@@ -2090,10 +2083,7 @@
      * @param privateOptions a Bundle of private arguments to the current voice interaction service
      */
     public void startLocalVoiceInteraction(Bundle privateOptions) {
-        try {
-            ActivityTaskManager.getService().startLocalVoiceInteraction(mToken, privateOptions);
-        } catch (RemoteException re) {
-        }
+        ActivityClient.getInstance().startLocalVoiceInteraction(mToken, privateOptions);
     }
 
     /**
@@ -2119,10 +2109,7 @@
      * terminated, {@link #onLocalVoiceInteractionStopped()} will be called.
      */
     public void stopLocalVoiceInteraction() {
-        try {
-            ActivityTaskManager.getService().stopLocalVoiceInteraction(mToken);
-        } catch (RemoteException re) {
-        }
+        ActivityClient.getInstance().stopLocalVoiceInteraction(mToken);
     }
 
     /**
@@ -2564,11 +2551,7 @@
      * false will be returned if the caller is not the current top activity.
      */
     public boolean showAssist(Bundle args) {
-        try {
-            return ActivityTaskManager.getService().showAssistFromActivity(mToken, args);
-        } catch (RemoteException e) {
-        }
-        return false;
+        return ActivityClient.getInstance().showAssistFromActivity(mToken, args);
     }
 
     /**
@@ -2708,10 +2691,9 @@
             }
             mDoReportFullyDrawn = false;
             try {
-                ActivityTaskManager.getService().reportActivityFullyDrawn(
+                ActivityClient.getInstance().reportActivityFullyDrawn(
                         mToken, mRestoredFromBundle);
                 VMRuntime.getRuntime().notifyStartupCompleted();
-            } catch (RemoteException e) {
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
             }
@@ -2841,27 +2823,23 @@
      * does not support picture-in-picture, return false.
      */
     public boolean enterPictureInPictureMode(@NonNull PictureInPictureParams params) {
-        try {
-            if (!deviceSupportsPictureInPictureMode()) {
-                return false;
-            }
-            if (params == null) {
-                throw new IllegalArgumentException("Expected non-null picture-in-picture params");
-            }
-            if (!mCanEnterPictureInPicture) {
-                throw new IllegalStateException("Activity must be resumed to enter"
-                        + " picture-in-picture");
-            }
-            // Set mIsInPictureInPictureMode earlier and don't wait for
-            // onPictureInPictureModeChanged callback here. This is to ensure that
-            // isInPictureInPictureMode returns true in the following onPause callback.
-            // See https://developer.android.com/guide/topics/ui/picture-in-picture for guidance.
-            mIsInPictureInPictureMode = ActivityTaskManager.getService().enterPictureInPictureMode(
-                    mToken, params);
-            return mIsInPictureInPictureMode;
-        } catch (RemoteException e) {
+        if (!deviceSupportsPictureInPictureMode()) {
             return false;
         }
+        if (params == null) {
+            throw new IllegalArgumentException("Expected non-null picture-in-picture params");
+        }
+        if (!mCanEnterPictureInPicture) {
+            throw new IllegalStateException("Activity must be resumed to enter"
+                    + " picture-in-picture");
+        }
+        // Set mIsInPictureInPictureMode earlier and don't wait for
+        // onPictureInPictureModeChanged callback here. This is to ensure that
+        // isInPictureInPictureMode returns true in the following onPause callback.
+        // See https://developer.android.com/guide/topics/ui/picture-in-picture for guidance.
+        mIsInPictureInPictureMode = ActivityClient.getInstance().enterPictureInPictureMode(
+                mToken, params);
+        return mIsInPictureInPictureMode;
     }
 
     /**
@@ -2871,16 +2849,13 @@
      * @param params the new parameters for the picture-in-picture.
      */
     public void setPictureInPictureParams(@NonNull PictureInPictureParams params) {
-        try {
-            if (!deviceSupportsPictureInPictureMode()) {
-                return;
-            }
-            if (params == null) {
-                throw new IllegalArgumentException("Expected non-null picture-in-picture params");
-            }
-            ActivityTaskManager.getService().setPictureInPictureParams(mToken, params);
-        } catch (RemoteException e) {
+        if (!deviceSupportsPictureInPictureMode()) {
+            return;
         }
+        if (params == null) {
+            throw new IllegalArgumentException("Expected non-null picture-in-picture params");
+        }
+        ActivityClient.getInstance().setPictureInPictureParams(mToken, params);
     }
 
     /**
@@ -3822,14 +3797,10 @@
             finishAfterTransition();
             return;
         }
-        try {
-            // Inform activity task manager that the activity received a back press
-            // while at the root of the task. This call allows ActivityTaskManager
-            // to intercept or move the task to the back.
-            ActivityTaskManager.getService().onBackPressedOnTaskRoot(mToken);
-        } catch (RemoteException e) {
-            finishAfterTransition();
-        }
+        // Inform activity task manager that the activity received a back press while at the
+        // root of the task. This call allows ActivityTaskManager to intercept or move the task
+        // to the back.
+        ActivityClient.getInstance().onBackPressedOnTaskRoot(mToken);
 
         // Activity was launched when user tapped a link in the Autofill Save UI - Save UI must
         // be restored now.
@@ -6114,11 +6085,8 @@
      * the outgoing activity.  Use 0 for no animation.
      */
     public void overridePendingTransition(int enterAnim, int exitAnim) {
-        try {
-            ActivityTaskManager.getService().overridePendingTransition(
-                    mToken, getPackageName(), enterAnim, exitAnim);
-        } catch (RemoteException e) {
-        }
+        ActivityClient.getInstance().overridePendingTransition(mToken, getPackageName(),
+                enterAnim, exitAnim);
     }
 
     /**
@@ -6239,11 +6207,7 @@
      */
     @Nullable
     public String getCallingPackage() {
-        try {
-            return ActivityTaskManager.getService().getCallingPackage(mToken);
-        } catch (RemoteException e) {
-            return null;
-        }
+        return ActivityClient.getInstance().getCallingPackage(mToken);
     }
 
     /**
@@ -6262,11 +6226,7 @@
      */
     @Nullable
     public ComponentName getCallingActivity() {
-        try {
-            return ActivityTaskManager.getService().getCallingActivity(mToken);
-        } catch (RemoteException e) {
-            return null;
-        }
+        return ActivityClient.getInstance().getCallingActivity(mToken);
     }
 
     /**
@@ -6364,16 +6324,12 @@
                 resultData = mResultData;
             }
             if (false) Log.v(TAG, "Finishing self: token=" + mToken);
-            try {
-                if (resultData != null) {
-                    resultData.prepareToLeaveProcess(this);
-                }
-                if (ActivityTaskManager.getService()
-                        .finishActivity(mToken, resultCode, resultData, finishTask)) {
-                    mFinished = true;
-                }
-            } catch (RemoteException e) {
-                // Empty
+            if (resultData != null) {
+                resultData.prepareToLeaveProcess(this);
+            }
+            if (ActivityClient.getInstance().finishActivity(mToken, resultCode, resultData,
+                    finishTask)) {
+                mFinished = true;
             }
         } else {
             mParent.finishFromChild(this);
@@ -6429,12 +6385,8 @@
         if (mResultCode != RESULT_CANCELED || mResultData != null) {
             throw new IllegalStateException("Can not be called to deliver a result");
         }
-        try {
-            if (ActivityTaskManager.getService().finishActivityAffinity(mToken)) {
-                mFinished = true;
-            }
-        } catch (RemoteException e) {
-            // Empty
+        if (ActivityClient.getInstance().finishActivityAffinity(mToken)) {
+            mFinished = true;
         }
     }
 
@@ -6477,12 +6429,7 @@
      */
     public void finishActivity(int requestCode) {
         if (mParent == null) {
-            try {
-                ActivityTaskManager.getService()
-                    .finishSubActivity(mToken, mEmbeddedID, requestCode);
-            } catch (RemoteException e) {
-                // Empty
-            }
+            ActivityClient.getInstance().finishSubActivity(mToken, mEmbeddedID, requestCode);
         } else {
             mParent.finishActivityFromChild(this, requestCode);
         }
@@ -6499,12 +6446,7 @@
      */
     @Deprecated
     public void finishActivityFromChild(@NonNull Activity child, int requestCode) {
-        try {
-            ActivityTaskManager.getService()
-                .finishSubActivity(mToken, child.mEmbeddedID, requestCode);
-        } catch (RemoteException e) {
-            // Empty
-        }
+        ActivityClient.getInstance().finishSubActivity(mToken, child.mEmbeddedID, requestCode);
     }
 
     /**
@@ -6527,12 +6469,7 @@
      * being finished, it hasn't yet saved its state, etc.
      */
     public boolean releaseInstance() {
-        try {
-            return ActivityTaskManager.getService().releaseActivityInstance(mToken);
-        } catch (RemoteException e) {
-            // Empty
-        }
-        return false;
+        return ActivityClient.getInstance().releaseActivityInstance(mToken);
     }
 
     /**
@@ -6644,12 +6581,7 @@
      */
     public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
         if (mParent == null) {
-            try {
-                ActivityTaskManager.getService().setRequestedOrientation(
-                        mToken, requestedOrientation);
-            } catch (RemoteException e) {
-                // Empty
-            }
+            ActivityClient.getInstance().setRequestedOrientation(mToken, requestedOrientation);
         } else {
             mParent.setRequestedOrientation(requestedOrientation);
         }
@@ -6667,16 +6599,10 @@
     @ActivityInfo.ScreenOrientation
     public int getRequestedOrientation() {
         if (mParent == null) {
-            try {
-                return ActivityTaskManager.getService()
-                        .getRequestedOrientation(mToken);
-            } catch (RemoteException e) {
-                // Empty
-            }
+            return ActivityClient.getInstance().getRequestedOrientation(mToken);
         } else {
             return mParent.getRequestedOrientation();
         }
-        return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     }
 
     /**
@@ -6686,11 +6612,7 @@
      * @return Task identifier, an opaque integer.
      */
     public int getTaskId() {
-        try {
-            return ActivityTaskManager.getService().getTaskForActivity(mToken, false);
-        } catch (RemoteException e) {
-            return -1;
-        }
+        return ActivityClient.getInstance().getTaskForActivity(mToken, false /* onlyRoot */);
     }
 
     /**
@@ -6715,12 +6637,7 @@
      *         back) true is returned, else false.
      */
     public boolean moveTaskToBack(boolean nonRoot) {
-        try {
-            return ActivityTaskManager.getService().moveActivityTaskToBack(mToken, nonRoot);
-        } catch (RemoteException e) {
-            // Empty
-        }
-        return false;
+        return ActivityClient.getInstance().moveActivityTaskToBack(mToken, nonRoot);
     }
 
     /**
@@ -6896,10 +6813,7 @@
                 mTaskDescription.setIcon(Icon.createWithBitmap(icon));
             }
         }
-        try {
-            ActivityTaskManager.getService().setTaskDescription(mToken, mTaskDescription);
-        } catch (RemoteException e) {
-        }
+        ActivityClient.getInstance().setTaskDescription(mToken, mTaskDescription);
     }
 
     /**
@@ -7210,11 +7124,7 @@
      * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE
      */
     public boolean isImmersive() {
-        try {
-            return ActivityTaskManager.getService().isImmersive(mToken);
-        } catch (RemoteException e) {
-            return false;
-        }
+        return ActivityClient.getInstance().isImmersive(mToken);
     }
 
     /**
@@ -7228,11 +7138,7 @@
         if (mToken == null || mWindow == null) {
             return false;
         }
-        try {
-            return ActivityTaskManager.getService().isTopOfTask(getActivityToken());
-        } catch (RemoteException e) {
-            return false;
-        }
+        return ActivityClient.getInstance().isTopOfTask(getActivityToken());
     }
 
     /**
@@ -7271,14 +7177,10 @@
     }
 
     private boolean convertFromTranslucentInternal() {
-        try {
-            mTranslucentCallback = null;
-            if (ActivityTaskManager.getService().convertFromTranslucent(mToken)) {
-                WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true);
-                return true;
-            }
-        } catch (RemoteException e) {
-            // pass
+        mTranslucentCallback = null;
+        if (ActivityClient.getInstance().convertFromTranslucent(mToken)) {
+            WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true /* opaque */);
+            return true;
         }
         return false;
     }
@@ -7307,21 +7209,14 @@
     @SystemApi
     public boolean convertToTranslucent(TranslucentConversionListener callback,
             ActivityOptions options) {
-        boolean drawComplete;
-        try {
-            mTranslucentCallback = callback;
-            mChangeCanvasToTranslucent = ActivityTaskManager.getService().convertToTranslucent(
-                    mToken, options == null ? null : options.toBundle());
-            WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
-            drawComplete = true;
-        } catch (RemoteException e) {
-            // Make callback return as though it timed out.
-            mChangeCanvasToTranslucent = false;
-            drawComplete = false;
-        }
+        mTranslucentCallback = callback;
+        mChangeCanvasToTranslucent = ActivityClient.getInstance().convertToTranslucent(
+                mToken, options == null ? null : options.toBundle());
+        WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
+
         if (!mChangeCanvasToTranslucent && mTranslucentCallback != null) {
             // Window is already translucent.
-            mTranslucentCallback.onTranslucentConversionComplete(drawComplete);
+            mTranslucentCallback.onTranslucentConversionComplete(true /* drawComplete */);
         }
         return mChangeCanvasToTranslucent;
     }
@@ -7355,12 +7250,7 @@
      */
     @UnsupportedAppUsage
     ActivityOptions getActivityOptions() {
-        try {
-            return ActivityOptions.fromBundle(
-                    ActivityTaskManager.getService().getActivityOptions(mToken));
-        } catch (RemoteException e) {
-        }
-        return null;
+        return ActivityOptions.fromBundle(ActivityClient.getInstance().getActivityOptions(mToken));
     }
 
     /**
@@ -7504,11 +7394,7 @@
      * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE
      */
     public void setImmersive(boolean i) {
-        try {
-            ActivityTaskManager.getService().setImmersive(mToken, i);
-        } catch (RemoteException e) {
-            // pass
-        }
+        ActivityClient.getInstance().setImmersive(mToken, i);
     }
 
     /**
@@ -7567,14 +7453,8 @@
      */
     public void setVrModeEnabled(boolean enabled, @NonNull ComponentName requestedComponent)
           throws PackageManager.NameNotFoundException {
-        try {
-            if (ActivityTaskManager.getService().setVrMode(mToken, enabled, requestedComponent)
-                    != 0) {
-                throw new PackageManager.NameNotFoundException(
-                        requestedComponent.flattenToString());
-            }
-        } catch (RemoteException e) {
-            // pass
+        if (ActivityClient.getInstance().setVrMode(mToken, enabled, requestedComponent) != 0) {
+            throw new PackageManager.NameNotFoundException(requestedComponent.flattenToString());
         }
     }
 
@@ -7689,9 +7569,7 @@
             if (info.taskAffinity == null) {
                 return false;
             }
-            return ActivityTaskManager.getService().shouldUpRecreateTask(mToken, info.taskAffinity);
-        } catch (RemoteException e) {
-            return false;
+            return ActivityClient.getInstance().shouldUpRecreateTask(mToken, info.taskAffinity);
         } catch (NameNotFoundException e) {
             return false;
         }
@@ -7739,13 +7617,9 @@
             if (resultData != null) {
                 resultData.prepareToLeaveProcess(this);
             }
-            try {
-                upIntent.prepareToLeaveProcess(this);
-                return ActivityTaskManager.getService().navigateUpTo(mToken, upIntent,
-                        resultCode, resultData);
-            } catch (RemoteException e) {
-                return false;
-            }
+            upIntent.prepareToLeaveProcess(this);
+            return ActivityClient.getInstance().navigateUpTo(mToken, upIntent, resultCode,
+                    resultData);
         } else {
             return mParent.navigateUpToFromChild(this, upIntent);
         }
@@ -8361,10 +8235,7 @@
      * @see android.R.attr#lockTaskMode
      */
     public void startLockTask() {
-        try {
-            ActivityTaskManager.getService().startLockTaskModeByToken(mToken);
-        } catch (RemoteException e) {
-        }
+        ActivityClient.getInstance().startLockTaskModeByToken(mToken);
     }
 
     /**
@@ -8384,10 +8255,7 @@
      * @see ActivityManager#getLockTaskModeState()
      */
     public void stopLockTask() {
-        try {
-            ActivityTaskManager.getService().stopLockTaskModeByToken(mToken);
-        } catch (RemoteException e) {
-        }
+        ActivityClient.getInstance().stopLockTaskModeByToken(mToken);
     }
 
     /**
@@ -8396,10 +8264,7 @@
      * of this call for the message to be displayed.
      */
     public void showLockTaskEscapeMessage() {
-        try {
-            ActivityTaskManager.getService().showLockTaskEscapeMessage(mToken);
-        } catch (RemoteException e) {
-        }
+        ActivityClient.getInstance().showLockTaskEscapeMessage(mToken);
     }
 
     /**
@@ -8667,11 +8532,7 @@
      */
     @UnsupportedAppUsage
     public void setDisablePreviewScreenshots(boolean disable) {
-        try {
-            ActivityTaskManager.getService().setDisablePreviewScreenshots(mToken, disable);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        ActivityClient.getInstance().setDisablePreviewScreenshots(mToken, disable);
     }
 
     /**
@@ -8688,11 +8549,7 @@
      * @see android.R.attr#showWhenLocked
      */
     public void setShowWhenLocked(boolean showWhenLocked) {
-        try {
-            ActivityTaskManager.getService().setShowWhenLocked(mToken, showWhenLocked);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        ActivityClient.getInstance().setShowWhenLocked(mToken, showWhenLocked);
     }
 
     /**
@@ -8711,12 +8568,7 @@
      * @see android.R.attr#inheritShowWhenLocked
      */
     public void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
-        try {
-            ActivityTaskManager.getService().setInheritShowWhenLocked(
-                    mToken, inheritShowWhenLocked);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        ActivityClient.getInstance().setInheritShowWhenLocked(mToken, inheritShowWhenLocked);
     }
 
     /**
@@ -8741,11 +8593,7 @@
      * @see KeyguardManager#isDeviceSecure()
      */
     public void setTurnScreenOn(boolean turnScreenOn) {
-        try {
-            ActivityTaskManager.getService().setTurnScreenOn(mToken, turnScreenOn);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        ActivityClient.getInstance().setTurnScreenOn(mToken, turnScreenOn);
     }
 
     /**
@@ -8757,11 +8605,7 @@
      */
     @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS)
     public void registerRemoteAnimations(RemoteAnimationDefinition definition) {
-        try {
-            ActivityTaskManager.getService().registerRemoteAnimations(mToken, definition);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        ActivityClient.getInstance().registerRemoteAnimations(mToken, definition);
     }
 
     /**
@@ -8771,11 +8615,7 @@
      */
     @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS)
     public void unregisterRemoteAnimations() {
-        try {
-            ActivityTaskManager.getService().unregisterRemoteAnimations(mToken);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        ActivityClient.getInstance().unregisterRemoteAnimations(mToken);
     }
 
     class HostCallbacks extends FragmentHostCallback<Activity> {
diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java
new file mode 100644
index 0000000..84ecd24
--- /dev/null
+++ b/core/java/android/app/ActivityClient.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2020 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.app;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.util.Singleton;
+import android.view.RemoteAnimationDefinition;
+
+/**
+ * Provides the activity associated operations that communicate with system.
+ *
+ * @hide
+ */
+public class ActivityClient {
+    private ActivityClient() {}
+
+    /** Reports the main thread is idle after the activity is resumed. */
+    public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
+        try {
+            getActivityClientController().activityIdle(token, config, stopProfiling);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Reports {@link Activity#onResume()} is done. */
+    public void activityResumed(IBinder token) {
+        try {
+            getActivityClientController().activityResumed(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Reports after {@link Activity#onTopResumedActivityChanged(boolean)} is called for losing the
+     * top most position.
+     */
+    public void activityTopResumedStateLost() {
+        try {
+            getActivityClientController().activityTopResumedStateLost();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Reports {@link Activity#onPause()} is done. */
+    public void activityPaused(IBinder token) {
+        try {
+            getActivityClientController().activityPaused(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Reports {@link Activity#onStop()} is done. */
+    public void activityStopped(IBinder token, Bundle state, PersistableBundle persistentState,
+            CharSequence description) {
+        try {
+            getActivityClientController().activityStopped(token, state, persistentState,
+                    description);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Reports {@link Activity#onDestroy()} is done. */
+    public void activityDestroyed(IBinder token) {
+        try {
+            getActivityClientController().activityDestroyed(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /** Reports the activity has completed relaunched. */
+    public void activityRelaunched(IBinder token) {
+        try {
+            getActivityClientController().activityRelaunched(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
+            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
+        try {
+            getActivityClientController().reportSizeConfigurations(token,
+                    horizontalSizeConfiguration, verticalSizeConfigurations,
+                    smallestSizeConfigurations);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
+        try {
+            return getActivityClientController().moveActivityTaskToBack(token, nonRoot);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
+        try {
+            return getActivityClientController().shouldUpRecreateTask(token, destAffinity);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
+            Intent resultData) {
+        try {
+            return getActivityClientController().navigateUpTo(token, destIntent, resultCode,
+                    resultData);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean releaseActivityInstance(IBinder token) {
+        try {
+            return getActivityClientController().releaseActivityInstance(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public boolean finishActivity(IBinder token, int resultCode, Intent resultData,
+            int finishTask) {
+        try {
+            return getActivityClientController().finishActivity(token, resultCode, resultData,
+                    finishTask);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean finishActivityAffinity(IBinder token) {
+        try {
+            return getActivityClientController().finishActivityAffinity(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    void finishSubActivity(IBinder token, String resultWho, int requestCode) {
+        try {
+            getActivityClientController().finishSubActivity(token, resultWho, requestCode);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    public boolean isTopOfTask(IBinder token) {
+        try {
+            return getActivityClientController().isTopOfTask(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean willActivityBeVisible(IBinder token) {
+        try {
+            return getActivityClientController().willActivityBeVisible(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public int getDisplayId(IBinder token) {
+        try {
+            return getActivityClientController().getDisplayId(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
+        try {
+            return getActivityClientController().getTaskForActivity(token, onlyRoot);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    ComponentName getCallingActivity(IBinder token) {
+        try {
+            return getActivityClientController().getCallingActivity(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    String getCallingPackage(IBinder token) {
+        try {
+            return getActivityClientController().getCallingPackage(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    Bundle getActivityOptions(IBinder token) {
+        try {
+            return getActivityClientController().getActivityOptions(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
+        try {
+            getActivityClientController().setRequestedOrientation(token, requestedOrientation);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    int getRequestedOrientation(IBinder token) {
+        try {
+            return getActivityClientController().getRequestedOrientation(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean convertFromTranslucent(IBinder token) {
+        try {
+            return getActivityClientController().convertFromTranslucent(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean convertToTranslucent(IBinder token, Bundle options) {
+        try {
+            return getActivityClientController().convertToTranslucent(token, options);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
+        try {
+            getActivityClientController().reportActivityFullyDrawn(token, restoredFromBundle);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean isImmersive(IBinder token) {
+        try {
+            return getActivityClientController().isImmersive(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    void setImmersive(IBinder token, boolean immersive) {
+        try {
+            getActivityClientController().setImmersive(token, immersive);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean enterPictureInPictureMode(IBinder token, PictureInPictureParams params) {
+        try {
+            return getActivityClientController().enterPictureInPictureMode(token, params);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    void setPictureInPictureParams(IBinder token, PictureInPictureParams params) {
+        try {
+            getActivityClientController().setPictureInPictureParams(token, params);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void toggleFreeformWindowingMode(IBinder token) {
+        try {
+            getActivityClientController().toggleFreeformWindowingMode(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void startLockTaskModeByToken(IBinder token) {
+        try {
+            getActivityClientController().startLockTaskModeByToken(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void stopLockTaskModeByToken(IBinder token) {
+        try {
+            getActivityClientController().stopLockTaskModeByToken(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void showLockTaskEscapeMessage(IBinder token) {
+        try {
+            getActivityClientController().showLockTaskEscapeMessage(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
+        try {
+            getActivityClientController().setTaskDescription(token, td);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean showAssistFromActivity(IBinder token, Bundle args) {
+        try {
+            return getActivityClientController().showAssistFromActivity(token, args);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    boolean isRootVoiceInteraction(IBinder token) {
+        try {
+            return getActivityClientController().isRootVoiceInteraction(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
+        try {
+            getActivityClientController().startLocalVoiceInteraction(callingActivity, options);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void stopLocalVoiceInteraction(IBinder callingActivity) {
+        try {
+            getActivityClientController().stopLocalVoiceInteraction(callingActivity);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
+        try {
+            getActivityClientController().setShowWhenLocked(token, showWhenLocked);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked) {
+        try {
+            getActivityClientController().setInheritShowWhenLocked(token, inheritShowWhenLocked);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
+        try {
+            getActivityClientController().setTurnScreenOn(token, turnScreenOn);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
+        try {
+            return getActivityClientController().setVrMode(token, enabled, packageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    void overridePendingTransition(IBinder token, String packageName,
+            int enterAnim, int exitAnim) {
+        try {
+            getActivityClientController().overridePendingTransition(token, packageName,
+                    enterAnim, exitAnim);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void setDisablePreviewScreenshots(IBinder token, boolean disable) {
+        try {
+            getActivityClientController().setDisablePreviewScreenshots(token, disable);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
+        try {
+            getActivityClientController().registerRemoteAnimations(token, definition);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void unregisterRemoteAnimations(IBinder token) {
+        try {
+            getActivityClientController().unregisterRemoteAnimations(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    void onBackPressedOnTaskRoot(IBinder token) {
+        try {
+            getActivityClientController().onBackPressedOnTaskRoot(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    public static ActivityClient getInstance() {
+        return sInstance.get();
+    }
+
+    private static IActivityClientController getActivityClientController() {
+        return sActivityClientController.get();
+    }
+
+    private static final Singleton<ActivityClient> sInstance = new Singleton<ActivityClient>() {
+        @Override
+        protected ActivityClient create() {
+            return new ActivityClient();
+        }
+    };
+
+    private static final Singleton<IActivityClientController> sActivityClientController =
+            new Singleton<IActivityClientController>() {
+        @Override
+        protected IActivityClientController create() {
+            try {
+                return ActivityTaskManager.getService().getActivityClientController();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    };
+}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index e3048df..38a22d8 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -77,6 +77,8 @@
 import android.util.DisplayMetrics;
 import android.util.Singleton;
 import android.util.Size;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 import android.view.Surface;
 import android.view.WindowInsetsController.Appearance;
 
@@ -1502,57 +1504,54 @@
         }
 
         /** @hide */
-        public void saveToXml(XmlSerializer out) throws IOException {
+        public void saveToXml(TypedXmlSerializer out) throws IOException {
             if (mLabel != null) {
                 out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, mLabel);
             }
             if (mColorPrimary != 0) {
-                out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_PRIMARY,
-                        Integer.toHexString(mColorPrimary));
+                out.attributeIntHex(null, ATTR_TASKDESCRIPTIONCOLOR_PRIMARY, mColorPrimary);
             }
             if (mColorBackground != 0) {
-                out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND,
-                        Integer.toHexString(mColorBackground));
+                out.attributeIntHex(null, ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND, mColorBackground);
             }
             if (mIconFilename != null) {
                 out.attribute(null, ATTR_TASKDESCRIPTIONICON_FILENAME, mIconFilename);
             }
             if (mIcon != null && mIcon.getType() == Icon.TYPE_RESOURCE) {
-                out.attribute(null, ATTR_TASKDESCRIPTIONICON_RESOURCE,
-                        Integer.toString(mIcon.getResId()));
+                out.attributeInt(null, ATTR_TASKDESCRIPTIONICON_RESOURCE, mIcon.getResId());
                 out.attribute(null, ATTR_TASKDESCRIPTIONICON_RESOURCE_PACKAGE,
                         mIcon.getResPackage());
             }
         }
 
         /** @hide */
-        public void restoreFromXml(XmlPullParser in) {
+        public void restoreFromXml(TypedXmlPullParser in) {
             final String label = in.getAttributeValue(null, ATTR_TASKDESCRIPTIONLABEL);
             if (label != null) {
                 setLabel(label);
             }
-            final String colorPrimary = in.getAttributeValue(null,
-                    ATTR_TASKDESCRIPTIONCOLOR_PRIMARY);
-            if (colorPrimary != null) {
-                setPrimaryColor((int) Long.parseLong(colorPrimary, 16));
+            final int colorPrimary = in.getAttributeIntHex(null,
+                    ATTR_TASKDESCRIPTIONCOLOR_PRIMARY, 0);
+            if (colorPrimary != 0) {
+                setPrimaryColor(colorPrimary);
             }
-            final String colorBackground = in.getAttributeValue(null,
-                    ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND);
-            if (colorBackground != null) {
-                setBackgroundColor((int) Long.parseLong(colorBackground, 16));
+            final int colorBackground = in.getAttributeIntHex(null,
+                    ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND, 0);
+            if (colorBackground != 0) {
+                setBackgroundColor(colorBackground);
             }
             final String iconFilename = in.getAttributeValue(null,
                     ATTR_TASKDESCRIPTIONICON_FILENAME);
             if (iconFilename != null) {
                 setIconFilename(iconFilename);
             }
-            final String iconResourceId = in.getAttributeValue(null,
-                    ATTR_TASKDESCRIPTIONICON_RESOURCE);
+            final int iconResourceId = in.getAttributeInt(null,
+                    ATTR_TASKDESCRIPTIONICON_RESOURCE, Resources.ID_NULL);
             final String iconResourcePackage = in.getAttributeValue(null,
                     ATTR_TASKDESCRIPTIONICON_RESOURCE_PACKAGE);
-            if (iconResourceId != null && iconResourcePackage != null) {
+            if (iconResourceId != Resources.ID_NULL && iconResourcePackage != null) {
                 setIcon(Icon.createWithResource(iconResourcePackage,
-                        Integer.parseInt(iconResourceId, 10)));
+                        iconResourceId));
             }
         }
 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 2e08fc8..ed6dea8 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -85,6 +85,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.HardwareRenderer;
+import android.graphics.Rect;
 import android.graphics.Typeface;
 import android.hardware.display.DisplayManagerGlobal;
 import android.inputmethodservice.InputMethodService;
@@ -2154,7 +2155,7 @@
             }
             if (a != null) {
                 mNewActivities = null;
-                IActivityTaskManager am = ActivityTaskManager.getService();
+                final ActivityClient ac = ActivityClient.getInstance();
                 ActivityClientRecord prev;
                 do {
                     if (localLOGV) Slog.v(
@@ -2162,12 +2163,8 @@
                         " finished=" +
                         (a.activity != null && a.activity.mFinished));
                     if (a.activity != null && !a.activity.mFinished) {
-                        try {
-                            am.activityIdle(a.token, a.createdConfig, stopProfiling);
-                            a.createdConfig = null;
-                        } catch (RemoteException ex) {
-                            throw ex.rethrowFromSystemServer();
-                        }
+                        ac.activityIdle(a.token, a.createdConfig, stopProfiling);
+                        a.createdConfig = null;
                     }
                     prev = a;
                     a = a.nextIdle;
@@ -3576,13 +3573,7 @@
     }
 
     private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
-        final int displayId;
-        try {
-            displayId = ActivityTaskManager.getService().getDisplayId(r.token);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
+        final int displayId = ActivityClient.getInstance().getDisplayId(r.token);
         ContextImpl appContext = ContextImpl.createActivityContext(
                 this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
 
@@ -3669,13 +3660,8 @@
             }
         } else {
             // If there was an error, for any reason, tell the activity manager to stop us.
-            try {
-                ActivityTaskManager.getService()
-                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
-                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
-            } catch (RemoteException ex) {
-                throw ex.rethrowFromSystemServer();
-            }
+            ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,
+                    null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
         }
 
         return a;
@@ -3705,12 +3691,8 @@
                 smallest.put(config.smallestScreenWidthDp, 0);
             }
         }
-        try {
-            ActivityTaskManager.getService().reportSizeConfigurations(r.token,
-                    horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys());
-        } catch (RemoteException ex) {
-            throw ex.rethrowFromSystemServer();
-        }
+        ActivityClient.getInstance().reportSizeConfigurations(r.token, horizontal.copyKeys(),
+                vertical.copyKeys(), smallest.copyKeys());
     }
 
     private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
@@ -4559,12 +4541,8 @@
         // then go ahead and add the window.
         boolean willBeVisible = !a.mStartedActivity;
         if (!willBeVisible) {
-            try {
-                willBeVisible = ActivityTaskManager.getService().willActivityBeVisible(
-                        a.getActivityToken());
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
+            willBeVisible = ActivityClient.getInstance().willActivityBeVisible(
+                    a.getActivityToken());
         }
         if (r.window == null && !a.mFinished && willBeVisible) {
             r.window = r.activity.getWindow();
@@ -5209,11 +5187,7 @@
             ((ContextImpl) c).scheduleFinalCleanup(r.activity.getClass().getName(), "Activity");
         }
         if (finishing) {
-            try {
-                ActivityTaskManager.getService().activityDestroyed(r.token);
-            } catch (RemoteException ex) {
-                throw ex.rethrowFromSystemServer();
-            }
+            ActivityClient.getInstance().activityDestroyed(r.token);
         }
         mSomeActivitiesChanged = true;
     }
@@ -5477,13 +5451,9 @@
 
     @Override
     public void reportRelaunch(ActivityClientRecord r, PendingTransactionActions pendingActions) {
-        try {
-            ActivityTaskManager.getService().activityRelaunched(r.token);
-            if (pendingActions.shouldReportRelaunchToWindowManager() && r.window != null) {
-                r.window.reportActivityRelaunched();
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
+        ActivityClient.getInstance().activityRelaunched(r.token);
+        if (pendingActions.shouldReportRelaunchToWindowManager() && r.window != null) {
+            r.window.reportActivityRelaunched();
         }
     }
 
@@ -5623,10 +5593,13 @@
             // If the new config is the same as the config this Activity is already running with and
             // the override config also didn't change, then don't bother calling
             // onConfigurationChanged.
+            // TODO(b/173090263): Use diff instead after the improvement of AssetManager and
+            // ResourcesImpl constructions.
             final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig);
-            if (diff == 0 && !movedToDifferentDisplay
-                    && mResourcesManager.isSameResourcesOverrideConfig(activityToken,
-                    amOverrideConfig)) {
+
+            if (diff == 0 && !shouldUpdateWindowMetricsBounds(activity.mCurrentConfig, newConfig)
+                    && !movedToDifferentDisplay && mResourcesManager.isSameResourcesOverrideConfig(
+                            activityToken, amOverrideConfig)) {
                 // Nothing significant, don't proceed with updating and reporting.
                 return null;
             } else if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
@@ -5678,6 +5651,26 @@
         return configToReport;
     }
 
+    // TODO(b/173090263): Remove this method after the improvement of AssetManager and ResourcesImpl
+    // constructions.
+    /**
+     * Returns {@code true} if the metrics reported by {@link android.view.WindowMetrics} APIs
+     * should be updated.
+     *
+     * @see WindowManager#getCurrentWindowMetrics()
+     * @see WindowManager#getMaximumWindowMetrics()
+     */
+    private static boolean shouldUpdateWindowMetricsBounds(@NonNull Configuration currentConfig,
+            @NonNull Configuration newConfig) {
+        final Rect currentBounds = currentConfig.windowConfiguration.getBounds();
+        final Rect newBounds = newConfig.windowConfiguration.getBounds();
+
+        final Rect currentMaxBounds = currentConfig.windowConfiguration.getMaxBounds();
+        final Rect newMaxBounds = newConfig.windowConfiguration.getMaxBounds();
+
+        return !currentBounds.equals(newBounds) || !currentMaxBounds.equals(newMaxBounds);
+    }
+
     public final void applyConfigurationToResources(Configuration config) {
         synchronized (mResourcesManager) {
             mResourcesManager.applyConfigurationToResourcesLocked(config, null);
@@ -5912,7 +5905,7 @@
     /**
      * Sets the supplied {@code overrideConfig} as pending for the {@code activityToken}. Calling
      * this method prevents any calls to
-     * {@link #handleActivityConfigurationChanged(IBinder, Configuration, int, boolean)} from
+     * {@link #handleActivityConfigurationChanged(ActivityClientRecord, Configuration, int)} from
      * processing any configurations older than {@code overrideConfig}.
      */
     @Override
@@ -5934,8 +5927,8 @@
 
     /**
      * Handle new activity configuration and/or move to a different display. This method is a noop
-     * if {@link #updatePendingActivityConfiguration(IBinder, Configuration)} has been called with
-     * a newer config than {@code overrideConfig}.
+     * if {@link #updatePendingActivityConfiguration(ActivityClientRecord, Configuration)} has been
+     * called with a newer config than {@code overrideConfig}.
      *
      * @param r Target activity record.
      * @param overrideConfig Activity override config.
@@ -6000,7 +5993,7 @@
 
     /**
      * Checks if the display id of activity is different from the given one. Note that
-     * {@link #INVALID_DISPLAY} means no difference.
+     * {@link Display#INVALID_DISPLAY} means no difference.
      */
     private static boolean isDifferentDisplay(@NonNull Activity activity, int displayId) {
         return displayId != INVALID_DISPLAY && displayId != activity.getDisplayId();
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 34437af..3642d31 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -30,6 +30,7 @@
 import android.annotation.StringRes;
 import android.annotation.UserIdInt;
 import android.annotation.XmlRes;
+import android.app.role.RoleManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -2306,20 +2307,14 @@
 
     @Override
     public String getDefaultBrowserPackageNameAsUser(int userId) {
-        try {
-            return mPermissionManager.getDefaultBrowser(userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+        return roleManager.getBrowserRoleHolder(userId);
     }
 
     @Override
     public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
-        try {
-            return mPermissionManager.setDefaultBrowser(packageName, userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+        return roleManager.setBrowserRoleHolder(packageName, userId);
     }
 
     @Override
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 298c455..a16f6a8 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -16,11 +16,15 @@
 
 package android.app;
 
+import android.annotation.IntDef;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.os.Build;
 import android.os.Bundle;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Helper class for building an options Bundle that can be used with
  * {@link android.content.Context#sendBroadcast(android.content.Intent)
@@ -30,6 +34,7 @@
 @SystemApi
 public class BroadcastOptions {
     private long mTemporaryAppWhitelistDuration;
+    private @TempAllowListType int mTemporaryAppWhitelistType;
     private int mMinManifestReceiverApiLevel = 0;
     private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
     private boolean mDontSendToRestrictedApps = false;
@@ -42,6 +47,9 @@
     static final String KEY_TEMPORARY_APP_WHITELIST_DURATION
             = "android:broadcast.temporaryAppWhitelistDuration";
 
+    static final String KEY_TEMPORARY_APP_WHITELIST_TYPE
+            = "android:broadcast.temporaryAppWhitelistType";
+
     /**
      * Corresponds to {@link #setMinManifestReceiverApiLevel}.
      */
@@ -66,6 +74,27 @@
     static final String KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS =
             "android:broadcast.allowBackgroundActivityStarts";
 
+    /**
+     * Allow the temp allowlist behavior, plus allow foreground service start from background.
+     */
+    public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0;
+    /**
+     * Only allow the temp allowlist behavior, not allow foreground service start from
+     * background.
+     */
+    public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1;
+
+    /**
+     * The list of temp allowlist types.
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "TEMPORARY_WHITELIST_TYPE_" }, value = {
+            TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
+            TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TempAllowListType {}
+
     public static BroadcastOptions makeBasic() {
         BroadcastOptions opts = new BroadcastOptions();
         return opts;
@@ -77,6 +106,7 @@
     /** @hide */
     public BroadcastOptions(Bundle opts) {
         mTemporaryAppWhitelistDuration = opts.getLong(KEY_TEMPORARY_APP_WHITELIST_DURATION);
+        mTemporaryAppWhitelistType = opts.getInt(KEY_TEMPORARY_APP_WHITELIST_TYPE);
         mMinManifestReceiverApiLevel = opts.getInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, 0);
         mMaxManifestReceiverApiLevel = opts.getInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL,
                 Build.VERSION_CODES.CUR_DEVELOPMENT);
@@ -95,6 +125,22 @@
             android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND})
     public void setTemporaryAppWhitelistDuration(long duration) {
         mTemporaryAppWhitelistDuration = duration;
+        mTemporaryAppWhitelistType = TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
+    }
+
+    /**
+     * Set a duration for which the system should temporary place an application on the
+     * power allowlist when this broadcast is being delivered to it, specify the temp allowlist
+     * type.
+     * @param type one of {@link TempAllowListType}
+     * @param duration the duration in milliseconds; 0 means to not place on allowlist.
+     */
+    @RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
+            android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
+            android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND})
+    public void setTemporaryAppWhitelistDuration(@TempAllowListType int type, long duration) {
+        mTemporaryAppWhitelistDuration = duration;
+        mTemporaryAppWhitelistType = type;
     }
 
     /**
@@ -106,6 +152,14 @@
     }
 
     /**
+     * Return {@link #mTemporaryAppWhitelistType}.
+     * @hide
+     */
+    public @TempAllowListType int getTemporaryAppWhitelistType() {
+        return mTemporaryAppWhitelistType;
+    }
+
+    /**
      * Set the minimum target API level of receivers of the broadcast.  If an application
      * is targeting an API level less than this, the broadcast will not be delivered to
      * them.  This only applies to receivers declared in the app's AndroidManifest.xml.
@@ -190,6 +244,9 @@
         if (mTemporaryAppWhitelistDuration > 0) {
             b.putLong(KEY_TEMPORARY_APP_WHITELIST_DURATION, mTemporaryAppWhitelistDuration);
         }
+        if (mTemporaryAppWhitelistType != 0) {
+            b.putInt(KEY_TEMPORARY_APP_WHITELIST_TYPE, mTemporaryAppWhitelistType);
+        }
         if (mMinManifestReceiverApiLevel != 0) {
             b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel);
         }
diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl
new file mode 100644
index 0000000..f9449f2
--- /dev/null
+++ b/core/java/android/app/IActivityClientController.aidl
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2020 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.app;
+
+import android.app.ActivityManager;
+import android.app.PictureInPictureParams;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.view.RemoteAnimationDefinition;
+
+/**
+ * Interface for the callback and request from an activity to system.
+ *
+ * {@hide}
+ */
+interface IActivityClientController {
+    oneway void activityIdle(in IBinder token, in Configuration config, in boolean stopProfiling);
+    void activityResumed(in IBinder token);
+    void activityTopResumedStateLost();
+    void activityPaused(in IBinder token);
+    void activityStopped(in IBinder token, in Bundle state, in PersistableBundle persistentState,
+            in CharSequence description);
+    oneway void activityDestroyed(in IBinder token);
+    void activityRelaunched(in IBinder token);
+
+    void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration,
+            in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations);
+    boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot);
+    boolean shouldUpRecreateTask(in IBinder token, in String destAffinity);
+    boolean navigateUpTo(in IBinder token, in Intent target, int resultCode,
+            in Intent resultData);
+    boolean releaseActivityInstance(in IBinder token);
+    boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask);
+    boolean finishActivityAffinity(in IBinder token);
+    /** Finish all activities that were started for result from the specified activity. */
+    void finishSubActivity(in IBinder token, in String resultWho, int requestCode);
+
+    boolean isTopOfTask(in IBinder token);
+    boolean willActivityBeVisible(in IBinder token);
+    int getDisplayId(in IBinder activityToken);
+    int getTaskForActivity(in IBinder token, in boolean onlyRoot);
+    ComponentName getCallingActivity(in IBinder token);
+    String getCallingPackage(in IBinder token);
+    Bundle getActivityOptions(in IBinder token);
+
+    void setRequestedOrientation(in IBinder token, int requestedOrientation);
+    int getRequestedOrientation(in IBinder token);
+
+    boolean convertFromTranslucent(in IBinder token);
+    boolean convertToTranslucent(in IBinder token, in Bundle options);
+
+    boolean isImmersive(in IBinder token);
+    void setImmersive(in IBinder token, boolean immersive);
+
+    boolean enterPictureInPictureMode(in IBinder token, in PictureInPictureParams params);
+    void setPictureInPictureParams(in IBinder token, in PictureInPictureParams params);
+    void toggleFreeformWindowingMode(in IBinder token);
+
+    void startLockTaskModeByToken(in IBinder token);
+    void stopLockTaskModeByToken(in IBinder token);
+    oneway void showLockTaskEscapeMessage(in IBinder token);
+    void setTaskDescription(in IBinder token, in ActivityManager.TaskDescription values);
+
+    boolean showAssistFromActivity(in IBinder token, in Bundle args);
+    boolean isRootVoiceInteraction(in IBinder token);
+    void startLocalVoiceInteraction(in IBinder token, in Bundle options);
+    void stopLocalVoiceInteraction(in IBinder token);
+
+    void setShowWhenLocked(in IBinder token, boolean showWhenLocked);
+    void setInheritShowWhenLocked(in IBinder token, boolean setInheritShownWhenLocked);
+    void setTurnScreenOn(in IBinder token, boolean turnScreenOn);
+    void reportActivityFullyDrawn(in IBinder token, boolean restoredFromBundle);
+    void overridePendingTransition(in IBinder token, in String packageName,
+            int enterAnim, int exitAnim);
+    int setVrMode(in IBinder token, boolean enabled, in ComponentName packageName);
+
+    /** See {@link android.app.Activity#setDisablePreviewScreenshots}. */
+    void setDisablePreviewScreenshots(in IBinder token, boolean disable);
+
+    /** Registers remote animations for a specific activity. */
+    void registerRemoteAnimations(in IBinder token, in RemoteAnimationDefinition definition);
+
+    /** Unregisters all remote animations for a specific activity. */
+    void unregisterRemoteAnimations(in IBinder token);
+
+    /**
+     * Reports that an Activity received a back key press when there were no additional activities
+     * on the back stack.
+     */
+    void onBackPressedOnTaskRoot(in IBinder token);
+}
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index ab48bae..4b25573 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -22,6 +22,7 @@
 import android.app.ContentProviderHolder;
 import android.app.GrantedUriPermission;
 import android.app.IApplicationThread;
+import android.app.IActivityClientController;
 import android.app.IActivityController;
 import android.app.IAppTask;
 import android.app.IAssistDataReceiver;
@@ -35,7 +36,6 @@
 import android.app.IUserSwitchObserver;
 import android.app.Notification;
 import android.app.PendingIntent;
-import android.app.PictureInPictureParams;
 import android.app.ProfilerInfo;
 import android.app.WaitResult;
 import android.app.assist.AssistContent;
@@ -63,7 +63,6 @@
 import android.os.IBinder;
 import android.os.IProgressListener;
 import android.os.ParcelFileDescriptor;
-import android.os.PersistableBundle;
 import android.os.StrictMode;
 import android.os.WorkSource;
 import android.service.voice.IVoiceInteractionSession;
@@ -144,54 +143,25 @@
             int userId);
 
     void unhandledBack();
-    boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask);
-    boolean finishActivityAffinity(in IBinder token);
 
-    oneway void activityIdle(in IBinder token, in Configuration config,
-            in boolean stopProfiling);
-    void activityResumed(in IBinder token);
-    void activityTopResumedStateLost();
-    void activityPaused(in IBinder token);
-    void activityStopped(in IBinder token, in Bundle state,
-            in PersistableBundle persistentState, in CharSequence description);
-    oneway void activityDestroyed(in IBinder token);
-    void activityRelaunched(in IBinder token);
+    /** Returns an interface to control the activity related operations. */
+    IActivityClientController getActivityClientController();
+
     int getFrontActivityScreenCompatMode();
     void setFrontActivityScreenCompatMode(int mode);
-    String getCallingPackage(in IBinder token);
-    ComponentName getCallingActivity(in IBinder token);
     void setFocusedTask(int taskId);
     boolean removeTask(int taskId);
     void removeAllVisibleRecentTasks();
     List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, boolean filterOnlyVisibleRecents);
-    boolean shouldUpRecreateTask(in IBinder token, in String destAffinity);
-    boolean navigateUpTo(in IBinder token, in Intent target, int resultCode,
-            in Intent resultData);
     void moveTaskToFront(in IApplicationThread app, in String callingPackage, int task,
             int flags, in Bundle options);
-    int getTaskForActivity(in IBinder token, in boolean onlyRoot);
-    /** Finish all activities that were started for result from the specified activity. */
-    void finishSubActivity(in IBinder token, in String resultWho, int requestCode);
     ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
             int userId);
-    boolean willActivityBeVisible(in IBinder token);
-    void setRequestedOrientation(in IBinder token, int requestedOrientation);
-    int getRequestedOrientation(in IBinder token);
-    boolean convertFromTranslucent(in IBinder token);
-    boolean convertToTranslucent(in IBinder token, in Bundle options);
-    void notifyActivityDrawn(in IBinder token);
-    void reportActivityFullyDrawn(in IBinder token, boolean restoredFromBundle);
-    int getDisplayId(in IBinder activityToken);
-    boolean isImmersive(in IBinder token);
-    void setImmersive(in IBinder token, boolean immersive);
     boolean isTopActivityImmersive();
-    boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot);
     ActivityManager.TaskDescription getTaskDescription(int taskId);
-    void overridePendingTransition(in IBinder token, in String packageName,
-            int enterAnim, int exitAnim);
     int getLaunchedFromUid(in IBinder activityToken);
     String getLaunchedFromPackage(in IBinder activityToken);
-    void reportAssistContextExtras(in IBinder token, in Bundle extras,
+    void reportAssistContextExtras(in IBinder assistToken, in Bundle extras,
             in AssistStructure structure, in AssistContent content, in Uri referrer);
 
     void setFocusedRootTask(int taskId);
@@ -199,24 +169,16 @@
     Rect getTaskBounds(int taskId);
 
     void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition);
-    void startLockTaskModeByToken(in IBinder token);
-    void stopLockTaskModeByToken(in IBinder token);
     void updateLockTaskPackages(int userId, in String[] packages);
     boolean isInLockTaskMode();
     int getLockTaskModeState();
-    void setTaskDescription(in IBinder token, in ActivityManager.TaskDescription values);
-    Bundle getActivityOptions(in IBinder token);
     List<IBinder> getAppTasks(in String callingPackage);
     void startSystemLockTaskMode(int taskId);
     void stopSystemLockTaskMode();
     void finishVoiceTask(in IVoiceInteractionSession session);
-    boolean isTopOfTask(in IBinder token);
-    void notifyLaunchTaskBehindComplete(in IBinder token);
-    void notifyEnterAnimationComplete(in IBinder token);
     int addAppTask(in IBinder activityToken, in Intent intent,
             in ActivityManager.TaskDescription description, in Bitmap thumbnail);
     Point getAppTaskThumbnailSize();
-    boolean releaseActivityInstance(in IBinder token);
     /**
      * Only callable from the system. This token grants a temporary permission to call
      * #startActivityAsCallerWithToken. The token will time out after
@@ -236,7 +198,6 @@
     void registerTaskStackListener(in ITaskStackListener listener);
     void unregisterTaskStackListener(in ITaskStackListener listener);
     void setTaskResizeable(int taskId, int resizeableMode);
-    void toggleFreeformWindowingMode(in IBinder token);
 
     /**
      * Resize the task with given bounds
@@ -287,9 +248,6 @@
     boolean requestAutofillData(in IAssistDataReceiver receiver, in Bundle receiverExtras,
             in IBinder activityToken, int flags);
     boolean isAssistDataAllowedOnCurrentActivity();
-    boolean showAssistFromActivity(in IBinder token, in Bundle args);
-    boolean isRootVoiceInteraction(in IBinder token);
-    oneway void showLockTaskEscapeMessage(in IBinder token);
 
     /**
      * Notify the system that the keyguard is going away.
@@ -302,15 +260,9 @@
     ComponentName getActivityClassForToken(in IBinder token);
     String getPackageForToken(in IBinder token);
 
-    void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration,
-            in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations);
-
     void suppressResizeConfigChanges(boolean suppress);
     boolean moveTopActivityToPinnedRootTask(int rootTaskId, in Rect bounds);
-    boolean enterPictureInPictureMode(in IBinder token, in PictureInPictureParams params);
-    void setPictureInPictureParams(in IBinder token, in PictureInPictureParams params);
     void requestPictureInPictureMode(in IBinder token);
-    IBinder getUriPermissionOwnerForActivity(in IBinder activityToken);
 
     /**
      * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change.
@@ -343,9 +295,6 @@
      * are changing the docked stack size.
      */
     void setSplitScreenResizing(boolean resizing);
-    int setVrMode(in IBinder token, boolean enabled, in ComponentName packageName);
-    void startLocalVoiceInteraction(in IBinder token, in Bundle options);
-    void stopLocalVoiceInteraction(in IBinder token);
     boolean supportsLocalVoiceInteraction();
 
     // Get device configuration
@@ -366,11 +315,6 @@
     ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution);
 
     /**
-     * See {@link android.app.Activity#setDisablePreviewScreenshots}
-     */
-    void setDisablePreviewScreenshots(IBinder token, boolean disable);
-
-    /**
      * It should only be called from home activity to remove its outdated snapshot. The home
      * snapshot is used to speed up entering home from screen off. If the content of home activity
      * is significantly different from before taking the snapshot, then the home activity can use
@@ -393,20 +337,6 @@
     boolean updateConfiguration(in Configuration values);
     void updateLockTaskFeatures(int userId, int flags);
 
-    void setShowWhenLocked(in IBinder token, boolean showWhenLocked);
-    void setInheritShowWhenLocked(in IBinder token, boolean setInheritShownWhenLocked);
-    void setTurnScreenOn(in IBinder token, boolean turnScreenOn);
-
-    /**
-     * Registers remote animations for a specific activity.
-     */
-    void registerRemoteAnimations(in IBinder token, in RemoteAnimationDefinition definition);
-
-    /**
-     * Unregisters all remote animations for a specific activity.
-     */
-    void unregisterRemoteAnimations(in IBinder token);
-
     /**
      * Registers a remote animation to be run for all activity starts from a certain package during
      * a short predefined amount of time.
@@ -448,10 +378,4 @@
      * @param activityToken The token of the target activity to restart.
      */
     void restartActivityProcessIfVisible(in IBinder activityToken);
-
-    /**
-     * Reports that an Activity received a back key press when there were no additional activities
-     * on the back stack.
-     */
-    void onBackPressedOnTaskRoot(in IBinder activityToken);
 }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 6535387a..99785e1 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -1284,7 +1284,7 @@
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                 throw new RuntimeException(
                     "Unable to instantiate application " + appClass
-                    + ": " + e.toString(), e);
+                    + " package " + mPackageName + ": " + e.toString(), e);
             }
         }
         mActivityThread.mAllApplications.add(app);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index a113580..82f61a4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -83,6 +83,7 @@
 import android.util.Pair;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
+import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -6120,8 +6121,11 @@
             int defaultColor = mInNightMode ? Color.BLACK : Color.WHITE;
             Resources.Theme theme = mContext.getTheme();
             if (theme == null) {
+                // Running unit tests with mocked context
                 return defaultColor;
             }
+            theme = new ContextThemeWrapper(mContext, R.style.Theme_DeviceDefault_DayNight)
+                    .getTheme();
             TypedArray ta = theme.obtainStyledAttributes(new int[]{R.attr.colorBackground});
             if (ta == null) {
                 return defaultColor;
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 080aac9..b1a8f9b 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -32,9 +32,12 @@
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.text.TextUtils;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.XmlUtils;
 
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -869,7 +872,7 @@
      * @hide
      */
     public void populateFromXmlForRestore(XmlPullParser parser, Context context) {
-        populateFromXml(parser, true, context);
+        populateFromXml(XmlUtils.makeTyped(parser), true, context);
     }
 
     /**
@@ -877,13 +880,13 @@
      */
     @SystemApi
     public void populateFromXml(XmlPullParser parser) {
-        populateFromXml(parser, false, null);
+        populateFromXml(XmlUtils.makeTyped(parser), false, null);
     }
 
     /**
      * If {@param forRestore} is true, {@param Context} MUST be non-null.
      */
-    private void populateFromXml(XmlPullParser parser, boolean forRestore,
+    private void populateFromXml(TypedXmlPullParser parser, boolean forRestore,
             @Nullable Context context) {
         Preconditions.checkArgument(!forRestore || context != null,
                 "forRestore is true but got null context");
@@ -941,14 +944,14 @@
      */
     @SystemApi
     public void writeXml(XmlSerializer out) throws IOException {
-        writeXml(out, false, null);
+        writeXml(XmlUtils.makeTyped(out), false, null);
     }
 
     /**
      * @hide
      */
     public void writeXmlForBackup(XmlSerializer out, Context context) throws IOException {
-        writeXml(out, true, context);
+        writeXml(XmlUtils.makeTyped(out), true, context);
     }
 
     private Uri getSoundForBackup(Context context) {
@@ -967,7 +970,7 @@
     /**
      * If {@param forBackup} is true, {@param Context} MUST be non-null.
      */
-    private void writeXml(XmlSerializer out, boolean forBackup, @Nullable Context context)
+    private void writeXml(TypedXmlSerializer out, boolean forBackup, @Nullable Context context)
             throws IOException {
         Preconditions.checkArgument(!forBackup || context != null,
                 "forBackup is true but got null context");
@@ -980,62 +983,58 @@
             out.attribute(null, ATT_DESC, getDescription());
         }
         if (getImportance() != DEFAULT_IMPORTANCE) {
-            out.attribute(
-                    null, ATT_IMPORTANCE, Integer.toString(getImportance()));
+            out.attributeInt(null, ATT_IMPORTANCE, getImportance());
         }
         if (canBypassDnd()) {
-            out.attribute(
-                    null, ATT_PRIORITY, Integer.toString(Notification.PRIORITY_MAX));
+            out.attributeInt(null, ATT_PRIORITY, Notification.PRIORITY_MAX);
         }
         if (getLockscreenVisibility() != DEFAULT_VISIBILITY) {
-            out.attribute(null, ATT_VISIBILITY,
-                    Integer.toString(getLockscreenVisibility()));
+            out.attributeInt(null, ATT_VISIBILITY, getLockscreenVisibility());
         }
         Uri sound = forBackup ? getSoundForBackup(context) : getSound();
         if (sound != null) {
             out.attribute(null, ATT_SOUND, sound.toString());
         }
         if (getAudioAttributes() != null) {
-            out.attribute(null, ATT_USAGE, Integer.toString(getAudioAttributes().getUsage()));
-            out.attribute(null, ATT_CONTENT_TYPE,
-                    Integer.toString(getAudioAttributes().getContentType()));
-            out.attribute(null, ATT_FLAGS, Integer.toString(getAudioAttributes().getFlags()));
+            out.attributeInt(null, ATT_USAGE, getAudioAttributes().getUsage());
+            out.attributeInt(null, ATT_CONTENT_TYPE, getAudioAttributes().getContentType());
+            out.attributeInt(null, ATT_FLAGS, getAudioAttributes().getFlags());
         }
         if (shouldShowLights()) {
-            out.attribute(null, ATT_LIGHTS, Boolean.toString(shouldShowLights()));
+            out.attributeBoolean(null, ATT_LIGHTS, shouldShowLights());
         }
         if (getLightColor() != DEFAULT_LIGHT_COLOR) {
-            out.attribute(null, ATT_LIGHT_COLOR, Integer.toString(getLightColor()));
+            out.attributeInt(null, ATT_LIGHT_COLOR, getLightColor());
         }
         if (shouldVibrate()) {
-            out.attribute(null, ATT_VIBRATION_ENABLED, Boolean.toString(shouldVibrate()));
+            out.attributeBoolean(null, ATT_VIBRATION_ENABLED, shouldVibrate());
         }
         if (getVibrationPattern() != null) {
             out.attribute(null, ATT_VIBRATION, longArrayToString(getVibrationPattern()));
         }
         if (getUserLockedFields() != 0) {
-            out.attribute(null, ATT_USER_LOCKED, Integer.toString(getUserLockedFields()));
+            out.attributeInt(null, ATT_USER_LOCKED, getUserLockedFields());
         }
         if (isFgServiceShown()) {
-            out.attribute(null, ATT_FG_SERVICE_SHOWN, Boolean.toString(isFgServiceShown()));
+            out.attributeBoolean(null, ATT_FG_SERVICE_SHOWN, isFgServiceShown());
         }
         if (canShowBadge()) {
-            out.attribute(null, ATT_SHOW_BADGE, Boolean.toString(canShowBadge()));
+            out.attributeBoolean(null, ATT_SHOW_BADGE, canShowBadge());
         }
         if (isDeleted()) {
-            out.attribute(null, ATT_DELETED, Boolean.toString(isDeleted()));
+            out.attributeBoolean(null, ATT_DELETED, isDeleted());
         }
         if (getGroup() != null) {
             out.attribute(null, ATT_GROUP, getGroup());
         }
         if (isBlockable()) {
-            out.attribute(null, ATT_BLOCKABLE_SYSTEM, Boolean.toString(isBlockable()));
+            out.attributeBoolean(null, ATT_BLOCKABLE_SYSTEM, isBlockable());
         }
         if (getAllowBubbles() != DEFAULT_ALLOW_BUBBLE) {
-            out.attribute(null, ATT_ALLOW_BUBBLE, Integer.toString(getAllowBubbles()));
+            out.attributeInt(null, ATT_ALLOW_BUBBLE, getAllowBubbles());
         }
         if (getOriginalImportance() != DEFAULT_IMPORTANCE) {
-            out.attribute(null, ATT_ORIG_IMP, Integer.toString(getOriginalImportance()));
+            out.attributeInt(null, ATT_ORIG_IMP, getOriginalImportance());
         }
         if (getParentChannelId() != null) {
             out.attribute(null, ATT_PARENT_CHANNEL, getParentChannelId());
@@ -1044,10 +1043,10 @@
             out.attribute(null, ATT_CONVERSATION_ID, getConversationId());
         }
         if (isDemoted()) {
-            out.attribute(null, ATT_DEMOTE, Boolean.toString(isDemoted()));
+            out.attributeBoolean(null, ATT_DEMOTE, isDemoted());
         }
         if (isImportantConversation()) {
-            out.attribute(null, ATT_IMP_CONVERSATION, Boolean.toString(isImportantConversation()));
+            out.attributeBoolean(null, ATT_IMP_CONVERSATION, isImportantConversation());
         }
 
         // mImportanceLockedDefaultApp and mImportanceLockedByOEM have a different source of
@@ -1099,7 +1098,7 @@
         return record;
     }
 
-    private static AudioAttributes safeAudioAttributes(XmlPullParser parser) {
+    private static AudioAttributes safeAudioAttributes(TypedXmlPullParser parser) {
         int usage = safeInt(parser, ATT_USAGE, AudioAttributes.USAGE_NOTIFICATION);
         int contentType = safeInt(parser, ATT_CONTENT_TYPE,
                 AudioAttributes.CONTENT_TYPE_SONIFICATION);
@@ -1111,32 +1110,20 @@
                 .build();
     }
 
-    private static Uri safeUri(XmlPullParser parser, String att) {
+    private static Uri safeUri(TypedXmlPullParser parser, String att) {
         final String val = parser.getAttributeValue(null, att);
         return val == null ? null : Uri.parse(val);
     }
 
-    private static int safeInt(XmlPullParser parser, String att, int defValue) {
-        final String val = parser.getAttributeValue(null, att);
-        return tryParseInt(val, defValue);
+    private static int safeInt(TypedXmlPullParser parser, String att, int defValue) {
+        return parser.getAttributeInt(null, att, defValue);
     }
 
-    private static int tryParseInt(String value, int defValue) {
-        if (TextUtils.isEmpty(value)) return defValue;
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException e) {
-            return defValue;
-        }
+    private static boolean safeBool(TypedXmlPullParser parser, String att, boolean defValue) {
+        return parser.getAttributeBoolean(null, att, defValue);
     }
 
-    private static boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
-        final String value = parser.getAttributeValue(null, att);
-        if (TextUtils.isEmpty(value)) return defValue;
-        return Boolean.parseBoolean(value);
-    }
-
-    private static long[] safeLongArray(XmlPullParser parser, String att, long[] defValue) {
+    private static long[] safeLongArray(TypedXmlPullParser parser, String att, long[] defValue) {
         final String attributeValue = parser.getAttributeValue(null, att);
         if (TextUtils.isEmpty(attributeValue)) return defValue;
         String[] values = attributeValue.split(DELIMITER);
diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java
index ec7fa33..cd6df0b 100644
--- a/core/java/android/app/NotificationChannelGroup.java
+++ b/core/java/android/app/NotificationChannelGroup.java
@@ -23,12 +23,12 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 import android.util.proto.ProtoOutputStream;
 
 import org.json.JSONException;
 import org.json.JSONObject;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -228,22 +228,16 @@
     /**
      * @hide
      */
-    public void populateFromXml(XmlPullParser parser) {
+    public void populateFromXml(TypedXmlPullParser parser) {
         // Name, id, and importance are set in the constructor.
         setDescription(parser.getAttributeValue(null, ATT_DESC));
-        setBlocked(safeBool(parser, ATT_BLOCKED, false));
-    }
-
-    private static boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
-        final String value = parser.getAttributeValue(null, att);
-        if (TextUtils.isEmpty(value)) return defValue;
-        return Boolean.parseBoolean(value);
+        setBlocked(parser.getAttributeBoolean(null, ATT_BLOCKED, false));
     }
 
     /**
      * @hide
      */
-    public void writeXml(XmlSerializer out) throws IOException {
+    public void writeXml(TypedXmlSerializer out) throws IOException {
         out.startTag(null, TAG_GROUP);
 
         out.attribute(null, ATT_ID, getId());
@@ -253,8 +247,8 @@
         if (getDescription() != null) {
             out.attribute(null, ATT_DESC, getDescription().toString());
         }
-        out.attribute(null, ATT_BLOCKED, Boolean.toString(isBlocked()));
-        out.attribute(null, ATT_USER_LOCKED, Integer.toString(mUserLockedFields));
+        out.attributeBoolean(null, ATT_BLOCKED, isBlocked());
+        out.attributeInt(null, ATT_USER_LOCKED, mUserLockedFields);
 
         out.endTag(null, TAG_GROUP);
     }
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 12460ba..da7a29f 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1501,7 +1501,8 @@
     }
 
     /** @hide */
-    public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
+    @TestApi
+    public boolean isNotificationPolicyAccessGrantedForPackage(@NonNull String pkg) {
         INotificationManager service = getService();
         try {
             return service.isNotificationPolicyAccessGrantedForPackage(pkg);
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
new file mode 100644
index 0000000..633d093
--- /dev/null
+++ b/core/java/android/app/OWNERS
@@ -0,0 +1 @@
+per-file *Zygote* = file:/ZYGOTE_OWNERS
diff --git a/core/java/android/app/PictureInPictureParams.java b/core/java/android/app/PictureInPictureParams.java
index 32252a3f..29c9c67 100644
--- a/core/java/android/app/PictureInPictureParams.java
+++ b/core/java/android/app/PictureInPictureParams.java
@@ -26,6 +26,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Represents a set of parameters used to initialize and update an Activity in picture-in-picture
@@ -194,6 +195,16 @@
     }
 
     /**
+     * Makes a copy from the other picture-in-picture args.
+     * @hide
+     */
+    public PictureInPictureParams(PictureInPictureParams other) {
+        this(other.mAspectRatio, other.mUserActions,
+                other.hasSourceBoundsHint() ? new Rect(other.getSourceRectHint()) : null,
+                other.mAutoEnterEnabled);
+    }
+
+    /**
      * Copies the set parameters from the other picture-in-picture args.
      * @hide
      */
@@ -297,6 +308,22 @@
     }
 
     @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PictureInPictureParams)) return false;
+        PictureInPictureParams that = (PictureInPictureParams) o;
+        return mAutoEnterEnabled == that.mAutoEnterEnabled
+                && Objects.equals(mAspectRatio, that.mAspectRatio)
+                && Objects.equals(mUserActions, that.mUserActions)
+                && Objects.equals(mSourceRectHint, that.mSourceRectHint);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mAspectRatio, mUserActions, mSourceRectHint, mAutoEnterEnabled);
+    }
+
+    @Override
     public int describeContents() {
         return 0;
     }
diff --git a/core/java/android/app/RemoteAction.java b/core/java/android/app/RemoteAction.java
index 5a4244f..26f324b 100644
--- a/core/java/android/app/RemoteAction.java
+++ b/core/java/android/app/RemoteAction.java
@@ -23,6 +23,7 @@
 import android.text.TextUtils;
 
 import java.io.PrintWriter;
+import java.util.Objects;
 
 /**
  * Represents a remote action that can be called from another process.  The action can have an
@@ -127,6 +128,25 @@
     }
 
     @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof RemoteAction)) return false;
+        RemoteAction that = (RemoteAction) o;
+        return mEnabled == that.mEnabled
+                && mShouldShowIcon == that.mShouldShowIcon
+                && mIcon.equals(that.mIcon)
+                && mTitle.equals(that.mTitle)
+                && mContentDescription.equals(that.mContentDescription)
+                && mActionIntent.equals(that.mActionIntent);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mIcon, mTitle, mContentDescription, mActionIntent, mEnabled,
+                mShouldShowIcon);
+    }
+
+    @Override
     public int describeContents() {
         return 0;
     }
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 36d5b5e..772833cc 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -1178,6 +1178,8 @@
                         continue;
                     }
 
+                    // TODO(b/173090263): Improve the performance of AssetManager & ResourcesImpl
+                    // constructions.
                     final ResourcesImpl resourcesImpl =
                             findOrCreateResourcesImplForKeyLocked(newKey);
                     if (resourcesImpl != null && resourcesImpl != resources.getImpl()) {
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 36241a8..61e93f7 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -70,6 +70,18 @@
             "name": "CtsAutoFillServiceTestCases",
             "options": [
                 {
+                    "include-filter": "android.autofillservice.cts.saveui.AutofillSaveDialogTest"
+                },
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                }
+            ],
+            "file_patterns": ["(/|^)Activity.java"]
+        },
+        {
+            "name": "CtsAutoFillServiceTestCases",
+            "options": [
+                {
                     "include-filter": "android.autofillservice.cts.saveui.PreSimpleSaveActivityTest"
                 },
                 {
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 1a8a4b7..8367bde 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -313,7 +313,7 @@
                 && isResizeable == that.isResizeable
                 && Objects.equals(positionInParent, that.positionInParent)
                 && equalsLetterboxParams(that)
-                && pictureInPictureParams == that.pictureInPictureParams
+                && Objects.equals(pictureInPictureParams, that.pictureInPictureParams)
                 && getWindowingMode() == that.getWindowingMode()
                 && Objects.equals(taskDescription, that.taskDescription)
                 && isFocused == that.isFocused
diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java
index 1ee8e4f..41256d0 100644
--- a/core/java/android/app/admin/DeviceAdminInfo.java
+++ b/core/java/android/app/admin/DeviceAdminInfo.java
@@ -37,11 +37,12 @@
 import android.util.Log;
 import android.util.Printer;
 import android.util.SparseArray;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -472,16 +473,15 @@
     }
 
     /** @hide */
-    public void writePoliciesToXml(XmlSerializer out)
+    public void writePoliciesToXml(TypedXmlSerializer out)
             throws IllegalArgumentException, IllegalStateException, IOException {
-        out.attribute(null, "flags", Integer.toString(mUsesPolicies));
+        out.attributeInt(null, "flags", mUsesPolicies);
     }
 
     /** @hide */
-    public void readPoliciesFromXml(XmlPullParser parser)
+    public void readPoliciesFromXml(TypedXmlPullParser parser)
             throws XmlPullParserException, IOException {
-        mUsesPolicies = Integer.parseInt(
-                parser.getAttributeValue(null, "flags"));
+        mUsesPolicies = parser.getAttributeInt(null, "flags");
     }
 
     public void dump(Printer pw, String prefix) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 5eb1922..4095acc 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -39,6 +39,7 @@
 import android.app.Activity;
 import android.app.IServiceConnection;
 import android.app.KeyguardManager;
+import android.app.admin.DevicePolicyManager.DevicePolicyOperation;
 import android.app.admin.SecurityLog.SecurityEvent;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
@@ -1206,7 +1207,7 @@
      * <ul>
      * <li>By the admin app when performing the admin-integrated
      * provisioning flow as a result of the {@link #ACTION_GET_PROVISIONING_MODE} activity</li>
-     * <li>With intent action {@link #ACTION_PROVISION_MANAGED_DEVICE}</li>
+     * <li>For managed account enrollment</li>
      * </ul>
      *
      * <p>If the education screens are skipped, it is the admin application's responsibility
@@ -1229,9 +1230,37 @@
             "android.app.extra.PROVISIONING_USE_MOBILE_DATA";
 
     /**
+     * Possible values for {@link #EXTRA_PROVISIONING_TRIGGER}.
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "PROVISIONING_TRIGGER_" }, value = {
+            PROVISIONING_TRIGGER_UNSPECIFIED,
+            PROVISIONING_TRIGGER_CLOUD_ENROLLMENT,
+            PROVISIONING_TRIGGER_QR_CODE,
+            PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER,
+            PROVISIONING_TRIGGER_MANAGED_ACCOUNT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ProvisioningTrigger {}
+
+    /**
+     * Possible values for {@link #EXTRA_PROVISIONING_SUPPORTED_MODES}.
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "SUPPORTED_MODES_" }, value = {
+            SUPPORTED_MODES_ORGANIZATION_OWNED,
+            SUPPORTED_MODES_PERSONALLY_OWNED,
+            SUPPORTED_MODES_ORGANIZATION_AND_PERSONALLY_OWNED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ProvisioningConfiguration {}
+
+    /**
      * A String extra holding the provisioning trigger. It could be one of
      * {@link #PROVISIONING_TRIGGER_CLOUD_ENROLLMENT}, {@link #PROVISIONING_TRIGGER_QR_CODE},
-     * {@link #PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER} or {@link
+     * {@link #PROVISIONING_TRIGGER_MANAGED_ACCOUNT} or {@link
      * #PROVISIONING_TRIGGER_UNSPECIFIED}.
      *
      * <p>Use in an intent with action {@link
@@ -1247,7 +1276,7 @@
      * trigger has not been specified.
      * @see #PROVISIONING_TRIGGER_CLOUD_ENROLLMENT
      * @see #PROVISIONING_TRIGGER_QR_CODE
-     * @see #PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER
+     * @see #PROVISIONING_TRIGGER_MANAGED_ACCOUNT
      * @hide
      */
     @SystemApi
@@ -1257,7 +1286,7 @@
      * A value for {@link #EXTRA_PROVISIONING_TRIGGER} indicating that the provisioning
      * trigger is cloud enrollment.
      * @see #PROVISIONING_TRIGGER_QR_CODE
-     * @see #PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER
+     * @see #PROVISIONING_TRIGGER_MANAGED_ACCOUNT
      * @see #PROVISIONING_TRIGGER_UNSPECIFIED
      * @hide
      */
@@ -1268,7 +1297,7 @@
      * A value for {@link #EXTRA_PROVISIONING_TRIGGER} indicating that the provisioning
      * trigger is the QR code scanner.
      * @see #PROVISIONING_TRIGGER_CLOUD_ENROLLMENT
-     * @see #PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER
+     * @see #PROVISIONING_TRIGGER_MANAGED_ACCOUNT
      * @see #PROVISIONING_TRIGGER_UNSPECIFIED
      * @hide
      */
@@ -1278,15 +1307,78 @@
     /**
      * A value for {@link #EXTRA_PROVISIONING_TRIGGER} indicating that the provisioning
      * trigger is persistent device owner enrollment.
+     * @deprecated Use the broader {@link #PROVISIONING_TRIGGER_MANAGED_ACCOUNT} instead
      * @see #PROVISIONING_TRIGGER_CLOUD_ENROLLMENT
      * @see #PROVISIONING_TRIGGER_QR_CODE
      * @see #PROVISIONING_TRIGGER_UNSPECIFIED
      * @hide
      */
     @SystemApi
+    @Deprecated
     public static final int PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER = 3;
 
     /**
+     * A value for {@link #EXTRA_PROVISIONING_TRIGGER} indicating that the provisioning
+     * trigger is managed account enrollment.
+     * @see #PROVISIONING_TRIGGER_CLOUD_ENROLLMENT
+     * @see #PROVISIONING_TRIGGER_QR_CODE
+     * @see #PROVISIONING_TRIGGER_UNSPECIFIED
+     * @hide
+     */
+    @SystemApi
+    public static final int PROVISIONING_TRIGGER_MANAGED_ACCOUNT = 4;
+
+    /**
+     * A value for {@link #EXTRA_PROVISIONING_SUPPORTED_MODES} indicating that provisioning is
+     * organization-owned.
+     *
+     * <p>Using this value will cause the admin app's {@link #ACTION_GET_PROVISIONING_MODE}
+     * activity to have the {@link #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES} array extra
+     * contain {@link #PROVISIONING_MODE_MANAGED_PROFILE} and {@link
+     * #PROVISIONING_MODE_FULLY_MANAGED_DEVICE}.
+     *
+     * <p>Also, if this value is set, the admin app's {@link #ACTION_GET_PROVISIONING_MODE} activity
+     * will not receive the {@link #EXTRA_PROVISIONING_IMEI} and {@link
+     * #EXTRA_PROVISIONING_SERIAL_NUMBER} extras.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int SUPPORTED_MODES_ORGANIZATION_OWNED = 1;
+
+    /**
+     * A value for {@link #EXTRA_PROVISIONING_SUPPORTED_MODES} indicating that provisioning is
+     * personally-owned.
+     *
+     * <p>Using this value will cause the admin app's {@link #ACTION_GET_PROVISIONING_MODE}
+     * activity to have the {@link #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES} array extra
+     * contain only {@link #PROVISIONING_MODE_MANAGED_PROFILE}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int SUPPORTED_MODES_PERSONALLY_OWNED = 2;
+
+    /**
+     * A value for {@link #EXTRA_PROVISIONING_SUPPORTED_MODES} indicating that provisioning could
+     * be organization-owned or personally-owned.
+     *
+     * <p>Using this value will cause the admin app's {@link #ACTION_GET_PROVISIONING_MODE}
+     * activity to have the {@link #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES} array extra
+     * contain {@link
+     * #PROVISIONING_MODE_MANAGED_PROFILE}, {@link #PROVISIONING_MODE_FULLY_MANAGED_DEVICE} and
+     * {@link #PROVISIONING_MODE_MANAGED_PROFILE_ON_PERSONAL_DEVICE}.
+     *
+     * <p>Also, if this value is set, the admin app's {@link #ACTION_GET_PROVISIONING_MODE} activity
+     * will not receive the {@link #EXTRA_PROVISIONING_IMEI} and {@link
+     * #EXTRA_PROVISIONING_SERIAL_NUMBER} extras.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int SUPPORTED_MODES_ORGANIZATION_AND_PERSONALLY_OWNED = 3;
+
+    /**
      * This MIME type is used for starting the device owner provisioning.
      *
      * <p>During device owner provisioning a device admin app is set as the owner of the device.
@@ -2379,16 +2471,57 @@
 
     /**
      * An intent extra holding the provisioning mode returned by the administrator.
-     * The value for this extra should be one of the following:
-     * <ul>
-     *     <li>{@link #PROVISIONING_MODE_FULLY_MANAGED_DEVICE}</li>
-     *     <li>{@link #PROVISIONING_MODE_MANAGED_PROFILE}</li>
-     * </ul>
+     * The value of this extra must be one of the values provided in {@link
+     * #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES}, which is provided as an intent extra to
+     * the admin app's {@link #ACTION_GET_PROVISIONING_MODE} activity.
+     *
+     * @see #PROVISIONING_MODE_FULLY_MANAGED_DEVICE
+     * @see #PROVISIONING_MODE_MANAGED_PROFILE
      */
     public static final String EXTRA_PROVISIONING_MODE =
             "android.app.extra.PROVISIONING_MODE";
 
     /**
+     * An integer extra indication what provisioning modes should be available for the admin app
+     * to pick.
+     *
+     * <p>The default value is {@link #SUPPORTED_MODES_ORGANIZATION_OWNED}.
+     *
+     * <p>The value of this extra will determine the contents of the {@link
+     * #EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES} array that is passed to the admin app as an
+     * extra to its {@link #ACTION_GET_PROVISIONING_MODE} activity.
+     *
+     * <p>If one of the possible admin app choices is a personally-owned work profile, then the
+     * IMEI and serial number will not be passed to the admin app's {@link
+     * #ACTION_GET_PROVISIONING_MODE} activity via the {@link #EXTRA_PROVISIONING_IMEI} and {@link
+     * #EXTRA_PROVISIONING_SERIAL_NUMBER} respectively.
+     *
+     * <p>This extra is only respected when provided alongside the {@link
+     * #ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE} intent action.
+     *
+     * @see #SUPPORTED_MODES_ORGANIZATION_OWNED
+     * @see #SUPPORTED_MODES_PERSONALLY_OWNED
+     * @see #SUPPORTED_MODES_ORGANIZATION_AND_PERSONALLY_OWNED
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_PROVISIONING_SUPPORTED_MODES =
+            "android.app.extra.PROVISIONING_SUPPORTED_MODES";
+
+    /**
+     * An {@link ArrayList} of {@link Integer} extra specifying the allowed provisioning modes.
+     * <p>This extra will be passed to the admin app's {@link #ACTION_GET_PROVISIONING_MODE}
+     * activity, whose result intent must contain {@link #EXTRA_PROVISIONING_MODE} set to one of
+     * the values in this array.
+     * <p>If the value set to {@link #EXTRA_PROVISIONING_MODE} is not in the array,
+     * provisioning will fail.
+     * @see #PROVISIONING_MODE_MANAGED_PROFILE
+     * @see #PROVISIONING_MODE_FULLY_MANAGED_DEVICE
+     */
+    public static final String EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES =
+            "android.app.extra.PROVISIONING_ALLOWED_PROVISIONING_MODES";
+
+    /**
      * The provisioning mode for fully managed device.
      */
     public static final int PROVISIONING_MODE_FULLY_MANAGED_DEVICE = 1;
@@ -2399,6 +2532,11 @@
     public static final int PROVISIONING_MODE_MANAGED_PROFILE = 2;
 
     /**
+     * The provisioning mode for a work profile on a personal device.
+     */
+    public static final int PROVISIONING_MODE_MANAGED_PROFILE_ON_PERSONAL_DEVICE = 3;
+
+    /**
      * Activity action: Starts the administrator to show policy compliance for the provisioning.
      * This action is used any time that the administrator has an opportunity to show policy
      * compliance before the end of setup wizard. This could happen as part of the admin-integrated
@@ -2454,27 +2592,27 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface PersonalAppsSuspensionReason {}
 
-    // TODO(b/172376923) - make all (or none) @TestApi
-
     /** @hide */
     @TestApi
     public static final int OPERATION_LOCK_NOW = 1;
-
     /** @hide */
+    @TestApi
     public static final int OPERATION_SWITCH_USER = 2;
     /** @hide */
+    @TestApi
     public static final int OPERATION_START_USER_IN_BACKGROUND = 3;
     /** @hide */
+    @TestApi
     public static final int OPERATION_STOP_USER = 4;
     /** @hide */
+    @TestApi
     public static final int OPERATION_CREATE_AND_MANAGE_USER = 5;
     /** @hide */
+    @TestApi
     public static final int OPERATION_REMOVE_USER = 6;
 
     private static final String PREFIX_OPERATION = "OPERATION_";
 
-
-    // TODO(b/172376923) - add all operations
     /** @hide */
     @IntDef(prefix = PREFIX_OPERATION, value = {
             OPERATION_LOCK_NOW,
@@ -2489,6 +2627,8 @@
     }
 
     /** @hide */
+    @TestApi
+    @NonNull
     public static String operationToString(@DevicePolicyOperation int operation) {
         return DebugUtils.constantToString(DevicePolicyManager.class, PREFIX_OPERATION, operation);
     }
@@ -12397,4 +12537,21 @@
         }
         return false;
     }
+
+    /**
+     * Used by CTS to set the result of the next safety operation check.
+     *
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS)
+    public void setNextOperationSafety(@DevicePolicyOperation int operation, boolean safe) {
+        if (mService != null) {
+            try {
+                mService.setNextOperationSafety(operation, safe);
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        }
+    }
 }
diff --git a/core/java/android/app/admin/FactoryResetProtectionPolicy.java b/core/java/android/app/admin/FactoryResetProtectionPolicy.java
index aa94e81..40ae1f0 100644
--- a/core/java/android/app/admin/FactoryResetProtectionPolicy.java
+++ b/core/java/android/app/admin/FactoryResetProtectionPolicy.java
@@ -26,10 +26,10 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -201,10 +201,10 @@
      * @hide
      */
     @Nullable
-    public static FactoryResetProtectionPolicy readFromXml(@NonNull XmlPullParser parser) {
+    public static FactoryResetProtectionPolicy readFromXml(@NonNull TypedXmlPullParser parser) {
         try {
-            boolean factoryResetProtectionEnabled = Boolean.parseBoolean(
-                    parser.getAttributeValue(null, KEY_FACTORY_RESET_PROTECTION_ENABLED));
+            boolean factoryResetProtectionEnabled = parser.getAttributeBoolean(null,
+                    KEY_FACTORY_RESET_PROTECTION_ENABLED, false);
 
             List<String> factoryResetProtectionAccounts = new ArrayList<>();
             int outerDepth = parser.getDepth();
@@ -232,9 +232,9 @@
     /**
      * @hide
      */
-    public void writeToXml(@NonNull XmlSerializer out) throws IOException {
-        out.attribute(null, KEY_FACTORY_RESET_PROTECTION_ENABLED,
-                Boolean.toString(mFactoryResetProtectionEnabled));
+    public void writeToXml(@NonNull TypedXmlSerializer out) throws IOException {
+        out.attributeBoolean(null, KEY_FACTORY_RESET_PROTECTION_ENABLED,
+                mFactoryResetProtectionEnabled);
         for (String account : mFactoryResetProtectionAccounts) {
             out.startTag(null, KEY_FACTORY_RESET_PROTECTION_ACCOUNT);
             out.attribute(null, ATTR_VALUE, account);
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 8be3cdc..e21fee2 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -484,5 +484,7 @@
 
     long getManagedProfileMaximumTimeOff(in ComponentName admin);
     void setManagedProfileMaximumTimeOff(in ComponentName admin, long timeoutMs);
-    boolean canProfileOwnerResetPasswordWhenLocked(in int userId);
+    boolean canProfileOwnerResetPasswordWhenLocked(int userId);
+
+    void setNextOperationSafety(int operation, boolean safe);
 }
diff --git a/core/java/android/app/admin/OWNERS b/core/java/android/app/admin/OWNERS
new file mode 100644
index 0000000..64a1d27
--- /dev/null
+++ b/core/java/android/app/admin/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 142675
+
+yamasani@google.com
+rubinxu@google.com
diff --git a/core/java/android/app/admin/SystemUpdateInfo.java b/core/java/android/app/admin/SystemUpdateInfo.java
index 53b2386..b88bf76 100644
--- a/core/java/android/app/admin/SystemUpdateInfo.java
+++ b/core/java/android/app/admin/SystemUpdateInfo.java
@@ -21,9 +21,11 @@
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.Log;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
+import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -34,6 +36,7 @@
  * A class containing information about a pending system update.
  */
 public final class SystemUpdateInfo implements Parcelable {
+    private static final String TAG = "SystemUpdateInfo";
 
     /**
      * Represents it is unknown whether the system update is a security patch.
@@ -125,27 +128,32 @@
             };
 
     /** @hide */
-    public void writeToXml(XmlSerializer out, String tag) throws IOException {
+    public void writeToXml(TypedXmlSerializer out, String tag) throws IOException {
         out.startTag(null, tag);
-        out.attribute(null, ATTR_RECEIVED_TIME, String.valueOf(mReceivedTime));
-        out.attribute(null, ATTR_SECURITY_PATCH_STATE, String.valueOf(mSecurityPatchState));
+        out.attributeLong(null, ATTR_RECEIVED_TIME, mReceivedTime);
+        out.attributeInt(null, ATTR_SECURITY_PATCH_STATE, mSecurityPatchState);
         out.attribute(null, ATTR_ORIGINAL_BUILD , Build.FINGERPRINT);
         out.endTag(null, tag);
     }
 
     /** @hide */
     @Nullable
-    public static SystemUpdateInfo readFromXml(XmlPullParser parser) {
+    public static SystemUpdateInfo readFromXml(TypedXmlPullParser parser) {
         // If an OTA has been applied (build fingerprint has changed), discard stale info.
         final String buildFingerprint = parser.getAttributeValue(null, ATTR_ORIGINAL_BUILD );
         if (!Build.FINGERPRINT.equals(buildFingerprint)) {
             return null;
         }
-        final long receivedTime =
-                Long.parseLong(parser.getAttributeValue(null, ATTR_RECEIVED_TIME));
-        final int securityPatchState =
-                Integer.parseInt(parser.getAttributeValue(null, ATTR_SECURITY_PATCH_STATE));
-        return new SystemUpdateInfo(receivedTime, securityPatchState);
+        try {
+            final long receivedTime =
+                    parser.getAttributeLong(null, ATTR_RECEIVED_TIME);
+            final int securityPatchState =
+                    parser.getAttributeInt(null, ATTR_SECURITY_PATCH_STATE);
+            return new SystemUpdateInfo(receivedTime, securityPatchState);
+        } catch (XmlPullParserException e) {
+            Log.w(TAG, "Load xml failed", e);
+            return null;
+        }
     }
 
     @Override
diff --git a/core/java/android/app/admin/SystemUpdatePolicy.java b/core/java/android/app/admin/SystemUpdatePolicy.java
index 2ba2c04..68ac4cc 100644
--- a/core/java/android/app/admin/SystemUpdatePolicy.java
+++ b/core/java/android/app/admin/SystemUpdatePolicy.java
@@ -26,10 +26,10 @@
 import android.os.Parcelable;
 import android.util.Log;
 import android.util.Pair;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -741,38 +741,31 @@
      * system server from a validated policy object previously.
      * @hide
      */
-    public static SystemUpdatePolicy restoreFromXml(XmlPullParser parser) {
+    public static SystemUpdatePolicy restoreFromXml(TypedXmlPullParser parser) {
         try {
             SystemUpdatePolicy policy = new SystemUpdatePolicy();
-            String value = parser.getAttributeValue(null, KEY_POLICY_TYPE);
-            if (value != null) {
-                policy.mPolicyType = Integer.parseInt(value);
+            policy.mPolicyType =
+                    parser.getAttributeInt(null, KEY_POLICY_TYPE, TYPE_UNKNOWN);
+            policy.mMaintenanceWindowStart =
+                    parser.getAttributeInt(null, KEY_INSTALL_WINDOW_START, 0);
+            policy.mMaintenanceWindowEnd =
+                    parser.getAttributeInt(null, KEY_INSTALL_WINDOW_END, 0);
 
-                value = parser.getAttributeValue(null, KEY_INSTALL_WINDOW_START);
-                if (value != null) {
-                    policy.mMaintenanceWindowStart = Integer.parseInt(value);
+            int outerDepth = parser.getDepth();
+            int type;
+            while ((type = parser.next()) != END_DOCUMENT
+                    && (type != END_TAG || parser.getDepth() > outerDepth)) {
+                if (type == END_TAG || type == TEXT) {
+                    continue;
                 }
-                value = parser.getAttributeValue(null, KEY_INSTALL_WINDOW_END);
-                if (value != null) {
-                    policy.mMaintenanceWindowEnd = Integer.parseInt(value);
+                if (!parser.getName().equals(KEY_FREEZE_TAG)) {
+                    continue;
                 }
-
-                int outerDepth = parser.getDepth();
-                int type;
-                while ((type = parser.next()) != END_DOCUMENT
-                        && (type != END_TAG || parser.getDepth() > outerDepth)) {
-                    if (type == END_TAG || type == TEXT) {
-                        continue;
-                    }
-                    if (!parser.getName().equals(KEY_FREEZE_TAG)) {
-                        continue;
-                    }
-                    policy.mFreezePeriods.add(new FreezePeriod(
-                            MonthDay.parse(parser.getAttributeValue(null, KEY_FREEZE_START)),
-                            MonthDay.parse(parser.getAttributeValue(null, KEY_FREEZE_END))));
-                }
-                return policy;
+                policy.mFreezePeriods.add(new FreezePeriod(
+                        MonthDay.parse(parser.getAttributeValue(null, KEY_FREEZE_START)),
+                        MonthDay.parse(parser.getAttributeValue(null, KEY_FREEZE_END))));
             }
+            return policy;
         } catch (NumberFormatException | XmlPullParserException | IOException e) {
             // Fail through
             Log.w(TAG, "Load xml failed", e);
@@ -783,10 +776,10 @@
     /**
      * @hide
      */
-    public void saveToXml(XmlSerializer out) throws IOException {
-        out.attribute(null, KEY_POLICY_TYPE, Integer.toString(mPolicyType));
-        out.attribute(null, KEY_INSTALL_WINDOW_START, Integer.toString(mMaintenanceWindowStart));
-        out.attribute(null, KEY_INSTALL_WINDOW_END, Integer.toString(mMaintenanceWindowEnd));
+    public void saveToXml(TypedXmlSerializer out) throws IOException {
+        out.attributeInt(null, KEY_POLICY_TYPE, mPolicyType);
+        out.attributeInt(null, KEY_INSTALL_WINDOW_START, mMaintenanceWindowStart);
+        out.attributeInt(null, KEY_INSTALL_WINDOW_END, mMaintenanceWindowEnd);
         for (int i = 0; i < mFreezePeriods.size(); i++) {
             FreezePeriod interval = mFreezePeriods.get(i);
             out.startTag(null, KEY_FREEZE_TAG);
diff --git a/core/java/android/app/assist/OWNERS b/core/java/android/app/assist/OWNERS
new file mode 100644
index 0000000..46b5ea0
--- /dev/null
+++ b/core/java/android/app/assist/OWNERS
@@ -0,0 +1,7 @@
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 44a4b78..673de8f 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -205,13 +205,16 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
         OperationType.BACKUP,
-        OperationType.MIGRATION
+        OperationType.MIGRATION,
+        OperationType.ADB_BACKUP,
     })
     public @interface OperationType {
-        // A regular backup / restore operation.
+        // A backup / restore to / from an off-device location, e.g. cloud.
         int BACKUP = 0;
-        // A full migration: all app data for non-system apps is eligible.
+        // A direct transfer to another device.
         int MIGRATION = 1;
+        // Backup via adb, data saved on the host machine.
+        int ADB_BACKUP = 3;
     }
 
     private Context mContext;
diff --git a/core/java/android/app/contentsuggestions/OWNERS b/core/java/android/app/contentsuggestions/OWNERS
new file mode 100644
index 0000000..482abb2
--- /dev/null
+++ b/core/java/android/app/contentsuggestions/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 643919
+
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/app/prediction/OWNERS b/core/java/android/app/prediction/OWNERS
new file mode 100644
index 0000000..fe012da
--- /dev/null
+++ b/core/java/android/app/prediction/OWNERS
@@ -0,0 +1,2 @@
+adamcohen@google.com
+sunnygoyal@google.com
diff --git a/core/java/android/app/role/IRoleManager.aidl b/core/java/android/app/role/IRoleManager.aidl
index 6d790b3..5fc25f0 100644
--- a/core/java/android/app/role/IRoleManager.aidl
+++ b/core/java/android/app/role/IRoleManager.aidl
@@ -53,5 +53,9 @@
 
     List<String> getHeldRolesFromController(in String packageName);
 
-    String getDefaultSmsPackage(int userId);
+    String getBrowserRoleHolder(int userId);
+
+    boolean setBrowserRoleHolder(String packageName, int userId);
+
+    String getSmsRoleHolder(int userId);
 }
diff --git a/core/java/android/app/role/OWNERS b/core/java/android/app/role/OWNERS
index b94d988..b8076366 100644
--- a/core/java/android/app/role/OWNERS
+++ b/core/java/android/app/role/OWNERS
@@ -1,6 +1,4 @@
-svetoslavganov@google.com
-moltmann@google.com
+# Bug component: 137825
+
 zhanghai@google.com
-evanseverson@google.com
-eugenesusla@google.com
-ntmyren@google.com
+moltmann@google.com
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index 408ce0f..8b2e07b 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -613,12 +613,56 @@
     }
 
     /**
-     * Allows getting the role holder for {@link #ROLE_SMS} without
-     * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}, as required by
-     * {@link android.provider.Telephony.Sms#getDefaultSmsPackage(Context)}
+     * Get the role holder of {@link #ROLE_BROWSER} without requiring
+     * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}, as in
+     * {@link android.content.pm.PackageManager#getDefaultBrowserPackageNameAsUser(int)}
      *
-     * @param userId The user ID to get the default SMS package for.
-     * @return the package name of the default SMS app, or {@code null} if not configured.
+     * @param userId the user ID
+     * @return the package name of the default browser, or {@code null} if none
+     *
+     * @hide
+     */
+    @Nullable
+    //@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public String getBrowserRoleHolder(@UserIdInt int userId) {
+        try {
+            return mService.getBrowserRoleHolder(userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set the role holder of {@link #ROLE_BROWSER} requiring
+     * {@link Manifest.permission.SET_PREFERRED_APPLICATIONS} instead of
+     * {@link Manifest.permission#MANAGE_ROLE_HOLDERS}, as in
+     * {@link android.content.pm.PackageManager#setDefaultBrowserPackageNameAsUser(String, int)}
+     *
+     * @param packageName the package name of the default browser, or {@code null} if none
+     * @param userId the user ID
+     * @return whether the default browser was set successfully
+     *
+     * @hide
+     */
+    @Nullable
+    @RequiresPermission(Manifest.permission.SET_PREFERRED_APPLICATIONS)
+    //@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public boolean setBrowserRoleHolder(@Nullable String packageName, @UserIdInt int userId) {
+        try {
+            return mService.setBrowserRoleHolder(packageName, userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Allows getting the role holder for {@link #ROLE_SMS} without requiring
+     * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}, as in
+     * {@link android.provider.Telephony.Sms#getDefaultSmsPackage(Context)}.
+     *
+     * @param userId the user ID to get the default SMS package for
+     * @return the package name of the default SMS app, or {@code null} if none
+     *
      * @hide
      */
     @Nullable
@@ -626,7 +670,7 @@
     @TestApi
     public String getSmsRoleHolder(@UserIdInt int userId) {
         try {
-            return mService.getDefaultSmsPackage(userId);
+            return mService.getSmsRoleHolder(userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/servertransaction/OWNERS b/core/java/android/app/servertransaction/OWNERS
new file mode 100644
index 0000000..aa6248e
--- /dev/null
+++ b/core/java/android/app/servertransaction/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 316125
+
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java
index f7c645e..813e0f9 100644
--- a/core/java/android/app/servertransaction/PauseActivityItem.java
+++ b/core/java/android/app/servertransaction/PauseActivityItem.java
@@ -20,12 +20,11 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.ActivityTaskManager;
+import android.app.ActivityClient;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.os.IBinder;
 import android.os.Parcel;
-import android.os.RemoteException;
 import android.os.Trace;
 
 /**
@@ -61,12 +60,8 @@
         if (mDontReport) {
             return;
         }
-        try {
-            // TODO(lifecycler): Use interface callback instead of AMS.
-            ActivityTaskManager.getService().activityPaused(token);
-        } catch (RemoteException ex) {
-            throw ex.rethrowFromSystemServer();
-        }
+        // TODO(lifecycler): Use interface callback instead of actual implementation.
+        ActivityClient.getInstance().activityPaused(token);
     }
 
 
diff --git a/core/java/android/app/servertransaction/PendingTransactionActions.java b/core/java/android/app/servertransaction/PendingTransactionActions.java
index 52ba8fb..a47fe82 100644
--- a/core/java/android/app/servertransaction/PendingTransactionActions.java
+++ b/core/java/android/app/servertransaction/PendingTransactionActions.java
@@ -18,13 +18,11 @@
 
 import static android.app.ActivityThread.DEBUG_MEMORY_TRIM;
 
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
+import android.app.ActivityClient;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.PersistableBundle;
-import android.os.RemoteException;
 import android.os.TransactionTooLargeException;
 import android.util.Log;
 import android.util.LogWriter;
@@ -142,9 +140,9 @@
             try {
                 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + mActivity);
                 // TODO(lifecycler): Use interface callback instead of AMS.
-                ActivityTaskManager.getService().activityStopped(
+                ActivityClient.getInstance().activityStopped(
                         mActivity.token, mState, mPersistentState, mDescription);
-            } catch (RemoteException ex) {
+            } catch (RuntimeException ex) {
                 // Dump statistics about bundle to help developers debug
                 final LogWriter writer = new LogWriter(Log.WARN, TAG);
                 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
@@ -153,12 +151,12 @@
                 pw.println("PersistableBundle stats:");
                 Bundle.dumpStats(pw, mPersistentState);
 
-                if (ex instanceof TransactionTooLargeException
+                if (ex.getCause() instanceof TransactionTooLargeException
                         && mActivity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
                     Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
                     return;
                 }
-                throw ex.rethrowFromSystemServer();
+                throw ex;
             }
         }
     }
diff --git a/core/java/android/app/servertransaction/ResumeActivityItem.java b/core/java/android/app/servertransaction/ResumeActivityItem.java
index b4523f5..d451599 100644
--- a/core/java/android/app/servertransaction/ResumeActivityItem.java
+++ b/core/java/android/app/servertransaction/ResumeActivityItem.java
@@ -20,13 +20,12 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityClient;
 import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.os.IBinder;
 import android.os.Parcel;
-import android.os.RemoteException;
 import android.os.Trace;
 
 /**
@@ -60,12 +59,8 @@
     @Override
     public void postExecute(ClientTransactionHandler client, IBinder token,
             PendingTransactionActions pendingActions) {
-        try {
-            // TODO(lifecycler): Use interface callback instead of AMS.
-            ActivityTaskManager.getService().activityResumed(token);
-        } catch (RemoteException ex) {
-            throw ex.rethrowFromSystemServer();
-        }
+        // TODO(lifecycler): Use interface callback instead of actual implementation.
+        ActivityClient.getInstance().activityResumed(token);
     }
 
     @Override
diff --git a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
index 2b0c1b9..5cd3d68f 100644
--- a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
+++ b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
@@ -19,12 +19,11 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.ActivityTaskManager;
+import android.app.ActivityClient;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.ClientTransactionHandler;
 import android.os.IBinder;
 import android.os.Parcel;
-import android.os.RemoteException;
 import android.os.Trace;
 
 /**
@@ -56,11 +55,7 @@
         // 2. Activity wasn't RESUMED yet, which means that it didn't receive the top state yet.
         // 3. Activity is PAUSED or in other lifecycle state after PAUSED. In this case top resumed
         // state loss was already called right before pausing.
-        try {
-            ActivityTaskManager.getService().activityTopResumedStateLost();
-        } catch (RemoteException ex) {
-            throw ex.rethrowFromSystemServer();
-        }
+        ActivityClient.getInstance().activityTopResumedStateLost();
     }
 
 
diff --git a/core/java/android/app/slice/OWNERS b/core/java/android/app/slice/OWNERS
new file mode 100644
index 0000000..b0a44fb
--- /dev/null
+++ b/core/java/android/app/slice/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 342804
+
+sunnygoyal@google.com
+dsandler@android.com
+dsandler@google.com
+adamcohen@google.com
diff --git a/core/java/android/app/timedetector/OWNERS b/core/java/android/app/timedetector/OWNERS
new file mode 100644
index 0000000..8c11324
--- /dev/null
+++ b/core/java/android/app/timedetector/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 847766
+
+narayan@google.com
+nfuller@google.com
diff --git a/core/java/android/app/timezone/OWNERS b/core/java/android/app/timezone/OWNERS
new file mode 100644
index 0000000..8c11324
--- /dev/null
+++ b/core/java/android/app/timezone/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 847766
+
+narayan@google.com
+nfuller@google.com
diff --git a/core/java/android/app/usage/OWNERS b/core/java/android/app/usage/OWNERS
new file mode 100644
index 0000000..a33d0ad
--- /dev/null
+++ b/core/java/android/app/usage/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 532296
+
+yamasani@google.com
+mwachens@google.com
+varunshah@google.com
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 3522b1b..081f4fd 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -383,6 +383,10 @@
         public int mClassToken = UNASSIGNED_TOKEN;
 
         /**
+         * Uniquely identifies an activity. It's possible for two activities with the same
+         * pkg/class name to be in lifecycle at the same time. The mInstanceId is guaranteed to be
+         * unique per activity across all apps (not just within a single app).
+         *
          * {@hide}
          */
         public int mInstanceId;
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 130a20d..c4333ac 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -68,6 +68,9 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface ResizeModeFlags {}
 
+    /** {@hide} */
+    public static final int WIDGET_CATEGORY_UNKNOWN = -1;
+
     /**
      * Indicates that the widget can be displayed on the home screen. This is the default value.
      */
diff --git a/core/java/android/attention/OWNERS b/core/java/android/attention/OWNERS
new file mode 100644
index 0000000..dd579b6
--- /dev/null
+++ b/core/java/android/attention/OWNERS
@@ -0,0 +1 @@
+asalo@google.com
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index c07cd52..1713a0c 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -3689,7 +3689,7 @@
      *
      * @hide
      */
-    public abstract class BluetoothConnectionCallback {
+    public abstract static class BluetoothConnectionCallback {
         /**
          * Callback triggered when a bluetooth device (classic or BLE) is connected
          * @param device is the connected bluetooth device
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 603a7ff..7fe18a0 100755
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -426,13 +426,13 @@
                     return false;
             }
         } else if (profile == PROFILE_HID) {
-            return (getDeviceClass() & Device.Major.PERIPHERAL) == Device.Major.PERIPHERAL;
+            return getMajorDeviceClass() == Device.Major.PERIPHERAL;
         } else if (profile == PROFILE_PANU || profile == PROFILE_NAP) {
             // No good way to distinguish between the two, based on class bits.
             if (hasService(Service.NETWORKING)) {
                 return true;
             }
-            return (getDeviceClass() & Device.Major.NETWORKING) == Device.Major.NETWORKING;
+            return getMajorDeviceClass() == Device.Major.NETWORKING;
         } else {
             return false;
         }
diff --git a/core/java/android/bluetooth/OWNERS b/core/java/android/bluetooth/OWNERS
new file mode 100644
index 0000000..3523ee0
--- /dev/null
+++ b/core/java/android/bluetooth/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 27441
+
+zachoverflow@google.com
+siyuanh@google.com
diff --git a/core/java/android/bluetooth/le/OWNERS b/core/java/android/bluetooth/le/OWNERS
new file mode 100644
index 0000000..3523ee0
--- /dev/null
+++ b/core/java/android/bluetooth/le/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 27441
+
+zachoverflow@google.com
+siyuanh@google.com
diff --git a/core/java/android/companion/Association.java b/core/java/android/companion/Association.java
index 06a3f2f..17bf11b 100644
--- a/core/java/android/companion/Association.java
+++ b/core/java/android/companion/Association.java
@@ -37,6 +37,8 @@
     private final @UserIdInt int mUserId;
     private final @NonNull String mDeviceMacAddress;
     private final @NonNull String mPackageName;
+    private final @Nullable String mDeviceProfile;
+    private final boolean mKeepProfilePrivilegesWhenDeviceAway;
 
     /** @hide */
     public int getUserId() {
@@ -45,7 +47,7 @@
 
 
 
-    // Code below generated by codegen v1.0.15.
+    // Code below generated by codegen v1.0.21.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -67,7 +69,9 @@
     public Association(
             @UserIdInt int userId,
             @NonNull String deviceMacAddress,
-            @NonNull String packageName) {
+            @NonNull String packageName,
+            @Nullable String deviceProfile,
+            boolean keepProfilePrivilegesWhenDeviceAway) {
         this.mUserId = userId;
         com.android.internal.util.AnnotationValidations.validate(
                 UserIdInt.class, null, mUserId);
@@ -77,6 +81,8 @@
         this.mPackageName = packageName;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mPackageName);
+        this.mDeviceProfile = deviceProfile;
+        this.mKeepProfilePrivilegesWhenDeviceAway = keepProfilePrivilegesWhenDeviceAway;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -91,6 +97,16 @@
         return mPackageName;
     }
 
+    @DataClass.Generated.Member
+    public @Nullable String getDeviceProfile() {
+        return mDeviceProfile;
+    }
+
+    @DataClass.Generated.Member
+    public boolean isKeepProfilePrivilegesWhenDeviceAway() {
+        return mKeepProfilePrivilegesWhenDeviceAway;
+    }
+
     @Override
     @DataClass.Generated.Member
     public String toString() {
@@ -100,7 +116,9 @@
         return "Association { " +
                 "userId = " + mUserId + ", " +
                 "deviceMacAddress = " + mDeviceMacAddress + ", " +
-                "packageName = " + mPackageName +
+                "packageName = " + mPackageName + ", " +
+                "deviceProfile = " + mDeviceProfile + ", " +
+                "keepProfilePrivilegesWhenDeviceAway = " + mKeepProfilePrivilegesWhenDeviceAway +
         " }";
     }
 
@@ -119,7 +137,9 @@
         return true
                 && mUserId == that.mUserId
                 && Objects.equals(mDeviceMacAddress, that.mDeviceMacAddress)
-                && Objects.equals(mPackageName, that.mPackageName);
+                && Objects.equals(mPackageName, that.mPackageName)
+                && Objects.equals(mDeviceProfile, that.mDeviceProfile)
+                && mKeepProfilePrivilegesWhenDeviceAway == that.mKeepProfilePrivilegesWhenDeviceAway;
     }
 
     @Override
@@ -132,6 +152,8 @@
         _hash = 31 * _hash + mUserId;
         _hash = 31 * _hash + Objects.hashCode(mDeviceMacAddress);
         _hash = 31 * _hash + Objects.hashCode(mPackageName);
+        _hash = 31 * _hash + Objects.hashCode(mDeviceProfile);
+        _hash = 31 * _hash + Boolean.hashCode(mKeepProfilePrivilegesWhenDeviceAway);
         return _hash;
     }
 
@@ -141,9 +163,14 @@
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
+        byte flg = 0;
+        if (mKeepProfilePrivilegesWhenDeviceAway) flg |= 0x10;
+        if (mDeviceProfile != null) flg |= 0x8;
+        dest.writeByte(flg);
         dest.writeInt(mUserId);
         dest.writeString(mDeviceMacAddress);
         dest.writeString(mPackageName);
+        if (mDeviceProfile != null) dest.writeString(mDeviceProfile);
     }
 
     @Override
@@ -157,9 +184,12 @@
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
+        byte flg = in.readByte();
+        boolean keepProfilePrivilegesWhenDeviceAway = (flg & 0x10) != 0;
         int userId = in.readInt();
         String deviceMacAddress = in.readString();
         String packageName = in.readString();
+        String deviceProfile = (flg & 0x8) == 0 ? null : in.readString();
 
         this.mUserId = userId;
         com.android.internal.util.AnnotationValidations.validate(
@@ -170,6 +200,8 @@
         this.mPackageName = packageName;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mPackageName);
+        this.mDeviceProfile = deviceProfile;
+        this.mKeepProfilePrivilegesWhenDeviceAway = keepProfilePrivilegesWhenDeviceAway;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -189,10 +221,10 @@
     };
 
     @DataClass.Generated(
-            time = 1599083149942L,
-            codegenVersion = "1.0.15",
+            time = 1606940835778L,
+            codegenVersion = "1.0.21",
             sourceFile = "frameworks/base/core/java/android/companion/Association.java",
-            inputSignatures = "private final @android.annotation.UserIdInt int mUserId\nprivate final @android.annotation.NonNull java.lang.String mDeviceMacAddress\nprivate final @android.annotation.NonNull java.lang.String mPackageName\npublic  int getUserId()\nclass Association extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstructor=true)")
+            inputSignatures = "private final @android.annotation.UserIdInt int mUserId\nprivate final @android.annotation.NonNull java.lang.String mDeviceMacAddress\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate final  boolean mKeepProfilePrivilegesWhenDeviceAway\npublic  int getUserId()\nclass Association extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstructor=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java
index 58445a7..495f94f 100644
--- a/core/java/android/content/SyncAdaptersCache.java
+++ b/core/java/android/content/SyncAdaptersCache.java
@@ -25,12 +25,12 @@
 import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.SparseArray;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
 import com.android.internal.annotations.GuardedBy;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -142,12 +142,12 @@
     }
 
     static class MySerializer implements XmlSerializerAndParser<SyncAdapterType> {
-        public void writeAsXml(SyncAdapterType item, XmlSerializer out) throws IOException {
+        public void writeAsXml(SyncAdapterType item, TypedXmlSerializer out) throws IOException {
             out.attribute(null, "authority", item.authority);
             out.attribute(null, "accountType", item.accountType);
         }
 
-        public SyncAdapterType createFromXml(XmlPullParser parser)
+        public SyncAdapterType createFromXml(TypedXmlPullParser parser)
                 throws IOException, XmlPullParserException {
             final String authority = parser.getAttributeValue(null, "authority");
             final String accountType = parser.getAttributeValue(null, "accountType");
diff --git a/core/java/android/content/om/OWNERS b/core/java/android/content/om/OWNERS
new file mode 100644
index 0000000..91a0abf
--- /dev/null
+++ b/core/java/android/content/om/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 568631
+
+toddke@android.com
+toddke@google.com
+patb@google.com
+rtmitchell@google.com
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index 6ccbc36..9a73be9 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -33,6 +33,7 @@
     ParcelFileDescriptor openRead(String name);
 
     void write(String name, long offsetBytes, long lengthBytes, in ParcelFileDescriptor fd);
+    void stageViaHardLink(String target);
 
     void addChecksums(String name, in Checksum[] checksums);
 
diff --git a/core/java/android/content/pm/IntentFilterVerificationInfo.java b/core/java/android/content/pm/IntentFilterVerificationInfo.java
index 0a913ac..56b8bd8 100644
--- a/core/java/android/content/pm/IntentFilterVerificationInfo.java
+++ b/core/java/android/content/pm/IntentFilterVerificationInfo.java
@@ -16,11 +16,11 @@
 
 package android.content.pm;
 
-import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
-import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
 
 import android.annotation.SystemApi;
 import android.os.Parcel;
@@ -28,12 +28,13 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
 import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -72,7 +73,7 @@
     }
 
     /** @hide */
-    public IntentFilterVerificationInfo(XmlPullParser parser)
+    public IntentFilterVerificationInfo(TypedXmlPullParser parser)
             throws IOException, XmlPullParserException {
         readFromXml(parser);
     }
@@ -121,7 +122,7 @@
         return sb.toString();
     }
 
-    String getStringFromXml(XmlPullParser parser, String attribute, String defaultValue) {
+    String getStringFromXml(TypedXmlPullParser parser, String attribute, String defaultValue) {
         String value = parser.getAttributeValue(null, attribute);
         if (value == null) {
             String msg = "Missing element under " + TAG +": " + attribute + " at " +
@@ -133,20 +134,12 @@
         }
     }
 
-    int getIntFromXml(XmlPullParser parser, String attribute, int defaultValue) {
-        String value = parser.getAttributeValue(null, attribute);
-        if (TextUtils.isEmpty(value)) {
-            String msg = "Missing element under " + TAG +": " + attribute + " at " +
-                    parser.getPositionDescription();
-            Log.w(TAG, msg);
-            return defaultValue;
-        } else {
-            return Integer.parseInt(value);
-        }
+    int getIntFromXml(TypedXmlPullParser parser, String attribute, int defaultValue) {
+        return parser.getAttributeInt(null, attribute, defaultValue);
     }
 
     /** @hide */
-    public void readFromXml(XmlPullParser parser) throws XmlPullParserException,
+    public void readFromXml(TypedXmlPullParser parser) throws XmlPullParserException,
             IOException {
         mPackageName = getStringFromXml(parser, ATTR_PACKAGE_NAME, null);
         if (mPackageName == null) {
@@ -182,9 +175,9 @@
     }
 
     /** @hide */
-    public void writeToXml(XmlSerializer serializer) throws IOException {
+    public void writeToXml(TypedXmlSerializer serializer) throws IOException {
         serializer.attribute(null, ATTR_PACKAGE_NAME, mPackageName);
-        serializer.attribute(null, ATTR_STATUS, String.valueOf(mStatus));
+        serializer.attributeInt(null, ATTR_STATUS, mStatus);
         for (String str : mDomains) {
             serializer.startTag(null, TAG_DOMAIN);
             serializer.attribute(null, ATTR_DOMAIN_NAME, str);
diff --git a/core/java/android/content/pm/OWNERS b/core/java/android/content/pm/OWNERS
index a16bb4f..3a590da 100644
--- a/core/java/android/content/pm/OWNERS
+++ b/core/java/android/content/pm/OWNERS
@@ -1 +1,7 @@
+# Bug component: 36137
+
+toddke@android.com
+toddke@google.com
+patb@google.com
+
 per-file PackageParser.java = chiuwinson@google.com
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 0dcfd38..4347f99 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -37,6 +37,7 @@
 import android.content.IntentSender;
 import android.content.pm.PackageManager.DeleteFlags;
 import android.content.pm.PackageManager.InstallReason;
+import android.content.pm.PackageManager.InstallScenario;
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Build;
@@ -1049,6 +1050,31 @@
         }
 
         /**
+         * Populate an APK file by creating a hard link to avoid the need to copy.
+         * <p>
+         * Note this API is used by RollbackManager only and can only be called from system_server.
+         * {@code target} will be relabeled if link is created successfully. RollbackManager has
+         * to delete {@code target} when the session is committed successfully to avoid SELinux
+         * label conflicts.
+         * <p>
+         * Note No more bytes should be written to the file once the link is created successfully.
+         *
+         * @param target the path of the link target
+         *
+         * @hide
+         */
+        public void stageViaHardLink(String target) throws IOException {
+            try {
+                mSession.stageViaHardLink(target);
+            } catch (RuntimeException e) {
+                ExceptionUtils.maybeUnwrapIOException(e);
+                throw e;
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
          * Ensure that any outstanding data for given stream has been committed
          * to disk. This is only valid for streams returned from
          * {@link #openWrite(String, long, long)}.
@@ -1500,6 +1526,14 @@
         public int installLocation = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
         /** {@hide} */
         public @InstallReason int installReason = PackageManager.INSTALL_REASON_UNKNOWN;
+        /**
+         * {@hide}
+         *
+         * This flag indicates which installation scenario best describes this session.  The system
+         * may use this value when making decisions about how to handle the installation, such as
+         * prioritizing system health or user experience.
+         */
+        public @InstallScenario int installScenario = PackageManager.INSTALL_SCENARIO_DEFAULT;
         /** {@hide} */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         public long sizeBytes = -1;
@@ -1563,6 +1597,7 @@
             installFlags = source.readInt();
             installLocation = source.readInt();
             installReason = source.readInt();
+            installScenario = source.readInt();
             sizeBytes = source.readLong();
             appPackageName = source.readString();
             appIcon = source.readParcelable(null);
@@ -1594,6 +1629,7 @@
             ret.installFlags = installFlags;
             ret.installLocation = installLocation;
             ret.installReason = installReason;
+            ret.installScenario = installScenario;
             ret.sizeBytes = sizeBytes;
             ret.appPackageName = appPackageName;
             ret.appIcon = appIcon;  // not a copy.
@@ -2019,6 +2055,8 @@
             pw.printPair("mode", mode);
             pw.printHexPair("installFlags", installFlags);
             pw.printPair("installLocation", installLocation);
+            pw.printPair("installReason", installReason);
+            pw.printPair("installScenario", installScenario);
             pw.printPair("sizeBytes", sizeBytes);
             pw.printPair("appPackageName", appPackageName);
             pw.printPair("appIcon", (appIcon != null));
@@ -2052,6 +2090,7 @@
             dest.writeInt(installFlags);
             dest.writeInt(installLocation);
             dest.writeInt(installReason);
+            dest.writeInt(installScenario);
             dest.writeLong(sizeBytes);
             dest.writeString(appPackageName);
             dest.writeParcelable(appIcon, flags);
@@ -2170,6 +2209,8 @@
         /** {@hide} */
         public @InstallReason int installReason;
         /** {@hide} */
+        public @InstallReason int installScenario;
+        /** {@hide} */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
         public long sizeBytes;
         /** {@hide} */
@@ -2248,6 +2289,7 @@
 
             mode = source.readInt();
             installReason = source.readInt();
+            installScenario = source.readInt();
             sizeBytes = source.readLong();
             appPackageName = source.readString();
             appIcon = source.readParcelable(null);
@@ -2795,6 +2837,7 @@
 
             dest.writeInt(mode);
             dest.writeInt(installReason);
+            dest.writeInt(installScenario);
             dest.writeLong(sizeBytes);
             dest.writeString(appPackageName);
             dest.writeParcelable(appIcon, flags);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 19e4d14..cf3f706 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1323,6 +1323,60 @@
     public static final int INSTALL_REASON_ROLLBACK = 5;
 
     /** @hide */
+    @IntDef(prefix = { "INSTALL_SCENARIO_" }, value = {
+            INSTALL_SCENARIO_DEFAULT,
+            INSTALL_SCENARIO_FAST,
+            INSTALL_SCENARIO_BULK,
+            INSTALL_SCENARIO_BULK_SECONDARY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InstallScenario {}
+
+    /**
+     * A value to indicate the lack of CUJ information, disabling all installation scenario logic.
+     *
+     * @hide
+     */
+    public static final int INSTALL_SCENARIO_DEFAULT = 0;
+
+    /**
+     * Installation scenario providing the fastest “install button to launch" experience possible.
+     *
+     * @hide
+     */
+    public static final int INSTALL_SCENARIO_FAST = 1;
+
+    /**
+     * Installation scenario indicating a bulk operation with the desired result of a fully
+     * optimized application.  If the system is busy or resources are scarce the system will
+     * perform less work to avoid impacting system health.
+     *
+     * Examples of bulk installation scenarios might include device restore, background updates of
+     * multiple applications, or user-triggered updates for all applications.
+     *
+     * The decision to use BULK or BULK_SECONDARY should be based on the desired user experience.
+     * BULK_SECONDARY operations may take less time to complete but, when they do, will produce
+     * less optimized applications.  The device state (e.g. memory usage or battery status) should
+     * not be considered when making this decision as those factors are taken into account by the
+     * Package Manager when acting on the installation scenario.
+     *
+     * @hide
+     */
+    public static final int INSTALL_SCENARIO_BULK = 2;
+
+    /**
+     * Installation scenario indicating a bulk operation that prioritizes minimal system health
+     * impact over application optimization.  The application may undergo additional optimization
+     * if the system is idle and system resources are abundant.  The more elements of a bulk
+     * operation that are marked BULK_SECONDARY, the faster the entire bulk operation will be.
+     *
+     * See the comments for INSTALL_SCENARIO_BULK for more information.
+     *
+     * @hide
+     */
+    public static final int INSTALL_SCENARIO_BULK_SECONDARY = 3;
+
+    /** @hide */
     @IntDef(prefix = { "UNINSTALL_REASON_" }, value = {
             UNINSTALL_REASON_UNKNOWN,
             UNINSTALL_REASON_USER_TYPE,
@@ -4131,6 +4185,14 @@
      */
     public static final int UNSTARTABLE_REASON_INSUFFICIENT_STORAGE = 2;
 
+    /**
+     * A manifest property to control app's participation in {@code adb backup}. Should only
+     * be used by system / privileged apps.
+     *
+     * @hide
+     */
+    public static final String PROPERTY_ALLOW_ADB_BACKUP = "android.backup.ALLOW_ADB_BACKUP";
+
     /** {@hide} */
     public int getUserId() {
         return UserHandle.myUserId();
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index cb0decf..4dfbd75 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -406,9 +406,15 @@
         public final boolean extractNativeLibs;
         public final boolean isolatedSplits;
 
-        public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
-                boolean[] isFeatureSplits, String[] usesSplitNames, String[] configForSplit,
-                String[] splitCodePaths, int[] splitRevisionCodes) {
+        // This does not represent the actual manifest structure since the 'profilable' tag
+        // could be used with attributes other than 'shell'. Extend if necessary.
+        public final boolean profilableByShell;
+        public final boolean isSplitRequired;
+        public final boolean useEmbeddedDex;
+
+        public PackageLite(String codePath, String baseCodePath, ApkLite baseApk,
+                String[] splitNames, boolean[] isFeatureSplits, String[] usesSplitNames,
+                String[] configForSplit, String[] splitCodePaths, int[] splitRevisionCodes) {
             this.packageName = baseApk.packageName;
             this.versionCode = baseApk.versionCode;
             this.versionCodeMajor = baseApk.versionCodeMajor;
@@ -418,8 +424,10 @@
             this.isFeatureSplits = isFeatureSplits;
             this.usesSplitNames = usesSplitNames;
             this.configForSplit = configForSplit;
+            // The following paths may be different from the path in ApkLite because we
+            // move or rename the APK files. Use parameters to indicate the correct paths.
             this.codePath = codePath;
-            this.baseCodePath = baseApk.codePath;
+            this.baseCodePath = baseCodePath;
             this.splitCodePaths = splitCodePaths;
             this.baseRevisionCode = baseApk.revisionCode;
             this.splitRevisionCodes = splitRevisionCodes;
@@ -429,6 +437,9 @@
             this.use32bitAbi = baseApk.use32bitAbi;
             this.extractNativeLibs = baseApk.extractNativeLibs;
             this.isolatedSplits = baseApk.isolatedSplits;
+            this.useEmbeddedDex = baseApk.useEmbeddedDex;
+            this.isSplitRequired = baseApk.isSplitRequired;
+            this.profilableByShell = baseApk.profilableByShell;
         }
 
         public List<String> getAllCodePaths() {
@@ -439,6 +450,10 @@
             }
             return paths;
         }
+
+        public long getLongVersionCode() {
+            return PackageInfo.composeLongVersionCode(versionCodeMajor, versionCode);
+        }
     }
 
     /**
@@ -941,7 +956,8 @@
         final ApkLite baseApk = parseApkLite(packageFile, flags);
         final String packagePath = packageFile.getAbsolutePath();
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        return new PackageLite(packagePath, baseApk, null, null, null, null, null, null);
+        return new PackageLite(packagePath, baseApk.codePath, baseApk, null, null, null, null, null,
+                null);
     }
 
     static PackageLite parseClusterPackageLite(File packageDir, int flags)
@@ -1031,8 +1047,8 @@
         }
 
         final String codePath = packageDir.getAbsolutePath();
-        return new PackageLite(codePath, baseApk, splitNames, isFeatureSplits, usesSplitNames,
-                configForSplits, splitCodePaths, splitRevisionCodes);
+        return new PackageLite(codePath, baseApk.codePath, baseApk, splitNames, isFeatureSplits,
+                usesSplitNames, configForSplits, splitCodePaths, splitRevisionCodes);
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 2fca980..9925871 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -41,6 +41,8 @@
 import android.util.DebugUtils;
 import android.util.Pair;
 import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
@@ -560,7 +562,7 @@
          * @param out the {@link XmlSerializer} object
          * @throws IOException
          */
-        public void saveToXml(XmlSerializer out) throws IOException {
+        public void saveToXml(TypedXmlSerializer out) throws IOException {
             if (dialogInfo != null) {
                 out.startTag(null, TAG_DIALOG_INFO);
                 dialogInfo.saveToXml(out);
@@ -594,7 +596,7 @@
          * @param in the reader
          * @return
          */
-        public static SuspendParams restoreFromXml(XmlPullParser in) throws IOException {
+        public static SuspendParams restoreFromXml(TypedXmlPullParser in) throws IOException {
             SuspendDialogInfo readDialogInfo = null;
             PersistableBundle readAppExtras = null;
             PersistableBundle readLauncherExtras = null;
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 192470e..7ecb112 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -36,21 +36,21 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.FastXmlSerializer;
+
+import libcore.io.IoUtils;
 
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
-import libcore.io.IoUtils;
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -58,7 +58,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -672,8 +671,7 @@
      */
     private void readPersistentServicesLocked(InputStream is)
             throws XmlPullParserException, IOException {
-        XmlPullParser parser = Xml.newPullParser();
-        parser.setInput(is, StandardCharsets.UTF_8.name());
+        TypedXmlPullParser parser = Xml.resolvePullParser(is);
         int eventType = parser.getEventType();
         while (eventType != XmlPullParser.START_TAG
                 && eventType != XmlPullParser.END_DOCUMENT) {
@@ -690,8 +688,7 @@
                         if (service == null) {
                             break;
                         }
-                        String uidString = parser.getAttributeValue(null, "uid");
-                        final int uid = Integer.parseInt(uidString);
+                        final int uid = parser.getAttributeInt(null, "uid");
                         final int userId = UserHandle.getUserId(uid);
                         final UserServices<V> user = findOrCreateUserLocked(userId,
                                 false /*loadFromFileIfNew*/) ;
@@ -762,14 +759,13 @@
         FileOutputStream fos = null;
         try {
             fos = atomicFile.startWrite();
-            XmlSerializer out = new FastXmlSerializer();
-            out.setOutput(fos, StandardCharsets.UTF_8.name());
+            TypedXmlSerializer out = Xml.resolveSerializer(fos);
             out.startDocument(null, true);
             out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
             out.startTag(null, "services");
             for (Map.Entry<V, Integer> service : user.persistentServices.entrySet()) {
                 out.startTag(null, "service");
-                out.attribute(null, "uid", Integer.toString(service.getValue()));
+                out.attributeInt(null, "uid", service.getValue());
                 mSerializerAndParser.writeAsXml(service.getKey(), out);
                 out.endTag(null, "service");
             }
diff --git a/core/java/android/content/pm/SuspendDialogInfo.java b/core/java/android/content/pm/SuspendDialogInfo.java
index 851a081..60f3218 100644
--- a/core/java/android/content/pm/SuspendDialogInfo.java
+++ b/core/java/android/content/pm/SuspendDialogInfo.java
@@ -29,13 +29,12 @@
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
-
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -169,38 +168,38 @@
     /**
      * @hide
      */
-    public void saveToXml(XmlSerializer out) throws IOException {
+    public void saveToXml(TypedXmlSerializer out) throws IOException {
         if (mIconResId != ID_NULL) {
-            XmlUtils.writeIntAttribute(out, XML_ATTR_ICON_RES_ID, mIconResId);
+            out.attributeInt(null, XML_ATTR_ICON_RES_ID, mIconResId);
         }
         if (mTitleResId != ID_NULL) {
-            XmlUtils.writeIntAttribute(out, XML_ATTR_TITLE_RES_ID, mTitleResId);
+            out.attributeInt(null, XML_ATTR_TITLE_RES_ID, mTitleResId);
         }
         if (mDialogMessageResId != ID_NULL) {
-            XmlUtils.writeIntAttribute(out, XML_ATTR_DIALOG_MESSAGE_RES_ID, mDialogMessageResId);
+            out.attributeInt(null, XML_ATTR_DIALOG_MESSAGE_RES_ID, mDialogMessageResId);
         } else {
             XmlUtils.writeStringAttribute(out, XML_ATTR_DIALOG_MESSAGE, mDialogMessage);
         }
         if (mNeutralButtonTextResId != ID_NULL) {
-            XmlUtils.writeIntAttribute(out, XML_ATTR_BUTTON_TEXT_RES_ID, mNeutralButtonTextResId);
+            out.attributeInt(null, XML_ATTR_BUTTON_TEXT_RES_ID, mNeutralButtonTextResId);
         }
-        XmlUtils.writeIntAttribute(out, XML_ATTR_BUTTON_ACTION, mNeutralButtonAction);
+        out.attributeInt(null, XML_ATTR_BUTTON_ACTION, mNeutralButtonAction);
     }
 
     /**
      * @hide
      */
-    public static SuspendDialogInfo restoreFromXml(XmlPullParser in) {
+    public static SuspendDialogInfo restoreFromXml(TypedXmlPullParser in) {
         final SuspendDialogInfo.Builder dialogInfoBuilder = new SuspendDialogInfo.Builder();
         try {
-            final int iconId = XmlUtils.readIntAttribute(in, XML_ATTR_ICON_RES_ID, ID_NULL);
-            final int titleId = XmlUtils.readIntAttribute(in, XML_ATTR_TITLE_RES_ID, ID_NULL);
-            final int buttonTextId = XmlUtils.readIntAttribute(in, XML_ATTR_BUTTON_TEXT_RES_ID,
-                    ID_NULL);
-            final int buttonAction = XmlUtils.readIntAttribute(in, XML_ATTR_BUTTON_ACTION,
-                    BUTTON_ACTION_MORE_DETAILS);
-            final int dialogMessageResId = XmlUtils.readIntAttribute(
-                    in, XML_ATTR_DIALOG_MESSAGE_RES_ID, ID_NULL);
+            final int iconId = in.getAttributeInt(null, XML_ATTR_ICON_RES_ID, ID_NULL);
+            final int titleId = in.getAttributeInt(null, XML_ATTR_TITLE_RES_ID, ID_NULL);
+            final int buttonTextId =
+                    in.getAttributeInt(null, XML_ATTR_BUTTON_TEXT_RES_ID, ID_NULL);
+            final int buttonAction =
+                    in.getAttributeInt(null, XML_ATTR_BUTTON_ACTION, BUTTON_ACTION_MORE_DETAILS);
+            final int dialogMessageResId =
+                    in.getAttributeInt(null, XML_ATTR_DIALOG_MESSAGE_RES_ID, ID_NULL);
             final String dialogMessage = XmlUtils.readStringAttribute(in, XML_ATTR_DIALOG_MESSAGE);
 
             if (iconId != ID_NULL) {
diff --git a/core/java/android/content/pm/XmlSerializerAndParser.java b/core/java/android/content/pm/XmlSerializerAndParser.java
index 5dce839..51cd6ca 100644
--- a/core/java/android/content/pm/XmlSerializerAndParser.java
+++ b/core/java/android/content/pm/XmlSerializerAndParser.java
@@ -17,6 +17,10 @@
 package android.content.pm;
 
 import android.compat.annotation.UnsupportedAppUsage;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+
+import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -26,8 +30,16 @@
 
 /** @hide */
 public interface XmlSerializerAndParser<T> {
+    void writeAsXml(T item, TypedXmlSerializer out) throws IOException;
+    T createFromXml(TypedXmlPullParser parser) throws IOException, XmlPullParserException;
+
     @UnsupportedAppUsage
-    void writeAsXml(T item, XmlSerializer out) throws IOException;
+    default void writeAsXml(T item, XmlSerializer out) throws IOException {
+        writeAsXml(item, XmlUtils.makeTyped(out));
+    }
+
     @UnsupportedAppUsage
-    T createFromXml(XmlPullParser parser) throws IOException, XmlPullParserException;
+    default T createFromXml(XmlPullParser parser) throws IOException, XmlPullParserException {
+        return createFromXml(XmlUtils.makeTyped(parser));
+    }
 }
diff --git a/core/java/android/content/pm/dex/OWNERS b/core/java/android/content/pm/dex/OWNERS
new file mode 100644
index 0000000..267e5d58
--- /dev/null
+++ b/core/java/android/content/pm/dex/OWNERS
@@ -0,0 +1,7 @@
+# Bug component: 86431
+
+toddke@android.com
+toddke@google.com
+patb@google.com
+calin@google.com
+ngeoffray@google.com
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 72a66ed..f583e25 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -18,9 +18,11 @@
 
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
 import static android.content.pm.parsing.ParsingPackageUtils.validateName;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 
+import android.annotation.NonNull;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
@@ -50,6 +52,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 
 /** @hide */
 public class ApkLiteParseUtils {
@@ -95,8 +98,8 @@
             final PackageParser.ApkLite baseApk = result.getResult();
             final String packagePath = packageFile.getAbsolutePath();
             return input.success(
-                    new PackageParser.PackageLite(packagePath, baseApk, null, null, null, null,
-                            null, null));
+                    new PackageParser.PackageLite(packagePath, baseApk.codePath, baseApk, null,
+                            null, null, null, null, null));
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
@@ -159,13 +162,43 @@
         }
 
         final PackageParser.ApkLite baseApk = apks.remove(null);
+        return composePackageLiteFromApks(input, packageDir, baseApk, apks);
+    }
+
+    /**
+     * Utility method that retrieves lightweight details about the package by given location,
+     * base APK, and split APKs.
+     *
+     * @param packageDir Path to the package
+     * @param baseApk Parsed base APK
+     * @param splitApks Parsed split APKs
+     * @return PackageLite
+     */
+    public static ParseResult<PackageParser.PackageLite> composePackageLiteFromApks(
+            ParseInput input, File packageDir, PackageParser.ApkLite baseApk,
+            ArrayMap<String, PackageParser.ApkLite> splitApks) {
+        return composePackageLiteFromApks(input, packageDir, baseApk, splitApks, false);
+    }
+
+    /**
+     * Utility method that retrieves lightweight details about the package by given location,
+     * base APK, and split APKs.
+     *
+     * @param packageDir Path to the package
+     * @param baseApk Parsed base APK
+     * @param splitApks Parsed split APKs
+     * @param apkRenamed Indicate whether the APKs are renamed after parsed.
+     * @return PackageLite
+     */
+    public static ParseResult<PackageParser.PackageLite> composePackageLiteFromApks(
+            ParseInput input, File packageDir, PackageParser.ApkLite baseApk,
+            ArrayMap<String, PackageParser.ApkLite> splitApks, boolean apkRenamed) {
         if (baseApk == null) {
             return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
                     "Missing base APK in " + packageDir);
         }
-
         // Always apply deterministic ordering based on splitName
-        final int size = apks.size();
+        final int size = ArrayUtils.size(splitApks);
 
         String[] splitNames = null;
         boolean[] isFeatureSplits = null;
@@ -181,23 +214,39 @@
             splitCodePaths = new String[size];
             splitRevisionCodes = new int[size];
 
-            splitNames = apks.keySet().toArray(splitNames);
+            splitNames = splitApks.keySet().toArray(splitNames);
             Arrays.sort(splitNames, PackageParser.sSplitNameComparator);
 
             for (int i = 0; i < size; i++) {
-                final PackageParser.ApkLite apk = apks.get(splitNames[i]);
+                final PackageParser.ApkLite apk = splitApks.get(splitNames[i]);
                 usesSplitNames[i] = apk.usesSplitName;
                 isFeatureSplits[i] = apk.isFeatureSplit;
                 configForSplits[i] = apk.configForSplit;
-                splitCodePaths[i] = apk.codePath;
+                splitCodePaths[i] = apkRenamed ? new File(packageDir,
+                        splitNameToFileName(apk)).getAbsolutePath() : apk.codePath;
                 splitRevisionCodes[i] = apk.revisionCode;
             }
         }
 
         final String codePath = packageDir.getAbsolutePath();
-        return input.success(new PackageParser.PackageLite(codePath, baseApk, splitNames,
-                isFeatureSplits, usesSplitNames, configForSplits, splitCodePaths,
-                splitRevisionCodes));
+        final String baseCodePath = apkRenamed ? new File(packageDir,
+                splitNameToFileName(baseApk)).getAbsolutePath() : baseApk.codePath;
+        return input.success(
+                new PackageParser.PackageLite(codePath, baseCodePath, baseApk, splitNames,
+                        isFeatureSplits, usesSplitNames, configForSplits, splitCodePaths,
+                        splitRevisionCodes));
+    }
+
+    /**
+     * Utility method that retrieves canonical file name by given split name from parsed APK.
+     *
+     * @param apk Parsed APK
+     * @return The canonical file name
+     */
+    public static String splitNameToFileName(@NonNull PackageParser.ApkLite apk) {
+        Objects.requireNonNull(apk);
+        final String fileName = apk.splitName == null ? "base" : "split_" + apk.splitName;
+        return fileName + APK_FILE_EXTENSION;
     }
 
     /**
diff --git a/core/java/android/content/pm/permission/OWNERS b/core/java/android/content/pm/permission/OWNERS
new file mode 100644
index 0000000..cde7b2a
--- /dev/null
+++ b/core/java/android/content/pm/permission/OWNERS
@@ -0,0 +1,11 @@
+# Bug component: 137825
+
+toddke@android.com
+toddke@google.com
+patb@google.com
+moltmann@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
+zhanghai@google.com
+evanseverson@google.com
+ntmyren@google.com
diff --git a/core/java/android/content/pm/split/OWNERS b/core/java/android/content/pm/split/OWNERS
new file mode 100644
index 0000000..3d126d2
--- /dev/null
+++ b/core/java/android/content/pm/split/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 36137
+
+toddke@android.com
+toddke@google.com
+patb@google.com
diff --git a/core/java/android/content/res/OWNERS b/core/java/android/content/res/OWNERS
new file mode 100644
index 0000000..bc2355c
--- /dev/null
+++ b/core/java/android/content/res/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 568761
+
+toddke@android.com
+toddke@google.com
+patb@google.com
+rtmitchell@google.com
diff --git a/core/java/android/content/rollback/OWNERS b/core/java/android/content/rollback/OWNERS
new file mode 100644
index 0000000..3093fd6
--- /dev/null
+++ b/core/java/android/content/rollback/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 557916
+
+narayan@google.com
+nandana@google.com
+olilan@google.com
diff --git a/core/java/android/database/OWNERS b/core/java/android/database/OWNERS
index 7e19942..1734cfc 100644
--- a/core/java/android/database/OWNERS
+++ b/core/java/android/database/OWNERS
@@ -1,3 +1,3 @@
 omakoto@google.com
-jsharkey@android.com
+jsharkey@google.com
 yamasani@google.com
diff --git a/core/java/android/gesture/OWNERS b/core/java/android/gesture/OWNERS
new file mode 100644
index 0000000..b3b8775
--- /dev/null
+++ b/core/java/android/gesture/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 25700
+
+romainguy@google.com
+alanv@google.com
+adamp@google.com
+aurimas@google.com
+nduca@google.com
+sumir@google.com
diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
index cb43943..cc12125 100644
--- a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
@@ -36,7 +36,7 @@
     // Retrieve static sensor properties
     SensorPropertiesInternal getSensorProperties(String opPackageName);
 
-    // Requests a proto dump of the service. See biometrics.proto
+    // Requests a proto dump of the sensor. See biometrics.proto
     byte[] dumpSensorServiceStateProto();
 
     // This method prepares the service to start authenticating, but doesn't start authentication.
diff --git a/core/java/android/hardware/biometrics/OWNERS b/core/java/android/hardware/biometrics/OWNERS
new file mode 100644
index 0000000..33527f8
--- /dev/null
+++ b/core/java/android/hardware/biometrics/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 879035
+
+jaggies@google.com
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 232056c..0f595b7 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1467,12 +1467,13 @@
      * to any real physical measurement, but <code>0.0f</code> still represents farthest
      * focus, and {@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} represents the
      * nearest focus the device can achieve.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED UNCALIBRATED}</li>
      *   <li>{@link #LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE APPROXIMATE}</li>
      *   <li>{@link #LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED CALIBRATED}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -1495,12 +1496,13 @@
     /**
      * <p>Direction the camera faces relative to
      * device screen.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #LENS_FACING_FRONT FRONT}</li>
      *   <li>{@link #LENS_FACING_BACK BACK}</li>
      *   <li>{@link #LENS_FACING_EXTERNAL EXTERNAL}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      * @see #LENS_FACING_FRONT
      * @see #LENS_FACING_BACK
@@ -1726,12 +1728,13 @@
      * {@link CameraCharacteristics#LENS_POSE_TRANSLATION android.lens.poseTranslation} and {@link CameraCharacteristics#LENS_POSE_ROTATION android.lens.poseRotation}.</p>
      * <p>Different calibration methods and use cases can produce better or worse results
      * depending on the selected coordinate origin.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #LENS_POSE_REFERENCE_PRIMARY_CAMERA PRIMARY_CAMERA}</li>
      *   <li>{@link #LENS_POSE_REFERENCE_GYROSCOPE GYROSCOPE}</li>
      *   <li>{@link #LENS_POSE_REFERENCE_UNDEFINED UNDEFINED}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
      *
@@ -2057,7 +2060,7 @@
      * </ul>
      * <p>Other capabilities may be available on either FULL or LIMITED
      * devices, but the application should query this key to be sure.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE BACKWARD_COMPATIBLE}</li>
      *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR MANUAL_SENSOR}</li>
@@ -2075,7 +2078,8 @@
      *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA SECURE_IMAGE_DATA}</li>
      *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA SYSTEM_CAMERA}</li>
      *   <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING OFFLINE_PROCESSING}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
@@ -2772,14 +2776,17 @@
      * </ol>
      * </li>
      * <li>Setting {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} to values different than 1.0 and
-     * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to be windowboxing at the same time is undefined behavior.</li>
+     * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to be windowboxing at the same time are not supported. In this
+     * case, the camera framework will override the {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to be the active
+     * array.</li>
      * </ul>
      * <p>LEGACY capability devices will only support CENTER_ONLY cropping.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SCALER_CROPPING_TYPE_CENTER_ONLY CENTER_ONLY}</li>
      *   <li>{@link #SCALER_CROPPING_TYPE_FREEFORM FREEFORM}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_ZOOM_RATIO
@@ -2964,7 +2971,7 @@
      * represents the colors in the top-left 2x2 section of
      * the sensor, in reading order, for a Bayer camera, or the
      * light spectrum it captures for MONOCHROME camera.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB RGGB}</li>
      *   <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG GRBG}</li>
@@ -2973,7 +2980,8 @@
      *   <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB RGB}</li>
      *   <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO MONO}</li>
      *   <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR NIR}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Full capability</b> -
      * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
@@ -3115,11 +3123,12 @@
      * may not based on a time source that can be compared to other system time sources.</p>
      * <p>This characteristic defines the source for the timestamps, and therefore whether they
      * can be compared against other system time sources/timestamps.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN UNKNOWN}</li>
      *   <li>{@link #SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME REALTIME}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      * @see #SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN
      * @see #SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME
@@ -3229,7 +3238,7 @@
      * {@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2 android.sensor.referenceIlluminant2} and its corresponding matrices.</p>
      * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
      * the camera device has RAW capability.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT DAYLIGHT}</li>
      *   <li>{@link #SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT FLUORESCENT}</li>
@@ -3250,7 +3259,8 @@
      *   <li>{@link #SENSOR_REFERENCE_ILLUMINANT1_D75 D75}</li>
      *   <li>{@link #SENSOR_REFERENCE_ILLUMINANT1_D50 D50}</li>
      *   <li>{@link #SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN ISO_STUDIO_TUNGSTEN}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
      *
@@ -3725,10 +3735,11 @@
 
     /**
      * <p>A list of camera LEDs that are available on this system.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #LED_AVAILABLE_LEDS_TRANSMIT TRANSMIT}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * @see #LED_AVAILABLE_LEDS_TRANSMIT
      * @hide
@@ -3797,14 +3808,15 @@
      *   ({@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization},
      *    {@link CameraCharacteristics#CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES android.control.availableVideoStabilizationModes})</li>
      * </ul>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED}</li>
      *   <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}</li>
      *   <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}</li>
      *   <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_3 3}</li>
      *   <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL EXTERNAL}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CameraCharacteristics#CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES
@@ -3848,11 +3860,12 @@
      * must occur before the camera device knows for a fact that the new
      * submitted camera settings have been applied in outgoing frames.</p>
      * <p><b>Units</b>: Frame counts</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SYNC_MAX_LATENCY_PER_FRAME_CONTROL PER_FRAME_CONTROL}</li>
      *   <li>{@link #SYNC_MAX_LATENCY_UNKNOWN UNKNOWN}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * A positive value, PER_FRAME_CONTROL, or UNKNOWN.</p>
      * <p>This key is available on all devices.</p>
@@ -4100,11 +4113,12 @@
      * onCaptureStarted callback.</p>
      * <p>This tag is only applicable if the logical camera device supports concurrent physical
      * streams from different physical cameras.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE APPROXIMATE}</li>
      *   <li>{@link #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED CALIBRATED}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index d931789..d7aee10 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1028,12 +1028,13 @@
      * </code></pre>
      * <p>Both the input and output value ranges must match. Overflow/underflow
      * values are clipped to fit within the range.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #COLOR_CORRECTION_MODE_TRANSFORM_MATRIX TRANSFORM_MATRIX}</li>
      *   <li>{@link #COLOR_CORRECTION_MODE_FAST FAST}</li>
      *   <li>{@link #COLOR_CORRECTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Full capability</b> -
      * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
@@ -1121,12 +1122,13 @@
      * capture rate. FAST means the camera device will not slow down capture rate when
      * applying aberration correction.</p>
      * <p>LEGACY devices will always be in FAST mode.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #COLOR_CORRECTION_ABERRATION_MODE_OFF OFF}</li>
      *   <li>{@link #COLOR_CORRECTION_ABERRATION_MODE_FAST FAST}</li>
      *   <li>{@link #COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES android.colorCorrection.availableAberrationModes}</p>
      * <p>This key is available on all devices.</p>
@@ -1173,13 +1175,14 @@
      * ensure it selects exposure times that do not cause banding
      * issues. The {@link CaptureResult#STATISTICS_SCENE_FLICKER android.statistics.sceneFlicker} key can assist
      * the application in this.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AE_ANTIBANDING_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_AE_ANTIBANDING_MODE_50HZ 50HZ}</li>
      *   <li>{@link #CONTROL_AE_ANTIBANDING_MODE_60HZ 60HZ}</li>
      *   <li>{@link #CONTROL_AE_ANTIBANDING_MODE_AUTO AUTO}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br></p>
      * <p>{@link CameraCharacteristics#CONTROL_AE_AVAILABLE_ANTIBANDING_MODES android.control.aeAvailableAntibandingModes}</p>
      * <p>This key is available on all devices.</p>
@@ -1304,7 +1307,7 @@
      * camera device auto-exposure routine for the overridden
      * fields for a given capture will be available in its
      * CaptureResult.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AE_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_AE_MODE_ON ON}</li>
@@ -1312,7 +1315,8 @@
      *   <li>{@link #CONTROL_AE_MODE_ON_ALWAYS_FLASH ON_ALWAYS_FLASH}</li>
      *   <li>{@link #CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE ON_AUTO_FLASH_REDEYE}</li>
      *   <li>{@link #CONTROL_AE_MODE_ON_EXTERNAL_FLASH ON_EXTERNAL_FLASH}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_MODES android.control.aeAvailableModes}</p>
      * <p>This key is available on all devices.</p>
@@ -1478,12 +1482,13 @@
      * example.</p>
      * <p>If both the precapture and the auto-focus trigger are activated on the same request, then
      * the camera device will complete them in the optimal order for that device.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE IDLE}</li>
      *   <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_START START}</li>
      *   <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL CANCEL}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -1514,7 +1519,7 @@
      * <p>If the lens is controlled by the camera device auto-focus algorithm,
      * the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
      * in result metadata.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AF_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_AF_MODE_AUTO AUTO}</li>
@@ -1522,7 +1527,8 @@
      *   <li>{@link #CONTROL_AF_MODE_CONTINUOUS_VIDEO CONTINUOUS_VIDEO}</li>
      *   <li>{@link #CONTROL_AF_MODE_CONTINUOUS_PICTURE CONTINUOUS_PICTURE}</li>
      *   <li>{@link #CONTROL_AF_MODE_EDOF EDOF}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AF_AVAILABLE_MODES android.control.afAvailableModes}</p>
      * <p>This key is available on all devices.</p>
@@ -1637,12 +1643,13 @@
      * focus sweep), the camera device may delay acting on a later trigger until the previous
      * trigger has been fully handled. This may lead to longer intervals between the trigger and
      * changes to {@link CaptureResult#CONTROL_AF_STATE android.control.afState}, for example.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AF_TRIGGER_IDLE IDLE}</li>
      *   <li>{@link #CONTROL_AF_TRIGGER_START START}</li>
      *   <li>{@link #CONTROL_AF_TRIGGER_CANCEL CANCEL}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
@@ -1710,7 +1717,7 @@
      * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform},
      * {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} are ignored.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AWB_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_AWB_MODE_AUTO AUTO}</li>
@@ -1721,7 +1728,8 @@
      *   <li>{@link #CONTROL_AWB_MODE_CLOUDY_DAYLIGHT CLOUDY_DAYLIGHT}</li>
      *   <li>{@link #CONTROL_AWB_MODE_TWILIGHT TWILIGHT}</li>
      *   <li>{@link #CONTROL_AWB_MODE_SHADE SHADE}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AWB_AVAILABLE_MODES android.control.awbAvailableModes}</p>
      * <p>This key is available on all devices.</p>
@@ -1835,7 +1843,7 @@
      * MANUAL_SENSOR.
      *   * MOTION_TRACKING will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
      * MOTION_TRACKING.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_PREVIEW PREVIEW}</li>
@@ -1845,7 +1853,8 @@
      *   <li>{@link #CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_MANUAL MANUAL}</li>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_MOTION_TRACKING MOTION_TRACKING}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_MODE
@@ -1872,7 +1881,7 @@
      * implementor of the camera device, and should not be
      * depended on to be consistent (or present) across all
      * devices.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_EFFECT_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_EFFECT_MODE_MONO MONO}</li>
@@ -1883,7 +1892,8 @@
      *   <li>{@link #CONTROL_EFFECT_MODE_WHITEBOARD WHITEBOARD}</li>
      *   <li>{@link #CONTROL_EFFECT_MODE_BLACKBOARD BLACKBOARD}</li>
      *   <li>{@link #CONTROL_EFFECT_MODE_AQUA AQUA}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AVAILABLE_EFFECTS android.control.availableEffects}</p>
      * <p>This key is available on all devices.</p>
@@ -1922,14 +1932,15 @@
      * update, as if this frame is never captured. This mode can be used in the scenario
      * where the application doesn't want a 3A manual control capture to affect
      * the subsequent auto 3A capture results.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_MODE_AUTO AUTO}</li>
      *   <li>{@link #CONTROL_MODE_USE_SCENE_MODE USE_SCENE_MODE}</li>
      *   <li>{@link #CONTROL_MODE_OFF_KEEP_STATE OFF_KEEP_STATE}</li>
      *   <li>{@link #CONTROL_MODE_USE_EXTENDED_SCENE_MODE USE_EXTENDED_SCENE_MODE}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AVAILABLE_MODES android.control.availableModes}</p>
      * <p>This key is available on all devices.</p>
@@ -1959,7 +1970,7 @@
      * to the implementor of the camera device. Their behavior will not be
      * consistent across all devices, and any given device may only implement
      * a subset of these modes.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_SCENE_MODE_DISABLED DISABLED}</li>
      *   <li>{@link #CONTROL_SCENE_MODE_FACE_PRIORITY FACE_PRIORITY}</li>
@@ -1980,7 +1991,8 @@
      *   <li>{@link #CONTROL_SCENE_MODE_BARCODE BARCODE}</li>
      *   <li>{@link #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO}</li>
      *   <li>{@link #CONTROL_SCENE_MODE_HDR HDR}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}</p>
      * <p>This key is available on all devices.</p>
@@ -2041,11 +2053,12 @@
      * ({@link CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE android.lens.opticalStabilizationMode}), turning both modes on may
      * produce undesirable interaction, so it is recommended not to enable
      * both at the same time.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_VIDEO_STABILIZATION_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_VIDEO_STABILIZATION_MODE_ON ON}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
@@ -2155,12 +2168,13 @@
      * with different field of view. As a result, when bokeh mode is enabled, the camera device
      * may override {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} or {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}, and the field of
      * view may be smaller than when bokeh mode is off.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_EXTENDED_SCENE_MODE_DISABLED DISABLED}</li>
      *   <li>{@link #CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE BOKEH_STILL_CAPTURE}</li>
      *   <li>{@link #CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS BOKEH_CONTINUOUS}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      *
      * @see CaptureRequest#CONTROL_ZOOM_RATIO
@@ -2243,7 +2257,10 @@
      * explicitly set {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}, its value defaults to 1.0.</p>
      * <p>One limitation of controlling zoom using zoomRatio is that the {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}
      * must only be used for letterboxing or pillarboxing of the sensor active array, and no
-     * FREEFORM cropping can be used with {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} other than 1.0.</p>
+     * FREEFORM cropping can be used with {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} other than 1.0. If
+     * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} is not 1.0, and {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} is set to be
+     * windowboxing, the camera framework will override the {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to be
+     * the active array.</p>
      * <p><b>Range of valid values:</b><br>
      * {@link CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE android.control.zoomRatioRange}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2284,13 +2301,14 @@
      * device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively.
      * The camera device may adjust its internal edge enhancement parameters for best
      * image quality based on the {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}, if it is set.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #EDGE_MODE_OFF OFF}</li>
      *   <li>{@link #EDGE_MODE_FAST FAST}</li>
      *   <li>{@link #EDGE_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
      *   <li>{@link #EDGE_MODE_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES android.edge.availableEdgeModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2326,12 +2344,13 @@
      * <p>When set to TORCH, the flash will be on continuously. This mode can be used
      * for use cases such as preview, auto-focus assist, still capture, or video recording.</p>
      * <p>The flash status will be reported by {@link CaptureResult#FLASH_STATE android.flash.state} in the capture result metadata.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #FLASH_MODE_OFF OFF}</li>
      *   <li>{@link #FLASH_MODE_SINGLE SINGLE}</li>
      *   <li>{@link #FLASH_MODE_TORCH TORCH}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_AE_MODE
@@ -2352,12 +2371,13 @@
      * <p>Hotpixel correction interpolates out, or otherwise removes, pixels
      * that do not accurately measure the incoming light (i.e. pixels that
      * are stuck at an arbitrary value or are oversensitive).</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #HOT_PIXEL_MODE_OFF OFF}</li>
      *   <li>{@link #HOT_PIXEL_MODE_FAST FAST}</li>
      *   <li>{@link #HOT_PIXEL_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES android.hotPixel.availableHotPixelModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2685,11 +2705,12 @@
      * <p>Not all devices will support OIS; see
      * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization} for
      * available controls.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #LENS_OPTICAL_STABILIZATION_MODE_OFF OFF}</li>
      *   <li>{@link #LENS_OPTICAL_STABILIZATION_MODE_ON ON}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2735,14 +2756,15 @@
      * will apply FAST/HIGH_QUALITY YUV domain noise reduction, respectively. The camera device
      * may adjust the noise reduction parameters for best image quality based on the
      * {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor} if it is set.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #NOISE_REDUCTION_MODE_OFF OFF}</li>
      *   <li>{@link #NOISE_REDUCTION_MODE_FAST FAST}</li>
      *   <li>{@link #NOISE_REDUCTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
      *   <li>{@link #NOISE_REDUCTION_MODE_MINIMAL MINIMAL}</li>
      *   <li>{@link #NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2956,14 +2978,15 @@
      * <li>640x480 stream: top-left: <code>(781, 375)</code> on active array, size: <code>(640, 480)</code>, downscaled 1.17x from sensor pixels</li>
      * <li>1280x720 stream: top-left: <code>(711, 375)</code> on active array, size: <code>(1280, 720)</code>, upscaled 1.71x from sensor pixels</li>
      * </ul>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_NONE NONE}</li>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_90 90}</li>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_180 180}</li>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_270 270}</li>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_AUTO AUTO}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES android.scaler.availableRotateAndCropModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -3163,7 +3186,7 @@
      * occur (and that the test pattern remain unmodified, since the flash
      * would not actually affect it).</p>
      * <p>Defaults to OFF.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_OFF OFF}</li>
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_SOLID_COLOR SOLID_COLOR}</li>
@@ -3171,7 +3194,8 @@
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY COLOR_BARS_FADE_TO_GRAY}</li>
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_PN9 PN9}</li>
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_CUSTOM1 CUSTOM1}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#SENSOR_AVAILABLE_TEST_PATTERN_MODES android.sensor.availableTestPatternModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -3215,12 +3239,13 @@
      * AWB are in AUTO modes({@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} <code>!=</code> OFF and {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} <code>!=</code>
      * OFF), to get best results, it is recommended that the applications wait for the AE and AWB
      * to be converged before using the returned shading map data.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SHADING_MODE_OFF OFF}</li>
      *   <li>{@link #SHADING_MODE_FAST FAST}</li>
      *   <li>{@link #SHADING_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#SHADING_AVAILABLE_MODES android.shading.availableModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -3249,12 +3274,13 @@
      * <p>Whether face detection is enabled, and whether it
      * should output just the basic fields or the full set of
      * fields.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #STATISTICS_FACE_DETECT_MODE_OFF OFF}</li>
      *   <li>{@link #STATISTICS_FACE_DETECT_MODE_SIMPLE SIMPLE}</li>
      *   <li>{@link #STATISTICS_FACE_DETECT_MODE_FULL FULL}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES android.statistics.info.availableFaceDetectModes}</p>
      * <p>This key is available on all devices.</p>
@@ -3292,11 +3318,12 @@
      * android.statistics.lensShadingMap will be provided in
      * the output result metadata.</p>
      * <p>ON is always supported on devices with the RAW capability.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #STATISTICS_LENS_SHADING_MAP_MODE_OFF OFF}</li>
      *   <li>{@link #STATISTICS_LENS_SHADING_MAP_MODE_ON ON}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES android.statistics.info.availableLensShadingMapModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -3323,11 +3350,12 @@
      * at 30fps may have 6-7 OIS samples per capture result. This information can be combined
      * with the rolling shutter skew to account for lens motion during image exposure in
      * post-processing algorithms.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li>
      *   <li>{@link #STATISTICS_OIS_DATA_MODE_ON ON}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES android.statistics.info.availableOisDataModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -3520,14 +3548,15 @@
      * <p>If a request is sent with CONTRAST_CURVE with the camera device's
      * provided curve in FAST or HIGH_QUALITY, the image's tonemap will be
      * roughly the same.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #TONEMAP_MODE_CONTRAST_CURVE CONTRAST_CURVE}</li>
      *   <li>{@link #TONEMAP_MODE_FAST FAST}</li>
      *   <li>{@link #TONEMAP_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
      *   <li>{@link #TONEMAP_MODE_GAMMA_VALUE GAMMA_VALUE}</li>
      *   <li>{@link #TONEMAP_MODE_PRESET_CURVE PRESET_CURVE}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES android.tonemap.availableToneMapModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -3582,11 +3611,12 @@
      * <p><img alt="Rec. 709 tonemapping curve" src="/reference/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png" /></p>
      * <p>Note that above figures show a 16 control points approximation of preset
      * curves. Camera devices may apply a different approximation to the curve.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #TONEMAP_PRESET_CURVE_SRGB SRGB}</li>
      *   <li>{@link #TONEMAP_PRESET_CURVE_REC709 REC709}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      *
      * @see CaptureRequest#TONEMAP_MODE
@@ -3751,12 +3781,13 @@
      * <li>{@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}</li>
      * <li>{@link CaptureResult#STATISTICS_FACES android.statistics.faces}</li>
      * </ul>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #DISTORTION_CORRECTION_MODE_OFF OFF}</li>
      *   <li>{@link #DISTORTION_CORRECTION_MODE_FAST FAST}</li>
      *   <li>{@link #DISTORTION_CORRECTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES android.distortionCorrection.availableModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index cd69788..66d8b50 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -449,12 +449,13 @@
      * </code></pre>
      * <p>Both the input and output value ranges must match. Overflow/underflow
      * values are clipped to fit within the range.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #COLOR_CORRECTION_MODE_TRANSFORM_MATRIX TRANSFORM_MATRIX}</li>
      *   <li>{@link #COLOR_CORRECTION_MODE_FAST FAST}</li>
      *   <li>{@link #COLOR_CORRECTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Full capability</b> -
      * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
@@ -542,12 +543,13 @@
      * capture rate. FAST means the camera device will not slow down capture rate when
      * applying aberration correction.</p>
      * <p>LEGACY devices will always be in FAST mode.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #COLOR_CORRECTION_ABERRATION_MODE_OFF OFF}</li>
      *   <li>{@link #COLOR_CORRECTION_ABERRATION_MODE_FAST FAST}</li>
      *   <li>{@link #COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES android.colorCorrection.availableAberrationModes}</p>
      * <p>This key is available on all devices.</p>
@@ -594,13 +596,14 @@
      * ensure it selects exposure times that do not cause banding
      * issues. The {@link CaptureResult#STATISTICS_SCENE_FLICKER android.statistics.sceneFlicker} key can assist
      * the application in this.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AE_ANTIBANDING_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_AE_ANTIBANDING_MODE_50HZ 50HZ}</li>
      *   <li>{@link #CONTROL_AE_ANTIBANDING_MODE_60HZ 60HZ}</li>
      *   <li>{@link #CONTROL_AE_ANTIBANDING_MODE_AUTO AUTO}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br></p>
      * <p>{@link CameraCharacteristics#CONTROL_AE_AVAILABLE_ANTIBANDING_MODES android.control.aeAvailableAntibandingModes}</p>
      * <p>This key is available on all devices.</p>
@@ -725,7 +728,7 @@
      * camera device auto-exposure routine for the overridden
      * fields for a given capture will be available in its
      * CaptureResult.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AE_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_AE_MODE_ON ON}</li>
@@ -733,7 +736,8 @@
      *   <li>{@link #CONTROL_AE_MODE_ON_ALWAYS_FLASH ON_ALWAYS_FLASH}</li>
      *   <li>{@link #CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE ON_AUTO_FLASH_REDEYE}</li>
      *   <li>{@link #CONTROL_AE_MODE_ON_EXTERNAL_FLASH ON_EXTERNAL_FLASH}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_MODES android.control.aeAvailableModes}</p>
      * <p>This key is available on all devices.</p>
@@ -899,12 +903,13 @@
      * example.</p>
      * <p>If both the precapture and the auto-focus trigger are activated on the same request, then
      * the camera device will complete them in the optimal order for that device.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE IDLE}</li>
      *   <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_START START}</li>
      *   <li>{@link #CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL CANCEL}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -1139,7 +1144,7 @@
      * </tr>
      * </tbody>
      * </table>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AE_STATE_INACTIVE INACTIVE}</li>
      *   <li>{@link #CONTROL_AE_STATE_SEARCHING SEARCHING}</li>
@@ -1147,7 +1152,8 @@
      *   <li>{@link #CONTROL_AE_STATE_LOCKED LOCKED}</li>
      *   <li>{@link #CONTROL_AE_STATE_FLASH_REQUIRED FLASH_REQUIRED}</li>
      *   <li>{@link #CONTROL_AE_STATE_PRECAPTURE PRECAPTURE}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -1184,7 +1190,7 @@
      * <p>If the lens is controlled by the camera device auto-focus algorithm,
      * the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
      * in result metadata.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AF_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_AF_MODE_AUTO AUTO}</li>
@@ -1192,7 +1198,8 @@
      *   <li>{@link #CONTROL_AF_MODE_CONTINUOUS_VIDEO CONTINUOUS_VIDEO}</li>
      *   <li>{@link #CONTROL_AF_MODE_CONTINUOUS_PICTURE CONTINUOUS_PICTURE}</li>
      *   <li>{@link #CONTROL_AF_MODE_EDOF EDOF}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AF_AVAILABLE_MODES android.control.afAvailableModes}</p>
      * <p>This key is available on all devices.</p>
@@ -1307,12 +1314,13 @@
      * focus sweep), the camera device may delay acting on a later trigger until the previous
      * trigger has been fully handled. This may lead to longer intervals between the trigger and
      * changes to {@link CaptureResult#CONTROL_AF_STATE android.control.afState}, for example.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AF_TRIGGER_IDLE IDLE}</li>
      *   <li>{@link #CONTROL_AF_TRIGGER_START START}</li>
      *   <li>{@link #CONTROL_AF_TRIGGER_CANCEL CANCEL}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
@@ -1708,7 +1716,7 @@
      * </tr>
      * </tbody>
      * </table>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AF_STATE_INACTIVE INACTIVE}</li>
      *   <li>{@link #CONTROL_AF_STATE_PASSIVE_SCAN PASSIVE_SCAN}</li>
@@ -1717,7 +1725,8 @@
      *   <li>{@link #CONTROL_AF_STATE_FOCUSED_LOCKED FOCUSED_LOCKED}</li>
      *   <li>{@link #CONTROL_AF_STATE_NOT_FOCUSED_LOCKED NOT_FOCUSED_LOCKED}</li>
      *   <li>{@link #CONTROL_AF_STATE_PASSIVE_UNFOCUSED PASSIVE_UNFOCUSED}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_AF_MODE
@@ -1790,7 +1799,7 @@
      * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform},
      * {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
      * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} are ignored.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AWB_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_AWB_MODE_AUTO AUTO}</li>
@@ -1801,7 +1810,8 @@
      *   <li>{@link #CONTROL_AWB_MODE_CLOUDY_DAYLIGHT CLOUDY_DAYLIGHT}</li>
      *   <li>{@link #CONTROL_AWB_MODE_TWILIGHT TWILIGHT}</li>
      *   <li>{@link #CONTROL_AWB_MODE_SHADE SHADE}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AWB_AVAILABLE_MODES android.control.awbAvailableModes}</p>
      * <p>This key is available on all devices.</p>
@@ -1915,7 +1925,7 @@
      * MANUAL_SENSOR.
      *   * MOTION_TRACKING will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains
      * MOTION_TRACKING.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_CUSTOM CUSTOM}</li>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_PREVIEW PREVIEW}</li>
@@ -1925,7 +1935,8 @@
      *   <li>{@link #CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_MANUAL MANUAL}</li>
      *   <li>{@link #CONTROL_CAPTURE_INTENT_MOTION_TRACKING MOTION_TRACKING}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_MODE
@@ -2061,13 +2072,14 @@
      * </tr>
      * </tbody>
      * </table>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AWB_STATE_INACTIVE INACTIVE}</li>
      *   <li>{@link #CONTROL_AWB_STATE_SEARCHING SEARCHING}</li>
      *   <li>{@link #CONTROL_AWB_STATE_CONVERGED CONVERGED}</li>
      *   <li>{@link #CONTROL_AWB_STATE_LOCKED LOCKED}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -2096,7 +2108,7 @@
      * implementor of the camera device, and should not be
      * depended on to be consistent (or present) across all
      * devices.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_EFFECT_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_EFFECT_MODE_MONO MONO}</li>
@@ -2107,7 +2119,8 @@
      *   <li>{@link #CONTROL_EFFECT_MODE_WHITEBOARD WHITEBOARD}</li>
      *   <li>{@link #CONTROL_EFFECT_MODE_BLACKBOARD BLACKBOARD}</li>
      *   <li>{@link #CONTROL_EFFECT_MODE_AQUA AQUA}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AVAILABLE_EFFECTS android.control.availableEffects}</p>
      * <p>This key is available on all devices.</p>
@@ -2146,14 +2159,15 @@
      * update, as if this frame is never captured. This mode can be used in the scenario
      * where the application doesn't want a 3A manual control capture to affect
      * the subsequent auto 3A capture results.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_MODE_AUTO AUTO}</li>
      *   <li>{@link #CONTROL_MODE_USE_SCENE_MODE USE_SCENE_MODE}</li>
      *   <li>{@link #CONTROL_MODE_OFF_KEEP_STATE OFF_KEEP_STATE}</li>
      *   <li>{@link #CONTROL_MODE_USE_EXTENDED_SCENE_MODE USE_EXTENDED_SCENE_MODE}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AVAILABLE_MODES android.control.availableModes}</p>
      * <p>This key is available on all devices.</p>
@@ -2183,7 +2197,7 @@
      * to the implementor of the camera device. Their behavior will not be
      * consistent across all devices, and any given device may only implement
      * a subset of these modes.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_SCENE_MODE_DISABLED DISABLED}</li>
      *   <li>{@link #CONTROL_SCENE_MODE_FACE_PRIORITY FACE_PRIORITY}</li>
@@ -2204,7 +2218,8 @@
      *   <li>{@link #CONTROL_SCENE_MODE_BARCODE BARCODE}</li>
      *   <li>{@link #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO}</li>
      *   <li>{@link #CONTROL_SCENE_MODE_HDR HDR}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}</p>
      * <p>This key is available on all devices.</p>
@@ -2265,11 +2280,12 @@
      * ({@link CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE android.lens.opticalStabilizationMode}), turning both modes on may
      * produce undesirable interaction, so it is recommended not to enable
      * both at the same time.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_VIDEO_STABILIZATION_MODE_OFF OFF}</li>
      *   <li>{@link #CONTROL_VIDEO_STABILIZATION_MODE_ON ON}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE
@@ -2362,11 +2378,12 @@
      * result. Otherwise the value will be NOT_DETECTED. The threshold for detection is similar
      * to what would trigger a new passive focus scan to begin in CONTINUOUS autofocus modes.</p>
      * <p>This key will be available if the camera device advertises this key via {@link android.hardware.camera2.CameraCharacteristics#getAvailableCaptureResultKeys }.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_AF_SCENE_CHANGE_NOT_DETECTED NOT_DETECTED}</li>
      *   <li>{@link #CONTROL_AF_SCENE_CHANGE_DETECTED DETECTED}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * @see #CONTROL_AF_SCENE_CHANGE_NOT_DETECTED
      * @see #CONTROL_AF_SCENE_CHANGE_DETECTED
@@ -2402,12 +2419,13 @@
      * with different field of view. As a result, when bokeh mode is enabled, the camera device
      * may override {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} or {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}, and the field of
      * view may be smaller than when bokeh mode is off.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #CONTROL_EXTENDED_SCENE_MODE_DISABLED DISABLED}</li>
      *   <li>{@link #CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE BOKEH_STILL_CAPTURE}</li>
      *   <li>{@link #CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS BOKEH_CONTINUOUS}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      *
      * @see CaptureRequest#CONTROL_ZOOM_RATIO
@@ -2490,7 +2508,10 @@
      * explicitly set {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}, its value defaults to 1.0.</p>
      * <p>One limitation of controlling zoom using zoomRatio is that the {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}
      * must only be used for letterboxing or pillarboxing of the sensor active array, and no
-     * FREEFORM cropping can be used with {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} other than 1.0.</p>
+     * FREEFORM cropping can be used with {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} other than 1.0. If
+     * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} is not 1.0, and {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} is set to be
+     * windowboxing, the camera framework will override the {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to be
+     * the active array.</p>
      * <p><b>Range of valid values:</b><br>
      * {@link CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE android.control.zoomRatioRange}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2531,13 +2552,14 @@
      * device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively.
      * The camera device may adjust its internal edge enhancement parameters for best
      * image quality based on the {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}, if it is set.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #EDGE_MODE_OFF OFF}</li>
      *   <li>{@link #EDGE_MODE_FAST FAST}</li>
      *   <li>{@link #EDGE_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
      *   <li>{@link #EDGE_MODE_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES android.edge.availableEdgeModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2573,12 +2595,13 @@
      * <p>When set to TORCH, the flash will be on continuously. This mode can be used
      * for use cases such as preview, auto-focus assist, still capture, or video recording.</p>
      * <p>The flash status will be reported by {@link CaptureResult#FLASH_STATE android.flash.state} in the capture result metadata.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #FLASH_MODE_OFF OFF}</li>
      *   <li>{@link #FLASH_MODE_SINGLE SINGLE}</li>
      *   <li>{@link #FLASH_MODE_TORCH TORCH}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_AE_MODE
@@ -2610,14 +2633,15 @@
      * </ul>
      * <p>In all other conditions the state will not be available on
      * LEGACY devices (i.e. it will be <code>null</code>).</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #FLASH_STATE_UNAVAILABLE UNAVAILABLE}</li>
      *   <li>{@link #FLASH_STATE_CHARGING CHARGING}</li>
      *   <li>{@link #FLASH_STATE_READY READY}</li>
      *   <li>{@link #FLASH_STATE_FIRED FIRED}</li>
      *   <li>{@link #FLASH_STATE_PARTIAL PARTIAL}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -2643,12 +2667,13 @@
      * <p>Hotpixel correction interpolates out, or otherwise removes, pixels
      * that do not accurately measure the incoming light (i.e. pixels that
      * are stuck at an arbitrary value or are oversensitive).</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #HOT_PIXEL_MODE_OFF OFF}</li>
      *   <li>{@link #HOT_PIXEL_MODE_FAST FAST}</li>
      *   <li>{@link #HOT_PIXEL_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES android.hotPixel.availableHotPixelModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2985,11 +3010,12 @@
      * <p>Not all devices will support OIS; see
      * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization} for
      * available controls.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #LENS_OPTICAL_STABILIZATION_MODE_OFF OFF}</li>
      *   <li>{@link #LENS_OPTICAL_STABILIZATION_MODE_ON ON}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION android.lens.info.availableOpticalStabilization}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -3029,11 +3055,12 @@
      * <p>Then this state will always be STATIONARY.</p>
      * <p>When the state is MOVING, it indicates that at least one of the lens parameters
      * is changing.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #LENS_STATE_STATIONARY STATIONARY}</li>
      *   <li>{@link #LENS_STATE_MOVING MOVING}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -3335,14 +3362,15 @@
      * will apply FAST/HIGH_QUALITY YUV domain noise reduction, respectively. The camera device
      * may adjust the noise reduction parameters for best image quality based on the
      * {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor} if it is set.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #NOISE_REDUCTION_MODE_OFF OFF}</li>
      *   <li>{@link #NOISE_REDUCTION_MODE_FAST FAST}</li>
      *   <li>{@link #NOISE_REDUCTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
      *   <li>{@link #NOISE_REDUCTION_MODE_MINIMAL MINIMAL}</li>
      *   <li>{@link #NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG ZERO_SHUTTER_LAG}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -3619,14 +3647,15 @@
      * <li>640x480 stream: top-left: <code>(781, 375)</code> on active array, size: <code>(640, 480)</code>, downscaled 1.17x from sensor pixels</li>
      * <li>1280x720 stream: top-left: <code>(711, 375)</code> on active array, size: <code>(1280, 720)</code>, upscaled 1.71x from sensor pixels</li>
      * </ul>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_NONE NONE}</li>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_90 90}</li>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_180 180}</li>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_270 270}</li>
      *   <li>{@link #SCALER_ROTATE_AND_CROP_AUTO AUTO}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES android.scaler.availableRotateAndCropModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -3948,7 +3977,7 @@
      * occur (and that the test pattern remain unmodified, since the flash
      * would not actually affect it).</p>
      * <p>Defaults to OFF.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_OFF OFF}</li>
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_SOLID_COLOR SOLID_COLOR}</li>
@@ -3956,7 +3985,8 @@
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY COLOR_BARS_FADE_TO_GRAY}</li>
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_PN9 PN9}</li>
      *   <li>{@link #SENSOR_TEST_PATTERN_MODE_CUSTOM1 CUSTOM1}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#SENSOR_AVAILABLE_TEST_PATTERN_MODES android.sensor.availableTestPatternModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -4102,12 +4132,13 @@
      * AWB are in AUTO modes({@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} <code>!=</code> OFF and {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} <code>!=</code>
      * OFF), to get best results, it is recommended that the applications wait for the AE and AWB
      * to be converged before using the returned shading map data.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SHADING_MODE_OFF OFF}</li>
      *   <li>{@link #SHADING_MODE_FAST FAST}</li>
      *   <li>{@link #SHADING_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#SHADING_AVAILABLE_MODES android.shading.availableModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -4136,12 +4167,13 @@
      * <p>Whether face detection is enabled, and whether it
      * should output just the basic fields or the full set of
      * fields.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #STATISTICS_FACE_DETECT_MODE_OFF OFF}</li>
      *   <li>{@link #STATISTICS_FACE_DETECT_MODE_SIMPLE SIMPLE}</li>
      *   <li>{@link #STATISTICS_FACE_DETECT_MODE_FULL FULL}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES android.statistics.info.availableFaceDetectModes}</p>
      * <p>This key is available on all devices.</p>
@@ -4506,12 +4538,13 @@
      * into this metadata field. See
      * {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} for more details.</p>
      * <p>Reports NONE if there doesn't appear to be flickering illumination.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #STATISTICS_SCENE_FLICKER_NONE NONE}</li>
      *   <li>{@link #STATISTICS_SCENE_FLICKER_50HZ 50HZ}</li>
      *   <li>{@link #STATISTICS_SCENE_FLICKER_60HZ 60HZ}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Full capability</b> -
      * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
@@ -4575,11 +4608,12 @@
      * android.statistics.lensShadingMap will be provided in
      * the output result metadata.</p>
      * <p>ON is always supported on devices with the RAW capability.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #STATISTICS_LENS_SHADING_MAP_MODE_OFF OFF}</li>
      *   <li>{@link #STATISTICS_LENS_SHADING_MAP_MODE_ON ON}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES android.statistics.info.availableLensShadingMapModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -4606,11 +4640,12 @@
      * at 30fps may have 6-7 OIS samples per capture result. This information can be combined
      * with the rolling shutter skew to account for lens motion during image exposure in
      * post-processing algorithms.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #STATISTICS_OIS_DATA_MODE_OFF OFF}</li>
      *   <li>{@link #STATISTICS_OIS_DATA_MODE_ON ON}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES android.statistics.info.availableOisDataModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -4878,14 +4913,15 @@
      * <p>If a request is sent with CONTRAST_CURVE with the camera device's
      * provided curve in FAST or HIGH_QUALITY, the image's tonemap will be
      * roughly the same.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #TONEMAP_MODE_CONTRAST_CURVE CONTRAST_CURVE}</li>
      *   <li>{@link #TONEMAP_MODE_FAST FAST}</li>
      *   <li>{@link #TONEMAP_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
      *   <li>{@link #TONEMAP_MODE_GAMMA_VALUE GAMMA_VALUE}</li>
      *   <li>{@link #TONEMAP_MODE_PRESET_CURVE PRESET_CURVE}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES android.tonemap.availableToneMapModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -4940,11 +4976,12 @@
      * <p><img alt="Rec. 709 tonemapping curve" src="/reference/images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png" /></p>
      * <p>Note that above figures show a 16 control points approximation of preset
      * curves. Camera devices may apply a different approximation to the curve.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #TONEMAP_PRESET_CURVE_SRGB SRGB}</li>
      *   <li>{@link #TONEMAP_PRESET_CURVE_REC709 REC709}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      *
      * @see CaptureRequest#TONEMAP_MODE
@@ -5045,11 +5082,12 @@
      * <p>In other words, results for this current request and up to
      * {@link CameraCharacteristics#REQUEST_PIPELINE_MAX_DEPTH android.request.pipelineMaxDepth} prior requests may have their
      * android.sync.frameNumber change to CONVERGING.</p>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #SYNC_FRAME_NUMBER_CONVERGING CONVERGING}</li>
      *   <li>{@link #SYNC_FRAME_NUMBER_UNKNOWN UNKNOWN}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * Either a non-negative value corresponding to a
      * <code>frame_number</code>, or one of the two enums (CONVERGING / UNKNOWN).</p>
@@ -5171,12 +5209,13 @@
      * <li>{@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}</li>
      * <li>{@link CaptureResult#STATISTICS_FACES android.statistics.faces}</li>
      * </ul>
-     * <p><b>Possible values:</b>
+     * <p><b>Possible values:</b></p>
      * <ul>
      *   <li>{@link #DISTORTION_CORRECTION_MODE_OFF OFF}</li>
      *   <li>{@link #DISTORTION_CORRECTION_MODE_FAST FAST}</li>
      *   <li>{@link #DISTORTION_CORRECTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
-     * </ul></p>
+     * </ul>
+     *
      * <p><b>Available values for this device:</b><br>
      * {@link CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES android.distortionCorrection.availableModes}</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
diff --git a/core/java/android/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java
index d9c1063..366734e 100644
--- a/core/java/android/hardware/display/BrightnessConfiguration.java
+++ b/core/java/android/hardware/display/BrightnessConfiguration.java
@@ -24,13 +24,13 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Pair;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -343,15 +343,15 @@
      *
      * @hide
      */
-    public void saveToXml(@NonNull XmlSerializer serializer) throws IOException {
+    public void saveToXml(@NonNull TypedXmlSerializer serializer) throws IOException {
         serializer.startTag(null, TAG_BRIGHTNESS_CURVE);
         if (mDescription != null) {
             serializer.attribute(null, ATTR_DESCRIPTION, mDescription);
         }
         for (int i = 0; i < mLux.length; i++) {
             serializer.startTag(null, TAG_BRIGHTNESS_POINT);
-            serializer.attribute(null, ATTR_LUX, Float.toString(mLux[i]));
-            serializer.attribute(null, ATTR_NITS, Float.toString(mNits[i]));
+            serializer.attributeFloat(null, ATTR_LUX, mLux[i]);
+            serializer.attributeFloat(null, ATTR_NITS, mNits[i]);
             serializer.endTag(null, TAG_BRIGHTNESS_POINT);
         }
         serializer.endTag(null, TAG_BRIGHTNESS_CURVE);
@@ -370,7 +370,7 @@
             final int category = entry.getKey();
             final BrightnessCorrection correction = entry.getValue();
             serializer.startTag(null, TAG_BRIGHTNESS_CORRECTION);
-            serializer.attribute(null, ATTR_CATEGORY, Integer.toString(category));
+            serializer.attributeInt(null, ATTR_CATEGORY, category);
             correction.saveToXml(serializer);
             serializer.endTag(null, TAG_BRIGHTNESS_CORRECTION);
         }
@@ -378,19 +378,18 @@
 
         serializer.startTag(null, TAG_BRIGHTNESS_PARAMS);
         if (mShouldCollectColorSamples) {
-            serializer.attribute(null, ATTR_COLLECT_COLOR, Boolean.toString(true));
+            serializer.attributeBoolean(null, ATTR_COLLECT_COLOR, true);
         }
         if (mShortTermModelTimeout >= 0) {
-            serializer.attribute(null, ATTR_MODEL_TIMEOUT,
-                    Long.toString(mShortTermModelTimeout));
+            serializer.attributeLong(null, ATTR_MODEL_TIMEOUT, mShortTermModelTimeout);
         }
         if (!Float.isNaN(mShortTermModelLowerLuxMultiplier)) {
-            serializer.attribute(null, ATTR_MODEL_LOWER_BOUND,
-                    Float.toString(mShortTermModelLowerLuxMultiplier));
+            serializer.attributeFloat(null, ATTR_MODEL_LOWER_BOUND,
+                    mShortTermModelLowerLuxMultiplier);
         }
         if (!Float.isNaN(mShortTermModelUpperLuxMultiplier)) {
-            serializer.attribute(null, ATTR_MODEL_UPPER_BOUND,
-                    Float.toString(mShortTermModelUpperLuxMultiplier));
+            serializer.attributeFloat(null, ATTR_MODEL_UPPER_BOUND,
+                    mShortTermModelUpperLuxMultiplier);
         }
         serializer.endTag(null, TAG_BRIGHTNESS_PARAMS);
     }
@@ -408,7 +407,7 @@
      *
      * @hide
      */
-    public static BrightnessConfiguration loadFromXml(@NonNull XmlPullParser parser)
+    public static BrightnessConfiguration loadFromXml(@NonNull TypedXmlPullParser parser)
             throws IOException, XmlPullParserException {
         String description = null;
         List<Float> luxList = new ArrayList<>();
@@ -440,22 +439,17 @@
                         continue;
                     }
                     final String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
-                    final String categoryText = parser.getAttributeValue(null, ATTR_CATEGORY);
+                    final int category = parser.getAttributeInt(null, ATTR_CATEGORY, -1);
                     BrightnessCorrection correction = BrightnessCorrection.loadFromXml(parser);
                     if (packageName != null) {
                         correctionsByPackageName.put(packageName, correction);
-                    } else if (categoryText != null) {
-                        try {
-                            final int category = Integer.parseInt(categoryText);
-                            correctionsByCategory.put(category, correction);
-                        } catch (NullPointerException | NumberFormatException e) {
-                            continue;
-                        }
+                    } else if (category != -1) {
+                        correctionsByCategory.put(category, correction);
                     }
                 }
             } else if (TAG_BRIGHTNESS_PARAMS.equals(parser.getName())) {
                 shouldCollectColorSamples =
-                        Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_COLLECT_COLOR));
+                        parser.getAttributeBoolean(null, ATTR_COLLECT_COLOR, false);
                 Long timeout = loadLongFromXml(parser, ATTR_MODEL_TIMEOUT);
                 if (timeout != null) {
                     shortTermModelTimeout = timeout;
@@ -491,23 +485,16 @@
         return builder.build();
     }
 
-    private static float loadFloatFromXml(XmlPullParser parser, String attribute) {
-        final String string = parser.getAttributeValue(null, attribute);
-        try {
-            return Float.parseFloat(string);
-        } catch (NullPointerException | NumberFormatException e) {
-            return Float.NaN;
-        }
+    private static float loadFloatFromXml(TypedXmlPullParser parser, String attribute) {
+        return parser.getAttributeFloat(null, attribute, Float.NaN);
     }
 
-    private static Long loadLongFromXml(XmlPullParser parser, String attribute) {
-        final String string = parser.getAttributeValue(null, attribute);
+    private static Long loadLongFromXml(TypedXmlPullParser parser, String attribute) {
         try {
-            return Long.parseLong(string);
-        } catch (NullPointerException | NumberFormatException e) {
-            // Ignoring
+            return parser.getAttributeLong(null, attribute);
+        } catch (Exception e) {
+            return null;
         }
-        return null;
     }
 
     /**
diff --git a/core/java/android/hardware/display/BrightnessCorrection.java b/core/java/android/hardware/display/BrightnessCorrection.java
index bbfc45e..2919ec3 100644
--- a/core/java/android/hardware/display/BrightnessCorrection.java
+++ b/core/java/android/hardware/display/BrightnessCorrection.java
@@ -23,12 +23,12 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.MathUtils;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
 import com.android.internal.util.XmlUtils;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 
@@ -153,7 +153,7 @@
      *
      * @hide
      */
-    public void saveToXml(XmlSerializer serializer) throws IOException {
+    public void saveToXml(TypedXmlSerializer serializer) throws IOException {
         mImplementation.saveToXml(serializer);
     }
 
@@ -170,7 +170,7 @@
      *
      * @hide
      */
-    public static BrightnessCorrection loadFromXml(XmlPullParser parser) throws IOException,
+    public static BrightnessCorrection loadFromXml(TypedXmlPullParser parser) throws IOException,
             XmlPullParserException {
         final int depth = parser.getDepth();
         while (XmlUtils.nextElementWithin(parser, depth)) {
@@ -181,20 +181,15 @@
         return null;
     }
 
-    private static float loadFloatFromXml(XmlPullParser parser, String attribute) {
-        final String string = parser.getAttributeValue(null, attribute);
-        try {
-            return Float.parseFloat(string);
-        } catch (NullPointerException | NumberFormatException e) {
-            return Float.NaN;
-        }
+    private static float loadFloatFromXml(TypedXmlPullParser parser, String attribute) {
+        return parser.getAttributeFloat(null, attribute, Float.NaN);
     }
 
     private interface BrightnessCorrectionImplementation {
         float apply(float brightness);
         String toString();
         void writeToParcel(Parcel dest);
-        void saveToXml(XmlSerializer serializer) throws IOException;
+        void saveToXml(TypedXmlSerializer serializer) throws IOException;
         // Package-private static methods:
         // static BrightnessCorrection readFromParcel(Parcel in);
         // static BrightnessCorrection loadFromXml(XmlPullParser parser) throws IOException,
@@ -263,10 +258,10 @@
         }
 
         @Override
-        public void saveToXml(XmlSerializer serializer) throws IOException {
+        public void saveToXml(TypedXmlSerializer serializer) throws IOException {
             serializer.startTag(null, TAG_SCALE_AND_TRANSLATE_LOG);
-            serializer.attribute(null, ATTR_SCALE, Float.toString(mScale));
-            serializer.attribute(null, ATTR_TRANSLATE, Float.toString(mTranslate));
+            serializer.attributeFloat(null, ATTR_SCALE, mScale);
+            serializer.attributeFloat(null, ATTR_TRANSLATE, mTranslate);
             serializer.endTag(null, TAG_SCALE_AND_TRANSLATE_LOG);
         }
 
@@ -276,7 +271,7 @@
             return BrightnessCorrection.createScaleAndTranslateLog(scale, translate);
         }
 
-        static BrightnessCorrection loadFromXml(XmlPullParser parser) throws IOException,
+        static BrightnessCorrection loadFromXml(TypedXmlPullParser parser) throws IOException,
                 XmlPullParserException {
             final float scale = loadFloatFromXml(parser, ATTR_SCALE);
             final float translate = loadFloatFromXml(parser, ATTR_TRANSLATE);
diff --git a/core/java/android/hardware/display/OWNERS b/core/java/android/hardware/display/OWNERS
index 9ca3910..5bcd9bb8 100644
--- a/core/java/android/hardware/display/OWNERS
+++ b/core/java/android/hardware/display/OWNERS
@@ -1,2 +1,6 @@
+# Bug component: 345010
+
+include /services/core/java/com/android/server/display/OWNERS
+
 michaelwr@google.com
 santoscordon@google.com
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index c5c51e4..468157a 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -33,8 +33,8 @@
     // Creates a test session with the specified sensorId
     ITestSession createTestSession(int sensorId, String opPackageName);
 
-    // Requests a proto dump of the service to the specified fd
-    byte[] dumpSensorServiceStateProto();
+    // Requests a proto dump of the specified sensor
+    byte[] dumpSensorServiceStateProto(int sensorId);
 
     // Retrieve static sensor properties for all face sensors
     List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
diff --git a/core/java/android/hardware/face/OWNERS b/core/java/android/hardware/face/OWNERS
new file mode 100644
index 0000000..33527f8
--- /dev/null
+++ b/core/java/android/hardware/face/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 879035
+
+jaggies@google.com
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index a4ce29b..64abbea 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -34,8 +34,8 @@
     // Creates a test session with the specified sensorId
     ITestSession createTestSession(int sensorId, String opPackageName);
 
-    // Requests a proto dump of the service to the specified fd
-    byte[] dumpSensorServiceStateProto();
+    // Requests a proto dump of the specified sensor
+    byte[] dumpSensorServiceStateProto(int sensorId);
 
     // Retrieve static sensor properties for all fingerprint sensors
     List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
diff --git a/core/java/android/hardware/fingerprint/OWNERS b/core/java/android/hardware/fingerprint/OWNERS
new file mode 100644
index 0000000..dcead40
--- /dev/null
+++ b/core/java/android/hardware/fingerprint/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 114777
+
+jaggies@google.com
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index eef4089..ae10f40 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -367,35 +367,35 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface HdmiCecVersion {}
 
-    // -- Which devices the playback device can send a <Standby> message to upon going to sleep.
+    // -- Scope of CEC power control messages sent by a playback device.
     /**
-     * Send <Standby> to TV only.
+     * Send CEC power control messages to TV only.
      *
      * @hide
      */
-    public static final String SEND_STANDBY_ON_SLEEP_TO_TV = "to_tv";
+    public static final String POWER_CONTROL_MODE_TV = "to_tv";
     /**
-     * Broadcast <Standby> to all devices in the network.
+     * Broadcast CEC power control messages to all devices in the network.
      *
      * @hide
      */
-    public static final String SEND_STANDBY_ON_SLEEP_BROADCAST = "broadcast";
+    public static final String POWER_CONTROL_MODE_BROADCAST = "broadcast";
     /**
-     * Don't send any <Standby> message.
+     * Don't send any CEC power control messages.
      *
      * @hide
      */
-    public static final String SEND_STANDBY_ON_SLEEP_NONE = "none";
+    public static final String POWER_CONTROL_MODE_NONE = "none";
     /**
      * @hide
      */
     @StringDef({
-            SEND_STANDBY_ON_SLEEP_TO_TV,
-            SEND_STANDBY_ON_SLEEP_BROADCAST,
-            SEND_STANDBY_ON_SLEEP_NONE
+            POWER_CONTROL_MODE_TV,
+            POWER_CONTROL_MODE_BROADCAST,
+            POWER_CONTROL_MODE_NONE
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface StandbyBehavior {}
+    public @interface PowerControlMode {}
 
     // -- Which power state action should be taken when Active Source is lost.
     /**
@@ -457,11 +457,11 @@
      */
     public static final String CEC_SETTING_NAME_HDMI_CEC_VERSION = "hdmi_cec_version";
     /**
-     * Name of a setting deciding on the Standby message behaviour on sleep.
+     * Name of a setting deciding on the power control mode.
      *
      * @hide
      */
-    public static final String CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP = "send_standby_on_sleep";
+    public static final String CEC_SETTING_NAME_POWER_CONTROL_MODE = "send_standby_on_sleep";
     /**
      * Name of a setting deciding on power state action when losing Active Source.
      *
@@ -482,7 +482,7 @@
     @StringDef({
         CEC_SETTING_NAME_HDMI_CEC_ENABLED,
         CEC_SETTING_NAME_HDMI_CEC_VERSION,
-        CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
+        CEC_SETTING_NAME_POWER_CONTROL_MODE,
         CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
         CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
     })
@@ -1506,7 +1506,7 @@
     }
 
     /**
-     * Set the 'send_standby_on_sleep' option.
+     * Set the 'power_control_mode' option.
      *
      * @param value the desired value
      * @throws IllegalArgumentException when the new value is not allowed.
@@ -1515,20 +1515,20 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.HDMI_CEC)
-    public void setSendStandbyOnSleep(@NonNull @StandbyBehavior String value) {
+    public void setPowerControlMode(@NonNull @PowerControlMode String value) {
         if (mService == null) {
             Log.e(TAG, "HdmiControlService is not available");
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            mService.setCecSettingStringValue(CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP, value);
+            mService.setCecSettingStringValue(CEC_SETTING_NAME_POWER_CONTROL_MODE, value);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Get the value of 'send_standby_on_sleep' option.
+     * Get the value of 'power_control_mode' option.
      *
      * @return the current value.
      * @throws RuntimeException when the HdmiControlService is not available.
@@ -1536,15 +1536,15 @@
      * @hide
      */
     @NonNull
-    @StandbyBehavior
+    @PowerControlMode
     @RequiresPermission(android.Manifest.permission.HDMI_CEC)
-    public String getSendStandbyOnSleep() {
+    public String getPowerControlMode() {
         if (mService == null) {
             Log.e(TAG, "HdmiControlService is not available");
             throw new RuntimeException("HdmiControlService is not available");
         }
         try {
-            return mService.getCecSettingStringValue(CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
+            return mService.getCecSettingStringValue(CEC_SETTING_NAME_POWER_CONTROL_MODE);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/hardware/hdmi/OWNERS b/core/java/android/hardware/hdmi/OWNERS
new file mode 100644
index 0000000..e9557f8
--- /dev/null
+++ b/core/java/android/hardware/hdmi/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 345010
+
+include /services/core/java/com/android/server/display/OWNERS
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index dc6f579..57c0398 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -22,6 +22,7 @@
 import android.hardware.input.IInputDevicesChangedListener;
 import android.hardware.input.ITabletModeChangedListener;
 import android.hardware.input.TouchCalibration;
+import android.os.CombinedVibrationEffect;
 import android.os.IBinder;
 import android.os.VibrationEffect;
 import android.view.InputDevice;
@@ -85,7 +86,10 @@
 
     // Input device vibrator control.
     void vibrate(int deviceId, in VibrationEffect effect, IBinder token);
+    void vibrateCombined(int deviceId, in CombinedVibrationEffect effect, IBinder token);
     void cancelVibrate(int deviceId, IBinder token);
+    int[] getVibratorIds(int deviceId);
+    boolean isVibrating(int deviceId);
 
     void setPointerIconType(int typeId);
     void setCustomPointerIcon(in PointerIcon icon);
diff --git a/core/java/android/hardware/input/InputDeviceVibrator.java b/core/java/android/hardware/input/InputDeviceVibrator.java
new file mode 100644
index 0000000..c60d6ce
--- /dev/null
+++ b/core/java/android/hardware/input/InputDeviceVibrator.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2020 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.hardware.input;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Vibrator implementation that communicates with the input device vibrators.
+ */
+final class InputDeviceVibrator extends Vibrator {
+    // mDeviceId represents InputDevice ID the vibrator belongs to
+    private final int mDeviceId;
+    private final int mVibratorId;
+    private final Binder mToken;
+    private final InputManager mInputManager;
+
+    InputDeviceVibrator(InputManager inputManager, int deviceId, int vibratorId) {
+        mInputManager = inputManager;
+        mDeviceId = deviceId;
+        mVibratorId = vibratorId;
+        mToken = new Binder();
+    }
+
+    @Override
+    public boolean hasVibrator() {
+        return true;
+    }
+
+    @Override
+    public boolean isVibrating() {
+        return mInputManager.isVibrating(mDeviceId);
+    }
+
+    /* TODO: b/161634264 Support Vibrator listener API in input devices */
+    @Override
+    public void addVibratorStateListener(@NonNull OnVibratorStateChangedListener listener) {
+        throw new UnsupportedOperationException(
+            "addVibratorStateListener not supported in InputDeviceVibrator");
+    }
+
+    @Override
+    public void addVibratorStateListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnVibratorStateChangedListener listener) {
+        throw new UnsupportedOperationException(
+            "addVibratorStateListener not supported in InputDeviceVibrator");
+    }
+
+    @Override
+    public void removeVibratorStateListener(@NonNull OnVibratorStateChangedListener listener) {
+        throw new UnsupportedOperationException(
+            "removeVibratorStateListener not supported in InputDeviceVibrator");
+    }
+
+    @Override
+    public boolean hasAmplitudeControl() {
+        return true;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void vibrate(int uid, String opPkg, @NonNull VibrationEffect effect,
+            String reason, @NonNull VibrationAttributes attributes) {
+        mInputManager.vibrate(mDeviceId, effect, mToken);
+    }
+
+    @Override
+    public void cancel() {
+        mInputManager.cancelVibrate(mDeviceId, mToken);
+    }
+}
diff --git a/core/java/android/hardware/input/InputDeviceVibratorManager.java b/core/java/android/hardware/input/InputDeviceVibratorManager.java
new file mode 100644
index 0000000..a381b02
--- /dev/null
+++ b/core/java/android/hardware/input/InputDeviceVibratorManager.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2020 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.hardware.input;
+
+import android.os.Binder;
+import android.os.CombinedVibrationEffect;
+import android.os.NullVibrator;
+import android.os.Vibrator;
+import android.os.VibratorManager;
+import android.util.SparseArray;
+import android.view.InputDevice;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * Vibrator manager implementation that communicates with the input device vibrators.
+ *
+ * @hide
+ */
+public class InputDeviceVibratorManager extends VibratorManager
+        implements InputManager.InputDeviceListener {
+    private static final String TAG = "InputDeviceVibratorManager";
+    private static final boolean DEBUG = false;
+
+    private final Binder mToken;
+    private final InputManager mInputManager;
+
+    // The input device Id.
+    private final int mDeviceId;
+    // Vibrator map from Vibrator Id to Vibrator
+    @GuardedBy("mVibrators")
+    private final SparseArray<Vibrator> mVibrators = new SparseArray<>();
+
+    public InputDeviceVibratorManager(InputManager inputManager, int deviceId) {
+        mInputManager = inputManager;
+        mDeviceId = deviceId;
+        mToken = new Binder();
+
+        initializeVibrators();
+    }
+
+    private void initializeVibrators() {
+        synchronized (mVibrators) {
+            mVibrators.clear();
+            InputDevice inputDevice = InputDevice.getDevice(mDeviceId);
+            final int[] vibratorIds =
+                    mInputManager.getVibratorIds(mDeviceId);
+            for (int i = 0; i < vibratorIds.length; i++) {
+                mVibrators.put(vibratorIds[i],
+                        new InputDeviceVibrator(mInputManager, mDeviceId, vibratorIds[i]));
+            }
+        }
+    }
+
+    @Override
+    public void onInputDeviceAdded(int deviceId) {
+    }
+
+    @Override
+    public void onInputDeviceRemoved(int deviceId) {
+        synchronized (mVibrators) {
+            if (deviceId == mDeviceId) {
+                mVibrators.clear();
+            }
+        }
+    }
+
+    @Override
+    public void onInputDeviceChanged(int deviceId) {
+        if (deviceId == mDeviceId) {
+            initializeVibrators();
+        }
+    }
+
+    @Override
+    public int[] getVibratorIds() {
+        synchronized (mVibrators) {
+            int[] vibratorIds = new int[mVibrators.size()];
+            for (int idx = 0; idx < mVibrators.size(); idx++) {
+                vibratorIds[idx++] = mVibrators.keyAt(idx);
+            }
+            return vibratorIds;
+        }
+    }
+
+    @Override
+    public Vibrator getVibrator(int vibratorId) {
+        synchronized (mVibrators) {
+            if (mVibrators.contains(vibratorId)) {
+                return mVibrators.get(vibratorId);
+            }
+        }
+        return NullVibrator.getInstance();
+    }
+
+    @Override
+    public Vibrator getDefaultVibrator() {
+        // Returns vibrator ID 0
+        synchronized (mVibrators) {
+            if (mVibrators.size() > 0) {
+                return mVibrators.valueAt(0);
+            }
+        }
+        return NullVibrator.getInstance();
+    }
+
+    @Override
+    public void vibrate(CombinedVibrationEffect effect) {
+        mInputManager.vibrate(mDeviceId, effect, mToken);
+    }
+}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 81ea2f5..f1d60f6 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -17,7 +17,6 @@
 package android.hardware.input;
 
 import android.Manifest;
-import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -29,9 +28,9 @@
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
-import android.os.Binder;
 import android.os.BlockUntrustedTouchesMode;
 import android.os.Build;
+import android.os.CombinedVibrationEffect;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.InputEventInjectionSync;
@@ -41,9 +40,9 @@
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.SystemClock;
-import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
+import android.os.VibratorManager;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.util.Log;
@@ -64,7 +63,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.Executor;
 
 /**
  * Provides information about input devices and available key layouts.
@@ -1287,8 +1285,75 @@
      * @return The vibrator, never null.
      * @hide
      */
-    public Vibrator getInputDeviceVibrator(int deviceId) {
-        return new InputDeviceVibrator(deviceId);
+    public Vibrator getInputDeviceVibrator(int deviceId, int vibratorId) {
+        return new InputDeviceVibrator(this, deviceId, vibratorId);
+    }
+
+    /**
+     * Gets a vibrator manager service associated with an input device, always create a new
+     * instance.
+     * @return The vibrator manager, never null.
+     * @hide
+     */
+    @NonNull
+    public VibratorManager getInputDeviceVibratorManager(int deviceId) {
+        return new InputDeviceVibratorManager(InputManager.this, deviceId);
+    }
+
+    /*
+     * Get the list of device vibrators
+     * @return The list of vibrators IDs
+     */
+    int[] getVibratorIds(int deviceId) {
+        try {
+            return mIm.getVibratorIds(deviceId);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /*
+     * Perform vibration effect
+     */
+    void vibrate(int deviceId, VibrationEffect effect, IBinder token) {
+        try {
+            mIm.vibrate(deviceId, effect, token);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /*
+     * Perform combined vibration effect
+     */
+    void vibrate(int deviceId, CombinedVibrationEffect effect, IBinder token) {
+        try {
+            mIm.vibrateCombined(deviceId, effect, token);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /*
+     * Cancel an ongoing vibration
+     */
+    void cancelVibrate(int deviceId, IBinder token) {
+        try {
+            mIm.cancelVibrate(deviceId, token);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /*
+     * Check if input device is vibrating
+     */
+    boolean isVibrating(int deviceId)  {
+        try {
+            return mIm.isVibrating(deviceId);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -1401,72 +1466,4 @@
             }
         }
     }
-
-    private final class InputDeviceVibrator extends Vibrator {
-        private final int mDeviceId;
-        private final Binder mToken;
-
-        public InputDeviceVibrator(int deviceId) {
-            mDeviceId = deviceId;
-            mToken = new Binder();
-        }
-
-        @Override
-        public boolean hasVibrator() {
-            return true;
-        }
-
-        @Override
-        public boolean isVibrating() {
-            throw new UnsupportedOperationException(
-                "isVibrating not supported in InputDeviceVibrator");
-        }
-
-        @Override
-        public void addVibratorStateListener(@NonNull OnVibratorStateChangedListener listener) {
-            throw new UnsupportedOperationException(
-                "addVibratorStateListener not supported in InputDeviceVibrator");
-        }
-
-        @Override
-        public void addVibratorStateListener(
-                @NonNull @CallbackExecutor Executor executor,
-                @NonNull OnVibratorStateChangedListener listener) {
-            throw new UnsupportedOperationException(
-                "addVibratorStateListener not supported in InputDeviceVibrator");
-        }
-
-        @Override
-        public void removeVibratorStateListener(@NonNull OnVibratorStateChangedListener listener) {
-            throw new UnsupportedOperationException(
-                "removeVibratorStateListener not supported in InputDeviceVibrator");
-        }
-
-        @Override
-        public boolean hasAmplitudeControl() {
-            return true;
-        }
-
-        /**
-         * @hide
-         */
-        @Override
-        public void vibrate(int uid, String opPkg, @NonNull VibrationEffect effect,
-                String reason, @NonNull VibrationAttributes attributes) {
-            try {
-                mIm.vibrate(mDeviceId, effect, mToken);
-            } catch (RemoteException ex) {
-                throw ex.rethrowFromSystemServer();
-            }
-        }
-
-        @Override
-        public void cancel() {
-            try {
-                mIm.cancelVibrate(mDeviceId, mToken);
-            } catch (RemoteException ex) {
-                throw ex.rethrowFromSystemServer();
-            }
-        }
-    }
 }
diff --git a/core/java/android/hardware/input/OWNERS b/core/java/android/hardware/input/OWNERS
index 0313a40..25e02e1 100644
--- a/core/java/android/hardware/input/OWNERS
+++ b/core/java/android/hardware/input/OWNERS
@@ -1,2 +1,6 @@
+# Bug component: 136048
+
+include /services/core/java/com/android/server/input/OWNERS
+
 michaelwr@google.com
 svv@google.com
diff --git a/core/java/android/hardware/iris/OWNERS b/core/java/android/hardware/iris/OWNERS
new file mode 100644
index 0000000..33527f8
--- /dev/null
+++ b/core/java/android/hardware/iris/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 879035
+
+jaggies@google.com
diff --git a/core/java/android/hardware/lights/OWNERS b/core/java/android/hardware/lights/OWNERS
new file mode 100644
index 0000000..cb46a80
--- /dev/null
+++ b/core/java/android/hardware/lights/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/lights/OWNERS
diff --git a/core/java/android/hardware/location/OWNERS b/core/java/android/hardware/location/OWNERS
new file mode 100644
index 0000000..383321b
--- /dev/null
+++ b/core/java/android/hardware/location/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 880425
+
+mstogaitis@google.com
+wyattriley@google.com
+etn@google.com
+weiwa@google.com
diff --git a/core/java/android/hardware/soundtrigger/OWNERS b/core/java/android/hardware/soundtrigger/OWNERS
new file mode 100644
index 0000000..816bc6b
--- /dev/null
+++ b/core/java/android/hardware/soundtrigger/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/media/soundtrigger/OWNERS
diff --git a/core/java/android/hardware/usb/OWNERS b/core/java/android/hardware/usb/OWNERS
index 8ee72b5..8f2b39d 100644
--- a/core/java/android/hardware/usb/OWNERS
+++ b/core/java/android/hardware/usb/OWNERS
@@ -1,6 +1,4 @@
-badhri@google.com
-elaurent@google.com
+# Bug component: 175220
+
 moltmann@google.com
-albertccwang@google.com
-jameswei@google.com
-howardyen@google.com
\ No newline at end of file
+badhri@google.com
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index aac57fe..c28bab7 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -609,7 +609,7 @@
     public @interface UsbFunctionMode {}
 
     /** @hide */
-    @IntDef(flag = true, prefix = { "GADGET_HAL_" }, value = {
+    @IntDef(prefix = { "GADGET_HAL_" }, value = {
             GADGET_HAL_NOT_SUPPORTED,
             GADGET_HAL_V1_0,
             GADGET_HAL_V1_1,
diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java
index 43c418e..bb7aff6 100644
--- a/core/java/android/hardware/usb/UsbPortStatus.java
+++ b/core/java/android/hardware/usb/UsbPortStatus.java
@@ -202,7 +202,7 @@
     public static final int CONTAMINANT_PROTECTION_DISABLED =
             android.hardware.usb.V1_2.Constants.ContaminantProtectionStatus.DISABLED;
 
-    @IntDef(prefix = { "CONTAMINANT_DETECION_" }, flag = true, value = {
+    @IntDef(prefix = { "CONTAMINANT_DETECTION_" }, value = {
             CONTAMINANT_DETECTION_NOT_SUPPORTED,
             CONTAMINANT_DETECTION_DISABLED,
             CONTAMINANT_DETECTION_NOT_DETECTED,
@@ -221,7 +221,7 @@
     @Retention(RetentionPolicy.SOURCE)
     @interface ContaminantProtectionStatus{}
 
-    @IntDef(prefix = { "MODE_" }, flag = true, value = {
+    @IntDef(prefix = { "MODE_" }, value = {
             MODE_NONE,
             MODE_DFP,
             MODE_UFP,
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 5576857..6831eca 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -630,6 +630,9 @@
         @MainThread
         @Override
         public void updateInputMethodDisplay(int displayId) {
+            if (getDisplayId() == displayId) {
+                return;
+            }
             // Update display for adding IME window to the right display.
             // TODO(b/111364446) Need to address context lifecycle issue if need to re-create
             // for update resources & configuration correctly when show soft input
@@ -804,12 +807,12 @@
                     null /* icProto */);
             final boolean wasVisible = isInputViewShown();
             if (dispatchOnShowInputRequested(flags, false)) {
-
                 showWindow(true);
                 applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */);
+            } else {
+                // If user uses hard keyboard, IME button should always be shown.
+                setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
             }
-            // If user uses hard keyboard, IME button should always be shown.
-            setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
             final boolean isVisible = isInputViewShown();
             final boolean visibilityChanged = isVisible != wasVisible;
             if (resultReceiver != null) {
@@ -1273,6 +1276,9 @@
         super.onCreate();
         mImm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
         mSettingsObserver = SettingsObserver.createAndRegister(this);
+        // cache preference so we don't have to read ContentProvider when IME is requested to be
+        // shown the first time (cold start).
+        mSettingsObserver.shouldShowImeWithHardKeyboard();
 
         mIsAutomotive = isAutomotive();
         mAutomotiveHideNavBarForKeyboard = getApplicationContext().getResources().getBoolean(
@@ -1341,13 +1347,7 @@
         mRootView = mInflater.inflate(
                 com.android.internal.R.layout.input_method, null);
         mWindow.setContentView(mRootView);
-        mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsComputer);
         mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);
-        if (Settings.Global.getInt(getContentResolver(),
-                Settings.Global.FANCY_IME_ANIMATIONS, 0) != 0) {
-            mWindow.getWindow().setWindowAnimations(
-                    com.android.internal.R.style.Animation_InputMethodFancy);
-        }
         mFullscreenArea = mRootView.findViewById(com.android.internal.R.id.fullscreenArea);
         mExtractViewHidden = false;
         mExtractFrame = mRootView.findViewById(android.R.id.extractArea);
@@ -1413,6 +1413,7 @@
         int showFlags = mShowInputFlags;
         boolean showingInput = mShowInputRequested;
         CompletionInfo[] completions = mCurCompletions;
+        mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsComputer);
         initViews();
         mInputViewStarted = false;
         mCandidatesViewStarted = false;
diff --git a/core/java/android/inputmethodservice/OWNERS b/core/java/android/inputmethodservice/OWNERS
index 4447197..e6a04da 100644
--- a/core/java/android/inputmethodservice/OWNERS
+++ b/core/java/android/inputmethodservice/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 34867
 set noparent
 
-include ../../../../services/core/java/com/android/server/inputmethod/OWNERS
+include /services/core/java/com/android/server/inputmethod/OWNERS
diff --git a/core/java/android/metrics/OWNERS b/core/java/android/metrics/OWNERS
new file mode 100644
index 0000000..ba867e0
--- /dev/null
+++ b/core/java/android/metrics/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 26805
+
+cwren@android.com
+cwren@google.com
diff --git a/core/java/android/net/ConnectivityMetricsEvent.java b/core/java/android/net/ConnectivityMetricsEvent.java
index 522add1..8b06ebe 100644
--- a/core/java/android/net/ConnectivityMetricsEvent.java
+++ b/core/java/android/net/ConnectivityMetricsEvent.java
@@ -19,7 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.android.internal.util.BitUtils;
+import java.util.BitSet;
 
 /**
  * Represents a core networking event defined in package android.net.metrics.
@@ -86,9 +86,7 @@
         if (ifname != null) {
             buffer.append(", ").append(ifname);
         }
-        for (int t : BitUtils.unpackBits(transports)) {
-            buffer.append(", ").append(NetworkCapabilities.transportNameOf(t));
-        }
+        buffer.append(", transports=").append(BitSet.valueOf(new long[] { transports }));
         buffer.append("): ").append(data.toString());
         return buffer.toString();
     }
diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java
index 9876fc6..183f500 100644
--- a/core/java/android/net/Ikev2VpnProfile.java
+++ b/core/java/android/net/Ikev2VpnProfile.java
@@ -16,12 +16,9 @@
 
 package android.net;
 
-import static android.net.PlatformVpnProfile.TYPE_IKEV2_IPSEC_PSK;
-import static android.net.PlatformVpnProfile.TYPE_IKEV2_IPSEC_RSA;
-import static android.net.PlatformVpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
-
 import static com.android.internal.annotations.VisibleForTesting.Visibility;
 import static com.android.internal.util.Preconditions.checkStringNotEmpty;
+import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -158,9 +155,8 @@
         // IPv6 MTU is greater; since profiles may be started by the system on IPv4 and IPv6
         // networks, the VPN must provide a link fulfilling the stricter of the two conditions
         // (at least that of the IPv6 MTU).
-        if (mMaxMtu < LinkProperties.MIN_MTU_V6) {
-            throw new IllegalArgumentException(
-                    "Max MTU must be at least" + LinkProperties.MIN_MTU_V6);
+        if (mMaxMtu < IPV6_MIN_MTU) {
+            throw new IllegalArgumentException("Max MTU must be at least" + IPV6_MIN_MTU);
         }
 
         switch (mType) {
@@ -811,9 +807,8 @@
             // IPv6 MTU is greater; since profiles may be started by the system on IPv4 and IPv6
             // networks, the VPN must provide a link fulfilling the stricter of the two conditions
             // (at least that of the IPv6 MTU).
-            if (mtu < LinkProperties.MIN_MTU_V6) {
-                throw new IllegalArgumentException(
-                        "Max MTU must be at least " + LinkProperties.MIN_MTU_V6);
+            if (mtu < IPV6_MIN_MTU) {
+                throw new IllegalArgumentException("Max MTU must be at least " + IPV6_MIN_MTU);
             }
             mMaxMtu = mtu;
             return this;
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index fa1497d..b48c1fd 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -17,8 +17,6 @@
 
 import static android.net.IpSecManager.INVALID_RESOURCE_ID;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
-
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -28,7 +26,6 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -182,7 +179,6 @@
         try {
             IIpSecService svc = getIpSecService();
             svc.deleteTransform(mResourceId);
-            stopNattKeepalive();
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         } catch (Exception e) {
@@ -213,36 +209,6 @@
     private int mResourceId;
     private final Context mContext;
     private final CloseGuard mCloseGuard = CloseGuard.get();
-    private ConnectivityManager.PacketKeepalive mKeepalive;
-    private Handler mCallbackHandler;
-    private final ConnectivityManager.PacketKeepaliveCallback mKeepaliveCallback =
-            new ConnectivityManager.PacketKeepaliveCallback() {
-
-                @Override
-                public void onStarted() {
-                    synchronized (this) {
-                        mCallbackHandler.post(() -> mUserKeepaliveCallback.onStarted());
-                    }
-                }
-
-                @Override
-                public void onStopped() {
-                    synchronized (this) {
-                        mKeepalive = null;
-                        mCallbackHandler.post(() -> mUserKeepaliveCallback.onStopped());
-                    }
-                }
-
-                @Override
-                public void onError(int error) {
-                    synchronized (this) {
-                        mKeepalive = null;
-                        mCallbackHandler.post(() -> mUserKeepaliveCallback.onError(error));
-                    }
-                }
-            };
-
-    private NattKeepaliveCallback mUserKeepaliveCallback;
 
     /** @hide */
     @VisibleForTesting
@@ -274,76 +240,6 @@
         public void onError(int error) {}
     }
 
-    /**
-     * Start a NAT-T keepalive session for the current transform.
-     *
-     * For a transform that is using UDP encapsulated IPv4, NAT-T offloading provides
-     * a power efficient mechanism of sending NAT-T packets at a specified interval.
-     *
-     * @param userCallback a {@link #NattKeepaliveCallback} to receive asynchronous status
-     *      information about the requested NAT-T keepalive session.
-     * @param intervalSeconds the interval between NAT-T keepalives being sent. The
-     *      the allowed range is between 20 and 3600 seconds.
-     * @param handler a handler on which to post callbacks when received.
-     *
-     * @hide
-     */
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.MANAGE_IPSEC_TUNNELS,
-            android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD
-    })
-    public void startNattKeepalive(@NonNull NattKeepaliveCallback userCallback,
-            int intervalSeconds, @NonNull Handler handler) throws IOException {
-        checkNotNull(userCallback);
-        if (intervalSeconds < 20 || intervalSeconds > 3600) {
-            throw new IllegalArgumentException("Invalid NAT-T keepalive interval");
-        }
-        checkNotNull(handler);
-        if (mResourceId == INVALID_RESOURCE_ID) {
-            throw new IllegalStateException(
-                    "Packet keepalive cannot be started for an inactive transform");
-        }
-
-        synchronized (mKeepaliveCallback) {
-            if (mKeepaliveCallback != null) {
-                throw new IllegalStateException("Keepalive already active");
-            }
-
-            mUserKeepaliveCallback = userCallback;
-            ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
-                    Context.CONNECTIVITY_SERVICE);
-            mKeepalive = cm.startNattKeepalive(
-                    mConfig.getNetwork(), intervalSeconds, mKeepaliveCallback,
-                    NetworkUtils.numericToInetAddress(mConfig.getSourceAddress()),
-                    4500, // FIXME urgently, we need to get the port number from the Encap socket
-                    NetworkUtils.numericToInetAddress(mConfig.getDestinationAddress()));
-            mCallbackHandler = handler;
-        }
-    }
-
-    /**
-     * Stop an ongoing NAT-T keepalive session.
-     *
-     * Calling this API will request that an ongoing NAT-T keepalive session be terminated.
-     * If this API is not called when a Transform is closed, the underlying NAT-T session will
-     * be terminated automatically.
-     *
-     * @hide
-     */
-    @RequiresPermission(anyOf = {
-            android.Manifest.permission.MANAGE_IPSEC_TUNNELS,
-            android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD
-    })
-    public void stopNattKeepalive() {
-        synchronized (mKeepaliveCallback) {
-            if (mKeepalive == null) {
-                Log.e(TAG, "No active keepalive to stop");
-                return;
-            }
-            mKeepalive.stop();
-        }
-    }
-
     /** This class is used to build {@link IpSecTransform} objects. */
     public static class Builder {
         private Context mContext;
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 81e6e78..e41ed72 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -82,8 +82,7 @@
 
     private static final int MIN_MTU    = 68;
 
-    /** @hide */
-    public static final int MIN_MTU_V6 = 1280;
+    private static final int MIN_MTU_V6 = 1280;
 
     private static final int MAX_MTU    = 10000;
 
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 9c10388..e65c27c 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -17,8 +17,6 @@
 package android.net;
 
 import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.ConnectivityManager.isNetworkTypeMobile;
 
 import android.annotation.Nullable;
 import android.content.Context;
@@ -27,7 +25,6 @@
 import android.os.Build;
 import android.service.NetworkIdentityProto;
 import android.telephony.Annotation.NetworkType;
-import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
 import java.util.Objects;
@@ -85,7 +82,7 @@
     @Override
     public String toString() {
         final StringBuilder builder = new StringBuilder("{");
-        builder.append("type=").append(getNetworkTypeName(mType));
+        builder.append("type=").append(mType);
         builder.append(", subType=");
         if (mSubType == SUBTYPE_COMBINED) {
             builder.append("COMBINED");
@@ -195,18 +192,9 @@
         boolean metered = !state.networkCapabilities.hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
 
-        if (isNetworkTypeMobile(type)) {
-            if (state.subscriberId == null) {
-                if (state.networkInfo.getState() != NetworkInfo.State.DISCONNECTED &&
-                        state.networkInfo.getState() != NetworkInfo.State.UNKNOWN) {
-                    Slog.w(TAG, "Active mobile network without subscriber! ni = "
-                            + state.networkInfo);
-                }
-            }
+        subscriberId = state.subscriberId;
 
-            subscriberId = state.subscriberId;
-
-        } else if (type == TYPE_WIFI) {
+        if (type == TYPE_WIFI) {
             if (state.networkId != null) {
                 networkId = state.networkId;
             } else {
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index a643d09..f05f033 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -144,6 +144,8 @@
     public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby";
     /** @hide */
     public static final String FIREWALL_CHAIN_NAME_POWERSAVE = "powersave";
+    /** @hide */
+    public static final String FIREWALL_CHAIN_NAME_RESTRICTED = "restricted";
 
     private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
 
diff --git a/core/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java
index a17a498..14cb51c 100644
--- a/core/java/android/net/NetworkProvider.java
+++ b/core/java/android/net/NetworkProvider.java
@@ -63,7 +63,7 @@
 
     private final Messenger mMessenger;
     private final String mName;
-    private final ConnectivityManager mCm;
+    private final Context mContext;
 
     private int mProviderId = ID_NONE;
 
@@ -78,8 +78,6 @@
      */
     @SystemApi
     public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) {
-        mCm = ConnectivityManager.from(context);
-
         Handler handler = new Handler(looper) {
             @Override
             public void handleMessage(Message m) {
@@ -95,6 +93,7 @@
                 }
             }
         };
+        mContext = context;
         mMessenger = new Messenger(handler);
         mName = name;
     }
@@ -158,6 +157,6 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
     public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) {
-        mCm.declareNetworkRequestUnfulfillable(request);
+        ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(request);
     }
 }
diff --git a/core/java/android/net/OWNERS b/core/java/android/net/OWNERS
index 5e2a718..2f8f685 100644
--- a/core/java/android/net/OWNERS
+++ b/core/java/android/net/OWNERS
@@ -2,7 +2,7 @@
 
 codewiz@google.com
 jchalard@google.com
-jsharkey@android.com
+jsharkey@google.com
 junyulai@google.com
 lorenzo@google.com
 reminv@google.com
diff --git a/core/java/android/net/metrics/ConnectStats.java b/core/java/android/net/metrics/ConnectStats.java
index b320b75..c67259d 100644
--- a/core/java/android/net/metrics/ConnectStats.java
+++ b/core/java/android/net/metrics/ConnectStats.java
@@ -16,14 +16,14 @@
 
 package android.net.metrics;
 
-import android.net.NetworkCapabilities;
 import android.system.OsConstants;
 import android.util.IntArray;
 import android.util.SparseIntArray;
 
-import com.android.internal.util.BitUtils;
 import com.android.internal.util.TokenBucket;
 
+import java.util.BitSet;
+
 /**
  * A class that aggregates connect() statistics.
  * {@hide}
@@ -120,10 +120,9 @@
     @Override
     public String toString() {
         StringBuilder builder =
-                new StringBuilder("ConnectStats(").append("netId=").append(netId).append(", ");
-        for (int t : BitUtils.unpackBits(transports)) {
-            builder.append(NetworkCapabilities.transportNameOf(t)).append(", ");
-        }
+                new StringBuilder("ConnectStats(").append("netId=").append(netId)
+                        .append(", transports=").append(BitSet.valueOf(new long[] { transports }))
+                        .append(", ");
         builder.append(String.format("%d events, ", eventCount));
         builder.append(String.format("%d success, ", connectCount));
         builder.append(String.format("%d blocking, ", connectBlockingCount));
diff --git a/core/java/android/net/metrics/DefaultNetworkEvent.java b/core/java/android/net/metrics/DefaultNetworkEvent.java
index 6f383b4..8988983 100644
--- a/core/java/android/net/metrics/DefaultNetworkEvent.java
+++ b/core/java/android/net/metrics/DefaultNetworkEvent.java
@@ -16,12 +16,7 @@
 
 package android.net.metrics;
 
-import static android.net.ConnectivityManager.NETID_UNSET;
-
-import android.net.NetworkCapabilities;
-
-import com.android.internal.util.BitUtils;
-
+import java.util.BitSet;
 import java.util.StringJoiner;
 
 /**
@@ -32,8 +27,8 @@
 
     // The creation time in milliseconds of this DefaultNetworkEvent.
     public final long creationTimeMs;
-    // The network ID of the network or NETID_UNSET if none.
-    public int netId = NETID_UNSET;
+    // The network ID of the network or 0 if none.
+    public int netId = 0;
     // The list of transport types, as defined in NetworkCapabilities.java.
     public int transports;
     // The list of transport types of the last previous default network.
@@ -63,9 +58,7 @@
     public String toString() {
         StringJoiner j = new StringJoiner(", ", "DefaultNetworkEvent(", ")");
         j.add("netId=" + netId);
-        for (int t : BitUtils.unpackBits(transports)) {
-            j.add(NetworkCapabilities.transportNameOf(t));
-        }
+        j.add("transports=" + BitSet.valueOf(new long[] { transports }));
         j.add("ip=" + ipSupport());
         if (initialScore > 0) {
             j.add("initial_score=" + initialScore);
diff --git a/core/java/android/net/metrics/DnsEvent.java b/core/java/android/net/metrics/DnsEvent.java
index 5aa705b..bf351ce 100644
--- a/core/java/android/net/metrics/DnsEvent.java
+++ b/core/java/android/net/metrics/DnsEvent.java
@@ -16,11 +16,8 @@
 
 package android.net.metrics;
 
-import android.net.NetworkCapabilities;
-
-import com.android.internal.util.BitUtils;
-
 import java.util.Arrays;
+import java.util.BitSet;
 
 /**
  * A batch of DNS events recorded by NetdEventListenerService for a specific network.
@@ -86,10 +83,10 @@
     @Override
     public String toString() {
         StringBuilder builder =
-                new StringBuilder("DnsEvent(").append("netId=").append(netId).append(", ");
-        for (int t : BitUtils.unpackBits(transports)) {
-            builder.append(NetworkCapabilities.transportNameOf(t)).append(", ");
-        }
+                new StringBuilder("DnsEvent(").append("netId=").append(netId)
+                        .append(", transports=")
+                        .append(BitSet.valueOf(new long[] { transports }))
+                        .append(", ");
         builder.append(String.format("%d events, ", eventCount));
         builder.append(String.format("%d success)", successCount));
         return builder.toString();
diff --git a/core/java/android/net/metrics/NetworkMetrics.java b/core/java/android/net/metrics/NetworkMetrics.java
index 66d92c4..8f2f612 100644
--- a/core/java/android/net/metrics/NetworkMetrics.java
+++ b/core/java/android/net/metrics/NetworkMetrics.java
@@ -16,11 +16,9 @@
 
 package android.net.metrics;
 
-import android.net.NetworkCapabilities;
-
-import com.android.internal.util.BitUtils;
 import com.android.internal.util.TokenBucket;
 
+import java.util.BitSet;
 import java.util.StringJoiner;
 
 /**
@@ -144,9 +142,7 @@
         public String toString() {
             StringJoiner j = new StringJoiner(", ", "{", "}");
             j.add("netId=" + netId);
-            for (int t : BitUtils.unpackBits(transports)) {
-                j.add(NetworkCapabilities.transportNameOf(t));
-            }
+            j.add("transports=" + BitSet.valueOf(new long[] { transports }));
             j.add(String.format("dns avg=%dms max=%dms err=%.1f%% tot=%d",
                     (int) dnsLatencies.average(), (int) dnsLatencies.max,
                     100 * dnsErrorRate.average(), dnsErrorRate.count));
diff --git a/core/java/android/nfc/OWNERS b/core/java/android/nfc/OWNERS
new file mode 100644
index 0000000..6aaf039
--- /dev/null
+++ b/core/java/android/nfc/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 48448
+
+zachoverflow@google.com
+alisher@google.com
diff --git a/core/java/android/nfc/cardemulation/OWNERS b/core/java/android/nfc/cardemulation/OWNERS
new file mode 100644
index 0000000..6aaf039
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 48448
+
+zachoverflow@google.com
+alisher@google.com
diff --git a/core/java/android/nfc/dta/OWNERS b/core/java/android/nfc/dta/OWNERS
new file mode 100644
index 0000000..6aaf039
--- /dev/null
+++ b/core/java/android/nfc/dta/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 48448
+
+zachoverflow@google.com
+alisher@google.com
diff --git a/core/java/android/nfc/tech/OWNERS b/core/java/android/nfc/tech/OWNERS
new file mode 100644
index 0000000..6aaf039
--- /dev/null
+++ b/core/java/android/nfc/tech/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 48448
+
+zachoverflow@google.com
+alisher@google.com
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
new file mode 100644
index 0000000..d00c3c3
--- /dev/null
+++ b/core/java/android/os/BatteryConsumer.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 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.os;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Interface for objects containing battery attribution data.
+ *
+ * @hide
+ */
+public abstract class BatteryConsumer {
+
+    /**
+     * Power usage component, describing the particular part of the system
+     * responsible for power drain.
+     *
+     * @hide
+     */
+    @IntDef(prefix = {"POWER_COMPONENT_"}, value = {
+            POWER_COMPONENT_CPU,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public static @interface PowerComponent {
+    }
+
+    public static final int POWER_COMPONENT_CPU = 0;
+
+    public static final int POWER_COMPONENT_COUNT = 1;
+
+    public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000;
+    public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999;
+
+    private final PowerComponents mPowerComponents;
+
+    protected BatteryConsumer(@NonNull PowerComponents powerComponents) {
+        mPowerComponents = powerComponents;
+    }
+
+    /**
+     * Total power consumed by this consumer, in mAh.
+     */
+    public double getConsumedPower() {
+        return mPowerComponents.getTotalPowerConsumed();
+    }
+
+    /**
+     * Returns the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
+     *
+     * @param componentId The ID of the power component, e.g.
+     *                    {@link BatteryConsumer#POWER_COMPONENT_CPU}.
+     * @return Amount of consumed power in mAh.
+     */
+    public double getConsumedPower(@PowerComponent int componentId) {
+        return mPowerComponents.getConsumedPower(componentId);
+    }
+
+    /**
+     * Returns the amount of drain attributed to the specified custom drain type.
+     *
+     * @param componentId The ID of the custom power component.
+     * @return Amount of consumed power in mAh.
+     */
+    public double getConsumedPowerForCustomComponent(int componentId) {
+        return mPowerComponents.getConsumedPowerForCustomComponent(componentId);
+    }
+
+    protected void writeToParcel(Parcel dest, int flags) {
+        mPowerComponents.writeToParcel(dest, flags);
+    }
+}
diff --git a/core/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java
index a9585c6..d9e01cd 100644
--- a/core/java/android/os/BatteryStatsManager.java
+++ b/core/java/android/os/BatteryStatsManager.java
@@ -161,6 +161,22 @@
     }
 
     /**
+     * Returns BatteryUsageStats, which contains power attribution data on a per-subsystem
+     * and per-UID basis.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.BATTERY_STATS)
+    @NonNull
+    public BatteryUsageStats getBatteryUsageStats() {
+        try {
+            return mBatteryStats.getBatteryUsageStats();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Indicates that the wifi connection RSSI has changed.
      *
      * @param newRssi The new RSSI value.
diff --git a/core/java/android/os/BatteryUsageStats.aidl b/core/java/android/os/BatteryUsageStats.aidl
new file mode 100644
index 0000000..0400f19
--- /dev/null
+++ b/core/java/android/os/BatteryUsageStats.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2020 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.os;
+
+parcelable BatteryUsageStats;
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
new file mode 100644
index 0000000..3f036cd
--- /dev/null
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2020 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.os;
+
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Contains a snapshot of battery attribution data, on a per-subsystem and per-UID basis.
+ *
+ * @hide
+ */
+public final class BatteryUsageStats implements Parcelable {
+    private final double mConsumedPower;
+    private final int mDischargePercentage;
+    private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers;
+
+    private BatteryUsageStats(@NonNull Builder builder) {
+        mConsumedPower = builder.mConsumedPower;
+        mDischargePercentage = builder.mDischargePercentage;
+        mUidBatteryConsumers = builder.mUidBatteryConsumers;
+    }
+
+    /**
+     * Portion of battery charge drained since BatteryStats reset (e.g. due to being fully
+     * charged), as percentage of the full charge in the range [0:100]
+     */
+    public int getDischargePercentage() {
+        return mDischargePercentage;
+    }
+
+    /**
+     * Total amount of battery charge drained since BatteryStats reset (e.g. due to being fully
+     * charged), in mAh
+     */
+    public double getConsumedPower() {
+        return mConsumedPower;
+    }
+
+    @NonNull
+    public List<UidBatteryConsumer> getUidBatteryConsumers() {
+        return mUidBatteryConsumers;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    private BatteryUsageStats(@NonNull Parcel source) {
+        mUidBatteryConsumers = new ArrayList<>();
+        source.readParcelableList(mUidBatteryConsumers, getClass().getClassLoader());
+        mConsumedPower = source.readDouble();
+        mDischargePercentage = source.readInt();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeParcelableList(mUidBatteryConsumers, flags);
+        dest.writeDouble(mConsumedPower);
+        dest.writeInt(mDischargePercentage);
+    }
+
+    @NonNull
+    public static final Creator<BatteryUsageStats> CREATOR = new Creator<BatteryUsageStats>() {
+        public BatteryUsageStats createFromParcel(@NonNull Parcel source) {
+            return new BatteryUsageStats(source);
+        }
+
+        public BatteryUsageStats[] newArray(int size) {
+            return new BatteryUsageStats[size];
+        }
+    };
+
+    /**
+     * Builder for BatteryUsageStats.
+     */
+    public static final class Builder {
+        private double mConsumedPower;
+        private int mDischargePercentage;
+        private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers = new ArrayList<>();
+
+        /**
+         * Constructs a read-only object using the Builder values.
+         */
+        @NonNull
+        public BatteryUsageStats build() {
+            return new BatteryUsageStats(this);
+        }
+
+        /**
+         * Sets the battery discharge amount since BatteryStats reset as percentage of the full
+         * charge.
+         */
+        @SuppressLint("PercentageInt") // See b/174188159
+        @NonNull
+        public Builder setDischargePercentage(int dischargePercentage) {
+            mDischargePercentage = dischargePercentage;
+            return this;
+        }
+
+        /**
+         * Sets the battery discharge amount since BatteryStats reset, in mAh.
+         */
+        @NonNull
+        public Builder setConsumedPower(double consumedPower) {
+            mConsumedPower = consumedPower;
+            return this;
+        }
+
+        /**
+         * Adds a UidBatteryConsumer, which represents battery attribution data for an
+         * individual UID.
+         */
+        @NonNull
+        public Builder addUidBatteryConsumer(@NonNull UidBatteryConsumer uidBatteryConsumer) {
+            mUidBatteryConsumers.add(uidBatteryConsumer);
+            return this;
+        }
+    }
+}
diff --git a/core/java/android/os/CombinedVibrationEffect.java b/core/java/android/os/CombinedVibrationEffect.java
index c9ebc1b..7ec7fff 100644
--- a/core/java/android/os/CombinedVibrationEffect.java
+++ b/core/java/android/os/CombinedVibrationEffect.java
@@ -30,8 +30,6 @@
  * Vibrator Vibrators}.
  *
  * These effects may be any number of things, from single shot vibrations to complex waveforms.
- *
- * @hide
  * @see VibrationEffect
  */
 @SuppressWarnings({"ParcelNotFinal", "ParcelCreator"}) // Parcel only extended here.
@@ -94,7 +92,6 @@
     /**
      * A combination of haptic effects that should be played in multiple vibrators in sync.
      *
-     * @hide
      * @see CombinedVibrationEffect#startSynced()
      */
     public static final class SyncedCombination {
@@ -144,7 +141,6 @@
     /**
      * A combination of haptic effects that should be played in multiple vibrators in sequence.
      *
-     * @hide
      * @see CombinedVibrationEffect#startSequential()
      */
     public static final class SequentialCombination {
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index a4af0db..e2e1bbe 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1946,7 +1946,13 @@
      */
     public static final int MEMINFO_KRECLAIMABLE = 15;
     /** @hide */
-    public static final int MEMINFO_COUNT = 16;
+    public static final int MEMINFO_ACTIVE = 16;
+    /** @hide */
+    public static final int MEMINFO_INACTIVE = 17;
+    /** @hide */
+    public static final int MEMINFO_UNEVICTABLE = 18;
+    /** @hide */
+    public static final int MEMINFO_COUNT = 19;
 
     /**
      * Retrieves /proc/meminfo.  outSizes is filled with fields
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 5db4107..379d6e6 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1436,7 +1436,8 @@
     public static FileDescriptor convertToModernFd(FileDescriptor fd) {
         try {
             Context context = AppGlobals.getInitialApplication();
-            if (!SystemProperties.getBoolean("persist.sys.fuse.transcode", false)
+            // TODO(b/169327180): Consider device config.
+            if (!SystemProperties.getBoolean("persist.sys.fuse.transcode_enabled", false)
                     || !SystemProperties.getBoolean("persist.sys.fuse.transcode_optimize", true)
                     || UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)) {
                 // If transcode is enabled we optimize by default, unless explicitly disabled.
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 91eb2a5..d392d71 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -16,7 +16,7 @@
 per-file PowerManager.java = michaelwr@google.com, santoscordon@google.com
 per-file PowerManagerInternal.java = michaelwr@google.com, santoscordon@google.com
 
-# Zygote
-per-file ZygoteProcess.java = calin@google.com, chriswailes@google.com, maco@google.com, narayan@google.com, ngeoffray@google.com
 
 per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com
+
+per-file *Zygote* = file:/ZYGOTE_OWNERS
diff --git a/core/java/android/os/ParcelableHolder.java b/core/java/android/os/ParcelableHolder.java
index fb9fa10..1be367c 100644
--- a/core/java/android/os/ParcelableHolder.java
+++ b/core/java/android/os/ParcelableHolder.java
@@ -120,31 +120,37 @@
 
     /**
      * Write a parcelable into ParcelableHolder, the previous parcelable will be removed.
-     * @return {@code false} if the parcelable's stability is more unstable ParcelableHolder.
+     * @throws BadParcelableException if the parcelable's stability is more unstable
+     *         ParcelableHolder.
      */
-    public boolean setParcelable(@Nullable Parcelable p) {
-        // a ParcelableHolder can only hold things at its stability or higher
+    public void setParcelable(@Nullable Parcelable p) {
+        // A ParcelableHolder can only hold things at its stability or higher.
         if (p != null && this.getStability() > p.getStability()) {
-            return false;
+            throw new BadParcelableException(
+                "A ParcelableHolder can only hold things at its stability or higher. "
+                + "The ParcelableHolder's stability is " + this.getStability()
+                + ", but the parcelable's stability is " + p.getStability());
         }
         mParcelable = p;
         if (mParcel != null) {
             mParcel.recycle();
             mParcel = null;
         }
-        return true;
     }
 
     /**
      * @return the parcelable that was written by {@link #setParcelable} or {@link #readFromParcel},
-     *         or {@code null} if the parcelable has not been written, or T is different from
-     *         the type written by (@link #setParcelable}.
+     *         or {@code null} if the parcelable has not been written.
+     * @throws BadParcelableException if T is different from the type written by
+     *         (@link #setParcelable}.
      */
     @Nullable
     public <T extends Parcelable> T getParcelable(@NonNull Class<T> clazz) {
         if (mParcel == null) {
-            if (!clazz.isInstance(mParcelable)) {
-                return null;
+            if (mParcelable != null && !clazz.isInstance(mParcelable)) {
+                throw new BadParcelableException(
+                    "The ParcelableHolder has " + mParcelable.getClass().getName()
+                    + ", but the requested type is " + clazz.getName());
             }
             return (T) mParcelable;
         }
@@ -152,8 +158,10 @@
         mParcel.setDataPosition(0);
 
         T parcelable = mParcel.readParcelable(clazz.getClassLoader());
-        if (!clazz.isInstance(parcelable)) {
-            return null;
+        if (parcelable != null && !clazz.isInstance(parcelable)) {
+            throw new BadParcelableException(
+                    "The ParcelableHolder has " + parcelable.getClass().getName()
+                    + ", but the requested type is " + clazz.getName());
         }
         mParcelable = parcelable;
 
diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java
new file mode 100644
index 0000000..42ba1ff
--- /dev/null
+++ b/core/java/android/os/PowerComponents.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2020 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.os;
+
+
+import android.annotation.NonNull;
+
+/**
+ * Contains details of battery attribution data broken down to individual power drain types
+ * such as CPU, RAM, GPU etc.
+ *
+ * @hide
+ */
+class PowerComponents {
+
+    private final double mTotalPowerConsumed;
+    private final double[] mPowerComponents;
+
+    PowerComponents(@NonNull Builder builder) {
+        mTotalPowerConsumed = builder.mTotalPowerConsumed;
+        mPowerComponents = builder.mPowerComponents;
+    }
+
+    PowerComponents(@NonNull Parcel source) {
+        mTotalPowerConsumed = source.readDouble();
+        mPowerComponents = source.createDoubleArray();
+    }
+
+    /** Writes contents to Parcel */
+    void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeDouble(mTotalPowerConsumed);
+        dest.writeDoubleArray(mPowerComponents);
+    }
+
+    /**
+     * Total power consumed by this consumer, in mAh.
+     */
+    public double getTotalPowerConsumed() {
+        return mTotalPowerConsumed;
+    }
+
+    /**
+     * Returns the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
+     *
+     * @param componentId The ID of the power component, e.g.
+     *                    {@link BatteryConsumer#POWER_COMPONENT_CPU}.
+     * @return Amount of consumed power in mAh.
+     */
+    public double getConsumedPower(@UidBatteryConsumer.PowerComponent int componentId) {
+        if (componentId >= BatteryConsumer.POWER_COMPONENT_COUNT) {
+            throw new IllegalArgumentException(
+                    "Unsupported power component ID: " + componentId);
+        }
+        try {
+            return mPowerComponents[componentId];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new IllegalArgumentException("Unsupported power component ID: " + componentId);
+        }
+    }
+
+    /**
+     * Returns the amount of drain attributed to the specified custom drain type.
+     *
+     * @param componentId The ID of the custom power component.
+     * @return Amount of consumed power in mAh.
+     */
+    public double getConsumedPowerForCustomComponent(int componentId) {
+        if (componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) {
+            throw new IllegalArgumentException(
+                    "Unsupported custom power component ID: " + componentId);
+        }
+        try {
+            return mPowerComponents[
+                    BatteryConsumer.POWER_COMPONENT_COUNT + componentId
+                            - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new IllegalArgumentException(
+                    "Unsupported custom power component ID: " + componentId);
+        }
+    }
+
+    /**
+     * Builder for PowerComponents.
+     */
+    static final class Builder {
+        private double mTotalPowerConsumed;
+        private final double[] mPowerComponents;
+
+        Builder(int customPowerComponentCount) {
+            mPowerComponents = new double[BatteryConsumer.POWER_COMPONENT_COUNT
+                    + customPowerComponentCount];
+        }
+
+        /**
+         * Sets the sum amount of power consumed since BatteryStats reset.
+         */
+        @NonNull
+        public Builder setTotalPowerConsumed(double totalPowerConsumed) {
+            mTotalPowerConsumed = totalPowerConsumed;
+            return this;
+        }
+
+        /**
+         * Sets the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
+         *
+         * @param componentId    The ID of the power component, e.g.
+         *                       {@link BatteryConsumer#POWER_COMPONENT_CPU}.
+         * @param componentPower Amount of consumed power in mAh.
+         */
+        @NonNull
+        public Builder setConsumedPower(@UidBatteryConsumer.PowerComponent int componentId,
+                double componentPower) {
+            if (componentId >= BatteryConsumer.POWER_COMPONENT_COUNT) {
+                throw new IllegalArgumentException(
+                        "Unsupported power component ID: " + componentId);
+            }
+            try {
+                mPowerComponents[componentId] = componentPower;
+            } catch (ArrayIndexOutOfBoundsException e) {
+                throw new IllegalArgumentException(
+                        "Unsupported power component ID: " + componentId);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the amount of drain attributed to the specified custom drain type.
+         *
+         * @param componentId    The ID of the custom power component.
+         * @param componentPower Amount of consumed power in mAh.
+         */
+        @NonNull
+        public Builder setConsumedPowerForCustomComponent(int componentId, double componentPower) {
+            if (componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) {
+                throw new IllegalArgumentException(
+                        "Unsupported custom power component ID: " + componentId);
+            }
+            try {
+                mPowerComponents[BatteryConsumer.POWER_COMPONENT_COUNT + componentId
+                        - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID] = componentPower;
+            } catch (ArrayIndexOutOfBoundsException e) {
+                throw new IllegalArgumentException(
+                        "Unsupported custom power component ID: " + componentId);
+            }
+            return this;
+        }
+
+        /**
+         * Creates a read-only object out of the Builder values.
+         */
+        @NonNull
+        public PowerComponents build() {
+            return new PowerComponents(this);
+        }
+    }
+}
diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java
new file mode 100644
index 0000000..7dcbf7d
--- /dev/null
+++ b/core/java/android/os/UidBatteryConsumer.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2020 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.os;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * Contains power consumption data attributed to a specific UID.
+ *
+ * @hide
+ */
+public final class UidBatteryConsumer extends BatteryConsumer implements Parcelable {
+
+    private final int mUid;
+    @Nullable
+    private final String mPackageWithHighestDrain;
+
+    public int getUid() {
+        return mUid;
+    }
+
+    @Nullable
+    public String getPackageWithHighestDrain() {
+        return mPackageWithHighestDrain;
+    }
+
+    private UidBatteryConsumer(@NonNull Builder builder) {
+        super(builder.mPowerComponentsBuilder.build());
+        mUid = builder.mUid;
+        mPackageWithHighestDrain = builder.mPackageWithHighestDrain;
+    }
+
+    private UidBatteryConsumer(@NonNull Parcel source) {
+        super(new PowerComponents(source));
+        mUid = source.readInt();
+        mPackageWithHighestDrain = source.readString();
+    }
+
+    /**
+     * Writes the contents into a Parcel.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(mUid);
+        dest.writeString(mPackageWithHighestDrain);
+    }
+
+    @NonNull
+    public static final Creator<UidBatteryConsumer> CREATOR = new Creator<UidBatteryConsumer>() {
+        public UidBatteryConsumer createFromParcel(@NonNull Parcel source) {
+            return new UidBatteryConsumer(source);
+        }
+
+        public UidBatteryConsumer[] newArray(int size) {
+            return new UidBatteryConsumer[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Builder for UidBatteryConsumer.
+     */
+    public static final class Builder {
+        private final PowerComponents.Builder mPowerComponentsBuilder;
+        private final int mUid;
+        private String mPackageWithHighestDrain;
+
+        public Builder(int customPowerComponentCount, int uid) {
+            mPowerComponentsBuilder = new PowerComponents.Builder(customPowerComponentCount);
+            mUid = uid;
+        }
+
+        /**
+         * Creates a read-only object out of the Builder values.
+         */
+        @NonNull
+        public UidBatteryConsumer build() {
+            return new UidBatteryConsumer(this);
+        }
+
+        /**
+         * Sets the amount of drain attributed to the specified drain type, e.g. CPU, WiFi etc.
+         *
+         * @param componentId    The ID of the power component, e.g.
+         * {@link BatteryConsumer#POWER_COMPONENT_CPU}.
+         * @param componentPower Amount of consumed power in mAh.
+         */
+        @NonNull
+        public Builder setConsumedPower(@PowerComponent int componentId, double componentPower) {
+            mPowerComponentsBuilder.setConsumedPower(componentId, componentPower);
+            return this;
+        }
+
+        /**
+         * Sets the amount of drain attributed to the specified custom drain type.
+         *
+         * @param componentId    The ID of the custom power component.
+         * @param componentPower Amount of consumed power in mAh.
+         */
+        @NonNull
+        public Builder setConsumedPowerForCustomComponent(int componentId, double componentPower) {
+            mPowerComponentsBuilder.setConsumedPowerForCustomComponent(componentId, componentPower);
+            return this;
+        }
+
+        /**
+         * Sets the amount of power consumed since BatteryStats reset, mAh.
+         */
+        @NonNull
+        public Builder setConsumedPower(double consumedPower) {
+            mPowerComponentsBuilder.setTotalPowerConsumed(consumedPower);
+            return this;
+        }
+
+        /**
+         * Sets the name of the package owned by this UID that consumed the highest amount
+         * of power since BatteryStats reset.
+         */
+        @NonNull
+        public Builder setPackageWithHighestDrain(@Nullable String packageName) {
+            mPackageWithHighestDrain = packageName;
+            return this;
+        }
+    }
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index aba1f28..e7d19c5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -136,6 +136,12 @@
     public static final String USER_TYPE_PROFILE_MANAGED = "android.os.usertype.profile.MANAGED";
 
     /**
+     * User type representing a generic profile for testing purposes. Only on debuggable builds.
+     * @hide
+     */
+    public static final String USER_TYPE_PROFILE_TEST = "android.os.usertype.profile.TEST";
+
+    /**
      * User type representing a {@link UserHandle#USER_SYSTEM system} user that is <b>not</b> a
      * human user.
      * This type of user cannot be created; it can only pre-exist on first boot.
diff --git a/core/java/android/os/VibratorManager.java b/core/java/android/os/VibratorManager.java
new file mode 100644
index 0000000..1d5a587
--- /dev/null
+++ b/core/java/android/os/VibratorManager.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 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.os;
+
+import android.annotation.NonNull;
+
+/**
+ * VibratorManager provides access to multiple vibrators, as well as the ability to run them in
+ * a synchronized fashion.
+ */
+public abstract class VibratorManager {
+    /** @hide */
+    protected static final String TAG = "VibratorManager";
+
+    /**
+     * {@hide}
+     */
+    public VibratorManager() {
+    }
+
+    /**
+     * This method lists all available actuator ids, returning a possible empty list.
+     * If the device has only a single actuator, this should return a single entry with a
+     * default id.
+     */
+    @NonNull
+    public abstract int[] getVibratorIds();
+
+    /**
+    * Returns a Vibrator service for given id.
+    * This allows users to perform a vibration effect on a single actuator.
+    */
+    @NonNull
+    public abstract Vibrator getVibrator(int vibratorId);
+
+    /**
+    * Returns the system default Vibrator service.
+    */
+    @NonNull
+    public abstract Vibrator getDefaultVibrator();
+
+    /**
+     * Vibrates all actuators by passing each VibrationEffect within CombinedVibrationEffect
+     * to the respective actuator, in sync.
+     */
+    public abstract void vibrate(@NonNull CombinedVibrationEffect effect);
+}
diff --git a/core/java/android/os/connectivity/OWNERS b/core/java/android/os/connectivity/OWNERS
new file mode 100644
index 0000000..a0f0238
--- /dev/null
+++ b/core/java/android/os/connectivity/OWNERS
@@ -0,0 +1 @@
+dplotnikov@google.com
diff --git a/core/java/android/os/health/OWNERS b/core/java/android/os/health/OWNERS
new file mode 100644
index 0000000..6045344
--- /dev/null
+++ b/core/java/android/os/health/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 26805
+
+dplotnikov@google.com
+mwachens@google.com
diff --git a/core/java/android/os/image/OWNERS b/core/java/android/os/image/OWNERS
new file mode 100644
index 0000000..389b55b
--- /dev/null
+++ b/core/java/android/os/image/OWNERS
@@ -0,0 +1 @@
+andrewhsieh@google.com
diff --git a/core/java/android/os/storage/OWNERS b/core/java/android/os/storage/OWNERS
new file mode 100644
index 0000000..8af7de5
--- /dev/null
+++ b/core/java/android/os/storage/OWNERS
@@ -0,0 +1,7 @@
+# Bug component: 95221
+
+narayan@google.com
+nandana@google.com
+corinac@google.com
+zezeozue@google.com
+maco@google.com
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 1001668..a94077d 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -73,10 +73,6 @@
 
     void resetRuntimePermissions();
 
-    boolean setDefaultBrowser(String packageName, int userId);
-
-    String getDefaultBrowser(int userId);
-
     void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
 
     void grantDefaultPermissionsToEnabledImsServices(in String[] packageNames, int userId);
@@ -91,10 +87,6 @@
 
     void revokeDefaultPermissionsFromLuiApps(in String[] packageNames, int userId);
 
-    void setPermissionEnforced(String permName, boolean enforced);
-
-    boolean isPermissionEnforced(String permName);
-
     boolean shouldShowRequestPermissionRationale(String permName,
             String packageName, int userId);
 
diff --git a/core/java/android/permission/OWNERS b/core/java/android/permission/OWNERS
new file mode 100644
index 0000000..d09f351
--- /dev/null
+++ b/core/java/android/permission/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 137825
+
+moltmann@google.com
+evanseverson@google.com
+ntmyren@google.com
+zhanghai@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/permission/PermissionManagerInternal.java b/core/java/android/permission/PermissionManagerInternal.java
index 3134ec0..a4676c4 100644
--- a/core/java/android/permission/PermissionManagerInternal.java
+++ b/core/java/android/permission/PermissionManagerInternal.java
@@ -19,11 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.os.UserHandle;
-
-import com.android.internal.util.function.TriFunction;
-
-import java.util.function.BiFunction;
 
 /**
  * Internal interfaces to be used by other components within the system server.
@@ -32,96 +27,39 @@
  *
  * @hide
  */
-public abstract class PermissionManagerInternal {
-
+public interface PermissionManagerInternal {
     /**
-     * Listener for package permission state (permissions or flags) changes.
-     */
-    public interface OnRuntimePermissionStateChangedListener {
-
-        /**
-         * Called when the runtime permission state (permissions or flags) changed.
-         *
-         * @param packageName The package for which the change happened.
-         * @param userId the user id for which the change happened.
-         */
-        @Nullable
-        void onRuntimePermissionStateChanged(@NonNull String packageName,
-                @UserIdInt int userId);
-    }
-
-    /** Interface to override permission checks via composition */
-    public interface CheckPermissionDelegate {
-        /**
-         * Checks whether the given package has been granted the specified permission.
-         *
-         * @return If the package has the permission, PERMISSION_GRANTED is
-         * returned.  If it does not have the permission, PERMISSION_DENIED
-         * is returned.
-         *
-         * @see android.content.pm.PackageManager#checkPermission(String, String)
-         */
-        int checkPermission(String permName, String pkgName, int userId,
-                TriFunction<String, String, Integer, Integer> superImpl);
-
-        /**
-        /**
-         * Checks whether the given uid has been granted the specified permission.
-         *
-         * @return If the package has the permission, PERMISSION_GRANTED is
-         * returned.  If it does not have the permission, PERMISSION_DENIED
-         * is returned.
-         *
-         */
-        int checkUidPermission(String permName, int uid,
-                BiFunction<String, Integer, Integer> superImpl);
-    }
-
-    /**
-     * Get the state of the runtime permissions as xml file.
+     * Get the state of the runtime permissions as a blob.
      *
-     * @param user The user the data should be extracted for
+     * @param userId The user ID the data should be extracted for
      *
-     * @return The state as a xml file
+     * @return the state as a blob
      */
-    public abstract @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user);
+    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+    @Nullable
+    byte[] backupRuntimePermissions(@UserIdInt int userId);
 
     /**
      * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
+     * <p>
+     * If not all state can be restored, the un-restorable state will be delayed and can be
+     * retried via {@link #restoreDelayedRuntimePermissions}.
      *
-     * <p>If not all state can be restored, the un-restoreable state will be delayed and can be
-     * re-tried via {@link #restoreDelayedRuntimePermissions}.
-     *
-     * @param backup The state as an xml file
-     * @param user The user the data should be restored for
+     * @param backup the state as a blob
+     * @param userId the user ID the data should be restored for
      */
-    public abstract void restoreRuntimePermissions(@NonNull byte[] backup,
-            @NonNull UserHandle user);
+    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+    void restoreRuntimePermissions(@NonNull byte[] backup, @UserIdInt int userId);
 
     /**
      * Try to apply permission backup of a package that was previously not applied.
      *
-     * @param packageName The package that is newly installed
-     * @param user The user the package is installed for
+     * @param packageName the package that is newly installed
+     * @param userId the user ID the package is installed for
      *
      * @see #restoreRuntimePermissions
      */
-    public abstract void restoreDelayedRuntimePermissions(@NonNull String packageName,
-            @NonNull UserHandle user);
-
-    /**
-     * Adds a listener for runtime permission state (permissions or flags) changes.
-     *
-     * @param listener The listener.
-     */
-    public abstract void addOnRuntimePermissionStateChangedListener(
-            @NonNull OnRuntimePermissionStateChangedListener listener);
-
-    /**
-     * Removes a listener for runtime permission state (permissions or flags) changes.
-     *
-     * @param listener The listener.
-     */
-    public abstract void removeOnRuntimePermissionStateChangedListener(
-            @NonNull OnRuntimePermissionStateChangedListener listener);
+    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+    void restoreDelayedRuntimePermissions(@NonNull String packageName,
+            @UserIdInt int userId);
 }
diff --git a/core/java/android/permissionpresenterservice/OWNERS b/core/java/android/permissionpresenterservice/OWNERS
new file mode 100644
index 0000000..d09f351
--- /dev/null
+++ b/core/java/android/permissionpresenterservice/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 137825
+
+moltmann@google.com
+evanseverson@google.com
+ntmyren@google.com
+zhanghai@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/print/OWNERS b/core/java/android/print/OWNERS
new file mode 100644
index 0000000..72f0983
--- /dev/null
+++ b/core/java/android/print/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 47273
+
+moltmann@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/print/pdf/OWNERS b/core/java/android/print/pdf/OWNERS
new file mode 100644
index 0000000..72f0983
--- /dev/null
+++ b/core/java/android/print/pdf/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 47273
+
+moltmann@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/printservice/OWNERS b/core/java/android/printservice/OWNERS
new file mode 100644
index 0000000..72f0983
--- /dev/null
+++ b/core/java/android/printservice/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 47273
+
+moltmann@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/printservice/recommendation/OWNERS b/core/java/android/printservice/recommendation/OWNERS
new file mode 100644
index 0000000..72f0983
--- /dev/null
+++ b/core/java/android/printservice/recommendation/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 47273
+
+moltmann@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 03e8a07..da06e82 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -19,6 +19,7 @@
 import android.accounts.Account;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
@@ -47,6 +48,9 @@
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.telecom.PhoneAccountHandle;
 import android.text.TextUtils;
@@ -54,11 +58,15 @@
 import android.util.Pair;
 import android.view.View;
 
+import com.google.android.collect.Sets;
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
+import java.util.Set;
 
 /**
  * <p>
@@ -8188,6 +8196,321 @@
         public static final String RAW_CONTACT_ID2 = "raw_contact_id2";
     }
 
+
+    /**
+     * Class containing utility methods around determine what accounts in the ContactsProvider are
+     * related to the SIM cards in the device.
+     * <p>
+     * Apps interested in managing contacts from SIM cards can query the ContactsProvider using
+     * {@link #getSimAccounts(ContentResolver)} to get all accounts that relate to SIM cards. They
+     * can also register a receiver for the {@link #ACTION_SIM_ACCOUNTS_CHANGED} broadcast to be
+     * notified when these accounts change.
+     */
+    public static final class SimContacts {
+        /**
+         * This utility class cannot be instantiated
+         */
+        private SimContacts() {
+        }
+
+        /**
+         * The method to invoke in order to add a new SIM account for a newly inserted SIM card.
+         *
+         * @hide
+         */
+        public static final String ADD_SIM_ACCOUNT_METHOD = "addSimAccount";
+
+        /**
+         * The method to invoke in order to remove a SIM account once the corresponding SIM card is
+         * ejected.
+         *
+         * @hide
+         */
+        public static final String REMOVE_SIM_ACCOUNT_METHOD = "removeSimAccount";
+
+        /**
+         * The method to invoke in order to query all SIM accounts.
+         *
+         * @hide
+         */
+        public static final String QUERY_SIM_ACCOUNTS_METHOD = "querySimAccounts";
+
+        /**
+         * Key to add in the outgoing Bundle for the SIM slot.
+         *
+         * @hide
+         */
+        public static final String KEY_SIM_SLOT_INDEX = "key_sim_slot_index";
+
+        /**
+         * Key to add in the outgoing Bundle for the SIM account's EF type.
+         * See {@link SimAccount#mEfType} for more information.
+         *
+         * @hide
+         */
+        public static final String KEY_SIM_EF_TYPE = "key_sim_ef_type";
+
+        /**
+         * Key to add in the outgoing Bundle for the account name.
+         *
+         * @hide
+         */
+        public static final String KEY_ACCOUNT_NAME = "key_sim_account_name";
+
+        /**
+         * Key to add in the outgoing Bundle for the account type.
+         *
+         * @hide
+         */
+        public static final String KEY_ACCOUNT_TYPE = "key_sim_account_type";
+
+        /**
+         * Key in the incoming Bundle for the all the SIM accounts.
+         *
+         * @hide
+         */
+        public static final String KEY_SIM_ACCOUNTS = "key_sim_accounts";
+
+        /**
+         * Broadcast Action: SIM accounts have changed, call
+         * {@link #getSimAccounts(ContentResolver)} to get the latest.
+         */
+        @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+        public static final String ACTION_SIM_ACCOUNTS_CHANGED =
+                "android.provider.action.SIM_ACCOUNTS_CHANGED";
+
+        /**
+         * Adds a new SIM account that maps to the corresponding SIM slot.
+         *
+         * @param accountName     accountName value for the account
+         * @param accountType     accountType value for the account
+         * @param contentResolver to perform the operation on.
+         * @param simSlotIndex    the SIM slot index of this new account.
+         * @param efType          the EF type of this new account.
+         * @hide
+         */
+        @SystemApi
+        @RequiresPermission("android.contacts.permission.MANAGE_SIM_ACCOUNTS")
+        public static void addSimAccount(@NonNull ContentResolver contentResolver,
+                @NonNull String accountName,
+                @NonNull String accountType,
+                int simSlotIndex,
+                int efType) {
+            if (simSlotIndex < 0) {
+                throw new IllegalArgumentException("Sim slot is negative");
+            }
+            if (!SimAccount.getValidEfTypes().contains(efType)) {
+                throw new IllegalArgumentException("Invalid EF type");
+            }
+            if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
+                throw new IllegalArgumentException("Account name or type is empty");
+            }
+
+            Bundle extras = new Bundle();
+            extras.putInt(KEY_SIM_SLOT_INDEX, simSlotIndex);
+            extras.putInt(KEY_SIM_EF_TYPE, efType);
+            extras.putString(KEY_ACCOUNT_NAME, accountName);
+            extras.putString(KEY_ACCOUNT_TYPE, accountType);
+
+            contentResolver.call(ContactsContract.AUTHORITY_URI,
+                    ContactsContract.SimContacts.ADD_SIM_ACCOUNT_METHOD,
+                    null, extras);
+        }
+
+        /**
+         * Removes all SIM accounts that map to the corresponding SIM slot.
+         *
+         * @param contentResolver to perform the operation on.
+         * @param simSlotIndex    the SIM slot index of the accounts to remove.
+         * @hide
+         */
+        @SystemApi
+        @RequiresPermission("android.contacts.permission.MANAGE_SIM_ACCOUNTS")
+        public static void removeSimAccounts(@NonNull ContentResolver contentResolver,
+                int simSlotIndex) {
+            if (simSlotIndex < 0) {
+                throw new IllegalArgumentException("Sim slot is negative");
+            }
+
+            Bundle extras = new Bundle();
+            extras.putInt(KEY_SIM_SLOT_INDEX, simSlotIndex);
+
+            contentResolver.call(ContactsContract.AUTHORITY_URI,
+                    ContactsContract.SimContacts.REMOVE_SIM_ACCOUNT_METHOD,
+                    null, extras);
+        }
+
+        /**
+         * Returns all known SIM accounts. May be empty but never null.
+         *
+         * @param contentResolver content resolver to query.
+         */
+        public static @NonNull List<SimAccount> getSimAccounts(
+                @NonNull ContentResolver contentResolver) {
+            Bundle response = contentResolver.call(ContactsContract.AUTHORITY_URI,
+                    ContactsContract.SimContacts.QUERY_SIM_ACCOUNTS_METHOD,
+                    null, null);
+            List<SimAccount> result = response.getParcelableArrayList(KEY_SIM_ACCOUNTS);
+
+            if (result == null) {
+                result = new ArrayList<>();
+            }
+
+            return result;
+        }
+    }
+
+    /**
+     * A parcelable class encapsulating account data for contacts that originate from a SIM card.
+     */
+    public static final class SimAccount implements Parcelable {
+        /** An invalid EF type identifier. */
+        public static final int UNKNOWN_EF_TYPE = 0;
+        /** EF type identifier for the ADN partition. */
+        public static final int ADN_EF_TYPE = 1;
+        /** EF type identifier for the SDN partition. */
+        public static final int SDN_EF_TYPE = 2;
+        /** EF type identifier for the FDN partition. */
+        public static final int FDN_EF_TYPE = 3;
+
+        /**
+         * The account_name of this SIM account. See {@link RawContacts#ACCOUNT_NAME}.
+         */
+        private final String mAccountName;
+
+        /**
+         * The account_type of this SIM account. See {@link RawContacts#ACCOUNT_TYPE}.
+         */
+        private final String mAccountType;
+
+        /**
+         * The slot index of the SIM card this account maps to. See {@link
+         * android.telephony.SubscriptionInfo#getSimSlotIndex()}.
+         */
+        private final int mSimSlotIndex;
+
+        /**
+         * The EF type of the contacts stored in this account. One of
+         * {@link #ADN_EF_TYPE}, {@link #SDN_EF_TYPE} or {@link #FDN_EF_TYPE}.
+         *
+         * EF type is the Elementary File type of the partition these contacts come from within the
+         * SIM card.
+         *
+         * ADN is the "abbreviated dialing numbers" or the user managed SIM contacts.
+         *
+         * SDN is the "service dialing numbers" which are usually preloaded onto the SIM by the
+         * carrier.
+         *
+         * FDN is the "fixed dialing numbers" which are contacts which can only be dialed from that
+         * SIM, used in cases such as parental control.
+         */
+        private final int mEfType;
+
+        /**
+         * @return A set containing all known EF type values
+         * @hide
+         */
+        public static @NonNull Set<Integer> getValidEfTypes() {
+            return Sets.newArraySet(ADN_EF_TYPE, SDN_EF_TYPE, FDN_EF_TYPE);
+        }
+
+        /**
+         * @hide
+         */
+        public SimAccount(@NonNull String accountName, @NonNull String accountType,
+                int simSlotIndex,
+                int efType) {
+            this.mAccountName = accountName;
+            this.mAccountType = accountType;
+            this.mSimSlotIndex = simSlotIndex;
+            this.mEfType = efType;
+        }
+
+        /**
+         * @return The account_name of this SIM account. See {@link RawContacts#ACCOUNT_NAME}.
+         */
+        public @NonNull String getAccountName() {
+            return mAccountName;
+        }
+
+        /**
+         * @return The account_type of this SIM account. See {@link RawContacts#ACCOUNT_TYPE}.
+         */
+        public @NonNull String getAccountType() {
+            return mAccountType;
+        }
+
+        /**
+         * @return The slot index of the SIM card this account maps to. See
+         * {@link android.telephony.SubscriptionInfo#getSimSlotIndex()}.
+         */
+        public int getSimSlotIndex() {
+            return mSimSlotIndex;
+        }
+
+        /**
+         * @return The EF type of the contacts stored in this account.
+         */
+        public int getEfType() {
+            return mEfType;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mAccountName, mAccountType, mSimSlotIndex, mEfType);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) return false;
+            if (obj == this) return true;
+
+            SimAccount toCompare;
+            try {
+                toCompare = (SimAccount) obj;
+            } catch (ClassCastException ex) {
+                return false;
+            }
+
+            return mSimSlotIndex == toCompare.mSimSlotIndex
+                    && mEfType == toCompare.mEfType
+                    && Objects.equals(mAccountName, toCompare.mAccountName)
+                    && Objects.equals(mAccountType, toCompare.mAccountType);
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeString(mAccountName);
+            dest.writeString(mAccountType);
+            dest.writeInt(mSimSlotIndex);
+            dest.writeInt(mEfType);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final @NonNull Parcelable.Creator<SimAccount> CREATOR =
+                new Parcelable.Creator<SimAccount>() {
+                    @Override
+                    public SimAccount createFromParcel(Parcel source) {
+                        String accountName = source.readString();
+                        String accountType = source.readString();
+                        int simSlot = source.readInt();
+                        int efType = source.readInt();
+                        SimAccount simAccount = new SimAccount(accountName, accountType, simSlot,
+                                efType);
+                        return simAccount;
+                    }
+
+                    @Override
+                    public SimAccount[] newArray(int size) {
+                        return new SimAccount[size];
+                    }
+                };
+    }
+
     /**
      * @see Settings
      */
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 44cc0f5..f58fa15 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -126,6 +126,14 @@
     public static final String NAMESPACE_AUTOFILL = "autofill";
 
     /**
+     * Namespace for battery saver feature.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_BATTERY_SAVER = "battery_saver";
+
+    /**
      * Namespace for blobstore feature that allows apps to share data blobs.
      *
      * @hide
diff --git a/core/java/android/provider/OWNERS b/core/java/android/provider/OWNERS
index 97e0156..792ff20 100644
--- a/core/java/android/provider/OWNERS
+++ b/core/java/android/provider/OWNERS
@@ -2,4 +2,8 @@
 per-file DeviceConfig.java = hackbod@google.com
 per-file DeviceConfig.java = schfan@google.com
 
-
+per-file CallLog.java = file:/telephony/OWNERS
+per-file DocumentsContract.java = file:/core/java/android/os/storage/OWNERS
+per-file DocumentsProvider.java = file:/core/java/android/os/storage/OWNERS
+per-file MediaStore.java = file:/core/java/android/os/storage/OWNERS
+per-file Telephony.java = file:/telephony/OWNERS
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b86b9ff8..fb0aea0 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9962,13 +9962,13 @@
          * upon going to sleep. It additionally controls whether a playback device attempts to turn
          * on the connected Audio system when waking up. Supported values are:
          * <ul>
-         * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_TO_TV} Upon going to sleep, device
+         * <li>{@link HdmiControlManager#POWER_CONTROL_MODE_TV} Upon going to sleep, device
          * sends {@code <Standby>} to TV only. Upon waking up, device does not turn on the Audio
          * system via {@code <System Audio Mode Request>}.</li>
-         * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_BROADCAST} Upon going to sleep,
+         * <li>{@link HdmiControlManager#POWER_CONTROL_MODE_BROADCAST} Upon going to sleep,
          * device sends {@code <Standby>} to all devices in the network. Upon waking up, device
          * attempts to turn on the Audio system via {@code <System Audio Mode Request>}.</li>
-         * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_NONE} Upon going to sleep, device
+         * <li>{@link HdmiControlManager#POWER_CONTROL_MODE_NONE} Upon going to sleep, device
          * does not send any {@code <Standby>} message. Upon waking up, device does not turn on the
          * Audio system via {@code <System Audio Mode Request>}.</li>
          * </ul>
@@ -11717,24 +11717,6 @@
                 "battery_saver_device_specific_constants";
 
         /**
-         * Settings for adaptive Battery Saver mode. Uses the same flags as
-         * {@link #BATTERY_SAVER_CONSTANTS}.
-         *
-         * @hide
-         */
-        public static final String BATTERY_SAVER_ADAPTIVE_CONSTANTS =
-                "battery_saver_adaptive_constants";
-
-        /**
-         * Device specific settings for adaptive Battery Saver mode. Uses the same flags as
-         * {@link #BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS}.
-         *
-         * @hide
-         */
-        public static final String BATTERY_SAVER_ADAPTIVE_DEVICE_SPECIFIC_CONSTANTS =
-                "battery_saver_adaptive_device_specific_constants";
-
-        /**
          * Battery tip specific settings
          * This is encoded as a key=value list, separated by commas. Ex:
          *
@@ -14502,10 +14484,11 @@
         public static final String SHOW_PEOPLE_SPACE = "show_people_space";
 
         /**
-         * Which types of conversations to show in People Space.
+         * Which types of conversation(s) to show in People Space.
          * Values are:
-         * 0: All conversations (default)
+         * 0: Single user-selected conversation (default)
          * 1: Priority conversations only
+         * 2: All conversations
          * @hide
          */
         public static final String PEOPLE_SPACE_CONVERSATION_TYPE =
diff --git a/core/java/android/se/OWNERS b/core/java/android/se/OWNERS
new file mode 100644
index 0000000..f1539dc
--- /dev/null
+++ b/core/java/android/se/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 456592
+
+cbrubaker@google.com
+vishwath@google.com
diff --git a/core/java/android/se/omapi/OWNERS b/core/java/android/se/omapi/OWNERS
new file mode 100644
index 0000000..f1539dc
--- /dev/null
+++ b/core/java/android/se/omapi/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 456592
+
+cbrubaker@google.com
+vishwath@google.com
diff --git a/core/java/android/security/OWNERS b/core/java/android/security/OWNERS
index 7120376..3f8d75e 100644
--- a/core/java/android/security/OWNERS
+++ b/core/java/android/security/OWNERS
@@ -1,3 +1,8 @@
+# Bug component: 36824
+
+cbrubaker@google.com
+vishwath@google.com
+
 per-file NetworkSecurityPolicy.java = cbrubaker@google.com
 per-file NetworkSecurityPolicy.java = klyubin@google.com
 per-file FrameworkNetworkSecurityPolicy.java = cbrubaker@google.com
diff --git a/core/java/android/security/keymaster/OWNERS b/core/java/android/security/keymaster/OWNERS
new file mode 100644
index 0000000..65129a4
--- /dev/null
+++ b/core/java/android/security/keymaster/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 189335
+
+swillden@google.com
+jdanis@google.com
+jbires@google.com
diff --git a/core/java/android/security/keystore/OWNERS b/core/java/android/security/keystore/OWNERS
index bb487fb..65129a4 100644
--- a/core/java/android/security/keystore/OWNERS
+++ b/core/java/android/security/keystore/OWNERS
@@ -1,4 +1,5 @@
-aseemk@google.com
-bozhu@google.com
-dementyev@google.com
-robertberry@google.com
+# Bug component: 189335
+
+swillden@google.com
+jdanis@google.com
+jbires@google.com
diff --git a/core/java/android/security/keystore/recovery/OWNERS b/core/java/android/security/keystore/recovery/OWNERS
new file mode 100644
index 0000000..65129a4
--- /dev/null
+++ b/core/java/android/security/keystore/recovery/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 189335
+
+swillden@google.com
+jdanis@google.com
+jbires@google.com
diff --git a/core/java/android/security/net/OWNERS b/core/java/android/security/net/OWNERS
new file mode 100644
index 0000000..d828164
--- /dev/null
+++ b/core/java/android/security/net/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 36824
+
+cbrubaker@google.com
+brambonne@google.com
diff --git a/core/java/android/security/net/config/OWNERS b/core/java/android/security/net/config/OWNERS
index 5350373..85ce3c6 100644
--- a/core/java/android/security/net/config/OWNERS
+++ b/core/java/android/security/net/config/OWNERS
@@ -1,3 +1,5 @@
+# Bug component: 36824
 set noparent
+
 cbrubaker@google.com
-klyubin@google.com
+brambonne@google.com
diff --git a/core/java/android/service/appprediction/OWNERS b/core/java/android/service/appprediction/OWNERS
new file mode 100644
index 0000000..fe012da
--- /dev/null
+++ b/core/java/android/service/appprediction/OWNERS
@@ -0,0 +1,2 @@
+adamcohen@google.com
+sunnygoyal@google.com
diff --git a/core/java/android/service/attention/OWNERS b/core/java/android/service/attention/OWNERS
new file mode 100644
index 0000000..dd579b6
--- /dev/null
+++ b/core/java/android/service/attention/OWNERS
@@ -0,0 +1 @@
+asalo@google.com
diff --git a/core/java/android/service/autofill/OWNERS b/core/java/android/service/autofill/OWNERS
new file mode 100644
index 0000000..a088632
--- /dev/null
+++ b/core/java/android/service/autofill/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 351486
+
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/service/autofill/augmented/OWNERS b/core/java/android/service/autofill/augmented/OWNERS
new file mode 100644
index 0000000..a088632
--- /dev/null
+++ b/core/java/android/service/autofill/augmented/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 351486
+
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/service/carrier/CarrierMessagingService.java b/core/java/android/service/carrier/CarrierMessagingService.java
index 88a78c3..61213e6 100644
--- a/core/java/android/service/carrier/CarrierMessagingService.java
+++ b/core/java/android/service/carrier/CarrierMessagingService.java
@@ -16,6 +16,7 @@
 
 package android.service.carrier;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -25,6 +26,8 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -74,6 +77,15 @@
      */
     public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE = 0x2;
 
+    /** @hide */
+    @IntDef(flag = true, prefix = { "RECEIVE_OPTIONS_" }, value = {
+            RECEIVE_OPTIONS_DEFAULT,
+            RECEIVE_OPTIONS_DROP,
+            RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FilterCompleteResult{}
+
     /**
      * Indicates that an SMS or MMS message was successfully sent.
      */
@@ -89,6 +101,15 @@
      */
     public static final int SEND_STATUS_ERROR = 2;
 
+    /** @hide */
+    @IntDef(prefix = { "SEND_STATUS_" }, value = {
+            SEND_STATUS_OK,
+            SEND_STATUS_RETRY_ON_CARRIER_NETWORK,
+            SEND_STATUS_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SendResult {}
+
     /**
      * Successfully downloaded an MMS message.
      */
@@ -104,10 +125,26 @@
      */
     public static final int DOWNLOAD_STATUS_ERROR = 2;
 
+    /** @hide */
+    @IntDef(prefix = { "DOWNLOAD_STATUS_" }, value = {
+            DOWNLOAD_STATUS_OK,
+            DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK,
+            DOWNLOAD_STATUS_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DownloadResult {}
+
     /**
      * Flag to request SMS delivery status report.
      */
-    public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 1;
+    public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 0x1;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "SEND_FLAG_" }, value = {
+            SEND_FLAG_REQUEST_DELIVERY_STATUS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SendRequest {}
 
     private final ICarrierMessagingWrapper mWrapper = new ICarrierMessagingWrapper();
 
diff --git a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
index 4ffffc6..197c5a6 100644
--- a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
+++ b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
@@ -16,19 +16,25 @@
 
 package android.service.carrier;
 
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.telephony.SmsMessage;
 
 import com.android.internal.util.Preconditions;
 
 import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executor;
 
 /**
  * Provides basic structure for platform to connect to the carrier messaging service.
@@ -46,6 +52,7 @@
  * CarrierMessagingService.
  * @hide
  */
+@SystemApi
 public final class CarrierMessagingServiceWrapper {
     // Populated by bindToCarrierMessagingService. bindToCarrierMessagingService must complete
     // prior to calling disposeConnection so that mCarrierMessagingServiceConnection is initialized.
@@ -53,6 +60,7 @@
 
     private volatile ICarrierMessagingService mICarrierMessagingService;
     private Runnable mOnServiceReadyCallback;
+    private Executor mServiceReadyCallbackExecutor;
 
     /**
      * Binds to the carrier messaging service under package {@code carrierPackageName}. This method
@@ -60,18 +68,27 @@
      *
      * @param context the context
      * @param carrierPackageName the carrier package name
+     * @param executor the executor to run the callback.
+     * @param onServiceReadyCallback the callback when service becomes ready.
      * @return true upon successfully binding to a carrier messaging service, false otherwise
      * @hide
      */
+    @SystemApi
     public boolean bindToCarrierMessagingService(@NonNull Context context,
             @NonNull String carrierPackageName,
+            @NonNull @CallbackExecutor Executor executor,
             @NonNull Runnable onServiceReadyCallback) {
         Preconditions.checkState(mCarrierMessagingServiceConnection == null);
+        Objects.requireNonNull(context);
+        Objects.requireNonNull(carrierPackageName);
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(onServiceReadyCallback);
 
         Intent intent = new Intent(CarrierMessagingService.SERVICE_INTERFACE);
         intent.setPackage(carrierPackageName);
         mCarrierMessagingServiceConnection = new CarrierMessagingServiceConnection();
         mOnServiceReadyCallback = onServiceReadyCallback;
+        mServiceReadyCallbackExecutor = executor;
         return context.bindService(intent, mCarrierMessagingServiceConnection,
                 Context.BIND_AUTO_CREATE);
     }
@@ -82,11 +99,13 @@
      * @param context the context
      * @hide
      */
+    @SystemApi
     public void disposeConnection(@NonNull Context context) {
         Preconditions.checkNotNull(mCarrierMessagingServiceConnection);
         context.unbindService(mCarrierMessagingServiceConnection);
         mCarrierMessagingServiceConnection = null;
         mOnServiceReadyCallback = null;
+        mServiceReadyCallbackExecutor = null;
     }
 
     /**
@@ -96,26 +115,38 @@
      */
     private void onServiceReady(ICarrierMessagingService carrierMessagingService) {
         mICarrierMessagingService = carrierMessagingService;
-        if (mOnServiceReadyCallback != null) mOnServiceReadyCallback.run();
+        if (mOnServiceReadyCallback != null && mServiceReadyCallbackExecutor != null) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                mServiceReadyCallbackExecutor.execute(mOnServiceReadyCallback);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
     }
 
     /**
-     * Request filtering an incoming SMS message.
+     * Request the CarrierMessagingService to process an incoming SMS text or data message.
      * The service will call callback.onFilterComplete with the filtering result.
      *
      * @param pdu the PDUs of the message
-     * @param format the format of the PDUs, typically "3gpp" or "3gpp2"
+     * @param format the format of the PDUs, typically "3gpp" or "3gpp2".
+     *               See {@link SmsMessage#FORMAT_3GPP} and {@link SmsMessage#FORMAT_3GPP2} for
+     *               more details.
      * @param destPort the destination port of a data SMS. It will be -1 for text SMS
      * @param subId SMS subscription ID of the SIM
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
-    public void filterSms(@NonNull MessagePdu pdu, @NonNull String format, int destPort,
-            int subId, @NonNull final CarrierMessagingCallback callback) {
+    @SystemApi
+    public void receiveSms(@NonNull MessagePdu pdu, @NonNull @SmsMessage.Format String format,
+            int destPort, int subId, @NonNull @CallbackExecutor final Executor executor,
+            @NonNull final CarrierMessagingCallback callback) {
         if (mICarrierMessagingService != null) {
             try {
                 mICarrierMessagingService.filterSms(pdu, format, destPort, subId,
-                        new CarrierMessagingCallbackInternal(callback));
+                        new CarrierMessagingCallbackInternal(callback, executor));
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -130,19 +161,23 @@
      * @param text the text to send
      * @param subId SMS subscription ID of the SIM
      * @param destAddress phone number of the recipient of the message
-     * @param sendSmsFlag flag for sending SMS
+     * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
+     *        {@link CarrierMessagingService#SEND_FLAG_REQUEST_DELIVERY_STATUS}.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void sendTextSms(@NonNull String text, int subId, @NonNull String destAddress,
-            int sendSmsFlag, @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.sendTextSms(text, subId, destAddress, sendSmsFlag,
-                        new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+            @CarrierMessagingService.SendRequest int sendSmsFlag,
+            @NonNull @CallbackExecutor final Executor executor,
+            @NonNull final CarrierMessagingCallback callback) {
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.sendTextSms(text, subId, destAddress, sendSmsFlag,
+                    new CarrierMessagingCallbackInternal(callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -155,20 +190,24 @@
      * @param subId SMS subscription ID of the SIM
      * @param destAddress phone number of the recipient of the message
      * @param destPort port number of the recipient of the message
-     * @param sendSmsFlag flag for sending SMS
+     * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
+     *        {@link CarrierMessagingService#SEND_FLAG_REQUEST_DELIVERY_STATUS}.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void sendDataSms(@NonNull byte[] data, int subId, @NonNull String destAddress,
-            int destPort, int sendSmsFlag,
+            int destPort, @CarrierMessagingService.SendRequest int sendSmsFlag,
+            @NonNull @CallbackExecutor final Executor executor,
             @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.sendDataSms(data, subId, destAddress, destPort,
-                        sendSmsFlag, new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.sendDataSms(data, subId, destAddress, destPort,
+                    sendSmsFlag, new CarrierMessagingCallbackInternal(
+                            callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -180,20 +219,24 @@
      * @param parts the parts of the multi-part text SMS to send
      * @param subId SMS subscription ID of the SIM
      * @param destAddress phone number of the recipient of the message
-     * @param sendSmsFlag flag for sending SMS
+     * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
+     *        {@link CarrierMessagingService#SEND_FLAG_REQUEST_DELIVERY_STATUS}.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void sendMultipartTextSms(@NonNull List<String> parts, int subId,
-            @NonNull String destAddress, int sendSmsFlag,
+            @NonNull String destAddress,
+            @CarrierMessagingService.SendRequest int sendSmsFlag,
+            @NonNull @CallbackExecutor final Executor executor,
             @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.sendMultipartTextSms(parts, subId, destAddress,
-                        sendSmsFlag, new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.sendMultipartTextSms(parts, subId, destAddress,
+                    sendSmsFlag, new CarrierMessagingCallbackInternal(callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -206,18 +249,20 @@
      * @param subId SMS subscription ID of the SIM
      * @param location the optional URI to send this MMS PDU. If this is {code null},
      *        the PDU should be sent to the default MMSC URL.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void sendMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
+            @NonNull @CallbackExecutor final Executor executor,
             @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.sendMms(pduUri, subId, location,
-                        new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.sendMms(pduUri, subId, location,
+                    new CarrierMessagingCallbackInternal(callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -229,18 +274,20 @@
      * @param pduUri the content provider URI of the PDU to be downloaded.
      * @param subId SMS subscription ID of the SIM
      * @param location the URI of the message to be downloaded.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void downloadMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
+            @NonNull @CallbackExecutor final Executor executor,
             @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.downloadMms(pduUri, subId, location,
-                        new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.downloadMms(pduUri, subId, location,
+                    new CarrierMessagingCallbackInternal(callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -263,19 +310,19 @@
      * {@link CarrierMessagingServiceWrapper}.
      * @hide
      */
+    @SystemApi
     public interface CarrierMessagingCallback {
-
         /**
-         * Response callback for {@link CarrierMessagingServiceWrapper#filterSms}.
+         * Response callback for {@link CarrierMessagingServiceWrapper#receiveSms}.
          * @param result a bitmask integer to indicate how the incoming text SMS should be handled
          *               by the platform. Bits set can be
          *               {@link CarrierMessagingService#RECEIVE_OPTIONS_DROP} and
          *               {@link CarrierMessagingService#
          *               RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE}.
-         *               {@see CarrierMessagingService#onReceiveTextSms}.
-         * @hide
+         *               {@link CarrierMessagingService#onReceiveTextSms}.
          */
-        default void onFilterComplete(int result) {
+        default void onReceiveSmsComplete(
+                @CarrierMessagingService.FilterCompleteResult int result) {
 
         }
 
@@ -287,10 +334,9 @@
          *               and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
          * @param messageRef message reference of the just-sent message. This field is applicable
          *                   only if result is {@link CarrierMessagingService#SEND_STATUS_OK}.
-         * @hide
          */
-        default void onSendSmsComplete(int result, int messageRef) {
-
+        default void onSendSmsComplete(@CarrierMessagingService.SendResult
+                int result, int messageRef) {
         }
 
         /**
@@ -301,9 +347,9 @@
          * @param messageRefs an array of message references, one for each part of the
          *                    multipart SMS. This field is applicable only if result is
          *                    {@link CarrierMessagingService#SEND_STATUS_OK}.
-         * @hide
          */
-        default void onSendMultipartSmsComplete(int result, @Nullable int[] messageRefs) {
+        default void onSendMultipartSmsComplete(@CarrierMessagingService.SendResult
+                int result, @Nullable int[] messageRefs) {
 
         }
 
@@ -315,56 +361,62 @@
          * @param sendConfPdu a possibly {code null} SendConf PDU, which confirms that the message
          *                    was sent. sendConfPdu is ignored if the {@code result} is not
          *                    {@link CarrierMessagingService#SEND_STATUS_OK}.
-         * @hide
          */
-        default void onSendMmsComplete(int result, @Nullable byte[] sendConfPdu) {
+        default void onSendMmsComplete(@CarrierMessagingService.SendResult
+                int result, @Nullable byte[] sendConfPdu) {
 
         }
 
         /**
          * Response callback for {@link CarrierMessagingServiceWrapper#downloadMms}.
-         * @param result download status, one of {@link CarrierMessagingService#SEND_STATUS_OK},
-         *               {@link CarrierMessagingService#SEND_STATUS_RETRY_ON_CARRIER_NETWORK},
-         *               and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
-         * @hide
+         * @param result download status, one of {@link CarrierMessagingService#DOWNLOAD_STATUS_OK},
+         *               {@link CarrierMessagingService#DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK},
+         *               and {@link CarrierMessagingService#DOWNLOAD_STATUS_ERROR}.
          */
-        default void onDownloadMmsComplete(int result) {
+        default void onDownloadMmsComplete(@CarrierMessagingService.DownloadResult
+                int result) {
 
         }
     }
 
     private final class CarrierMessagingCallbackInternal
             extends ICarrierMessagingCallback.Stub {
-        CarrierMessagingCallback mCarrierMessagingCallback;
+        final CarrierMessagingCallback mCarrierMessagingCallback;
+        final Executor mExecutor;
 
-        CarrierMessagingCallbackInternal(CarrierMessagingCallback callback) {
+        CarrierMessagingCallbackInternal(CarrierMessagingCallback callback,
+                final Executor executor) {
             mCarrierMessagingCallback = callback;
+            mExecutor = executor;
         }
 
         @Override
         public void onFilterComplete(int result) throws RemoteException {
-            mCarrierMessagingCallback.onFilterComplete(result);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onReceiveSmsComplete(result));
         }
 
         @Override
         public void onSendSmsComplete(int result, int messageRef) throws RemoteException {
-            mCarrierMessagingCallback.onSendSmsComplete(result, messageRef);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onSendSmsComplete(
+                    result, messageRef));
         }
 
         @Override
         public void onSendMultipartSmsComplete(int result, int[] messageRefs)
                 throws RemoteException {
-            mCarrierMessagingCallback.onSendMultipartSmsComplete(result, messageRefs);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onSendMultipartSmsComplete(
+                    result, messageRefs));
         }
 
         @Override
         public void onSendMmsComplete(int result, byte[] sendConfPdu) throws RemoteException {
-            mCarrierMessagingCallback.onSendMmsComplete(result, sendConfPdu);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onSendMmsComplete(
+                    result, sendConfPdu));
         }
 
         @Override
         public void onDownloadMmsComplete(int result) throws RemoteException {
-            mCarrierMessagingCallback.onDownloadMmsComplete(result);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onDownloadMmsComplete(result));
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/service/carrier/OWNERS b/core/java/android/service/carrier/OWNERS
new file mode 100644
index 0000000..d768ef4
--- /dev/null
+++ b/core/java/android/service/carrier/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+fionaxu@google.com
diff --git a/core/java/android/service/chooser/OWNERS b/core/java/android/service/chooser/OWNERS
new file mode 100644
index 0000000..a5acba5
--- /dev/null
+++ b/core/java/android/service/chooser/OWNERS
@@ -0,0 +1,4 @@
+asc@google.com
+mpietal@google.com
+dsandler@android.com
+dsandler@google.com
diff --git a/core/java/android/service/contentcapture/OWNERS b/core/java/android/service/contentcapture/OWNERS
new file mode 100644
index 0000000..6337327
--- /dev/null
+++ b/core/java/android/service/contentcapture/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 544200
+
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/service/contentsuggestions/OWNERS b/core/java/android/service/contentsuggestions/OWNERS
new file mode 100644
index 0000000..46b5ea0
--- /dev/null
+++ b/core/java/android/service/contentsuggestions/OWNERS
@@ -0,0 +1,7 @@
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/service/dreams/OWNERS b/core/java/android/service/dreams/OWNERS
index 708ab4c..f831805 100644
--- a/core/java/android/service/dreams/OWNERS
+++ b/core/java/android/service/dreams/OWNERS
@@ -1,4 +1,3 @@
-dsandler@android.com
-michaelwr@google.com
-roosa@google.com
-galinap@google.com
+# Bug component: 78010
+
+dsandler@google.com
diff --git a/core/java/android/service/gatekeeper/OWNERS b/core/java/android/service/gatekeeper/OWNERS
new file mode 100644
index 0000000..2ca52cd
--- /dev/null
+++ b/core/java/android/service/gatekeeper/OWNERS
@@ -0,0 +1,3 @@
+swillden@google.com
+jdanis@google.com
+jbires@google.com
diff --git a/core/java/android/service/media/OWNERS b/core/java/android/service/media/OWNERS
new file mode 100644
index 0000000..916fc36
--- /dev/null
+++ b/core/java/android/service/media/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 137631
+
+hdmoon@google.com
+insun@google.com
+jaewan@google.com
+jinpark@google.com
+klhyun@google.com
+gyumin@google.com
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index aa9e289..440eeb1 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1517,8 +1517,10 @@
      */
     public static class Ranking {
 
-        /** Value signifying that the user has not expressed a per-app visibility override value.
-         * @hide */
+        /**
+         * Value signifying that the user and device policy manager have not expressed a lockscreen
+         * visibility override for a notification.
+         */
         public static final int VISIBILITY_NO_OVERRIDE = NotificationManager.VISIBILITY_NO_OVERRIDE;
 
         /**
@@ -1695,14 +1697,13 @@
         }
 
         /**
-         * Returns the user specified visibility for the package that posted
-         * this notification, or
+         * Returns the user or device policy manager specified visibility (see
+         * {@link Notification#VISIBILITY_PRIVATE}, {@link Notification#VISIBILITY_PUBLIC},
+         * {@link Notification#VISIBILITY_SECRET}) for this notification, or
          * {@link NotificationListenerService.Ranking#VISIBILITY_NO_OVERRIDE} if
          * no such preference has been expressed.
-         * @hide
          */
-        @UnsupportedAppUsage
-        public int getVisibilityOverride() {
+        public int getLockscreenVisibilityOverride() {
             return mVisibilityOverride;
         }
 
diff --git a/core/java/android/service/notification/OWNERS b/core/java/android/service/notification/OWNERS
index 2e94be5..debb493 100644
--- a/core/java/android/service/notification/OWNERS
+++ b/core/java/android/service/notification/OWNERS
@@ -1,4 +1,6 @@
+# Bug component: 34005
+
 juliacr@google.com
-beverlyt@google.com
+pixel@google.com
 dsandler@android.com
-pixel@google.com
\ No newline at end of file
+dsandler@google.com
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 787a81b..12d9055 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -45,13 +45,14 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -515,7 +516,7 @@
         }
     }
 
-    public static ZenModeConfig readXml(XmlPullParser parser)
+    public static ZenModeConfig readXml(TypedXmlPullParser parser)
             throws XmlPullParserException, IOException {
         int type = parser.getEventType();
         if (type != XmlPullParser.START_TAG) return null;
@@ -611,28 +612,28 @@
      * @param version uses XML_VERSION if version is null
      * @throws IOException
      */
-    public void writeXml(XmlSerializer out, Integer version) throws IOException {
+    public void writeXml(TypedXmlSerializer out, Integer version) throws IOException {
         out.startTag(null, ZEN_TAG);
         out.attribute(null, ZEN_ATT_VERSION, version == null
                 ? Integer.toString(XML_VERSION) : Integer.toString(version));
-        out.attribute(null, ZEN_ATT_USER, Integer.toString(user));
+        out.attributeInt(null, ZEN_ATT_USER, user);
         out.startTag(null, ALLOW_TAG);
-        out.attribute(null, ALLOW_ATT_CALLS, Boolean.toString(allowCalls));
-        out.attribute(null, ALLOW_ATT_REPEAT_CALLERS, Boolean.toString(allowRepeatCallers));
-        out.attribute(null, ALLOW_ATT_MESSAGES, Boolean.toString(allowMessages));
-        out.attribute(null, ALLOW_ATT_REMINDERS, Boolean.toString(allowReminders));
-        out.attribute(null, ALLOW_ATT_EVENTS, Boolean.toString(allowEvents));
-        out.attribute(null, ALLOW_ATT_CALLS_FROM, Integer.toString(allowCallsFrom));
-        out.attribute(null, ALLOW_ATT_MESSAGES_FROM, Integer.toString(allowMessagesFrom));
-        out.attribute(null, ALLOW_ATT_ALARMS, Boolean.toString(allowAlarms));
-        out.attribute(null, ALLOW_ATT_MEDIA, Boolean.toString(allowMedia));
-        out.attribute(null, ALLOW_ATT_SYSTEM, Boolean.toString(allowSystem));
-        out.attribute(null, ALLOW_ATT_CONV, Boolean.toString(allowConversations));
-        out.attribute(null, ALLOW_ATT_CONV_FROM, Integer.toString(allowConversationsFrom));
+        out.attributeBoolean(null, ALLOW_ATT_CALLS, allowCalls);
+        out.attributeBoolean(null, ALLOW_ATT_REPEAT_CALLERS, allowRepeatCallers);
+        out.attributeBoolean(null, ALLOW_ATT_MESSAGES, allowMessages);
+        out.attributeBoolean(null, ALLOW_ATT_REMINDERS, allowReminders);
+        out.attributeBoolean(null, ALLOW_ATT_EVENTS, allowEvents);
+        out.attributeInt(null, ALLOW_ATT_CALLS_FROM, allowCallsFrom);
+        out.attributeInt(null, ALLOW_ATT_MESSAGES_FROM, allowMessagesFrom);
+        out.attributeBoolean(null, ALLOW_ATT_ALARMS, allowAlarms);
+        out.attributeBoolean(null, ALLOW_ATT_MEDIA, allowMedia);
+        out.attributeBoolean(null, ALLOW_ATT_SYSTEM, allowSystem);
+        out.attributeBoolean(null, ALLOW_ATT_CONV, allowConversations);
+        out.attributeInt(null, ALLOW_ATT_CONV_FROM, allowConversationsFrom);
         out.endTag(null, ALLOW_TAG);
 
         out.startTag(null, DISALLOW_TAG);
-        out.attribute(null, DISALLOW_ATT_VISUAL_EFFECTS, Integer.toString(suppressedVisualEffects));
+        out.attributeInt(null, DISALLOW_ATT_VISUAL_EFFECTS, suppressedVisualEffects);
         out.endTag(null, DISALLOW_TAG);
 
         if (manualRule != null) {
@@ -651,14 +652,13 @@
         }
 
         out.startTag(null, STATE_TAG);
-        out.attribute(null, STATE_ATT_CHANNELS_BYPASSING_DND,
-                Boolean.toString(areChannelsBypassingDnd));
+        out.attributeBoolean(null, STATE_ATT_CHANNELS_BYPASSING_DND, areChannelsBypassingDnd);
         out.endTag(null, STATE_TAG);
 
         out.endTag(null, ZEN_TAG);
     }
 
-    public static ZenRule readRuleXml(XmlPullParser parser) {
+    public static ZenRule readRuleXml(TypedXmlPullParser parser) {
         final ZenRule rt = new ZenRule();
         rt.enabled = safeBoolean(parser, RULE_ATT_ENABLED, true);
         rt.name = parser.getAttributeValue(null, RULE_ATT_NAME);
@@ -691,12 +691,12 @@
         return rt;
     }
 
-    public static void writeRuleXml(ZenRule rule, XmlSerializer out) throws IOException {
-        out.attribute(null, RULE_ATT_ENABLED, Boolean.toString(rule.enabled));
+    public static void writeRuleXml(ZenRule rule, TypedXmlSerializer out) throws IOException {
+        out.attributeBoolean(null, RULE_ATT_ENABLED, rule.enabled);
         if (rule.name != null) {
             out.attribute(null, RULE_ATT_NAME, rule.name);
         }
-        out.attribute(null, RULE_ATT_ZEN, Integer.toString(rule.zenMode));
+        out.attributeInt(null, RULE_ATT_ZEN, rule.zenMode);
         if (rule.component != null) {
             out.attribute(null, RULE_ATT_COMPONENT, rule.component.flattenToString());
         }
@@ -707,7 +707,7 @@
         if (rule.conditionId != null) {
             out.attribute(null, RULE_ATT_CONDITION_ID, rule.conditionId.toString());
         }
-        out.attribute(null, RULE_ATT_CREATION_TIME, Long.toString(rule.creationTime));
+        out.attributeLong(null, RULE_ATT_CREATION_TIME, rule.creationTime);
         if (rule.enabler != null) {
             out.attribute(null, RULE_ATT_ENABLER, rule.enabler);
         }
@@ -717,10 +717,10 @@
         if (rule.zenPolicy != null) {
             writeZenPolicyXml(rule.zenPolicy, out);
         }
-        out.attribute(null, RULE_ATT_MODIFIED, Boolean.toString(rule.modified));
+        out.attributeBoolean(null, RULE_ATT_MODIFIED, rule.modified);
     }
 
-    public static Condition readConditionXml(XmlPullParser parser) {
+    public static Condition readConditionXml(TypedXmlPullParser parser) {
         final Uri id = safeUri(parser, CONDITION_ATT_ID);
         if (id == null) return null;
         final String summary = parser.getAttributeValue(null, CONDITION_ATT_SUMMARY);
@@ -737,21 +737,21 @@
         }
     }
 
-    public static void writeConditionXml(Condition c, XmlSerializer out) throws IOException {
+    public static void writeConditionXml(Condition c, TypedXmlSerializer out) throws IOException {
         out.attribute(null, CONDITION_ATT_ID, c.id.toString());
         out.attribute(null, CONDITION_ATT_SUMMARY, c.summary);
         out.attribute(null, CONDITION_ATT_LINE1, c.line1);
         out.attribute(null, CONDITION_ATT_LINE2, c.line2);
-        out.attribute(null, CONDITION_ATT_ICON, Integer.toString(c.icon));
-        out.attribute(null, CONDITION_ATT_STATE, Integer.toString(c.state));
-        out.attribute(null, CONDITION_ATT_FLAGS, Integer.toString(c.flags));
+        out.attributeInt(null, CONDITION_ATT_ICON, c.icon);
+        out.attributeInt(null, CONDITION_ATT_STATE, c.state);
+        out.attributeInt(null, CONDITION_ATT_FLAGS, c.flags);
     }
 
     /**
      * Read the zen policy from xml
      * Returns null if no zen policy exists
      */
-    public static ZenPolicy readZenPolicyXml(XmlPullParser parser) {
+    public static ZenPolicy readZenPolicyXml(TypedXmlPullParser parser) {
         boolean policySet = false;
 
         ZenPolicy.Builder builder = new ZenPolicy.Builder();
@@ -845,7 +845,7 @@
     /**
      * Writes zen policy to xml
      */
-    public static void writeZenPolicyXml(ZenPolicy policy, XmlSerializer out)
+    public static void writeZenPolicyXml(ZenPolicy policy, TypedXmlSerializer out)
             throws IOException {
         writeZenPolicyState(ALLOW_ATT_CALLS_FROM, policy.getPriorityCallSenders(), out);
         writeZenPolicyState(ALLOW_ATT_MESSAGES_FROM, policy.getPriorityMessageSenders(), out);
@@ -868,16 +868,16 @@
                 out);
     }
 
-    private static void writeZenPolicyState(String attr, int val, XmlSerializer out)
+    private static void writeZenPolicyState(String attr, int val, TypedXmlSerializer out)
             throws IOException {
         if (Objects.equals(attr, ALLOW_ATT_CALLS_FROM)
                 || Objects.equals(attr, ALLOW_ATT_MESSAGES_FROM)) {
             if (val != ZenPolicy.PEOPLE_TYPE_UNSET) {
-                out.attribute(null, attr, Integer.toString(val));
+                out.attributeInt(null, attr, val);
             }
         } else {
             if (val != ZenPolicy.STATE_UNSET) {
-                out.attribute(null, attr, Integer.toString(val));
+                out.attributeInt(null, attr, val);
             }
         }
     }
@@ -894,15 +894,16 @@
         return source >= SOURCE_ANYONE && source <= MAX_SOURCE;
     }
 
-    private static Boolean unsafeBoolean(XmlPullParser parser, String att) {
-        final String val = parser.getAttributeValue(null, att);
-        if (TextUtils.isEmpty(val)) return null;
-        return Boolean.parseBoolean(val);
+    private static Boolean unsafeBoolean(TypedXmlPullParser parser, String att) {
+        try {
+            return parser.getAttributeBoolean(null, att);
+        } catch (Exception e) {
+            return null;
+        }
     }
 
-    private static boolean safeBoolean(XmlPullParser parser, String att, boolean defValue) {
-        final String val = parser.getAttributeValue(null, att);
-        return safeBoolean(val, defValue);
+    private static boolean safeBoolean(TypedXmlPullParser parser, String att, boolean defValue) {
+        return parser.getAttributeBoolean(null, att, defValue);
     }
 
     private static boolean safeBoolean(String val, boolean defValue) {
@@ -910,24 +911,23 @@
         return Boolean.parseBoolean(val);
     }
 
-    private static int safeInt(XmlPullParser parser, String att, int defValue) {
-        final String val = parser.getAttributeValue(null, att);
-        return tryParseInt(val, defValue);
+    private static int safeInt(TypedXmlPullParser parser, String att, int defValue) {
+        return parser.getAttributeInt(null, att, defValue);
     }
 
-    private static ComponentName safeComponentName(XmlPullParser parser, String att) {
+    private static ComponentName safeComponentName(TypedXmlPullParser parser, String att) {
         final String val = parser.getAttributeValue(null, att);
         if (TextUtils.isEmpty(val)) return null;
         return ComponentName.unflattenFromString(val);
     }
 
-    private static Uri safeUri(XmlPullParser parser, String att) {
+    private static Uri safeUri(TypedXmlPullParser parser, String att) {
         final String val = parser.getAttributeValue(null, att);
         if (TextUtils.isEmpty(val)) return null;
         return Uri.parse(val);
     }
 
-    private static long safeLong(XmlPullParser parser, String att, long defValue) {
+    private static long safeLong(TypedXmlPullParser parser, String att, long defValue) {
         final String val = parser.getAttributeValue(null, att);
         return tryParseLong(val, defValue);
     }
diff --git a/core/java/android/service/quicksettings/OWNERS b/core/java/android/service/quicksettings/OWNERS
new file mode 100644
index 0000000..12eb7c7
--- /dev/null
+++ b/core/java/android/service/quicksettings/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 78010
+
+kozynski@google.com
+pixel@google.com
+dsandler@android.com
+dsandler@google.com
diff --git a/core/java/android/service/resolver/OWNERS b/core/java/android/service/resolver/OWNERS
new file mode 100644
index 0000000..10150c37
--- /dev/null
+++ b/core/java/android/service/resolver/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 78010
+
+asc@google.com
+mpietal@google.com
+dsandler@android.com
+dsandler@google.com
diff --git a/core/java/android/service/restrictions/OWNERS b/core/java/android/service/restrictions/OWNERS
new file mode 100644
index 0000000..eaba2e9
--- /dev/null
+++ b/core/java/android/service/restrictions/OWNERS
@@ -0,0 +1 @@
+yamasani@google.com
diff --git a/core/java/android/service/textclassifier/OWNERS b/core/java/android/service/textclassifier/OWNERS
new file mode 100644
index 0000000..a535f52
--- /dev/null
+++ b/core/java/android/service/textclassifier/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 709498
+
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/service/textservice/OWNERS b/core/java/android/service/textservice/OWNERS
new file mode 100644
index 0000000..a637754
--- /dev/null
+++ b/core/java/android/service/textservice/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 34867
+
+ogunwale@google.com
+roosa@google.com
+yukawa@google.com
diff --git a/core/java/android/service/trust/OWNERS b/core/java/android/service/trust/OWNERS
new file mode 100644
index 0000000..affe471
--- /dev/null
+++ b/core/java/android/service/trust/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 36824
+
+cbrubaker@google.com
+vishwath@google.com
diff --git a/core/java/android/service/voice/OWNERS b/core/java/android/service/voice/OWNERS
new file mode 100644
index 0000000..46b5ea0
--- /dev/null
+++ b/core/java/android/service/voice/OWNERS
@@ -0,0 +1,7 @@
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/service/wallpaper/OWNERS b/core/java/android/service/wallpaper/OWNERS
new file mode 100644
index 0000000..756eef8
--- /dev/null
+++ b/core/java/android/service/wallpaper/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 78010
+
+dupin@google.com
+dsandler@android.com
+dsandler@google.com
diff --git a/core/java/android/service/watchdog/OWNERS b/core/java/android/service/watchdog/OWNERS
new file mode 100644
index 0000000..1c045e1
--- /dev/null
+++ b/core/java/android/service/watchdog/OWNERS
@@ -0,0 +1,3 @@
+narayan@google.com
+nandana@google.com
+olilan@google.com
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 479a0c1..ac6208b 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -17,7 +17,10 @@
 package android.telephony;
 
 import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.compat.annotation.ChangeId;
@@ -28,17 +31,27 @@
 import android.os.HandlerExecutor;
 import android.os.Looper;
 import android.telephony.Annotation.CallState;
+import android.telephony.Annotation.DataActivityType;
+import android.telephony.Annotation.DisconnectCauses;
+import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.PreciseDisconnectCauses;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SimActivationState;
 import android.telephony.Annotation.SrvccState;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.NetworkRegistrationInfo.Domain;
+import android.telephony.TelephonyManager.DataEnabledReason;
+import android.telephony.TelephonyManager.DataState;
+import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IPhoneStateListener;
 
 import dalvik.system.VMRuntime;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 import java.util.List;
 import java.util.Map;
@@ -113,7 +126,9 @@
      *
      *  @see #onServiceStateChanged
      *  @see ServiceState
+     *  @deprecated Use {@link ServiceStateChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_SERVICE_STATE                            = 0x00000001;
 
     /**
@@ -121,8 +136,7 @@
      * {@more}
      *
      * @see #onSignalStrengthChanged
-     *
-     * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS}
+     * @deprecated Use {@link SignalStrengthsChangedListener} instead.
      */
     @Deprecated
     public static final int LISTEN_SIGNAL_STRENGTH                          = 0x00000002;
@@ -138,7 +152,9 @@
      * voicemail icon.
      *
      * @see #onMessageWaitingIndicatorChanged
+     * @deprecated Use {@link MessageWaitingIndicatorChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_MESSAGE_WAITING_INDICATOR                = 0x00000004;
 
     /**
@@ -149,7 +165,9 @@
      * {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @see #onCallForwardingIndicatorChanged
+     * @deprecated Use {@link CallForwardingIndicatorChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_CALL_FORWARDING_INDICATOR                = 0x00000008;
 
     /**
@@ -165,7 +183,9 @@
      * instead.
      *
      * @see #onCellLocationChanged
+     * @deprecated Use {@link CellLocationChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_CELL_LOCATION                            = 0x00000010;
 
     /**
@@ -173,14 +193,18 @@
      * {@more}
      *
      * @see #onCallStateChanged
+     * @deprecated Use {@link CallStateChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_CALL_STATE                               = 0x00000020;
 
     /**
      * Listen for changes to the data connection state (cellular).
      *
      * @see #onDataConnectionStateChanged
+     * @deprecated Use {@link DataConnectionStateChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_DATA_CONNECTION_STATE                    = 0x00000040;
 
     /**
@@ -191,7 +215,9 @@
      * data-traffic icon.
      *
      * @see #onDataActivity
+     * @deprecated Use {@link DataActivityListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_DATA_ACTIVITY                            = 0x00000080;
 
     /**
@@ -201,7 +227,9 @@
      * icon.
      *
      * @see #onSignalStrengthsChanged
+     * @deprecated Use {@link SignalStrengthsChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_SIGNAL_STRENGTHS                         = 0x00000100;
 
     /**
@@ -211,7 +239,9 @@
      * @see #onSignalStrengthsChanged
      *
      * @hide
+     * @deprecated Use {@link AlwaysReportedSignalStrengthChangedListener} instead.
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
     public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH          = 0x00000200;
 
@@ -222,7 +252,9 @@
      * permission.
      *
      * @see #onCellInfoChanged
+     * @deprecated Use {@link CellInfoChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_CELL_INFO = 0x00000400;
 
     /**
@@ -234,8 +266,10 @@
      * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @hide
+     * @deprecated Use {@link PreciseCallStateChangedListener} instead.
      */
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
+    @Deprecated
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
     @SystemApi
     public static final int LISTEN_PRECISE_CALL_STATE                       = 0x00000800;
 
@@ -247,8 +281,10 @@
      * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @see #onPreciseDataConnectionStateChanged
+     * @deprecated Use {@link PreciseDataConnectionStateChangedListener} instead.
      */
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
+    @Deprecated
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
     public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE            = 0x00001000;
 
     /**
@@ -258,7 +294,7 @@
      * READ_PRECISE_PHONE_STATE}
      * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
      *
-     * @deprecated Use {@link TelephonyManager#getModemActivityInfo()}
+     * @deprecated Use {@link TelephonyManager#requestModemActivityInfo} instead.
      * @hide
      */
     @Deprecated
@@ -271,7 +307,9 @@
      *
      * @see #onServiceStateChanged(ServiceState)
      * @hide
+     * @deprecated Use {@link SrvccStateChangedListener} instead.
      */
+    @Deprecated
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public static final int LISTEN_SRVCC_STATE_CHANGED                     = 0x00004000;
@@ -289,10 +327,11 @@
     /**
      * Listen for carrier network changes indicated by a carrier app.
      *
-     * @see #onCarrierNetworkRequest
-     * @see TelephonyManager#notifyCarrierNetworkChange(boolean)
+     * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)
      * @hide
+     * @deprecated Use {@link CarrierNetworkChangeListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_CARRIER_NETWORK_CHANGE                   = 0x00010000;
 
     /**
@@ -311,7 +350,9 @@
      *
      * @see #onVoiceActivationStateChanged
      * @hide
+     * @deprecated Use {@link VoiceActivationStateChangedListener} instead.
      */
+    @Deprecated
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public static final int LISTEN_VOICE_ACTIVATION_STATE                   = 0x00020000;
@@ -323,20 +364,24 @@
      * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
      * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
      * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
-     * {@more}
+     *
      * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been
      * fully activated
      *
      * @see #onDataActivationStateChanged
      * @hide
+     * @deprecated Use {@link DataActivationStateChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_DATA_ACTIVATION_STATE                   = 0x00040000;
 
     /**
      *  Listen for changes to the user mobile data state
      *
      *  @see #onUserMobileDataStateChanged
+     *  @deprecated Use {@link UserMobileDataStateChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_USER_MOBILE_DATA_STATE                  = 0x00080000;
 
     /**
@@ -347,7 +392,9 @@
      *  {@link TelephonyManager#hasCarrierPrivileges}).
      *
      *  @see #onDisplayInfoChanged
+     * @deprecated Use {@link DisplayInfoChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_DISPLAY_INFO_CHANGED = 0x00100000;
 
     /**
@@ -355,7 +402,9 @@
      *
      *  @see #onPhoneCapabilityChanged
      *  @hide
+     *  @deprecated Use {@link PhoneCapabilityChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_PHONE_CAPABILITY_CHANGE                 = 0x00200000;
 
     /**
@@ -365,17 +414,19 @@
      *  subscription user selected as default data subscription in DSDS mode.
      *
      *  @see #onActiveDataSubscriptionIdChanged
+     *  @deprecated Use {@link ActiveDataSubscriptionIdChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000;
 
     /**
      *  Listen for changes to the radio power state.
      *
-     * <p>Requires permission {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
-     *
      *  @see #onRadioPowerStateChanged
      *  @hide
+     *  @deprecated Use {@link RadioPowerStateChangedListener} instead.
      */
+    @Deprecated
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public static final int LISTEN_RADIO_POWER_STATE_CHANGED               = 0x00800000;
@@ -385,7 +436,10 @@
      *
      * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
      * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @deprecated Use {@link EmergencyNumberListChangedListener} instead.
      */
+    @Deprecated
     public static final int LISTEN_EMERGENCY_NUMBER_LIST                   = 0x01000000;
 
     /**
@@ -396,8 +450,10 @@
      * or the calling app has carrier privileges
      * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
+     * @deprecated Use {@link CallDisconnectCauseChangedListener} instead.
      */
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
+    @Deprecated
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
     public static final int LISTEN_CALL_DISCONNECT_CAUSES                  = 0x02000000;
 
     /**
@@ -409,9 +465,11 @@
      *
      * @see #onCallAttributesChanged
      * @hide
+     * @deprecated Use {@link CallAttributesChangedListener} instead.
      */
+    @Deprecated
     @SystemApi
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
     public static final int LISTEN_CALL_ATTRIBUTES_CHANGED                 = 0x04000000;
 
     /**
@@ -423,18 +481,20 @@
      * (see {@link TelephonyManager#hasCarrierPrivileges}).
      *
      * @see #onImsCallDisconnectCauseChanged(ImsReasonInfo)
+     * @deprecated Use {@link ImsCallDisconnectCauseChangedListener} instead.
      */
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
+    @Deprecated
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
     public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES              = 0x08000000;
 
     /**
      * Listen for the emergency number placed from an outgoing call.
      *
-     * <p>Requires permission {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION}
-     *
      * @see #onOutgoingEmergencyCall
      * @hide
+     * @deprecated Use {@link OutgoingEmergencyCallListener} instead.
      */
+    @Deprecated
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
     public static final int LISTEN_OUTGOING_EMERGENCY_CALL                  = 0x10000000;
@@ -442,11 +502,11 @@
     /**
      * Listen for the emergency number placed from an outgoing SMS.
      *
-     * <p>Requires permission {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION}
-     *
      * @see #onOutgoingEmergencySms
      * @hide
+     * @deprecated Use {@link OutgoingEmergencySmsListener} instead.
      */
+    @Deprecated
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
     public static final int LISTEN_OUTGOING_EMERGENCY_SMS                   = 0x20000000;
@@ -465,7 +525,9 @@
      * of whether the calling app has carrier privileges.
      *
      * @see #onRegistrationFailed
+     * @deprecated Use {@link RegistrationFailedListener} instead.
      */
+    @Deprecated
     @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
     public static final int LISTEN_REGISTRATION_FAILURE = 0x40000000;
 
@@ -479,19 +541,525 @@
      * of whether the calling app has carrier privileges.
      *
      * @see #onBarringInfoChanged
+     * @deprecated Use {@link BarringInfoChangedListener} instead.
      */
+    @Deprecated
     @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
     public static final int LISTEN_BARRING_INFO = 0x80000000;
 
     /**
-     *  Listen for changes to the physical channel configuration.
+     *  Event for changes to the network service state (cellular).
      *
-     * @see #onPhysicalChannelConfigurationChanged
+     *  @see ServiceStateChangedListener#onServiceStateChanged
+     *  @see ServiceState
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int EVENT_SERVICE_STATE_CHANGED = 1;
+
+    /**
+     * Event for changes to the network signal strength (cellular).
+     *
+     * @see SignalStrengthsChangedListener#onSignalStrengthsChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2;
+
+    /**
+     * Event for changes to the message-waiting indicator.
+     *
+     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that
+     * the calling app has carrier privileges (see
+     * {@link TelephonyManager#hasCarrierPrivileges}).
+     * <p>
+     * Example: The status bar uses this to determine when to display the
+     * voicemail icon.
+     *
+     * @see MessageWaitingIndicatorChangedListener#onMessageWaitingIndicatorChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3;
+
+    /**
+     * Event for changes to the call-forwarding indicator.
+     *
+     * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that
+     * the calling app has carrier privileges (see
+     * {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @see CallForwardingIndicatorChangedListener#onCallForwardingIndicatorChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4;
+
+    /**
+     * Event for changes to the device's cell location. Note that
+     * this will result in frequent callbacks to the listener.
+     *
+     * If you need regular location updates but want more control over
+     * the update interval or location precision, you can set up a listener
+     * through the {@link android.location.LocationManager location manager}
+     * instead.
+     *
+     * @see CellLocationChangedListener#onCellLocationChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+    public static final int EVENT_CELL_LOCATION_CHANGED = 5;
+
+    /**
+     * Event for changes to the device call state.
+     *
+     * @see CallStateChangedListener#onCallStateChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
+    public static final int EVENT_CALL_STATE_CHANGED = 6;
+
+    /**
+     * Event for changes to the data connection state (cellular).
+     *
+     * @see DataConnectionStateChangedListener#onDataConnectionStateChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7;
+
+    /**
+     * Event for changes to the direction of data traffic on the data
+     * connection (cellular).
+     *
+     * Example: The status bar uses this to display the appropriate
+     * data-traffic icon.
+     *
+     * @see DataActivityListener#onDataActivity
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int EVENT_DATA_ACTIVITY_CHANGED = 8;
+
+    /**
+     * Event for changes to the network signal strengths (cellular).
+     * <p>
+     * Example: The status bar uses this to control the signal-strength
+     * icon.
+     *
+     * @see SignalStrengthsChangedListener#onSignalStrengthsChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9;
+
+    /**
+     * Event for changes of the network signal strengths (cellular) always reported from modem,
+     * even in some situations such as the screen of the device is off.
+     *
+     * @see AlwaysReportedSignalStrengthChangedListener#onSignalStrengthsChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
+    public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10;
+
+    /**
+     * Event for changes to observed cell info.
+     *
+     * @see CellInfoChangedListener#onCellInfoChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+    public static final int EVENT_CELL_INFO_CHANGED = 11;
+
+    /**
+     * Event for {@link android.telephony.Annotation.PreciseCallStates} of ringing,
+     * background and foreground calls.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @see PreciseCallStateChangedListener#onPreciseCallStateChanged
+     *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
-    public static final long LISTEN_PHYSICAL_CHANNEL_CONFIGURATION = 0x100000000L;
+    public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12;
+
+    /**
+     * Event for {@link PreciseDataConnectionState} on the data connection (cellular).
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @see PreciseDataConnectionStateChangedListener#onPreciseDataConnectionStateChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13;
+
+    /**
+     * Event for real time info for all data connections (cellular)).
+     *
+     * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
+     *
+     * @deprecated Use {@link TelephonyManager#requestModemActivityInfo}
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14;
+
+    /**
+     * Event for OEM hook raw event
+     *
+     * @see #onOemHookRawEvent
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public static final int EVENT_OEM_HOOK_RAW = 15;
+
+    /**
+     * Event for changes to the SRVCC state of the active call.
+     *
+     * @see SrvccStateChangedListener#onSrvccStateChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public static final int EVENT_SRVCC_STATE_CHANGED = 16;
+
+    /**
+     * Event for carrier network changes indicated by a carrier app.
+     *
+     * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)
+     * @see CarrierNetworkChangeListener#onCarrierNetworkChange
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int EVENT_CARRIER_NETWORK_CHANGED = 17;
+
+    /**
+     * Event for changes to the sim voice activation state
+     *
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
+     *
+     * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been
+     * fully activated
+     *
+     * @see VoiceActivationStateChangedListener#onVoiceActivationStateChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18;
+
+    /**
+     * Event for changes to the sim data activation state
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
+     * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
+     *
+     * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been
+     * fully activated
+     *
+     * @see DataActivationStateChangedListener#onDataActivationStateChanged
+     * @hide
+     */
+    @SystemApi
+    public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19;
+
+    /**
+     *  Event for changes to the user mobile data state
+     *
+     *  @see UserMobileDataStateChangedListener#onUserMobileDataStateChanged
+     *
+     *  @hide
+     */
+    @SystemApi
+    public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20;
+
+    /**
+     *  Event for display info changed event.
+     *
+     *  @see DisplayInfoChangedListener#onDisplayInfoChanged
+     *
+     *  @hide
+     */
+    @SystemApi
+    public static final int EVENT_DISPLAY_INFO_CHANGED = 21;
+
+    /**
+     *  Event for changes to the phone capability.
+     *
+     *  @see PhoneCapabilityChangedListener#onPhoneCapabilityChanged
+     *
+     *  @hide
+     */
+    @SystemApi
+    public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22;
+
+    /**
+     *  Event for changes to active data subscription ID. Active data subscription is
+     *  the current subscription used to setup Cellular Internet data. For example,
+     *  it could be the current active opportunistic subscription in use, or the
+     *  subscription user selected as default data subscription in DSDS mode.
+     *
+     *  <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
+     *  app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     *  @see ActiveDataSubscriptionIdChangedListener#onActiveDataSubscriptionIdChanged
+     *
+     *  @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23;
+
+    /**
+     *  Event for changes to the radio power state.
+     *
+     *  @see RadioPowerStateChangedListener#onRadioPowerStateChanged
+     *
+     *  @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24;
+
+    /**
+     * Event for changes to emergency number list based on all active subscriptions.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
+     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     *  @see EmergencyNumberListChangedListener#onEmergencyNumberListChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25;
+
+    /**
+     * Event for call disconnect causes which contains {@link DisconnectCause} and
+     * {@link PreciseDisconnectCause}.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     *  @see CallDisconnectCauseChangedListener#onCallDisconnectCauseChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26;
+
+    /**
+     * Event for changes to the call attributes of a currently active call.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @see CallAttributesChangedListener#onCallAttributesChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27;
+
+    /**
+     * Event for IMS call disconnect causes which contains
+     * {@link android.telephony.ims.ImsReasonInfo}
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @see ImsCallDisconnectCauseChangedListener#onImsCallDisconnectCauseChanged(ImsReasonInfo)
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28;
+
+    /**
+     * Event for the emergency number placed from an outgoing call.
+     *
+     * @see OutgoingEmergencyCallListener#onOutgoingEmergencyCall
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+    public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29;
+
+    /**
+     * Event for the emergency number placed from an outgoing SMS.
+     *
+     * @see OutgoingEmergencySmsListener#onOutgoingEmergencySms
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+    public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30;
+
+    /**
+     * Event for registration failures.
+     *
+     * Event for indications that a registration procedure has failed in either the CS or PS
+     * domain. This indication does not necessarily indicate a change of service state, which should
+     * be tracked via {@link #EVENT_SERVICE_STATE_CHANGED}.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
+     * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless
+     * of whether the calling app has carrier privileges.
+     *
+     * @see RegistrationFailedListener#onRegistrationFailed
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {
+            Manifest.permission.READ_PRECISE_PHONE_STATE,
+            Manifest.permission.ACCESS_FINE_LOCATION
+    })
+    public static final int EVENT_REGISTRATION_FAILURE = 31;
+
+    /**
+     * Event for Barring Information for the current registered / camped cell.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
+     * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless
+     * of whether the calling app has carrier privileges.
+     *
+     * @see BarringInfoChangedListener#onBarringInfoChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {
+            Manifest.permission.READ_PRECISE_PHONE_STATE,
+            Manifest.permission.ACCESS_FINE_LOCATION
+    })
+    public static final int EVENT_BARRING_INFO_CHANGED = 32;
+
+    /**
+     * Event for changes to the physical channel configuration.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @see PhysicalChannelConfigChangedListener#onPhysicalChannelConfigChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33;
+
+
+    /**
+     * Event for changes to the data enabled.
+     *
+     * Event for indications that the enabled status of current data has changed.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+     * or the calling app has carrier privileges
+     * (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @see DataEnabledChangedListener#onDataEnabledChanged
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public static final int EVENT_DATA_ENABLED_CHANGED = 34;
+
+    /** @hide */
+    @IntDef(prefix = { "EVENT_" }, value = {
+            EVENT_SERVICE_STATE_CHANGED,
+            EVENT_SIGNAL_STRENGTH_CHANGED,
+            EVENT_MESSAGE_WAITING_INDICATOR_CHANGED,
+            EVENT_CALL_FORWARDING_INDICATOR_CHANGED,
+            EVENT_CELL_LOCATION_CHANGED,
+            EVENT_CALL_STATE_CHANGED,
+            EVENT_DATA_CONNECTION_STATE_CHANGED,
+            EVENT_DATA_ACTIVITY_CHANGED,
+            EVENT_SIGNAL_STRENGTHS_CHANGED,
+            EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED,
+            EVENT_CELL_INFO_CHANGED,
+            EVENT_PRECISE_CALL_STATE_CHANGED,
+            EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED,
+            EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED,
+            EVENT_OEM_HOOK_RAW,
+            EVENT_SRVCC_STATE_CHANGED,
+            EVENT_CARRIER_NETWORK_CHANGED,
+            EVENT_VOICE_ACTIVATION_STATE_CHANGED,
+            EVENT_DATA_ACTIVATION_STATE_CHANGED,
+            EVENT_USER_MOBILE_DATA_STATE_CHANGED,
+            EVENT_DISPLAY_INFO_CHANGED,
+            EVENT_PHONE_CAPABILITY_CHANGED,
+            EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED,
+            EVENT_RADIO_POWER_STATE_CHANGED,
+            EVENT_EMERGENCY_NUMBER_LIST_CHANGED,
+            EVENT_CALL_DISCONNECT_CAUSE_CHANGED,
+            EVENT_CALL_ATTRIBUTES_CHANGED,
+            EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED,
+            EVENT_OUTGOING_EMERGENCY_CALL,
+            EVENT_OUTGOING_EMERGENCY_SMS,
+            EVENT_REGISTRATION_FAILURE,
+            EVENT_BARRING_INFO_CHANGED,
+            EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED,
+            EVENT_DATA_ENABLED_CHANGED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TelephonyEvent {}
 
     /*
      * Subscription used to listen to the phone state changes
@@ -504,9 +1072,13 @@
     /**
      * @hide
      */
+    //TODO: The maxTargetSdk should be S if the build time tool updates it.
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    @UnsupportedAppUsage
-    public final IPhoneStateListener callback;
+    @UnsupportedAppUsage(
+            maxTargetSdk = Build.VERSION_CODES.R,
+            publicAlternatives = "Use {@code TelephonyManager#registerPhoneStateListener(" +
+                    "Executor, PhoneStateListener)} instead")
+    public IPhoneStateListener callback;
 
     /**
      * Create a PhoneStateListener for the Phone with the default subscription.
@@ -563,17 +1135,742 @@
      * The Executor must not be null.
      *
      * @param executor a non-null Executor that will execute callbacks for the PhoneStateListener.
+     * @deprecated Use
+     * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)} instead.
      */
+    @Deprecated
     public PhoneStateListener(@NonNull Executor executor) {
         this(null, executor);
     }
 
-    private PhoneStateListener(Integer subId, Executor e) {
-        if (e == null) {
+    private @NonNull Executor mExecutor;
+
+    /**
+     * @hide
+     */
+    public void setExecutor(@NonNull @CallbackExecutor Executor executor) {
+        if (executor == null) {
             throw new IllegalArgumentException("PhoneStateListener Executor must be non-null");
         }
+        mExecutor = executor;
+    }
+
+    private PhoneStateListener(Integer subId, Executor executor) {
+        setExecutor(executor);
         mSubId = subId;
-        callback = new IPhoneStateListenerStub(this, e);
+        callback = new IPhoneStateListenerStub(this, mExecutor);
+    }
+
+    /**
+     * Interface for service state listener.
+     */
+    public interface ServiceStateChangedListener {
+        /**
+         * Callback invoked when device service state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * The instance of {@link ServiceState} passed as an argument here will have various
+         * levels of location information stripped from it depending on the location permissions
+         * that your app holds.
+         * Only apps holding the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission will
+         * receive all the information in {@link ServiceState}.
+         *
+         * @see ServiceState#STATE_EMERGENCY_ONLY
+         * @see ServiceState#STATE_IN_SERVICE
+         * @see ServiceState#STATE_OUT_OF_SERVICE
+         * @see ServiceState#STATE_POWER_OFF
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onServiceStateChanged(@NonNull ServiceState serviceState);
+    }
+
+    /**
+     * Interface for message waiting indicator listener.
+     */
+    public interface MessageWaitingIndicatorChangedListener {
+        /**
+         * Callback invoked when the message-waiting indicator changes on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onMessageWaitingIndicatorChanged(boolean mwi);
+    }
+
+    /**
+     * Interface for call-forwarding indicator listener.
+     */
+    public interface CallForwardingIndicatorChangedListener {
+        /**
+         * Callback invoked when the call-forwarding indicator changes on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onCallForwardingIndicatorChanged(boolean cfi);
+    }
+
+    /**
+     * Interface for device cell location listener.
+     */
+    public interface CellLocationChangedListener {
+        /**
+         * Callback invoked when device cell location changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+        public void onCellLocationChanged(@NonNull CellLocation location);
+    }
+
+    /**
+     * Interface for call state listener.
+     */
+    public interface CallStateChangedListener {
+        /**
+         * Callback invoked when device call state changes.
+         * <p>
+         * Reports the state of Telephony (mobile) calls on the device for the registered s
+         * ubscription.
+         * <p>
+         * Note: the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         * <p>
+         * Note: The state returned here may differ from that returned by
+         * {@link TelephonyManager#getCallState()}. Receivers of this callback should be aware that
+         * calling {@link TelephonyManager#getCallState()} from within this callback may return a
+         * different state than the callback reports.
+         *
+         * @param state call state
+         * @param phoneNumber call phone number. If application does not have
+         * {@link android.Manifest.permission#READ_CALL_LOG} permission or carrier
+         * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be
+         * passed as an argument.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_CALL_LOG)
+        public void onCallStateChanged(@CallState int state, @Nullable String phoneNumber);
+    }
+
+    /**
+     * Interface for data connection state listener.
+     */
+    public interface DataConnectionStateChangedListener {
+        /**
+         * Callback invoked when connection state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @see TelephonyManager#DATA_DISCONNECTED
+         * @see TelephonyManager#DATA_CONNECTING
+         * @see TelephonyManager#DATA_CONNECTED
+         * @see TelephonyManager#DATA_SUSPENDED
+         *
+         * @param state is the current state of data connection.
+         * @param networkType is the current network type of data connection.
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onDataConnectionStateChanged(@DataState int state,
+                                                 @NetworkType int networkType);
+    }
+
+    /**
+     * Interface for data activity state listener.
+     */
+    public interface DataActivityListener {
+        /**
+         * Callback invoked when data activity state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @see TelephonyManager#DATA_ACTIVITY_NONE
+         * @see TelephonyManager#DATA_ACTIVITY_IN
+         * @see TelephonyManager#DATA_ACTIVITY_OUT
+         * @see TelephonyManager#DATA_ACTIVITY_INOUT
+         * @see TelephonyManager#DATA_ACTIVITY_DORMANT
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onDataActivity(@DataActivityType int direction);
+    }
+
+    /**
+     * Interface for network signal strengths listener.
+     */
+    public interface SignalStrengthsChangedListener {
+        /**
+         * Callback invoked when network signal strengths changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength);
+    }
+
+    /**
+     * Interface for network signal strengths listener which always reported from modem.
+     */
+    public interface AlwaysReportedSignalStrengthChangedListener {
+        /**
+         * Callback always invoked from modem when network signal strengths changes on the
+         * registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
+        public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength);
+    }
+
+    /**
+     * Interface for cell info listener.
+     */
+    public interface CellInfoChangedListener {
+        /**
+         * Callback invoked when a observed cell info has changed or new cells have been added
+         * or removed on the registered subscription.
+         * Note, the registration subscription ID s from {@link TelephonyManager} object
+         * which registersPhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param cellInfo is the list of currently visible cells.
+         */
+        @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
+        public void onCellInfoChanged(@NonNull List<CellInfo> cellInfo);
+    }
+
+    /**
+     * Interface for precise device call state listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface PreciseCallStateChangedListener {
+        /**
+         * Callback invoked when precise device call state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param callState {@link PreciseCallState}
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onPreciseCallStateChanged(@NonNull PreciseCallState callState);
+    }
+
+    /**
+     * Interface for call disconnect cause listener.
+     */
+    public interface CallDisconnectCauseChangedListener {
+        /**
+         * Callback invoked when call disconnect cause changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param disconnectCause {@link DisconnectCause}.
+         * @param preciseDisconnectCause {@link PreciseDisconnectCause}.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onCallDisconnectCauseChanged(@DisconnectCauses int disconnectCause,
+                @PreciseDisconnectCauses int preciseDisconnectCause);
+    }
+
+    /**
+     * Interface for IMS call disconnect cause listener.
+     */
+    public interface ImsCallDisconnectCauseChangedListener {
+        /**
+         * Callback invoked when IMS call disconnect cause changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed.
+         *
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo);
+    }
+
+    /**
+     * Interface for precise data connection state listener.
+     */
+    public interface PreciseDataConnectionStateChangedListener {
+        /**
+         * Callback providing update about the default/internet data connection on the registered
+         * subscription.
+         *
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+         * or the calling app has carrier privileges
+         * (see {@link TelephonyManager#hasCarrierPrivileges}).
+         *
+         * @param dataConnectionState {@link PreciseDataConnectionState}
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onPreciseDataConnectionStateChanged(
+                @NonNull PreciseDataConnectionState dataConnectionState);
+    }
+
+    /**
+     * Interface for Single Radio Voice Call Continuity listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface SrvccStateChangedListener {
+        /**
+         * Callback invoked when there has been a change in the Single Radio Voice Call Continuity
+         * (SRVCC) state for the currently active call on the registered subscription.
+         *
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         */
+        @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+        public void onSrvccStateChanged(@SrvccState int srvccState);
+    }
+
+    /**
+     * Interface for SIM voice activation state listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface VoiceActivationStateChangedListener {
+        /**
+         * Callback invoked when the SIM voice activation state has changed on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param state is the current SIM voice activation state
+         */
+        @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+        public void onVoiceActivationStateChanged(@SimActivationState int state);
+
+    }
+
+    /**
+     * Interface for SIM data activation state listener.
+     */
+    public interface DataActivationStateChangedListener {
+        /**
+         * Callback invoked when the SIM data activation state has changed on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param state is the current SIM data activation state
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onDataActivationStateChanged(@SimActivationState int state);
+    }
+
+    /**
+     * Interface for user mobile data state listener.
+     */
+    public interface UserMobileDataStateChangedListener {
+        /**
+         * Callback invoked when the user mobile data state has changed on the registered
+         * subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param enabled indicates whether the current user mobile data state is enabled or
+         *                disabled.
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onUserMobileDataStateChanged(boolean enabled);
+    }
+
+    /**
+     * Interface for display info listener.
+     */
+    public interface DisplayInfoChangedListener {
+        /**
+         * Callback invoked when the display info has changed on the registered subscription.
+         * <p> The {@link TelephonyDisplayInfo} contains status information shown to the user
+         * based on carrier policy.
+         *
+         * @param telephonyDisplayInfo The display information.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo);
+    }
+
+    /**
+     * Interface for the current emergency number list listener.
+     */
+    public interface EmergencyNumberListChangedListener {
+        /**
+         * Callback invoked when the current emergency number list has changed on the registered
+         * subscription.
+         *
+         * Note, the registered subscription is associated with {@link TelephonyManager} object
+         * on which
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}
+         * was called.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * given subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param emergencyNumberList Map associating all active subscriptions on the device with
+         *                            the list of emergency numbers originating from that
+         *                            subscription.
+         *                            If there are no active subscriptions, the map will contain a
+         *                            single entry with
+         *                            {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} as
+         *                            the key and a list of emergency numbers as the value. If no
+         *                            emergency number information is available, the value will be
+         *                            empty.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onEmergencyNumberListChanged(
+                @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList);
+    }
+
+    /**
+     * Interface for outgoing emergency call listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface OutgoingEmergencyCallListener {
+        /**
+         * Callback invoked when an outgoing call is placed to an emergency number.
+         *
+         * This method will be called when an emergency call is placed on any subscription
+         * (including the no-SIM case), regardless of which subscription this listener was
+         * registered on.
+         *
+         * The default implementation of this method calls
+         * {@link #onOutgoingEmergencyCall(EmergencyNumber)} for backwards compatibility purposes.
+         * Do not call {@code super(...)} from within your implementation unless you want
+         * {@link #onOutgoingEmergencyCall(EmergencyNumber)} to be called as well.
+         *
+         * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was
+         *                              placed to.
+         * @param subscriptionId The subscription ID used to place the emergency call. If the
+         *                       emergency call was placed without a valid subscription
+         *                       (e.g. when there are no SIM cards in the device), this will be
+         *                       equal to {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
+         */
+        @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+        public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber,
+                                     int subscriptionId);
+    }
+
+    /**
+     * Interface for outgoing emergency sms listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface OutgoingEmergencySmsListener {
+        /**
+         * Smsback invoked when an outgoing sms is sent to an emergency number.
+         *
+         * This method will be called when an emergency sms is sent on any subscription,
+         * regardless of which subscription this listener was registered on.
+         *
+         * The default implementation of this method calls
+         * {@link #onOutgoingEmergencySms(EmergencyNumber)} for backwards compatibility purposes. Do
+         * not call {@code super(...)} from within your implementation unless you want
+         * {@link #onOutgoingEmergencySms(EmergencyNumber)} to be called as well.
+         *
+         * @param sentEmergencyNumber The {@link EmergencyNumber} the emergency sms was sent to.
+         * @param subscriptionId The subscription ID used to send the emergency sms.
+         */
+        @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+        public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber,
+                                    int subscriptionId);
+    }
+
+    /**
+     * Interface for phone capability listener.
+     *
+     */
+    public interface PhoneCapabilityChangedListener {
+        /**
+         * Callback invoked when phone capability changes.
+         * Note, this callback triggers regardless of registered subscription.
+         *
+         * @param capability the new phone capability
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+        public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability);
+    }
+
+    /**
+     * Interface for active data subscription ID listener.
+     */
+    public interface ActiveDataSubscriptionIdChangedListener {
+        /**
+         * Callback invoked when active data subscription ID changes.
+         * Note, this callback triggers regardless of registered subscription.
+         *
+         * @param subId current subscription used to setup Cellular Internet data.
+         *              For example, it could be the current active opportunistic subscription
+         *              in use, or the subscription user selected as default data subscription in
+         *              DSDS mode.
+         */
+        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+        public void onActiveDataSubscriptionIdChanged(int subId);
+    }
+
+    /**
+     * Interface for modem radio power state listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface RadioPowerStateChangedListener {
+        /**
+         * Callback invoked when modem radio power state changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param state the modem radio power state
+         */
+        @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+        public void onRadioPowerStateChanged(@RadioPowerState int state);
+    }
+
+    /**
+     * Interface for carrier network listener.
+     */
+    public interface CarrierNetworkChangeListener {
+        /**
+         * Callback invoked when telephony has received notice from a carrier
+         * app that a network action that could result in connectivity loss
+         * has been requested by an app using
+         * {@link android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)}
+         *
+         * This is optional and is only used to allow the system to provide alternative UI while
+         * telephony is performing an action that may result in intentional, temporary network
+         * lack of connectivity.
+         *
+         * Note, this callback is pinned to the registered subscription and will be invoked when
+         * the notifying carrier app has carrier privilege rule on the registered
+         * subscription. {@link android.telephony.TelephonyManager#hasCarrierPrivileges}
+         *
+         * @param active If the carrier network change is or shortly will be active,
+         *               {@code true} indicate that showing alternative UI, {@code false} otherwise.
+         */
+        public void onCarrierNetworkChange(boolean active);
+    }
+
+    /**
+     * Interface for registration failures listener.
+     */
+    public interface RegistrationFailedListener {
+        /**
+         * Report that Registration or a Location/Routing/Tracking Area update has failed.
+         *
+         * <p>Indicate whenever a registration procedure, including a location, routing, or tracking
+         * area update fails. This includes procedures that do not necessarily result in a change of
+         * the modem's registration status. If the modem's registration status changes, that is
+         * reflected in the onNetworkStateChanged() and subsequent
+         * get{Voice/Data}RegistrationState().
+         *
+         * <p>Because registration failures are ephemeral, this callback is not sticky.
+         * Registrants will not receive the most recent past value when registering.
+         *
+         * @param cellIdentity the CellIdentity, which must include the globally unique identifier
+         *        for the cell (for example, all components of the CGI or ECGI).
+         * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the
+         *         cell that was chosen for the failed registration attempt.
+         * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure.
+         * @param causeCode the primary failure cause code of the procedure.
+         *        For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95
+         *        For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147
+         *        For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9
+         *        For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2
+         *        Integer.MAX_VALUE if this value is unused.
+         * @param additionalCauseCode the cause code of any secondary/combined procedure
+         *                            if appropriate. For UMTS, if a combined attach succeeds for
+         *                            PS only, then the GMM cause code shall be included as an
+         *                            additionalCauseCode. For LTE (ESM), cause codes are in
+         *                            TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused.
+         */
+        @RequiresPermission(allOf = {
+                Manifest.permission.READ_PRECISE_PHONE_STATE,
+                Manifest.permission.ACCESS_FINE_LOCATION
+        })
+        public void onRegistrationFailed(@NonNull CellIdentity cellIdentity,
+                                         @NonNull String chosenPlmn, @Domain int domain,
+                                         int causeCode, int additionalCauseCode);
+    }
+
+    /**
+     * Interface for call attributes listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface CallAttributesChangedListener {
+        /**
+         * Callback invoked when the call attributes changes on the registered subscription.
+         * Note, the registration subscription ID comes from {@link TelephonyManager} object
+         * which registers PhoneStateListener by
+         * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
+         * If this TelephonyManager object was created with
+         * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
+         * subscription ID. Otherwise, this callback applies to
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}.
+         *
+         * @param callAttributes the call attributes
+         */
+        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+        void onCallAttributesChanged(@NonNull CallAttributes callAttributes);
+    }
+
+    /**
+     * Interface for barring information listener.
+     */
+    public interface BarringInfoChangedListener {
+        /**
+         * Report updated barring information for the current camped/registered cell.
+         *
+         * <p>Barring info is provided for all services applicable to the current camped/registered
+         * cell, for the registered PLMN and current access class/access category.
+         *
+         * @param barringInfo for all services on the current cell.
+         * @see android.telephony.BarringInfo
+         */
+        @RequiresPermission(allOf = {
+                Manifest.permission.READ_PRECISE_PHONE_STATE,
+                Manifest.permission.ACCESS_FINE_LOCATION
+        })
+        public void onBarringInfoChanged(@NonNull BarringInfo barringInfo);
+    }
+
+    /**
+     * Interface for current physical channel configuration listener.
+     * @hide
+     */
+    @SystemApi
+    public interface PhysicalChannelConfigChangedListener {
+        /**
+         * Callback invoked when the current physical channel configuration has changed
+         *
+         * @param configs List of the current {@link PhysicalChannelConfig}s
+         */
+        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs);
+    }
+
+    /**
+     * Interface for data enabled listener.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface DataEnabledChangedListener {
+        /**
+         * Callback invoked when the data enabled changes.
+         *
+         * @param enabled {@code true} if data is enabled, otherwise disabled.
+         * @param reason Reason for data enabled/disabled.
+         *               See {@link TelephonyManager.DataEnabledReason}.
+         */
+        @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+        public void onDataEnabledChanged(boolean enabled,
+                                  @DataEnabledReason int reason);
     }
 
     /**
@@ -707,6 +2004,7 @@
      * same as above, but with the network type.  Both called.
      */
     public void onDataConnectionStateChanged(int state, int networkType) {
+        // default implementation empty
     }
 
     /**
@@ -754,6 +2052,7 @@
      * @param cellInfo is the list of currently visible cells.
      */
     public void onCellInfoChanged(List<CellInfo> cellInfo) {
+        // default implementation empty
     }
 
     /**
@@ -767,7 +2066,7 @@
      * @param callState {@link PreciseCallState}
      * @hide
      */
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
     @SystemApi
     public void onPreciseCallStateChanged(@NonNull PreciseCallState callState) {
         // default implementation empty
@@ -786,9 +2085,9 @@
      * @param preciseDisconnectCause {@link PreciseDisconnectCause}.
      *
      */
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
-    public void onCallDisconnectCauseChanged(@Annotation.DisconnectCauses int disconnectCause,
-            int preciseDisconnectCause) {
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
+    public void onCallDisconnectCauseChanged(@DisconnectCauses int disconnectCause,
+            @PreciseDisconnectCauses int preciseDisconnectCause) {
         // default implementation empty
     }
 
@@ -804,7 +2103,7 @@
      * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed.
      *
      */
-    @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
+    @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE)
     public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) {
         // default implementation empty
     }
@@ -826,7 +2125,7 @@
      *
      * @param dataConnectionState {@link PreciseDataConnectionState}
      */
-    @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE))
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void onPreciseDataConnectionStateChanged(
             @NonNull PreciseDataConnectionState dataConnectionState) {
         // default implementation empty
@@ -864,6 +2163,7 @@
      */
     @SystemApi
     public void onSrvccStateChanged(@SrvccState int srvccState) {
+        // default implementation empty
 
     }
 
@@ -882,6 +2182,7 @@
      */
     @SystemApi
     public void onVoiceActivationStateChanged(@SimActivationState int state) {
+        // default implementation empty
     }
 
     /**
@@ -898,6 +2199,7 @@
      * @hide
      */
     public void onDataActivationStateChanged(@SimActivationState int state) {
+        // default implementation empty
     }
 
     /**
@@ -925,7 +2227,7 @@
      *
      * @param telephonyDisplayInfo The display information.
      */
-    @RequiresPermission((android.Manifest.permission.READ_PHONE_STATE))
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
         // default implementation empty
     }
@@ -1036,7 +2338,8 @@
     /**
      * Callback invoked when OEM hook raw event is received on the registered subscription.
      * Note, the registration subId comes from {@link TelephonyManager} object which registers
-     * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}.
+     * PhoneStateListener by
+     * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}.
      * If this TelephonyManager object was created with
      * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the
      * subId. Otherwise, this callback applies to
@@ -1058,7 +2361,7 @@
      * @param capability the new phone capability
      * @hide
      */
-    public void onPhoneCapabilityChanged(PhoneCapability capability) {
+    public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability) {
         // default implementation empty
     }
 
@@ -1102,7 +2405,8 @@
      * subId. Otherwise, this callback applies to
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
-     * @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE}
+     * Requires permission {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
+     *
      * @param state the modem radio power state
      * @hide
      */
@@ -1178,18 +2482,6 @@
     }
 
     /**
-     * Callback invoked when the current physical channel configuration has changed
-     *
-     * @param configs List of the current {@link PhysicalChannelConfig}s
-     * @hide
-     */
-    @SystemApi
-    public void onPhysicalChannelConfigurationChanged(
-            @NonNull List<PhysicalChannelConfig> configs) {
-        // default implementation empty
-    }
-
-    /**
      * The callback methods need to be called on the handler thread where
      * this object was created.  If the binder did that for us it'd be nice.
      *
@@ -1471,18 +2763,16 @@
             Binder.withCleanCallingIdentity(
                     () -> mExecutor.execute(
                             () -> psl.onImsCallDisconnectCauseChanged(disconnectCause)));
-
         }
 
         public void onRegistrationFailed(@NonNull CellIdentity cellIdentity,
-                @NonNull String chosenPlmn, int domain,
-                int causeCode, int additionalCauseCode) {
+                @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode) {
             PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
             if (psl == null) return;
 
             Binder.withCleanCallingIdentity(
                     () -> mExecutor.execute(() -> psl.onRegistrationFailed(
-                            cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode)));
+                                cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode)));
             // default implementation empty
         }
 
@@ -1494,17 +2784,30 @@
                     () -> mExecutor.execute(() -> psl.onBarringInfoChanged(barringInfo)));
         }
 
-        public void onPhysicalChannelConfigurationChanged(List<PhysicalChannelConfig> configs) {
+        public void onPhysicalChannelConfigChanged(List<PhysicalChannelConfig> configs) {
             PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
-            if (psl == null) return;
+            PhysicalChannelConfigChangedListener listener =
+                    (PhysicalChannelConfigChangedListener) mPhoneStateListenerWeakRef.get();
+            if (listener == null) return;
 
             Binder.withCleanCallingIdentity(
-                    () -> mExecutor.execute(
-                            () -> psl.onPhysicalChannelConfigurationChanged(configs)));
+                    () -> mExecutor.execute(() -> listener.onPhysicalChannelConfigChanged(
+                            configs)));
+        }
+
+        public void onDataEnabledChanged(boolean enabled, @DataEnabledReason int reason) {
+            if ((mPhoneStateListenerWeakRef.get() instanceof DataEnabledChangedListener)) {
+                DataEnabledChangedListener listener =
+                        (DataEnabledChangedListener) mPhoneStateListenerWeakRef.get();
+                if (listener == null) return;
+
+                Binder.withCleanCallingIdentity(
+                        () -> mExecutor.execute(() -> listener.onDataEnabledChanged(
+                                enabled, reason)));
+            }
         }
     }
 
-
     private void log(String s) {
         Rlog.d(LOG_TAG, s);
     }
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 24ed29a..cc3284a 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -15,6 +15,7 @@
  */
 package android.telephony;
 
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -24,6 +25,9 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.Annotation.CallState;
@@ -37,6 +41,7 @@
 import android.telephony.Annotation.SrvccState;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
@@ -45,6 +50,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Executor;
 
 /**
@@ -206,7 +212,7 @@
     }
 
     /**
-     * To check the SDK version for {@link #listenForSubscriber}.
+     * To check the SDK version for {@link #listenWithEventList}.
      */
     @ChangeId
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P)
@@ -218,23 +224,23 @@
      * @param pkg Package name
      * @param featureId Feature ID
      * @param listener Listener providing callback
-     * @param events Events
+     * @param events List events
      * @param notifyNow Whether to notify instantly
      */
-    public void listenForSubscriber(int subId, @NonNull String pkg, @NonNull String featureId,
-            @NonNull PhoneStateListener listener, long events, boolean notifyNow) {
+    public void listenWithEventList(int subId, @NonNull String pkg, @NonNull String featureId,
+            @NonNull PhoneStateListener listener, @NonNull int[] events, boolean notifyNow) {
         try {
             // subId from PhoneStateListener is deprecated Q on forward, use the subId from
             // TelephonyManager instance. Keep using subId from PhoneStateListener for pre-Q.
             if (Compatibility.isChangeEnabled(LISTEN_CODE_CHANGE)) {
                 // Since mSubId in PhoneStateListener is deprecated from Q on forward, this is
                 // the only place to set mSubId and its for "informational" only.
-                listener.mSubId = (events == PhoneStateListener.LISTEN_NONE)
+                listener.mSubId = (events.length == 0)
                         ? SubscriptionManager.INVALID_SUBSCRIPTION_ID : subId;
             } else if (listener.mSubId != null) {
                 subId = listener.mSubId;
             }
-            sRegistry.listenForSubscriber(
+            sRegistry.listenWithEventList(
                     subId, pkg, featureId, listener.callback, events, notifyNow);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -771,13 +777,345 @@
      * @param subId the subId
      * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
      */
-    public void notifyPhysicalChannelConfigurationForSubscriber(
+    public void notifyPhysicalChannelConfigForSubscriber(
             int subId, List<PhysicalChannelConfig> configs) {
         try {
-            sRegistry.notifyPhysicalChannelConfigurationForSubscriber(subId, configs);
+            sRegistry.notifyPhysicalChannelConfigForSubscriber(subId, configs);
         } catch (RemoteException ex) {
             // system server crash
         }
     }
 
+    public @NonNull Set<Integer> getEventsFromListener(@NonNull PhoneStateListener listener) {
+
+        Set<Integer> eventList = new ArraySet<>();
+
+        if (listener instanceof PhoneStateListener.ServiceStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.MessageWaitingIndicatorChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.CallForwardingIndicatorChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.CellLocationChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.CallStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_CALL_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.DataConnectionStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.DataActivityListener) {
+            eventList.add(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.SignalStrengthsChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.AlwaysReportedSignalStrengthChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.CellInfoChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_CELL_INFO_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.PreciseCallStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.CallDisconnectCauseChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.ImsCallDisconnectCauseChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.PreciseDataConnectionStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.SrvccStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.VoiceActivationStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.DataActivationStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.UserMobileDataStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.DisplayInfoChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.EmergencyNumberListChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.OutgoingEmergencyCallListener) {
+            eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL);
+        }
+
+        if (listener instanceof PhoneStateListener.OutgoingEmergencySmsListener) {
+            eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS);
+        }
+
+        if (listener instanceof PhoneStateListener.PhoneCapabilityChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.ActiveDataSubscriptionIdChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.RadioPowerStateChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.CarrierNetworkChangeListener) {
+            eventList.add(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.RegistrationFailedListener) {
+            eventList.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE);
+        }
+
+        if (listener instanceof PhoneStateListener.CallAttributesChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.BarringInfoChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.PhysicalChannelConfigChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+        }
+
+        if (listener instanceof PhoneStateListener.DataEnabledChangedListener) {
+            eventList.add(PhoneStateListener.EVENT_DATA_ENABLED_CHANGED);
+        }
+
+        return eventList;
+    }
+
+    private @NonNull Set<Integer> getEventsFromBitmask(int eventMask) {
+
+        Set<Integer> eventList = new ArraySet<>();
+
+        if ((eventMask & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
+            eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
+            eventList.add(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
+            eventList.add(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
+            eventList.add(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_CALL_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
+            eventList.add(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
+            eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) {
+            eventList.add(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
+            eventList.add(PhoneStateListener.EVENT_CELL_INFO_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) {
+            eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) {
+            eventList.add(PhoneStateListener.EVENT_OEM_HOOK_RAW);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) {
+            eventList.add(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) {
+            eventList.add(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) {
+            eventList.add(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) != 0) {
+            eventList.add(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
+            eventList.add(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) != 0) {
+            eventList.add(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) {
+            eventList.add(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL) != 0) {
+            eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS) != 0) {
+            eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_REGISTRATION_FAILURE) != 0) {
+            eventList.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE);
+        }
+
+        if ((eventMask & PhoneStateListener.LISTEN_BARRING_INFO) != 0) {
+            eventList.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED);
+        }
+        return eventList;
+
+    }
+
+    /**
+     * Registers a listener object to receive notification of changes
+     * in specified telephony states.
+     * <p>
+     * To register a listener, pass a {@link PhoneStateListener} which implements
+     * interfaces of events. For example,
+     * FakeServiceStateChangedListener extends {@link PhoneStateListener} implements
+     * {@link PhoneStateListener.ServiceStateChangedListener}.
+     *
+     * At registration, and when a specified telephony state changes, the telephony manager invokes
+     * the appropriate callback method on the listener object and passes the current (updated)
+     * values.
+     * <p>
+     *
+     * If this TelephonyManager object has been created with
+     * {@link TelephonyManager#createForSubscriptionId}, applies to the given subId.
+     * Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}.
+     * To listen events for multiple subIds, pass a separate listener object to
+     * each TelephonyManager object created with {@link TelephonyManager#createForSubscriptionId}.
+     *
+     * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
+     * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
+     * {@link SecurityException} will be thrown otherwise.
+     *
+     * This API should be used sparingly -- large numbers of listeners will cause system
+     * instability. If a process has registered too many listeners without unregistering them, it
+     * may encounter an {@link IllegalStateException} when trying to register more listeners.
+     *
+     * @param listener The {@link PhoneStateListener} object to register.
+     */
+    public void registerPhoneStateListener(@NonNull @CallbackExecutor Executor executor, int subId,
+            String pkgName, String attributionTag, @NonNull PhoneStateListener listener,
+            boolean notifyNow) {
+        listener.setExecutor(executor);
+        registerPhoneStateListener(subId, pkgName, attributionTag, listener,
+                getEventsFromListener(listener), notifyNow);
+    }
+
+    public void registerPhoneStateListenerWithEvents(int subId, String pkgName,
+            String attributionTag, @NonNull PhoneStateListener listener, int events,
+            boolean notifyNow) {
+        registerPhoneStateListener(
+                subId, pkgName, attributionTag, listener, getEventsFromBitmask(events), notifyNow);
+    }
+
+    private void registerPhoneStateListener(int subId,
+            String pkgName, String attributionTag, @NonNull PhoneStateListener listener,
+            @NonNull Set<Integer> events, boolean notifyNow) {
+        if (listener == null) {
+            throw new IllegalStateException("telephony service is null.");
+        }
+
+        listenWithEventList(subId, pkgName, attributionTag, listener,
+                events.stream().mapToInt(i -> i).toArray(), notifyNow);
+    }
+
+    /**
+     * Unregister an existing {@link PhoneStateListener}.
+     *
+     * @param listener The {@link PhoneStateListener} object to unregister.
+     */
+    public void unregisterPhoneStateListener(int subId, String pkgName, String attributionTag,
+                                             @NonNull PhoneStateListener listener,
+                                             boolean notifyNow) {
+        listenWithEventList(subId, pkgName, attributionTag, listener, new int[0], notifyNow);
+    }
 }
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 84c209b..00ff687 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -698,7 +698,7 @@
     }
 
     private static String zeroPad(int inValue, int inMinDigits) {
-        return TextUtils.formatSimple("%0" + inMinDigits + "d", inValue);
+        return String.format(Locale.getDefault(), "%0" + inMinDigits + "d", inValue);
     }
 
     /**
diff --git a/core/java/android/timezone/OWNERS b/core/java/android/timezone/OWNERS
new file mode 100644
index 0000000..09447a9
--- /dev/null
+++ b/core/java/android/timezone/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/timezone/OWNERS
diff --git a/core/java/android/transition/OWNERS b/core/java/android/transition/OWNERS
new file mode 100644
index 0000000..eb5a581
--- /dev/null
+++ b/core/java/android/transition/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 25700
+
+romainguy@google.com
+mount@google.com
+alanv@google.com
+adamp@google.com
diff --git a/core/java/android/util/Xml.java b/core/java/android/util/Xml.java
index cc6ed2e..c8193b3 100644
--- a/core/java/android/util/Xml.java
+++ b/core/java/android/util/Xml.java
@@ -18,6 +18,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.system.ErrnoException;
+import android.system.Os;
 
 import com.android.internal.util.BinaryXmlPullParser;
 import com.android.internal.util.BinaryXmlSerializer;
@@ -35,7 +37,7 @@
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -43,6 +45,7 @@
 import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
 import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
 
 /**
  * XML utility methods.
@@ -59,6 +62,12 @@
     public static String FEATURE_RELAXED = "http://xmlpull.org/v1/doc/features.html#relaxed";
 
     /**
+     * Feature flag: when set, {@link #resolveSerializer(OutputStream)} will
+     * emit binary XML by default.
+     */
+    private static final boolean ENABLE_BINARY_DEFAULT = false;
+
+    /**
      * Parses the given xml string and fires events on the given SAX handler.
      */
     public static void parse(String xml, ContentHandler contentHandler)
@@ -119,6 +128,7 @@
      *
      * @hide
      */
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static @NonNull TypedXmlPullParser newFastPullParser() {
         return XmlUtils.makeTyped(newPullParser());
     }
@@ -151,8 +161,28 @@
      */
     public static @NonNull TypedXmlPullParser resolvePullParser(@NonNull InputStream in)
             throws IOException {
-        // TODO: add support for binary format
-        final TypedXmlPullParser xml = newFastPullParser();
+        final byte[] magic = new byte[4];
+        if (in instanceof FileInputStream) {
+            try {
+                Os.pread(((FileInputStream) in).getFD(), magic, 0, magic.length, 0);
+            } catch (ErrnoException e) {
+                throw e.rethrowAsIOException();
+            }
+        } else {
+            if (!in.markSupported()) {
+                in = new BufferedInputStream(in);
+            }
+            in.mark(4);
+            in.read(magic);
+            in.reset();
+        }
+
+        final TypedXmlPullParser xml;
+        if (Arrays.equals(magic, BinaryXmlSerializer.PROTOCOL_MAGIC_VERSION_0)) {
+            xml = newBinaryPullParser();
+        } else {
+            xml = newFastPullParser();
+        }
         try {
             xml.setInput(in, StandardCharsets.UTF_8.name());
         } catch (XmlPullParserException e) {
@@ -177,6 +207,7 @@
      *
      * @hide
      */
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static @NonNull TypedXmlSerializer newFastSerializer() {
         return XmlUtils.makeTyped(new FastXmlSerializer());
     }
@@ -209,8 +240,12 @@
      */
     public static @NonNull TypedXmlSerializer resolveSerializer(@NonNull OutputStream out)
             throws IOException {
-        // TODO: add support for binary format
-        final TypedXmlSerializer xml = newFastSerializer();
+        final TypedXmlSerializer xml;
+        if (ENABLE_BINARY_DEFAULT) {
+            xml = newBinarySerializer();
+        } else {
+            xml = newFastSerializer();
+        }
         xml.setOutput(out, StandardCharsets.UTF_8.name());
         return xml;
     }
diff --git a/core/java/android/util/proto/OWNERS b/core/java/android/util/proto/OWNERS
new file mode 100644
index 0000000..1eb6abf
--- /dev/null
+++ b/core/java/android/util/proto/OWNERS
@@ -0,0 +1,2 @@
+dplotnikov@google.com
+mwachens@google.com
diff --git a/core/java/android/uwb/AdapterStateListener.java b/core/java/android/uwb/AdapterStateListener.java
new file mode 100644
index 0000000..8875af3
--- /dev/null
+++ b/core/java/android/uwb/AdapterStateListener.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.uwb.UwbManager.AdapterStateCallback;
+import android.uwb.UwbManager.AdapterStateCallback.StateChangedReason;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * @hide
+ */
+public class AdapterStateListener extends IUwbAdapterStateCallbacks.Stub {
+    private static final String TAG = "Uwb.StateListener";
+
+    private final IUwbAdapter mAdapter;
+    private boolean mIsRegistered = false;
+
+    private final Map<AdapterStateCallback, Executor> mCallbackMap = new HashMap<>();
+
+    @StateChangedReason
+    private int mAdapterStateChangeReason = AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN;
+    private boolean mAdapterEnabledState = false;
+
+    public AdapterStateListener(@NonNull IUwbAdapter adapter) {
+        mAdapter = adapter;
+    }
+
+    /**
+     * Register an {@link AdapterStateCallback} with this {@link AdapterStateListener}
+     *
+     * @param executor an {@link Executor} to execute given callback
+     * @param callback user implementation of the {@link AdapterStateCallback}
+     */
+    public void register(@NonNull Executor executor, @NonNull AdapterStateCallback callback) {
+        synchronized (this) {
+            if (mCallbackMap.containsKey(callback)) {
+                return;
+            }
+
+            mCallbackMap.put(callback, executor);
+
+            if (!mIsRegistered) {
+                try {
+                    mAdapter.registerAdapterStateCallbacks(this);
+                    mIsRegistered = true;
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Failed to register adapter state callback");
+                    executor.execute(() -> callback.onStateChanged(false,
+                            AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN));
+                }
+            } else {
+                sendCurrentState(callback);
+            }
+        }
+    }
+
+    /**
+     * Unregister the specified {@link AdapterStateCallback}
+     *
+     * @param callback user implementation of the {@link AdapterStateCallback}
+     */
+    public void unregister(@NonNull AdapterStateCallback callback) {
+        synchronized (this) {
+            if (!mCallbackMap.containsKey(callback)) {
+                return;
+            }
+
+            mCallbackMap.remove(callback);
+
+            if (mCallbackMap.isEmpty() && mIsRegistered) {
+                try {
+                    mAdapter.unregisterAdapterStateCallbacks(this);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Failed to unregister AdapterStateCallback with service");
+                }
+                mIsRegistered = false;
+            }
+        }
+    }
+
+    private void sendCurrentState(@NonNull AdapterStateCallback callback) {
+        synchronized (this) {
+            Executor executor = mCallbackMap.get(callback);
+
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                executor.execute(() -> callback.onStateChanged(
+                        mAdapterEnabledState, mAdapterStateChangeReason));
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+    }
+
+    @Override
+    public void onAdapterStateChanged(boolean isEnabled, int reason) {
+        synchronized (this) {
+            @StateChangedReason int localReason =
+                    convertToStateChangedReason(reason);
+            mAdapterEnabledState = isEnabled;
+            mAdapterStateChangeReason = localReason;
+            for (AdapterStateCallback cb : mCallbackMap.keySet()) {
+                sendCurrentState(cb);
+            }
+        }
+    }
+
+    private static @StateChangedReason int convertToStateChangedReason(
+            @StateChangeReason int reason) {
+        switch (reason) {
+            case StateChangeReason.ALL_SESSIONS_CLOSED:
+                return AdapterStateCallback.STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED;
+
+            case StateChangeReason.SESSION_STARTED:
+                return AdapterStateCallback.STATE_CHANGED_REASON_SESSION_STARTED;
+
+            case StateChangeReason.SYSTEM_POLICY:
+                return AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY;
+
+            case StateChangeReason.SYSTEM_BOOT:
+                return AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_BOOT;
+
+            case StateChangeReason.UNKNOWN:
+            default:
+                return AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN;
+        }
+    }
+}
diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl
index d29ed34..2c8b2e4 100644
--- a/core/java/android/uwb/IUwbAdapter.aidl
+++ b/core/java/android/uwb/IUwbAdapter.aidl
@@ -98,11 +98,18 @@
   int getMaxSimultaneousSessions();
 
   /**
-   * Get the maximum number of remote devices per session
+   * Get the maximum number of remote devices per session when local device is initiator
    *
    * @return the maximum number of remote devices supported in a single session
    */
-  int getMaxRemoteDevicesPerSession();
+  int getMaxRemoteDevicesPerInitiatorSession();
+
+  /**
+   * Get the maximum number of remote devices per session when local device is responder
+   *
+   * @return the maximum number of remote devices supported in a single session
+   */
+  int getMaxRemoteDevicesPerResponderSession();
 
   /**
    * Provides the capabilities and features of the device
diff --git a/core/java/android/uwb/StateChangeReason.aidl b/core/java/android/uwb/StateChangeReason.aidl
index 46a6e2e..28eaf9f 100644
--- a/core/java/android/uwb/StateChangeReason.aidl
+++ b/core/java/android/uwb/StateChangeReason.aidl
@@ -41,5 +41,10 @@
    * The adapter state changed because of a device system change.
    */
   SYSTEM_POLICY,
+
+  /**
+   * Used to signal the first adapter state message after boot
+   */
+   SYSTEM_BOOT,
 }
 
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 6488490..ed5cf36 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -16,6 +16,7 @@
 
 package android.uwb;
 
+import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
@@ -23,10 +24,13 @@
 import android.content.Context;
 import android.os.IBinder;
 import android.os.PersistableBundle;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Executor;
@@ -45,6 +49,8 @@
     private IUwbAdapter mUwbAdapter;
     private static final String SERVICE_NAME = "uwb";
 
+    private AdapterStateListener mAdapterStateListener;
+
     /**
      * Interface for receiving UWB adapter state changes
      */
@@ -109,6 +115,7 @@
      */
     private UwbManager(IUwbAdapter adapter) {
         mUwbAdapter = adapter;
+        mAdapterStateListener = new AdapterStateListener(adapter);
     }
 
     /**
@@ -140,8 +147,9 @@
      * @param executor an {@link Executor} to execute given callback
      * @param callback user implementation of the {@link AdapterStateCallback}
      */
-    public void registerAdapterStateCallback(Executor executor, AdapterStateCallback callback) {
-        throw new UnsupportedOperationException();
+    public void registerAdapterStateCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull AdapterStateCallback callback) {
+        mAdapterStateListener.register(executor, callback);
     }
 
     /**
@@ -153,8 +161,8 @@
      *
      * @param callback user implementation of the {@link AdapterStateCallback}
      */
-    public void unregisterAdapterStateCallback(AdapterStateCallback callback) {
-        throw new UnsupportedOperationException();
+    public void unregisterAdapterStateCallback(@NonNull AdapterStateCallback callback) {
+        mAdapterStateListener.unregister(callback);
     }
 
     /**
@@ -167,7 +175,11 @@
      */
     @NonNull
     public PersistableBundle getSpecificationInfo() {
-        throw new UnsupportedOperationException();
+        try {
+            return mUwbAdapter.getSpecificationInfo();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -176,7 +188,11 @@
      * @return true if ranging is supported
      */
     public boolean isRangingSupported() {
-        throw new UnsupportedOperationException();
+        try {
+            return mUwbAdapter.isRangingSupported();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     @Retention(RetentionPolicy.SOURCE)
@@ -225,7 +241,24 @@
      */
     @AngleOfArrivalSupportType
     public int getAngleOfArrivalSupport() {
-        throw new UnsupportedOperationException();
+        try {
+            switch (mUwbAdapter.getAngleOfArrivalSupport()) {
+                case AngleOfArrivalSupport.TWO_DIMENSIONAL:
+                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D;
+
+                case AngleOfArrivalSupport.THREE_DIMENSIONAL_HEMISPHERICAL:
+                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL;
+
+                case AngleOfArrivalSupport.THREE_DIMENSIONAL_SPHERICAL:
+                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL;
+
+                case AngleOfArrivalSupport.NONE:
+                default:
+                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -239,7 +272,15 @@
      */
     @NonNull
     public List<Integer> getSupportedChannelNumbers() {
-        throw new UnsupportedOperationException();
+        List<Integer> channels = new ArrayList<>();
+        try {
+            for (int channel : mUwbAdapter.getSupportedChannels()) {
+                channels.add(channel);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return channels;
     }
 
     /**
@@ -250,7 +291,15 @@
      */
     @NonNull
     public Set<Integer> getSupportedPreambleCodeIndices() {
-        throw new UnsupportedOperationException();
+        Set<Integer> preambles = new HashSet<>();
+        try {
+            for (int preamble : mUwbAdapter.getSupportedPreambleCodes()) {
+                preambles.add(preamble);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return preambles;
     }
 
     /**
@@ -262,7 +311,11 @@
      */
     @SuppressLint("MethodNameUnits")
     public long elapsedRealtimeResolutionNanos() {
-        throw new UnsupportedOperationException();
+        try {
+            return mUwbAdapter.getTimestampResolutionNanos();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -271,7 +324,11 @@
      * @return the maximum allowed number of simultaneously open {@link RangingSession} instances.
      */
     public int getMaxSimultaneousSessions() {
-        throw new UnsupportedOperationException();
+        try {
+            return mUwbAdapter.getMaxSimultaneousSessions();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -281,7 +338,11 @@
      * @return the maximum number of remote devices per {@link RangingSession}
      */
     public int getMaxRemoteDevicesPerInitiatorSession() {
-        throw new UnsupportedOperationException();
+        try {
+            return mUwbAdapter.getMaxRemoteDevicesPerInitiatorSession();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -291,7 +352,11 @@
      * @return the maximum number of remote devices per {@link RangingSession}
      */
     public int getMaxRemoteDevicesPerResponderSession() {
-        throw new UnsupportedOperationException();
+        try {
+            return mUwbAdapter.getMaxRemoteDevicesPerResponderSession();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
diff --git a/core/java/android/view/ContentInfo.java b/core/java/android/view/ContentInfo.java
index b58937b..fcf699f 100644
--- a/core/java/android/view/ContentInfo.java
+++ b/core/java/android/view/ContentInfo.java
@@ -20,16 +20,16 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ClipData;
+import android.content.ClipDescription;
 import android.net.Uri;
 import android.os.Bundle;
-import android.util.ArrayMap;
+import android.util.Pair;
 
 import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
-import java.util.Map;
 import java.util.Objects;
 import java.util.function.Predicate;
 
@@ -208,50 +208,51 @@
     }
 
     /**
-     * Partitions the content based on the given predicate.
+     * Partitions this content based on the given predicate.
      *
-     * <p>Similar to a
-     * {@link java.util.stream.Collectors#partitioningBy(Predicate) partitioning collector},
-     * this function classifies the content and organizes it into a map, grouping the items that
-     * matched vs didn't match the predicate.
+     * <p>This function classifies the content and organizes it into a pair, grouping the items
+     * that matched vs didn't match the predicate.
      *
      * <p>Except for the {@link ClipData} items, the returned objects will contain all the same
-     * metadata as the original.
+     * metadata as this {@link ContentInfo}.
      *
      * @param itemPredicate The predicate to test each {@link ClipData.Item} to determine which
-     * partition to place it into.
-     * @return A map containing the partitioned content. The map will contain a single entry if
-     * all items were classified into the same partition (all matched or all didn't match the
-     * predicate) or two entries (if there's at least one item that matched the predicate and at
-     * least one item that didn't match the predicate).
+     *                      partition to place it into.
+     * @return A pair containing the partitioned content. The pair's first object will have the
+     * content that matched the predicate, or null if none of the items matched. The pair's
+     * second object will have the content that didn't match the predicate, or null if all of
+     * the items matched.
      */
     @NonNull
-    public Map<Boolean, ContentInfo> partition(@NonNull Predicate<ClipData.Item> itemPredicate) {
+    public Pair<ContentInfo, ContentInfo> partition(
+            @NonNull Predicate<ClipData.Item> itemPredicate) {
         if (mClip.getItemCount() == 1) {
-            Map<Boolean, ContentInfo> result = new ArrayMap<>(1);
-            result.put(itemPredicate.test(mClip.getItemAt(0)), this);
-            return result;
+            boolean matched = itemPredicate.test(mClip.getItemAt(0));
+            return Pair.create(matched ? this : null, matched ? null : this);
         }
-        ArrayList<ClipData.Item> accepted = new ArrayList<>();
-        ArrayList<ClipData.Item> remaining = new ArrayList<>();
+        ArrayList<ClipData.Item> acceptedItems = new ArrayList<>();
+        ArrayList<ClipData.Item> remainingItems = new ArrayList<>();
         for (int i = 0; i < mClip.getItemCount(); i++) {
             ClipData.Item item = mClip.getItemAt(i);
             if (itemPredicate.test(item)) {
-                accepted.add(item);
+                acceptedItems.add(item);
             } else {
-                remaining.add(item);
+                remainingItems.add(item);
             }
         }
-        Map<Boolean, ContentInfo> result = new ArrayMap<>(2);
-        if (!accepted.isEmpty()) {
-            ClipData acceptedClip = new ClipData(mClip.getDescription(), accepted);
-            result.put(true, new Builder(this).setClip(acceptedClip).build());
+        if (acceptedItems.isEmpty()) {
+            return Pair.create(null, this);
         }
-        if (!remaining.isEmpty()) {
-            ClipData remainingClip = new ClipData(mClip.getDescription(), remaining);
-            result.put(false, new Builder(this).setClip(remainingClip).build());
+        if (remainingItems.isEmpty()) {
+            return Pair.create(this, null);
         }
-        return result;
+        ContentInfo accepted = new Builder(this)
+                .setClip(new ClipData(new ClipDescription(mClip.getDescription()), acceptedItems))
+                .build();
+        ContentInfo remaining = new Builder(this)
+                .setClip(new ClipData(new ClipDescription(mClip.getDescription()), remainingItems))
+                .build();
+        return Pair.create(accepted, remaining);
     }
 
     /**
diff --git a/core/java/android/view/IPinnedStackController.aidl b/core/java/android/view/IPinnedStackController.aidl
deleted file mode 100644
index 1cf83a3..0000000
--- a/core/java/android/view/IPinnedStackController.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Copyright (c) 2016, 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.view;
-
-import android.graphics.Rect;
-
-/**
- * An interface to the PinnedStackController to update it of state changes, and to query
- * information based on the current state.
- *
- * @hide
- */
-interface IPinnedStackController {
-    /**
-     * @return what WM considers to be the current device rotation.
-     */
-    int getDisplayRotation();
-}
diff --git a/core/java/android/view/IPinnedStackListener.aidl b/core/java/android/view/IPinnedStackListener.aidl
index f49fee3..84dd8af 100644
--- a/core/java/android/view/IPinnedStackListener.aidl
+++ b/core/java/android/view/IPinnedStackListener.aidl
@@ -21,7 +21,6 @@
 import android.content.pm.ParceledListSlice;
 import android.graphics.Rect;
 import android.view.DisplayInfo;
-import android.view.IPinnedStackController;
 
 /**
  * Listener for changes to the pinned stack made by the WindowManager.
@@ -31,12 +30,6 @@
 oneway interface IPinnedStackListener {
 
     /**
-     * Called when the listener is registered and provides an interface to call back to the pinned
-     * stack controller to update the controller of the pinned stack state.
-     */
-    void onListenerRegistered(IPinnedStackController controller);
-
-    /**
      * Called when the window manager has detected a change that would cause the movement bounds
      * to be changed (ie. after configuration change, aspect ratio change, etc).
      */
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index a23b7e1..025a977 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -780,4 +780,25 @@
      *         verified.
      */
     boolean verifyImpressionToken(in ImpressionToken impressionToken);
+
+    /**
+     * Registers a listener for a {@link android.app.WindowContext} to handle configuration changes
+     * from the server side.
+     *
+     * @param clientToken the window context's token
+     * @param type Window type of the window context
+     * @param displayId The display associated with the window context
+     * @param options A bundle used to pass window-related options and choose the right DisplayArea
+     *
+     * @return {@code true} if the listener was registered successfully.
+     */
+    boolean registerWindowContextListener(IBinder clientToken, int type, int displayId,
+            in Bundle options);
+
+    /**
+     * Unregisters a listener which registered with {@link #registerWindowContextListener()}.
+     *
+     * @param clientToken the window context's token
+     */
+    void unregisterWindowContextListener(IBinder clientToken);
 }
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 8da833a..df96dc3 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -28,7 +29,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Vibrator;
+import android.os.VibratorManager;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.lang.annotation.Retention;
@@ -72,6 +75,9 @@
 
     private Vibrator mVibrator; // guarded by mMotionRanges during initialization
 
+    @GuardedBy("mMotionRanges")
+    private VibratorManager mVibratorManager;
+
     /**
      * A mask for input source classes.
      *
@@ -415,6 +421,8 @@
 
     private static final int MAX_RANGES = 1000;
 
+    private static final int VIBRATOR_ID_ALL = -1;
+
     public static final @android.annotation.NonNull Parcelable.Creator<InputDevice> CREATOR =
             new Parcelable.Creator<InputDevice>() {
         public InputDevice createFromParcel(Parcel in) {
@@ -785,7 +793,8 @@
         synchronized (mMotionRanges) {
             if (mVibrator == null) {
                 if (mHasVibrator) {
-                    mVibrator = InputManager.getInstance().getInputDeviceVibrator(mId);
+                    mVibrator = InputManager.getInstance().getInputDeviceVibrator(mId,
+                            VIBRATOR_ID_ALL);
                 } else {
                     mVibrator = NullVibrator.getInstance();
                 }
@@ -795,6 +804,24 @@
     }
 
     /**
+     * Gets the vibrator manager associated with the device.
+     * Even if the device does not have a vibrator manager, the result is never null.
+     * Use {@link VibratorManager#getVibratorIds} to determine whether any vibrator is
+     * present.
+     *
+     * @return The vibrator manager associated with the device, never null.
+     */
+    @NonNull
+    public VibratorManager getVibratorManager() {
+        synchronized (mMotionRanges) {
+            if (mVibratorManager == null) {
+                mVibratorManager = InputManager.getInstance().getInputDeviceVibratorManager(mId);
+            }
+        }
+        return mVibratorManager;
+    }
+
+    /**
      * Returns true if input device is enabled.
      * @return Whether the input device is enabled.
      */
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index c4f32c4..80437be 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1057,6 +1057,11 @@
             boolean canRun = false;
             if (show) {
                 // Show request
+                if (fromIme) {
+                    ImeTracing.getInstance().triggerClientDump(
+                            "ImeInsetsSourceConsumer#requestShow", mHost.getInputMethodManager(),
+                            null /* icProto */);
+                }
                 switch(consumer.requestShow(fromIme)) {
                     case ShowResult.SHOW_IMMEDIATELY:
                         canRun = true;
@@ -1096,8 +1101,18 @@
                         + fromIme);
                 // We don't have a control at the moment. However, we still want to update requested
                 // visibility state such that in case we get control, we can apply show animation.
+                if (fromIme) {
+                    ImeTracing.getInstance().triggerClientDump(
+                            "InsetsSourceConsumer#show", mHost.getInputMethodManager(),
+                            null /* icProto */);
+                }
                 consumer.show(fromIme);
             } else if (animationType == ANIMATION_TYPE_HIDE) {
+                if (fromIme) {
+                    ImeTracing.getInstance().triggerClientDump(
+                            "InsetsSourceConsumer#hide", mHost.getInputMethodManager(),
+                            null /* icProto */);
+                }
                 consumer.hide();
             }
         }
@@ -1217,8 +1232,8 @@
 
     private void applyLocalVisibilityOverride() {
         for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
-            final InsetsSourceConsumer controller = mSourceConsumers.valueAt(i);
-            controller.applyLocalVisibilityOverride();
+            final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
+            consumer.applyLocalVisibilityOverride();
         }
     }
 
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 537fd42..fd1c3b8 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -25,6 +25,7 @@
 import static android.view.InsetsSourceConsumerProto.PENDING_FRAME;
 import static android.view.InsetsSourceConsumerProto.PENDING_VISIBLE_FRAME;
 import static android.view.InsetsSourceConsumerProto.SOURCE_CONTROL;
+import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.getDefaultVisibility;
 import static android.view.InsetsState.toPublicType;
 
@@ -34,6 +35,7 @@
 import android.annotation.Nullable;
 import android.graphics.Rect;
 import android.util.Log;
+import android.util.imetracing.ImeTracing;
 import android.util.proto.ProtoOutputStream;
 import android.view.InsetsState.InternalInsetsType;
 import android.view.SurfaceControl.Transaction;
@@ -108,6 +110,10 @@
      */
     public void setControl(@Nullable InsetsSourceControl control,
             @InsetsType int[] showTypes, @InsetsType int[] hideTypes) {
+        if (mType == ITYPE_IME) {
+            ImeTracing.getInstance().triggerClientDump("InsetsSourceConsumer#setControl",
+                    mController.getHost().getInputMethodManager(), null /* icProto */);
+        }
         if (mSourceControl == control) {
             return;
         }
@@ -237,6 +243,12 @@
         final boolean isVisible = source != null ? source.isVisible() : getDefaultVisibility(mType);
         final boolean hasControl = mSourceControl != null;
 
+        if (mType == ITYPE_IME) {
+            ImeTracing.getInstance().triggerClientDump(
+                    "InsetsSourceConsumer#applyLocalVisibilityOverride",
+                    mController.getHost().getInputMethodManager(), null /* icProto */);
+        }
+
         // We still need to let the legacy app know the visibility change even if we don't have the
         // control. If we don't have the source, we don't change the requested visibility for making
         // the callback behavior compatible.
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index 7b60f2e..4f82b86 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -1,3 +1,14 @@
+# Bug component: 25700
+
+romainguy@google.com
+alanv@google.com
+adamp@google.com
+aurimas@google.com
+nduca@google.com
+sumir@google.com
+ogunwale@google.com
+jjaggi@google.com
+
 # Display
 per-file Display.java = michaelwr@google.com, santoscordon@google.com
 per-file DisplayInfo.java = michaelwr@google.com, santoscordon@google.com
diff --git a/core/java/android/view/OnReceiveContentListener.java b/core/java/android/view/OnReceiveContentListener.java
index b551fa8..419f964 100644
--- a/core/java/android/view/OnReceiveContentListener.java
+++ b/core/java/android/view/OnReceiveContentListener.java
@@ -35,12 +35,12 @@
  *
  *     &#64;Override
  *     public ContentInfo onReceiveContent(View view, ContentInfo payload) {
- *         Map&lt;Boolean, ContentInfo&gt; split =
+ *         Pair&lt;ContentInfo, ContentInfo&gt; split =
  *                 payload.partition(item -&gt; item.getUri() != null);
- *         ContentInfo uriItems = split.get(true);
- *         ContentInfo remainingItems = split.get(false);
- *         if (uriItems != null) {
- *             ClipData clip = uriItems.getClip();
+ *         ContentInfo uriContent = split.first;
+ *         ContentInfo remaining = split.second;
+ *         if (uriContent != null) {
+ *             ClipData clip = uriContent.getClip();
  *             for (int i = 0; i < clip.getItemCount(); i++) {
  *                 Uri uri = clip.getItemAt(i).getUri();
  *                 // ... app-specific logic to handle the URI ...
@@ -48,7 +48,7 @@
  *         }
  *         // Return anything that we didn't handle ourselves. This preserves the default platform
  *         // behavior for text and anything else for which we are not implementing custom handling.
- *         return remainingItems;
+ *         return remaining;
  *     }
  * }
  *
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a274079..2d633cb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -19,6 +19,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.InputDevice.SOURCE_CLASS_NONE;
+import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.InsetsState.SIZE;
@@ -118,6 +119,7 @@
 import android.graphics.Region;
 import android.graphics.RenderNode;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
 import android.hardware.input.InputManager;
@@ -4413,6 +4415,14 @@
                         mView.mContext.getDrawable(value.resourceId);
             }
         }
+        // Sets the focus appearance data into the accessibility focus drawable.
+        if (mAttachInfo.mAccessibilityFocusDrawable instanceof GradientDrawable) {
+            final GradientDrawable drawable =
+                    (GradientDrawable) mAttachInfo.mAccessibilityFocusDrawable;
+            drawable.setStroke(mAccessibilityManager.getAccessibilityFocusStrokeWidth(),
+                    mAccessibilityManager.getAccessibilityFocusColor());
+        }
+
         return mAttachInfo.mAccessibilityFocusDrawable;
     }
 
@@ -7931,6 +7941,10 @@
         if (mTranslator != null) {
             mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
         }
+        if (insetsState != null && insetsState.getSource(ITYPE_IME).isVisible()) {
+            ImeTracing.getInstance().triggerClientDump("ViewRootImpl#dispatchInsetsChanged",
+                    getInsetsController().getHost().getInputMethodManager(), null /* icProto */);
+        }
         mHandler.obtainMessage(MSG_INSETS_CHANGED, insetsState).sendToTarget();
     }
 
@@ -7947,6 +7961,10 @@
         if (mTranslator != null) {
             mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
         }
+        if (insetsState != null && insetsState.getSource(ITYPE_IME).isVisible()) {
+            ImeTracing.getInstance().triggerClientDump("ViewRootImpl#dispatchInsetsControlChanged",
+                    getInsetsController().getHost().getInputMethodManager(), null /* icProto */);
+        }
         SomeArgs args = SomeArgs.obtain();
         args.arg1 = insetsState;
         args.arg2 = activeControls;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 9c16378..13d9eb9 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -45,7 +45,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.RemoteException;
 import android.transition.Scene;
 import android.transition.Transition;
 import android.transition.TransitionManager;
@@ -635,7 +634,7 @@
          * Moves the activity between {@link WindowConfiguration#WINDOWING_MODE_FREEFORM} windowing
          * mode and {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN}.
          */
-        void toggleFreeformWindowingMode() throws RemoteException;
+        void toggleFreeformWindowingMode();
 
         /**
          * Puts the activity in picture-in-picture mode if the activity supports.
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index a8534fa..56dcd59 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -19,9 +19,11 @@
 import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_ENABLE_ACCESSIBILITY_VOLUME;
 
 import android.Manifest;
+import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.AccessibilityServiceInfo.FeedbackType;
 import android.accessibilityservice.AccessibilityShortcutInfo;
+import android.annotation.ColorInt;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -59,6 +61,7 @@
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent.EventType;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IntPair;
 
@@ -233,6 +236,11 @@
 
     private int mPerformingAction = 0;
 
+    /** The stroke width of the focus rectangle in pixels */
+    private int mFocusStrokeWidth;
+    /** The color of the focus rectangle */
+    private int mFocusColor;
+
     @UnsupportedAppUsage
     private final ArrayMap<AccessibilityStateChangeListener, Handler>
             mAccessibilityStateChangeListeners = new ArrayMap<>();
@@ -410,6 +418,13 @@
         public void setRelevantEventTypes(int eventTypes) {
             mRelevantEventTypes = eventTypes;
         }
+
+        @Override
+        public void setFocusAppearance(int strokeWidth, int color) {
+            synchronized (mLock) {
+                updateFocusAppearanceLocked(strokeWidth, color);
+            }
+        }
     };
 
     /**
@@ -457,6 +472,7 @@
         mHandler = new Handler(context.getMainLooper(), mCallback);
         mUserId = userId;
         synchronized (mLock) {
+            initialFocusAppearanceLocked(context.getResources());
             tryConnectToServiceLocked(service);
         }
     }
@@ -464,18 +480,26 @@
     /**
      * Create an instance.
      *
+     * @param context A {@link Context}.
      * @param handler The handler to use
      * @param service An interface to the backing service.
      * @param userId User id under which to run.
+     * @param serviceConnect {@code true} to connect the service or
+     *                       {@code false} not to connect the service.
      *
      * @hide
      */
-    public AccessibilityManager(Handler handler, IAccessibilityManager service, int userId) {
+    @VisibleForTesting
+    public AccessibilityManager(Context context, Handler handler, IAccessibilityManager service,
+            int userId, boolean serviceConnect) {
         mCallback = new MyCallback();
         mHandler = handler;
         mUserId = userId;
         synchronized (mLock) {
-            tryConnectToServiceLocked(service);
+            initialFocusAppearanceLocked(context.getResources());
+            if (serviceConnect) {
+                tryConnectToServiceLocked(service);
+            }
         }
     }
 
@@ -954,6 +978,32 @@
     }
 
     /**
+     * Gets the strokeWidth of the focus rectangle. This value can be set by
+     * {@link AccessibilityService}.
+     *
+     * @return The strokeWidth of the focus rectangle in pixels.
+     *
+     */
+    public int getAccessibilityFocusStrokeWidth() {
+        synchronized (mLock) {
+            return mFocusStrokeWidth;
+        }
+    }
+
+    /**
+     * Gets the color of the focus rectangle. This value can be set by
+     * {@link AccessibilityService}.
+     *
+     * @return The color of the focus rectangle.
+     *
+     */
+    public @ColorInt int getAccessibilityFocusColor() {
+        synchronized (mLock) {
+            return mFocusColor;
+        }
+    }
+
+    /**
      * Get the preparers that are registered for an accessibility ID
      *
      * @param id The ID of interest
@@ -1551,6 +1601,7 @@
             setStateLocked(IntPair.first(userStateAndRelevantEvents));
             mRelevantEventTypes = IntPair.second(userStateAndRelevantEvents);
             updateUiTimeout(service.getRecommendedTimeoutMillis());
+            updateFocusAppearanceLocked(service.getFocusStrokeWidth(), service.getFocusColor());
             mService = service;
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "AccessibilityManagerService is dead", re);
@@ -1635,6 +1686,40 @@
     }
 
     /**
+     * Updates the stroke width and color of the focus rectangle.
+     *
+     * @param strokeWidth The strokeWidth of the focus rectangle.
+     * @param color The color of the focus rectangle.
+     */
+    private void updateFocusAppearanceLocked(int strokeWidth, int color) {
+        if (mFocusStrokeWidth == strokeWidth && mFocusColor == color) {
+            return;
+        }
+        mFocusStrokeWidth = strokeWidth;
+        mFocusColor = color;
+    }
+
+    /**
+     * Sets the stroke width and color of the focus rectangle to default value.
+     *
+     * @param resource The resources.
+     */
+    private void initialFocusAppearanceLocked(Resources resource) {
+        try {
+            mFocusStrokeWidth = resource.getDimensionPixelSize(
+                    R.dimen.accessibility_focus_highlight_stroke_width);
+            mFocusColor = resource.getColor(R.color.accessibility_focus_highlight_color);
+        } catch (Resources.NotFoundException re) {
+            // Sets the stroke width and color to default value by hardcoded for making
+            // the Talkback can work normally.
+            mFocusStrokeWidth = (int) (4 * resource.getDisplayMetrics().density);
+            mFocusColor = 0xbf39b500;
+            Log.e(LOG_TAG, "Error while initialing the focus appearance data then setting to"
+                    + " default value by hardcoded", re);
+        }
+    }
+
+    /**
      * Determines if the accessibility button within the system navigation area is supported.
      *
      * @return {@code true} if the accessibility button is supported on this device,
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 5d3c720..c71ea53 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -92,4 +92,8 @@
     void associateEmbeddedHierarchy(IBinder host, IBinder embedded);
 
     void disassociateEmbeddedHierarchy(IBinder token);
+
+    int getFocusStrokeWidth();
+
+    int getFocusColor();
 }
diff --git a/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl b/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
index 94b9ad1..041399c 100644
--- a/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
@@ -29,4 +29,6 @@
     void notifyServicesStateChanged(long updatedUiTimeout);
 
     void setRelevantEventTypes(int eventTypes);
+
+    void setFocusAppearance(int strokeWidth, int color);
 }
diff --git a/core/java/android/view/accessibility/OWNERS b/core/java/android/view/accessibility/OWNERS
index c6f42f7..93b5a2e 100644
--- a/core/java/android/view/accessibility/OWNERS
+++ b/core/java/android/view/accessibility/OWNERS
@@ -1,4 +1,11 @@
-svetoslavganov@google.com
+# Bug component: 44214
+
+romainguy@google.com
+alanv@google.com
+adamp@google.com
+aurimas@google.com
+nduca@google.com
+sumir@google.com
+ogunwale@google.com
+jjaggi@google.com
 pweaver@google.com
-rhedjao@google.com
-qasid@google.com
diff --git a/core/java/android/view/animation/OWNERS b/core/java/android/view/animation/OWNERS
new file mode 100644
index 0000000..9b8f4d9
--- /dev/null
+++ b/core/java/android/view/animation/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 25700
+
+romainguy@google.com
+tianliu@google.com
+alanv@google.com
+adamp@google.com
diff --git a/core/java/android/view/autofill/OWNERS b/core/java/android/view/autofill/OWNERS
new file mode 100644
index 0000000..a088632
--- /dev/null
+++ b/core/java/android/view/autofill/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 351486
+
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/view/contentcapture/OWNERS b/core/java/android/view/contentcapture/OWNERS
new file mode 100644
index 0000000..6337327
--- /dev/null
+++ b/core/java/android/view/contentcapture/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 544200
+
+joannechung@google.com
+adamhe@google.com
+tymtsai@google.com
+lpeter@google.com
+augale@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 907b5b0..eaf72dc 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -598,6 +598,9 @@
          */
         @Override
         public void finishInput() {
+            ImeTracing.getInstance().triggerClientDump(
+                    "InputMethodManager.DelegateImpl#finishInput", InputMethodManager.this,
+                    null /* icProto */);
             synchronized (mH) {
                 finishInputLocked();
             }
@@ -641,6 +644,10 @@
             int startInputFlags = getStartInputFlags(focusedView, 0);
             startInputFlags |= StartInputFlags.WINDOW_GAINED_FOCUS;
 
+            ImeTracing.getInstance().triggerClientDump(
+                    "InputMethodManager.DelegateImpl#startInputAsyncOnWindowFocusGain",
+                    InputMethodManager.this, null /* icProto */);
+
             final ImeFocusController controller = getFocusController();
             if (controller == null) {
                 return;
@@ -950,6 +957,9 @@
                 case MSG_APPLY_IME_VISIBILITY: {
                     synchronized (mH) {
                         if (mImeInsetsConsumer != null) {
+                            ImeTracing.getInstance().triggerClientDump(
+                                    "ImeInsetsSourceConsumer#applyImeVisibility",
+                                    InputMethodManager.this, null /* icProto */);
                             mImeInsetsConsumer.applyImeVisibility(msg.arg1 != 0);
                         }
                     }
@@ -1860,6 +1870,9 @@
      * {@link #HIDE_NOT_ALWAYS} bit set.
      **/
     public void toggleSoftInputFromWindow(IBinder windowToken, int showFlags, int hideFlags) {
+        ImeTracing.getInstance().triggerClientDump(
+                "InputMethodManager#toggleSoftInputFromWindow", InputMethodManager.this,
+                null /* icProto */);
         synchronized (mH) {
             final View servedView = getServedViewLocked();
             if (servedView == null || servedView.getWindowToken() != windowToken) {
@@ -1887,6 +1900,9 @@
      * {@link #HIDE_NOT_ALWAYS} bit set.
      */
     public void toggleSoftInput(int showFlags, int hideFlags) {
+        ImeTracing.getInstance().triggerClientDump(
+                "InputMethodManager#toggleSoftInput", InputMethodManager.this,
+                null /* icProto */);
         if (mCurMethod != null) {
             try {
                 mCurMethod.toggleSoftInput(showFlags, hideFlags);
diff --git a/core/java/android/view/inputmethod/OWNERS b/core/java/android/view/inputmethod/OWNERS
index 244cc30..e6a04da 100644
--- a/core/java/android/view/inputmethod/OWNERS
+++ b/core/java/android/view/inputmethod/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 34867
 set noparent
 
-include ../../../../../services/core/java/com/android/server/inputmethod/OWNERS
+include /services/core/java/com/android/server/inputmethod/OWNERS
diff --git a/core/java/android/view/inspector/OWNERS b/core/java/android/view/inspector/OWNERS
index c2827cc..705f4b3 100644
--- a/core/java/android/view/inspector/OWNERS
+++ b/core/java/android/view/inspector/OWNERS
@@ -1,3 +1,6 @@
+romainguy@google.com
 alanv@google.com
+adamp@google.com
 aurimas@google.com
-emberrose@google.com
+nduca@google.com
+sumir@google.com
diff --git a/core/java/android/view/textclassifier/OWNERS b/core/java/android/view/textclassifier/OWNERS
index be4fbaa..ac80d9f 100644
--- a/core/java/android/view/textclassifier/OWNERS
+++ b/core/java/android/view/textclassifier/OWNERS
@@ -1,14 +1,8 @@
 # Bug component: 709498
 
+mns@google.com
 toki@google.com
-tonymak@google.com
-zilka@google.com
-jalt@google.com
-joannechung@google.com
+svetoslavganov@android.com
 svetoslavganov@google.com
-eugeniom@google.com
-samsellem@google.com
-adamhe@google.com
 augale@google.com
-lpeter@google.com
-tymtsai@google.com
\ No newline at end of file
+joannechung@google.com
diff --git a/core/java/android/view/textclassifier/TextSelection.java b/core/java/android/view/textclassifier/TextSelection.java
index d8a632d..5b32649 100644
--- a/core/java/android/view/textclassifier/TextSelection.java
+++ b/core/java/android/view/textclassifier/TextSelection.java
@@ -45,15 +45,19 @@
     private final int mEndIndex;
     private final EntityConfidence mEntityConfidence;
     @Nullable private final String mId;
+    @Nullable
+    private final TextClassification mTextClassification;
     private final Bundle mExtras;
 
     private TextSelection(
             int startIndex, int endIndex, Map<String, Float> entityConfidence, String id,
+            @Nullable TextClassification textClassification,
             Bundle extras) {
         mStartIndex = startIndex;
         mEndIndex = endIndex;
         mEntityConfidence = new EntityConfidence(entityConfidence);
         mId = id;
+        mTextClassification = textClassification;
         mExtras = extras;
     }
 
@@ -111,6 +115,19 @@
     }
 
     /**
+     * Returns the text classification result of the suggested selection span. Enables the text
+     * classification by calling
+     * {@link TextSelection.Request.Builder#setIncludeTextClassification(boolean)}. If the text
+     * classifier does not support it, a {@code null} is returned.
+     *
+     * @see TextSelection.Request.Builder#setIncludeTextClassification(boolean)
+     */
+    @Nullable
+    public TextClassification getTextClassification() {
+        return mTextClassification;
+    }
+
+    /**
      * Returns the extended data.
      *
      * <p><b>NOTE: </b>Do not modify this bundle.
@@ -138,6 +155,8 @@
         private final Map<String, Float> mEntityConfidence = new ArrayMap<>();
         @Nullable private String mId;
         @Nullable
+        private TextClassification mTextClassification;
+        @Nullable
         private Bundle mExtras;
 
         /**
@@ -179,6 +198,21 @@
         }
 
         /**
+         * Sets the text classification result of the suggested selection. If
+         * {@link Request#shouldIncludeTextClassification()} is {@code true}, set this value.
+         * Otherwise this value may be set to null. The intention of this method is to avoid
+         * doing expensive work if the client is not interested in such result.
+         *
+         * @return this builder
+         * @see Request#shouldIncludeTextClassification()
+         */
+        @NonNull
+        public Builder setTextClassification(@Nullable TextClassification textClassification) {
+            mTextClassification = textClassification;
+            return this;
+        }
+
+        /**
          * Sets the extended data.
          *
          * @return this builder
@@ -196,7 +230,7 @@
         public TextSelection build() {
             return new TextSelection(
                     mStartIndex, mEndIndex, mEntityConfidence, mId,
-                    mExtras == null ? Bundle.EMPTY : mExtras);
+                    mTextClassification, mExtras == null ? Bundle.EMPTY : mExtras);
         }
     }
 
@@ -210,6 +244,7 @@
         private final int mEndIndex;
         @Nullable private final LocaleList mDefaultLocales;
         private final boolean mDarkLaunchAllowed;
+        private final boolean mIncludeTextClassification;
         private final Bundle mExtras;
         @Nullable private SystemTextClassifierMetadata mSystemTcMetadata;
 
@@ -219,12 +254,14 @@
                 int endIndex,
                 LocaleList defaultLocales,
                 boolean darkLaunchAllowed,
+                boolean includeTextClassification,
                 Bundle extras) {
             mText = text;
             mStartIndex = startIndex;
             mEndIndex = endIndex;
             mDefaultLocales = defaultLocales;
             mDarkLaunchAllowed = darkLaunchAllowed;
+            mIncludeTextClassification = includeTextClassification;
             mExtras = extras;
         }
 
@@ -303,6 +340,14 @@
         }
 
         /**
+         * Returns true if the client wants the text classifier to classify the text as well and
+         * include a {@link TextClassification} object in the result.
+         */
+        public boolean shouldIncludeTextClassification() {
+            return mIncludeTextClassification;
+        }
+
+        /**
          * Returns the extended data.
          *
          * <p><b>NOTE: </b>Do not modify this bundle.
@@ -320,9 +365,9 @@
             private final CharSequence mText;
             private final int mStartIndex;
             private final int mEndIndex;
-
             @Nullable private LocaleList mDefaultLocales;
             private boolean mDarkLaunchAllowed;
+            private boolean mIncludeTextClassification;
             private Bundle mExtras;
 
             /**
@@ -372,6 +417,21 @@
             }
 
             /**
+             * @param includeTextClassification If true, suggests the TextClassifier to classify the
+             *     text in the suggested selection span and include a TextClassification object in
+             *     the result. The TextClassifier may not support this and in which case,
+             *     {@link TextSelection#getTextClassification()} returns {@code null}.
+             *
+             * @return this builder.
+             * @see TextSelection#getTextClassification()
+             */
+            @NonNull
+            public Builder setIncludeTextClassification(boolean includeTextClassification) {
+                mIncludeTextClassification = includeTextClassification;
+                return this;
+            }
+
+            /**
              * Sets the extended data.
              *
              * @return this builder
@@ -389,6 +449,7 @@
             public Request build() {
                 return new Request(new SpannedString(mText), mStartIndex, mEndIndex,
                         mDefaultLocales, mDarkLaunchAllowed,
+                        mIncludeTextClassification,
                         mExtras == null ? Bundle.EMPTY : mExtras);
             }
         }
@@ -406,6 +467,7 @@
             dest.writeParcelable(mDefaultLocales, flags);
             dest.writeBundle(mExtras);
             dest.writeParcelable(mSystemTcMetadata, flags);
+            dest.writeBoolean(mIncludeTextClassification);
         }
 
         private static Request readFromParcel(Parcel in) {
@@ -415,9 +477,10 @@
             final LocaleList defaultLocales = in.readParcelable(null);
             final Bundle extras = in.readBundle();
             final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null);
+            final boolean includeTextClassification = in.readBoolean();
 
             final Request request = new Request(text, startIndex, endIndex, defaultLocales,
-                    /* darkLaunchAllowed= */ false, extras);
+                    /* darkLaunchAllowed= */ false, includeTextClassification, extras);
             request.setSystemTextClassifierMetadata(systemTcMetadata);
             return request;
         }
@@ -448,6 +511,7 @@
         mEntityConfidence.writeToParcel(dest, flags);
         dest.writeString(mId);
         dest.writeBundle(mExtras);
+        dest.writeParcelable(mTextClassification, flags);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<TextSelection> CREATOR =
@@ -469,5 +533,6 @@
         mEntityConfidence = EntityConfidence.CREATOR.createFromParcel(in);
         mId = in.readString();
         mExtras = in.readBundle();
+        mTextClassification = in.readParcelable(TextClassification.class.getClassLoader());
     }
 }
diff --git a/core/java/android/view/textclassifier/intent/OWNERS b/core/java/android/view/textclassifier/intent/OWNERS
new file mode 100644
index 0000000..ac80d9f
--- /dev/null
+++ b/core/java/android/view/textclassifier/intent/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 709498
+
+mns@google.com
+toki@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
+augale@google.com
+joannechung@google.com
diff --git a/core/java/android/view/textclassifier/logging/OWNERS b/core/java/android/view/textclassifier/logging/OWNERS
new file mode 100644
index 0000000..ac80d9f
--- /dev/null
+++ b/core/java/android/view/textclassifier/logging/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 709498
+
+mns@google.com
+toki@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
+augale@google.com
+joannechung@google.com
diff --git a/core/java/android/view/textservice/OWNERS b/core/java/android/view/textservice/OWNERS
new file mode 100644
index 0000000..a637754
--- /dev/null
+++ b/core/java/android/view/textservice/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 34867
+
+ogunwale@google.com
+roosa@google.com
+yukawa@google.com
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index ea906c6..ce29eea 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -1409,6 +1409,11 @@
         return mFilter;
     }
 
+    @Override
+    public CharSequence getAccessibilityClassName() {
+        return AutoCompleteTextView.class.getName();
+    }
+
     private class DropDownItemClickListener implements AdapterView.OnItemClickListener {
         public void onItemClick(AdapterView parent, View v, int position, long id) {
             performCompletion(v, position, id);
diff --git a/core/java/android/widget/OWNERS b/core/java/android/widget/OWNERS
index 5c79d21..fbb975b 100644
--- a/core/java/android/widget/OWNERS
+++ b/core/java/android/widget/OWNERS
@@ -1 +1,9 @@
+# Bug component: 25700
+
+romainguy@google.com
+alanv@google.com
+adamp@google.com
+aurimas@google.com
+siyamed@google.com
+
 per-file TextView.java, EditText.java, Editor.java = siyamed@google.com, nona@google.com, clarabayarri@google.com
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index e08ccfd..6f18920 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -1124,6 +1124,7 @@
                         mTrimmedText, mRelativeStart, mRelativeEnd)
                         .setDefaultLocales(mDefaultLocales)
                         .setDarkLaunchAllowed(true)
+                        .setIncludeTextClassification(true)
                         .build();
                 selection = mTextClassifier.get().suggestSelection(request);
             } else {
@@ -1181,6 +1182,8 @@
                     // Do not show smart actions for text containing unsupported characters.
                     android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, "");
                     classification = TextClassification.EMPTY;
+                } else if (selection != null && selection.getTextClassification() != null) {
+                    classification = selection.getTextClassification();
                 } else if (mContext.getApplicationInfo().targetSdkVersion
                         >= Build.VERSION_CODES.P) {
                     final TextClassification.Request request =
diff --git a/core/java/android/window/OWNERS b/core/java/android/window/OWNERS
index d10fb31..2c61df9 100644
--- a/core/java/android/window/OWNERS
+++ b/core/java/android/window/OWNERS
@@ -1,3 +1,3 @@
 set noparent
 
-include ../../../../services/core/java/com/android/server/wm/OWNERS
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index eda168d..c4bdb5a 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -213,12 +213,12 @@
     private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() {
         @Override
         public void addStartingWindow(ActivityManager.RunningTaskInfo taskInfo, IBinder appToken) {
-            TaskOrganizer.this.addStartingWindow(taskInfo, appToken);
+            mExecutor.execute(() -> TaskOrganizer.this.addStartingWindow(taskInfo, appToken));
         }
 
         @Override
         public void removeStartingWindow(ActivityManager.RunningTaskInfo taskInfo) {
-            TaskOrganizer.this.removeStartingWindow(taskInfo);
+            mExecutor.execute(() -> TaskOrganizer.this.removeStartingWindow(taskInfo));
         }
 
         @Override
diff --git a/core/java/com/android/ims/OWNERS b/core/java/com/android/ims/OWNERS
new file mode 100644
index 0000000..640baf2
--- /dev/null
+++ b/core/java/com/android/ims/OWNERS
@@ -0,0 +1 @@
+include /telephony/OWNERS
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 6d98a59..0b047a2 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -19,6 +19,7 @@
 import com.android.internal.os.BatteryStatsImpl;
 
 import android.bluetooth.BluetoothActivityEnergyInfo;
+import android.os.BatteryUsageStats;
 import android.os.ParcelFileDescriptor;
 import android.os.WorkSource;
 import android.os.connectivity.CellularBatteryStats;
@@ -49,6 +50,9 @@
     void noteResetFlashlight();
 
     // Remaining methods are only used in Java.
+
+    BatteryUsageStats getBatteryUsageStats();
+
     @UnsupportedAppUsage
     byte[] getStatistics();
 
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 83cbe38..2dbcbb5 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1220,25 +1220,6 @@
                         if (TextUtils.isEmpty(packageName)) {
                             pm.setDefaultBrowserPackageNameAsUser(ri.activityInfo.packageName, userId);
                         }
-                    } else {
-                        // Update Domain Verification status
-                        ComponentName cn = intent.getComponent();
-                        String packageName = cn.getPackageName();
-                        String dataScheme = (data != null) ? data.getScheme() : null;
-
-                        boolean isHttpOrHttps = (dataScheme != null) &&
-                                (dataScheme.equals(IntentFilter.SCHEME_HTTP) ||
-                                        dataScheme.equals(IntentFilter.SCHEME_HTTPS));
-
-                        boolean isViewAction = (action != null) && action.equals(Intent.ACTION_VIEW);
-                        boolean hasCategoryBrowsable = (categories != null) &&
-                                categories.contains(Intent.CATEGORY_BROWSABLE);
-
-                        if (isHttpOrHttps && isViewAction && hasCategoryBrowsable) {
-                            pm.updateIntentVerificationStatusAsUser(packageName,
-                                    PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
-                                    userId);
-                        }
                     }
                 } else {
                     try {
diff --git a/core/java/com/android/internal/config/sysui/OWNERS b/core/java/com/android/internal/config/sysui/OWNERS
new file mode 100644
index 0000000..2e96c97
--- /dev/null
+++ b/core/java/com/android/internal/config/sysui/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/OWNERS
diff --git a/core/java/com/android/internal/net/OWNERS b/core/java/com/android/internal/net/OWNERS
index 050cb5c..fec56c3 100644
--- a/core/java/com/android/internal/net/OWNERS
+++ b/core/java/com/android/internal/net/OWNERS
@@ -3,7 +3,7 @@
 codewiz@google.com
 ek@google.com
 jchalard@google.com
-jsharkey@android.com
+jsharkey@google.com
 lorenzo@google.com
 reminv@google.com
 satk@google.com
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index dcd74fd..fb6eb97 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -90,6 +90,8 @@
 import android.util.SparseIntArray;
 import android.util.SparseLongArray;
 import android.util.TimeUtils;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 import android.util.Xml;
 import android.view.Display;
 
@@ -112,7 +114,6 @@
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -10830,8 +10831,7 @@
             }
             final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
             try {
-                XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(memStream, StandardCharsets.UTF_8.name());
+                TypedXmlSerializer out = Xml.resolveSerializer(memStream);
                 writeDailyItemsLocked(out);
                 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs;
                 BackgroundThread.getHandler().post(new Runnable() {
@@ -10861,15 +10861,15 @@
         }
     }
 
-    private void writeDailyItemsLocked(XmlSerializer out) throws IOException {
+    private void writeDailyItemsLocked(TypedXmlSerializer out) throws IOException {
         StringBuilder sb = new StringBuilder(64);
         out.startDocument(null, true);
         out.startTag(null, "daily-items");
         for (int i=0; i<mDailyItems.size(); i++) {
             final DailyItem dit = mDailyItems.get(i);
             out.startTag(null, "item");
-            out.attribute(null, "start", Long.toString(dit.mStartTime));
-            out.attribute(null, "end", Long.toString(dit.mEndTime));
+            out.attributeLong(null, "start", dit.mStartTime);
+            out.attributeLong(null, "end", dit.mEndTime);
             writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb);
             writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb);
             if (dit.mPackageChanges != null) {
@@ -10878,7 +10878,7 @@
                     if (pc.mUpdate) {
                         out.startTag(null, "upd");
                         out.attribute(null, "pkg", pc.mPackageName);
-                        out.attribute(null, "ver", Long.toString(pc.mVersionCode));
+                        out.attributeLong(null, "ver", pc.mVersionCode);
                         out.endTag(null, "upd");
                     } else {
                         out.startTag(null, "rem");
@@ -10893,11 +10893,11 @@
         out.endDocument();
     }
 
-    private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps,
+    private void writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps,
             StringBuilder tmpBuilder) throws IOException {
         if (steps != null) {
             out.startTag(null, tag);
-            out.attribute(null, "n", Integer.toString(steps.mNumStepDurations));
+            out.attributeInt(null, "n", steps.mNumStepDurations);
             for (int i=0; i<steps.mNumStepDurations; i++) {
                 out.startTag(null, "s");
                 tmpBuilder.setLength(0);
@@ -10919,10 +10919,9 @@
             return;
         }
         try {
-            XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(stream, StandardCharsets.UTF_8.name());
+            TypedXmlPullParser parser = Xml.resolvePullParser(stream);
             readDailyItemsLocked(parser);
-        } catch (XmlPullParserException e) {
+        } catch (IOException e) {
         } finally {
             try {
                 stream.close();
@@ -10931,7 +10930,7 @@
         }
     }
 
-    private void readDailyItemsLocked(XmlPullParser parser) {
+    private void readDailyItemsLocked(TypedXmlPullParser parser) {
         try {
             int type;
             while ((type = parser.next()) != XmlPullParser.START_TAG
@@ -10975,17 +10974,11 @@
         }
     }
 
-    void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException,
+    void readDailyItemTagLocked(TypedXmlPullParser parser) throws NumberFormatException,
             XmlPullParserException, IOException {
         DailyItem dit = new DailyItem();
-        String attr = parser.getAttributeValue(null, "start");
-        if (attr != null) {
-            dit.mStartTime = Long.parseLong(attr);
-        }
-        attr = parser.getAttributeValue(null, "end");
-        if (attr != null) {
-            dit.mEndTime = Long.parseLong(attr);
-        }
+        dit.mStartTime = parser.getAttributeLong(null, "start", 0);
+        dit.mEndTime = parser.getAttributeLong(null, "end", 0);
         int outerDepth = parser.getDepth();
         int type;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -11006,8 +10999,7 @@
                 PackageChange pc = new PackageChange();
                 pc.mUpdate = true;
                 pc.mPackageName = parser.getAttributeValue(null, "pkg");
-                String verStr = parser.getAttributeValue(null, "ver");
-                pc.mVersionCode = verStr != null ? Long.parseLong(verStr) : 0;
+                pc.mVersionCode = parser.getAttributeLong(null, "ver", 0);
                 dit.mPackageChanges.add(pc);
                 XmlUtils.skipCurrentTag(parser);
             } else if (tagName.equals("rem")) {
@@ -11028,16 +11020,15 @@
         mDailyItems.add(dit);
     }
 
-    void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge,
+    void readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge,
             String tag)
             throws NumberFormatException, XmlPullParserException, IOException {
-        final String numAttr = parser.getAttributeValue(null, "n");
-        if (numAttr == null) {
+        final int num = parser.getAttributeInt(null, "n", -1);
+        if (num == -1) {
             Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription());
             XmlUtils.skipCurrentTag(parser);
             return;
         }
-        final int num = Integer.parseInt(numAttr);
         LevelStepTracker steps = new LevelStepTracker(num);
         if (isCharge) {
             dit.mChargeSteps = steps;
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
new file mode 100644
index 0000000..62e9f98
--- /dev/null
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2020 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 com.android.internal.os;
+
+import android.content.Context;
+import android.os.BatteryConsumer;
+import android.os.BatteryStats;
+import android.os.BatteryUsageStats;
+import android.os.Bundle;
+import android.os.UidBatteryConsumer;
+import android.os.UserManager;
+
+import java.util.List;
+
+/**
+ * Uses accumulated battery stats data and PowerCalculators to produce power
+ * usage data attributed to subsystems and UIDs.
+ */
+public class BatteryUsageStatsProvider {
+    private final Context mContext;
+    private final BatteryStatsImpl mStats;
+
+    public BatteryUsageStatsProvider(Context context, BatteryStatsImpl stats) {
+        mContext = context;
+        mStats = stats;
+    }
+
+    /**
+     * Returns a snapshot of battery attribution data.
+     */
+    public BatteryUsageStats getBatteryUsageStats() {
+
+        // TODO(b/174186345): instead of BatteryStatsHelper, use PowerCalculators directly.
+        final BatteryStatsHelper batteryStatsHelper = new BatteryStatsHelper(mContext,
+                false /* collectBatteryBroadcast */);
+        batteryStatsHelper.create((Bundle) null);
+        final UserManager userManager = mContext.getSystemService(UserManager.class);
+        batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED,
+                userManager.getUserProfiles());
+
+        // TODO(b/174186358): read extra power component number from configuration
+        final int customPowerComponentCount = 0;
+        final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder()
+                .setDischargePercentage(batteryStatsHelper.getStats().getDischargeAmount(0))
+                .setConsumedPower(batteryStatsHelper.getTotalPower());
+
+        final List<BatterySipper> usageList = batteryStatsHelper.getUsageList();
+        for (int i = 0; i < usageList.size(); i++) {
+            final BatterySipper sipper = usageList.get(i);
+            if (sipper.drainType == BatterySipper.DrainType.APP) {
+                batteryUsageStatsBuilder.addUidBatteryConsumer(
+                        new UidBatteryConsumer.Builder(customPowerComponentCount, sipper.getUid())
+                                .setPackageWithHighestDrain(sipper.packageWithHighestDrain)
+                                .setConsumedPower(sipper.sumPower())
+                                .setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU,
+                                        sipper.cpuPowerMah)
+                                .build());
+            }
+        }
+        return batteryUsageStatsBuilder.build();
+    }
+}
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index f668bba..e595db3 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -184,6 +184,7 @@
 
         try {
             wlStats = mSuspendControlService.getWakeLockStats();
+            Slog.i(TAG, "Number of wakelock obtained from SystemSuspend: " + wlStats.length);
             updateWakelockStats(wlStats, staleStats);
         } catch (RemoteException e) {
             Slog.wtf(TAG, "Failed to obtain wakelock stats from ISuspendControlService", e);
diff --git a/core/java/com/android/internal/os/OWNERS b/core/java/com/android/internal/os/OWNERS
index afc9432..633d093 100644
--- a/core/java/com/android/internal/os/OWNERS
+++ b/core/java/com/android/internal/os/OWNERS
@@ -1 +1 @@
-per-file ZygoteArguments.java,ZygoteConnection.java,ZygoteInit.java,Zygote.java,ZygoteServer.java = calin@google.com, chriswailes@google.com, maco@google.com, narayan@google.com, ngeoffray@google.com
+per-file *Zygote* = file:/ZYGOTE_OWNERS
diff --git a/core/java/com/android/internal/policy/OWNERS b/core/java/com/android/internal/policy/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/core/java/com/android/internal/policy/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/core/java/com/android/internal/statusbar/OWNERS b/core/java/com/android/internal/statusbar/OWNERS
new file mode 100644
index 0000000..2e96c97
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/OWNERS
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 44dca9b..854fb17 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -69,6 +69,6 @@
     void onRegistrationFailed(in CellIdentity cellIdentity,
              String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
     void onBarringInfoChanged(in BarringInfo barringInfo);
-    void onPhysicalChannelConfigurationChanged(in List<PhysicalChannelConfig> configs);
-
+    void onPhysicalChannelConfigChanged(in List<PhysicalChannelConfig> configs);
+    void onDataEnabledChanged(boolean enabled, int reason);
 }
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index a28a663..c2cbc04 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -41,16 +41,9 @@
             IOnSubscriptionsChangedListener callback);
     void removeOnSubscriptionsChangedListener(String pkg,
             IOnSubscriptionsChangedListener callback);
-    /**
-      * @deprecated Use {@link #listenWithFeature(String, String, IPhoneStateListener, int,
-      * boolean) instead
-      */
-    @UnsupportedAppUsage
-    void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow);
-    void listenWithFeature(String pkg, String featureId, IPhoneStateListener callback, long events,
-            boolean notifyNow);
-    void listenForSubscriber(in int subId, String pkg, String featureId,
-            IPhoneStateListener callback, long events, boolean notifyNow);
+
+    void listenWithEventList(in int subId, String pkg, String featureId,
+            IPhoneStateListener callback, in int[] events, boolean notifyNow);
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     void notifyCallStateForAllSubs(int state, String incomingNumber);
     void notifyCallState(in int phoneId, in int subId, int state, String incomingNumber);
@@ -99,6 +92,6 @@
     void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity,
             String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
     void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo);
-    void notifyPhysicalChannelConfigurationForSubscriber(in int subId,
+    void notifyPhysicalChannelConfigForSubscriber(in int subId,
             in List<PhysicalChannelConfig> configs);
 }
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index e067f5f..5388235 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -208,6 +208,13 @@
     }
 
     /**
+     * Length of the given map or 0 if it's null.
+     */
+    public static int size(@Nullable Map<?, ?> map) {
+        return map == null ? 0 : map.size();
+    }
+
+    /**
      * Checks that value is present as at least one of the elements of the array.
      * @param array the array to check in
      * @param value the value to check for
diff --git a/core/java/com/android/internal/util/BinaryXmlSerializer.java b/core/java/com/android/internal/util/BinaryXmlSerializer.java
index d3fcf71..bc3b1f8 100644
--- a/core/java/com/android/internal/util/BinaryXmlSerializer.java
+++ b/core/java/com/android/internal/util/BinaryXmlSerializer.java
@@ -69,7 +69,7 @@
      * {@code ABX_}, representing "Android Binary XML." The final byte is a
      * version number which may be incremented as the protocol changes.
      */
-    static final byte[] PROTOCOL_MAGIC_VERSION_0 = new byte[] { 0x41, 0x42, 0x58, 0x00 };
+    public static final byte[] PROTOCOL_MAGIC_VERSION_0 = new byte[] { 0x41, 0x42, 0x58, 0x00 };
 
     /**
      * Internal token which represents an attribute associated with the most
diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
index 8eb0e28..244efc5 100644
--- a/core/java/com/android/internal/util/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -53,6 +53,7 @@
 public class XmlUtils {
     private static final String STRING_ARRAY_SEPARATOR = ":";
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     private static class ForcedTypedXmlSerializer extends XmlSerializerWrapper
             implements TypedXmlSerializer {
         public ForcedTypedXmlSerializer(XmlSerializer wrapped) {
@@ -133,6 +134,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     private static class ForcedTypedXmlPullParser extends XmlPullParserWrapper
             implements TypedXmlPullParser {
         public ForcedTypedXmlPullParser(XmlPullParser wrapped) {
@@ -1715,6 +1717,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static int readIntAttribute(XmlPullParser in, String name, int defaultValue) {
         if (in instanceof TypedXmlPullParser) {
             return ((TypedXmlPullParser) in).getAttributeInt(null, name, defaultValue);
@@ -1730,6 +1733,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static int readIntAttribute(XmlPullParser in, String name) throws IOException {
         if (in instanceof TypedXmlPullParser) {
             try {
@@ -1746,6 +1750,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static void writeIntAttribute(XmlSerializer out, String name, int value)
             throws IOException {
         if (out instanceof TypedXmlSerializer) {
@@ -1755,6 +1760,7 @@
         out.attribute(null, name, Integer.toString(value));
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static long readLongAttribute(XmlPullParser in, String name, long defaultValue) {
         if (in instanceof TypedXmlPullParser) {
             return ((TypedXmlPullParser) in).getAttributeLong(null, name, defaultValue);
@@ -1770,6 +1776,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static long readLongAttribute(XmlPullParser in, String name) throws IOException {
         if (in instanceof TypedXmlPullParser) {
             try {
@@ -1786,6 +1793,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static void writeLongAttribute(XmlSerializer out, String name, long value)
             throws IOException {
         if (out instanceof TypedXmlSerializer) {
@@ -1795,6 +1803,7 @@
         out.attribute(null, name, Long.toString(value));
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static float readFloatAttribute(XmlPullParser in, String name) throws IOException {
         if (in instanceof TypedXmlPullParser) {
             try {
@@ -1811,6 +1820,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static void writeFloatAttribute(XmlSerializer out, String name, float value)
             throws IOException {
         if (out instanceof TypedXmlSerializer) {
@@ -1820,10 +1830,12 @@
         out.attribute(null, name, Float.toString(value));
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static boolean readBooleanAttribute(XmlPullParser in, String name) {
         return readBooleanAttribute(in, name, false);
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static boolean readBooleanAttribute(XmlPullParser in, String name,
             boolean defaultValue) {
         if (in instanceof TypedXmlPullParser) {
@@ -1837,6 +1849,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static void writeBooleanAttribute(XmlSerializer out, String name, boolean value)
             throws IOException {
         if (out instanceof TypedXmlSerializer) {
@@ -1869,6 +1882,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static byte[] readByteArrayAttribute(XmlPullParser in, String name) {
         if (in instanceof TypedXmlPullParser) {
             try {
@@ -1885,6 +1899,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkEfficientXml")
     public static void writeByteArrayAttribute(XmlSerializer out, String name, byte[] value)
             throws IOException {
         if (value != null) {
diff --git a/core/java/com/android/internal/widget/DecorCaptionView.java b/core/java/com/android/internal/widget/DecorCaptionView.java
index 2102145..362fd7b 100644
--- a/core/java/com/android/internal/widget/DecorCaptionView.java
+++ b/core/java/com/android/internal/widget/DecorCaptionView.java
@@ -18,9 +18,7 @@
 
 import android.content.Context;
 import android.graphics.Rect;
-import android.os.RemoteException;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.GestureDetector;
 import android.view.MotionEvent;
 import android.view.View;
@@ -72,7 +70,6 @@
  */
 public class DecorCaptionView extends ViewGroup implements View.OnTouchListener,
         GestureDetector.OnGestureListener {
-    private final static String TAG = "DecorCaptionView";
     private PhoneWindow mOwner = null;
     private boolean mShow = false;
 
@@ -327,11 +324,7 @@
     private void toggleFreeformWindowingMode() {
         Window.WindowControllerCallback callback = mOwner.getWindowControllerCallback();
         if (callback != null) {
-            try {
-                callback.toggleFreeformWindowingMode();
-            } catch (RemoteException ex) {
-                Log.e(TAG, "Cannot change task workspace.");
-            }
+            callback.toggleFreeformWindowingMode();
         }
     }
 
diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index ac2361d..b4d8e50 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -35,24 +35,23 @@
 import android.util.AtomicFile;
 import android.util.EventLog;
 import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
-import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.regex.Matcher;
@@ -712,8 +711,7 @@
             HashMap<String, Long> timestamps = new HashMap<String, Long>();
             boolean success = false;
             try (final FileInputStream stream = sFile.openRead()) {
-                XmlPullParser parser = Xml.newPullParser();
-                parser.setInput(stream, StandardCharsets.UTF_8.name());
+                TypedXmlPullParser parser = Xml.resolvePullParser(stream);
 
                 int type;
                 while ((type = parser.next()) != XmlPullParser.START_TAG
@@ -735,8 +733,7 @@
                     String tagName = parser.getName();
                     if (tagName.equals("log")) {
                         final String filename = parser.getAttributeValue(null, "filename");
-                        final long timestamp = Long.valueOf(parser.getAttributeValue(
-                                    null, "timestamp"));
+                        final long timestamp = parser.getAttributeLong(null, "timestamp");
                         timestamps.put(filename, timestamp);
                     } else {
                         Slog.w(TAG, "Unknown tag: " + parser.getName());
@@ -775,8 +772,7 @@
             }
 
             try {
-                XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(stream, StandardCharsets.UTF_8.name());
+                TypedXmlSerializer out = Xml.resolveSerializer(stream);
                 out.startDocument(null, true);
                 out.startTag(null, "log-files");
 
@@ -785,7 +781,7 @@
                     String filename = itor.next();
                     out.startTag(null, "log");
                     out.attribute(null, "filename", filename);
-                    out.attribute(null, "timestamp", timestamps.get(filename).toString());
+                    out.attributeLong(null, "timestamp", timestamps.get(filename));
                     out.endTag(null, "log");
                 }
 
diff --git a/core/java/com/android/server/backup/PermissionBackupHelper.java b/core/java/com/android/server/backup/PermissionBackupHelper.java
index c7c423b..4d1949e 100644
--- a/core/java/com/android/server/backup/PermissionBackupHelper.java
+++ b/core/java/com/android/server/backup/PermissionBackupHelper.java
@@ -17,8 +17,8 @@
 package com.android.server.backup;
 
 import android.annotation.NonNull;
+import android.annotation.UserIdInt;
 import android.app.backup.BlobBackupHelper;
-import android.os.UserHandle;
 import android.permission.PermissionManagerInternal;
 import android.util.Slog;
 
@@ -34,14 +34,14 @@
     // key under which the permission-grant state blob is committed to backup
     private static final String KEY_PERMISSIONS = "permissions";
 
-    private final @NonNull UserHandle mUser;
+    private final @UserIdInt int mUserId;
 
     private final @NonNull PermissionManagerInternal mPermissionManager;
 
     public PermissionBackupHelper(int userId) {
         super(STATE_VERSION, KEY_PERMISSIONS);
 
-        mUser = UserHandle.of(userId);
+        mUserId = userId;
         mPermissionManager = LocalServices.getService(PermissionManagerInternal.class);
     }
 
@@ -53,7 +53,7 @@
         try {
             switch (key) {
                 case KEY_PERMISSIONS:
-                    return mPermissionManager.backupRuntimePermissions(mUser);
+                    return mPermissionManager.backupRuntimePermissions(mUserId);
 
                 default:
                     Slog.w(TAG, "Unexpected backup key " + key);
@@ -72,7 +72,7 @@
         try {
             switch (key) {
                 case KEY_PERMISSIONS:
-                    mPermissionManager.restoreRuntimePermissions(payload, mUser);
+                    mPermissionManager.restoreRuntimePermissions(payload, mUserId);
                     break;
 
                 default:
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 7d80993..bcd1278 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -16,5 +16,21 @@
 per-file android_view_*MotionEvent.* = michaelwr@google.com, svv@google.com
 per-file android_view_PointerIcon.* = michaelwr@google.com, svv@google.com
 
-# Zygote
-per-file com_android_internal_os_Zygote.*,fd_utils.* = calin@google.com, chriswailes@google.com, maco@google.com, narayan@google.com, ngeoffray@google.com
+per-file *Zygote* = file:/ZYGOTE_OWNERS
+per-file Android.bp = file:platform/build/soong:/OWNERS
+per-file android_animation_* = file:/core/java/android/animation/OWNERS
+per-file android_app_admin_* = file:/core/java/android/app/admin/OWNERS
+per-file android_content_res_* = file:/core/java/android/content/res/OWNERS
+per-file android_graphics_* = file:/graphics/java/android/graphics/OWNERS
+per-file android_hardware_Usb* = file:/services/usb/OWNERS
+per-file android_hardware_display_* = file:/core/java/android/hardware/display/OWNERS
+per-file android_hardware_input_* = file:/core/java/android/hardware/input/OWNERS
+per-file android_hardware_location_* = file:/core/java/android/hardware/location/OWNERS
+per-file android_media_* = file:/media/java/android/media/OWNERS
+per-file android_media_midi_* = file:/media/java/android/media/midi/OWNERS
+per-file android_opengl_* = file:/opengl/java/android/opengl/OWNERS
+per-file android_os_storage_* = file:/core/java/android/os/storage/OWNERS
+per-file android_se_* = file:/core/java/android/se/OWNERS
+per-file android_security_* = file:/core/java/android/security/OWNERS
+per-file android_view_* = file:/core/java/android/view/OWNERS
+per-file com_android_internal_net_* = file:/services/core/java/com/android/server/net/OWNERS
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 5a859aa..bf79a44 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -571,6 +571,9 @@
     MEMINFO_PAGE_TABLES,
     MEMINFO_KERNEL_STACK,
     MEMINFO_KERNEL_RECLAIMABLE,
+    MEMINFO_ACTIVE,
+    MEMINFO_INACTIVE,
+    MEMINFO_UNEVICTABLE,
     MEMINFO_COUNT
 };
 
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index d187220..9113111 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -313,7 +313,41 @@
         // The minimum amount of time between quota check alarms.
         optional int64 min_quota_check_delay_ms = 23;
 
-        // Next tag: 24
+        // The total session limit of the particular standby bucket. Apps in this standby bucket can
+        // only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+        // HPJs).
+        optional int64 hpj_limit_active_ms = 24;
+        // The total session limit of the particular standby bucket. Apps in this standby bucket can
+        // only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+        // HPJs).
+        optional int64 hpj_limit_working_ms = 25;
+        // The total session limit of the particular standby bucket. Apps in this standby bucket can
+        // only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+        // HPJs).
+        optional int64 hpj_limit_frequent_ms = 26;
+        // The total session limit of the particular standby bucket. Apps in this standby bucket can
+        // only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+        // HPJs).
+        optional int64 hpj_limit_rare_ms = 27;
+        // The total session limit of the particular standby bucket. Apps in this standby bucket can
+        // only have HPJ sessions totalling HPJ_LIMIT (without factoring in any rewards or free
+        // HPJs).
+        optional int64 hpj_limit_restricted_ms = 28;
+        // The period of time used to calculate HPJ sessions. Apps can only have HPJ sessions
+        // totalling HPJ_LIMIT_<bucket>_MS within this period of time (without factoring in any
+        // rewards or free HPJs).
+        optional int64 hpj_window_size_ms = 29;
+        // Length of time used to split an app's top time into chunks.
+        optional int64 hpj_top_app_time_chunk_size_ms = 30;
+        // How much HPJ quota to give back to an app based on the number of top app time chunks
+        // it had.
+        optional int64 hpj_reward_top_app_ms = 31;
+        // How much HPJ quota to give back to an app based on each non-top user interaction.
+        optional int64 hpj_reward_interaction_ms = 32;
+        // How much HPJ quota to give back to an app based on each notification seen event.
+        optional int64 hpj_reward_notification_seen_ms = 33;
+
+        // Next tag: 34
     }
     optional QuotaController quota_controller = 24;
 
@@ -560,6 +594,11 @@
             // The amount of time that this job has remaining in its quota. This
             // can be negative if the job is out of quota.
             optional int64 remaining_quota_ms = 6;
+            // True if the app has requested that this be a foreground job.
+            optional bool is_requested_foreground_job = 7;
+            // True if this job is within the foreground quota bounds and is therefore allowed to
+            // run as a foreground job. Valid only if is_foreground_requested_job is true.
+            optional bool is_within_fg_job_quota = 8;
         }
         repeated TrackedJob tracked_jobs = 4;
 
@@ -665,6 +704,19 @@
             repeated JobStatusShortInfoProto running_jobs = 5;
         }
 
+        message TopAppTimer {
+            option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+            optional Package pkg = 1;
+            // True if the Timer is actively tracking jobs.
+            optional bool is_active = 2;
+            // The time this timer last became active. Only valid if is_active is true.
+            optional int64 start_time_elapsed = 3;
+            // How many activities are currently in the RESUMED state. Valid only if is_active is
+            // true.
+            optional int32 activity_count = 4;
+        }
+
         message PackageStats {
             option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
@@ -677,6 +729,8 @@
             repeated ExecutionStats execution_stats = 4;
 
             reserved 5; // in_quota_alarm_listener
+
+            optional Timer fg_job_timer = 6;
         }
         repeated PackageStats package_stats = 5;
 
diff --git a/core/res/OWNERS b/core/res/OWNERS
new file mode 100644
index 0000000..263d638
--- /dev/null
+++ b/core/res/OWNERS
@@ -0,0 +1,17 @@
+adamp@google.com
+alanv@google.com
+dsandler@android.com
+dsandler@google.com
+hackbod@android.com
+hackbod@google.com
+jsharkey@android.com
+jsharkey@google.com
+michaelwr@google.com
+nandana@google.com
+narayan@google.com
+ogunwale@google.com
+patb@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
+toddke@google.com
+yamasani@google.com
diff --git a/core/res/res/drawable/view_accessibility_focused.xml b/core/res/res/drawable/view_accessibility_focused.xml
index 025916b..aa3031e 100644
--- a/core/res/res/drawable/view_accessibility_focused.xml
+++ b/core/res/res/drawable/view_accessibility_focused.xml
@@ -17,8 +17,8 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android" >
 
     <stroke
-        android:width="4dp"
-        android:color="@color/accessibility_focus_highlight" />
+        android:width="@dimen/accessibility_focus_highlight_stroke_width"
+        android:color="@color/accessibility_focus_highlight_color" />
 
     <corners android:radius="2dp" />
 
diff --git a/core/res/res/layout/notification_top_line_views.xml b/core/res/res/layout/notification_top_line_views.xml
index c71e886..60507ed 100644
--- a/core/res/res/layout/notification_top_line_views.xml
+++ b/core/res/res/layout/notification_top_line_views.xml
@@ -88,7 +88,7 @@
 
     <DateTimeView
         android:id="@+id/time"
-        android:textAppearance="@style/TextAppearance.Material.Notification.Time"
+        android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Time"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginStart="@dimen/notification_header_separating_margin"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 03e64a4..f4c3063 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3334,11 +3334,11 @@
 
         <!-- Sets whether this ViewGroup should split MotionEvents
              to separate child views during touch event dispatch.
-             If false (default), touch events will be dispatched to
+             If false (default prior to HONEYCOMB), touch events will be dispatched to
              the child view where the first pointer went down until
              the last pointer goes up.
-             If true, touch events may be dispatched to multiple children.
-             MotionEvents for each pointer will be dispatched to the child
+             If true (default for HONEYCOMB and later), touch events may be dispatched to
+             multiple children. MotionEvents for each pointer will be dispatched to the child
              view where the initial ACTION_DOWN event happened.
              See {@link android.view.ViewGroup#setMotionEventSplittingEnabled(boolean)}
              for more information. -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 0079d8c..110e77a 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -159,7 +159,7 @@
     <color name="keyguard_avatar_nick_color">#ffffffff</color>
     <color name="keyguard_avatar_frame_pressed_color">#ff35b5e5</color>
 
-    <color name="accessibility_focus_highlight">#bf39b500</color>
+    <color name="accessibility_focus_highlight_color">#bf39b500</color>
     <color name="autofilled_highlight">#4dffeb3b</color>
 
     <color name="system_notification_accent_color">#ff607D8B</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 84e6f12c..40e11cb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1613,21 +1613,28 @@
     <!-- Whether the geolocation time zone detection feature is enabled. -->
     <bool name="config_enableGeolocationTimeZoneDetection" translatable="false">true</bool>
 
-    <!-- Whether to enable primary location time zone provider overlay which allows the primary
-         location time zone provider to be replaced by an app at run-time. When disabled, only the
+    <!-- Whether the primary LocationTimeZoneProvider is enabled device.
+         Ignored if config_enableGeolocationTimeZoneDetection is false -->
+    <bool name="config_enablePrimaryLocationTimeZoneProvider" translatable="false">false</bool>
+    <!-- Used when enablePrimaryLocationTimeZoneProvider is true. Controls whether to enable primary
+         location time zone provider overlay which allows the primary location time zone provider to
+         be replaced by an app at run-time. When disabled, only the
          config_primaryLocationTimeZoneProviderPackageName package will be searched for the primary
          location time zone provider, otherwise any system package is eligible. Anyone who wants to
-         disable the overlay mechanism can set it to false. -->
+         disable the runtime overlay mechanism can set it to false. -->
     <bool name="config_enablePrimaryLocationTimeZoneOverlay" translatable="false">false</bool>
     <!-- Package name providing the primary location time zone provider. Used only when
          config_enablePrimaryLocationTimeZoneOverlay is false. -->
     <string name="config_primaryLocationTimeZoneProviderPackageName" translatable="false">@null</string>
 
-    <!-- Whether to enable secondary location time zone provider overlay which allows the secondary
-         location time zone provider to be replaced by an app at run-time. When disabled, only the
-         config_secondaryLocationTimeZoneProviderPackageName package will be searched for the
-         secondary location time zone provider, otherwise any system package is eligible. Anyone who
-         wants to disable the overlay mechanism can set it to false. -->
+    <!-- Whether the secondary LocationTimeZoneProvider is enabled device.
+         Ignored if config_enableGeolocationTimeZoneDetection is false -->
+    <bool name="config_enableSecondaryLocationTimeZoneProvider" translatable="false">true</bool>
+    <!-- Used when enableSecondaryLocationTimeZoneProvider is true. Controls whether to enable
+         secondary location time zone provider overlay which allows the primary location time zone
+         provider to config_secondaryLocationTimeZoneProviderPackageName package will be searched
+         for the secondary location time zone provider, otherwise any system package is eligible.
+         Anyone who wants to disable the runtime overlay mechanism can set it to false. -->
     <bool name="config_enableSecondaryLocationTimeZoneOverlay" translatable="false">false</bool>
     <!-- Package name providing the secondary location time zone provider. Used only when
          config_enableSecondaryLocationTimeZoneOverlay is false.
@@ -4515,7 +4522,7 @@
     <integer name="config_pdp_reject_retry_delay_ms">-1</integer>
 
     <!-- Whether or not to enable the binder heavy hitter watcher by default -->
-    <bool name="config_defaultBinderHeavyHitterWatcherEnabled">true</bool>
+    <bool name="config_defaultBinderHeavyHitterWatcherEnabled">false</bool>
 
     <!-- The default batch size for the binder heavy hitter watcher -->
     <integer name="config_defaultBinderHeavyHitterWatcherBatchSize">2000</integer>
@@ -4526,7 +4533,7 @@
     </item>
 
     <!-- Whether or not to enable the binder heavy hitter auto sampler by default -->
-    <bool name="config_defaultBinderHeavyHitterAutoSamplerEnabled">true</bool>
+    <bool name="config_defaultBinderHeavyHitterAutoSamplerEnabled">false</bool>
 
     <!-- The default batch size for the binder heavy hitter auto sampler -->
     <integer name="config_defaultBinderHeavyHitterAutoSamplerBatchSize">400</integer>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 4bcabff..05db741 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -553,6 +553,9 @@
     <!-- Width of the outline stroke used by the accessibility screen magnification indicator -->
     <dimen name="accessibility_magnification_indicator_width">4dip</dimen>
 
+    <!-- Width of the outline stroke used by the accessibility focus rectangle -->
+    <dimen name="accessibility_focus_highlight_stroke_width">4dp</dimen>
+
     <!-- Margin around the various security views -->
     <dimen name="keyguard_muliuser_selector_margin">8dp</dimen>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index cd00fbf..e50eee6 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2168,8 +2168,10 @@
   <java-symbol type="string" name="config_deviceConfiguratorPackageName" />
   <java-symbol type="array" name="config_autoTimeSourcesPriority" />
   <java-symbol type="bool" name="config_enableGeolocationTimeZoneDetection" />
+  <java-symbol type="bool" name="config_enablePrimaryLocationTimeZoneProvider" />
   <java-symbol type="bool" name="config_enablePrimaryLocationTimeZoneOverlay" />
   <java-symbol type="string" name="config_primaryLocationTimeZoneProviderPackageName" />
+  <java-symbol type="bool" name="config_enableSecondaryLocationTimeZoneProvider" />
   <java-symbol type="bool" name="config_enableSecondaryLocationTimeZoneOverlay" />
   <java-symbol type="string" name="config_secondaryLocationTimeZoneProviderPackageName" />
 
@@ -4115,4 +4117,9 @@
 
   <!-- Component with platform query permissions for AppSearch -->
   <java-symbol type="string" name="config_defaultAppSearchPlatformQuerierComponent" />
+
+  <!-- Color used by the accessibility focus rectangle -->
+  <java-symbol type="color" name="accessibility_focus_highlight_color" />
+  <!-- Width of the outline stroke used by the accessibility focus rectangle -->
+  <java-symbol type="dimen" name="accessibility_focus_highlight_stroke_width" />
 </resources>
diff --git a/core/tests/ConnectivityManagerTest/OWNERS b/core/tests/ConnectivityManagerTest/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/core/tests/ConnectivityManagerTest/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/core/tests/PackageInstallerSessions/OWNERS b/core/tests/PackageInstallerSessions/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/core/tests/PackageInstallerSessions/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/core/tests/benchmarks/src/android/net/OWNERS b/core/tests/benchmarks/src/android/net/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/core/tests/benchmarks/src/android/net/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/core/tests/bluetoothtests/OWNERS b/core/tests/bluetoothtests/OWNERS
new file mode 100644
index 0000000..98bb877
--- /dev/null
+++ b/core/tests/bluetoothtests/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/bluetooth/OWNERS
diff --git a/core/tests/coretests/apks/OWNERS b/core/tests/coretests/apks/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/core/tests/coretests/apks/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/core/tests/coretests/src/android/accessibilityservice/OWNERS b/core/tests/coretests/src/android/accessibilityservice/OWNERS
new file mode 100644
index 0000000..b74281e
--- /dev/null
+++ b/core/tests/coretests/src/android/accessibilityservice/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/accessibility/OWNERS
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/SetSchemaRequestTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/SetSchemaRequestTest.java
new file mode 100644
index 0000000..e03cea3
--- /dev/null
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/SetSchemaRequestTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2020 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.app.appsearch;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.expectThrows;
+
+import org.junit.Test;
+
+public class SetSchemaRequestTest {
+
+    @Test
+    public void testInvalidSchemaReferences() {
+        IllegalArgumentException expected =
+                expectThrows(
+                        IllegalArgumentException.class,
+                        () ->
+                                new SetSchemaRequest.Builder()
+                                        .setSchemaTypeVisibilityForSystemUi(false, "InvalidSchema")
+                                        .build());
+        assertThat(expected).hasMessageThat().contains("referenced, but were not added");
+    }
+
+    @Test
+    public void testSchemaTypeVisibilityForSystemUi_Visible() {
+        AppSearchSchema schema = new AppSearchSchema.Builder("Schema").build();
+
+        // By default, the schema is visible.
+        SetSchemaRequest request = new SetSchemaRequest.Builder().addSchema(schema).build();
+        assertThat(request.getSchemasNotPlatformSurfaceable()).isEmpty();
+
+        request =
+                new SetSchemaRequest.Builder()
+                        .addSchema(schema)
+                        .setSchemaTypeVisibilityForSystemUi(true, "Schema")
+                        .build();
+        assertThat(request.getSchemasNotPlatformSurfaceable()).isEmpty();
+    }
+
+    @Test
+    public void testSchemaTypeVisibilityForSystemUi_NotVisible() {
+        AppSearchSchema schema = new AppSearchSchema.Builder("Schema").build();
+        SetSchemaRequest request =
+                new SetSchemaRequest.Builder()
+                        .addSchema(schema)
+                        .setSchemaTypeVisibilityForSystemUi(false, "Schema")
+                        .build();
+        assertThat(request.getSchemasNotPlatformSurfaceable()).containsExactly("Schema");
+    }
+}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/cts/AppSearchSchemaCtsTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/cts/AppSearchSchemaCtsTest.java
index 2eaebd6..7072a81 100644
--- a/core/tests/coretests/src/android/app/appsearch/external/app/cts/AppSearchSchemaCtsTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/cts/AppSearchSchemaCtsTest.java
@@ -78,4 +78,125 @@
                                                 .build()));
         assertThat(e).hasMessageThat().contains("Property defined more than once: subject");
     }
+
+    @Test
+    public void testEquals_identical() {
+        AppSearchSchema schema1 =
+                new AppSearchSchema.Builder("Email")
+                        .addProperty(
+                                new PropertyConfig.Builder("subject")
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .build())
+                        .build();
+        AppSearchSchema schema2 =
+                new AppSearchSchema.Builder("Email")
+                        .addProperty(
+                                new PropertyConfig.Builder("subject")
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .build())
+                        .build();
+        assertThat(schema1).isEqualTo(schema2);
+        assertThat(schema1.hashCode()).isEqualTo(schema2.hashCode());
+    }
+
+    @Test
+    public void testEquals_differentOrder() {
+        AppSearchSchema schema1 =
+                new AppSearchSchema.Builder("Email")
+                        .addProperty(
+                                new PropertyConfig.Builder("subject")
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .build())
+                        .build();
+        AppSearchSchema schema2 =
+                new AppSearchSchema.Builder("Email")
+                        .addProperty(
+                                new PropertyConfig.Builder("subject")
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .build())
+                        .build();
+        assertThat(schema1).isEqualTo(schema2);
+        assertThat(schema1.hashCode()).isEqualTo(schema2.hashCode());
+    }
+
+    @Test
+    public void testEquals_failure() {
+        AppSearchSchema schema1 =
+                new AppSearchSchema.Builder("Email")
+                        .addProperty(
+                                new PropertyConfig.Builder("subject")
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .build())
+                        .build();
+        AppSearchSchema schema2 =
+                new AppSearchSchema.Builder("Email")
+                        .addProperty(
+                                new PropertyConfig.Builder("subject")
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .setIndexingType(
+                                                PropertyConfig
+                                                        .INDEXING_TYPE_EXACT_TERMS) // Different
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .build())
+                        .build();
+        assertThat(schema1).isNotEqualTo(schema2);
+        assertThat(schema1.hashCode()).isNotEqualTo(schema2.hashCode());
+    }
+
+    @Test
+    public void testEquals_failure_differentOrder() {
+        AppSearchSchema schema1 =
+                new AppSearchSchema.Builder("Email")
+                        .addProperty(
+                                new PropertyConfig.Builder("subject")
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .build())
+                        .addProperty(
+                                new PropertyConfig.Builder("body")
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .build())
+                        .build();
+        // Order of 'body' and 'subject' has been switched
+        AppSearchSchema schema2 =
+                new AppSearchSchema.Builder("Email")
+                        .addProperty(
+                                new PropertyConfig.Builder("body")
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .build())
+                        .addProperty(
+                                new PropertyConfig.Builder("subject")
+                                        .setDataType(PropertyConfig.DATA_TYPE_STRING)
+                                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES)
+                                        .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                        .build())
+                        .build();
+        assertThat(schema1).isNotEqualTo(schema2);
+        assertThat(schema1.hashCode()).isNotEqualTo(schema2.hashCode());
+    }
 }
diff --git a/core/tests/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java b/core/tests/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java
new file mode 100644
index 0000000..cfcfcc8
--- /dev/null
+++ b/core/tests/coretests/src/android/app/appsearch/external/util/BundleUtilTest.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2020 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.app.appsearch.util;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.os.ParcelUuid;
+import android.os.Parcelable;
+import android.util.Size;
+import android.util.SizeF;
+import android.util.SparseArray;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.UUID;
+
+public class BundleUtilTest {
+    @Test
+    public void testDeepEquals_self() {
+        Bundle one = new Bundle();
+        one.putString("a", "a");
+        assertThat(BundleUtil.deepEquals(one, one)).isTrue();
+    }
+
+    @Test
+    public void testDeepEquals_simple() {
+        Bundle one = new Bundle();
+        one.putString("a", "a");
+
+        Bundle two = new Bundle();
+        two.putString("a", "a");
+
+        assertThat(one).isNotEqualTo(two);
+        assertThat(BundleUtil.deepEquals(one, two)).isTrue();
+    }
+
+    @Test
+    public void testDeepEquals_keyMismatch() {
+        Bundle one = new Bundle();
+        one.putString("a", "a");
+
+        Bundle two = new Bundle();
+        two.putString("a", "a");
+        two.putString("b", "b");
+        assertThat(BundleUtil.deepEquals(one, two)).isFalse();
+    }
+
+    @Test
+    public void testDeepEquals_thorough_equal() {
+        Bundle[] inputs = new Bundle[2];
+        for (int i = 0; i < 2; i++) {
+            inputs[i] = createThoroughBundle();
+        }
+        assertThat(inputs[0]).isNotEqualTo(inputs[1]);
+        assertThat(BundleUtil.deepEquals(inputs[0], inputs[1])).isTrue();
+    }
+
+    @Test
+    public void testDeepEquals_thorough_notEqual() {
+        Bundle[] inputs = new Bundle[2];
+        for (int i = 0; i < 2; i++) {
+            Bundle b = createThoroughBundle();
+            // Create a difference
+            assertThat(b.containsKey("doubleArray")).isTrue();
+            b.putDoubleArray("doubleArray", new double[] {18., i});
+            inputs[i] = b;
+        }
+        assertThat(inputs[0]).isNotEqualTo(inputs[1]);
+        assertThat(BundleUtil.deepEquals(inputs[0], inputs[1])).isFalse();
+    }
+
+    @Test
+    public void testDeepEquals_nestedNotEquals() {
+        Bundle one = new Bundle();
+        one.putString("a", "a");
+        Bundle two = new Bundle();
+        two.putBundle("b", one);
+        Bundle twoClone = new Bundle();
+        twoClone.putBundle("b", one);
+        Bundle three = new Bundle();
+        three.putBundle("b", two);
+
+        ArrayList<Bundle> listOne = new ArrayList<>(ImmutableList.of(one, two, three));
+        ArrayList<Bundle> listOneClone = new ArrayList<>(ImmutableList.of(one, twoClone, three));
+        ArrayList<Bundle> listTwo = new ArrayList<>(ImmutableList.of(one, three, two));
+        Bundle b1 = new Bundle();
+        b1.putParcelableArrayList("key", listOne);
+        Bundle b1Clone = new Bundle();
+        b1Clone.putParcelableArrayList("key", listOneClone);
+        Bundle b2 = new Bundle();
+        b2.putParcelableArrayList("key", listTwo);
+
+        assertThat(b1).isNotEqualTo(b1Clone);
+        assertThat(BundleUtil.deepEquals(b1, b1Clone)).isTrue();
+        assertThat(BundleUtil.deepEquals(b1, b2)).isFalse();
+        assertThat(BundleUtil.deepEquals(b1Clone, b2)).isFalse();
+    }
+
+    @Test
+    public void testDeepEquals_sparseArray() {
+        Parcelable parcelable1 = new ParcelUuid(UUID.randomUUID());
+        Parcelable parcelable2 = new ParcelUuid(UUID.randomUUID());
+        Parcelable parcelable3 = new ParcelUuid(UUID.randomUUID());
+
+        SparseArray<Parcelable> array1 = new SparseArray<>();
+        array1.put(1, parcelable1);
+        array1.put(10, parcelable2);
+
+        SparseArray<Parcelable> array1Clone = new SparseArray<>();
+        array1Clone.put(1, parcelable1);
+        array1Clone.put(10, parcelable2);
+
+        SparseArray<Parcelable> array2 = new SparseArray<>();
+        array2.put(1, parcelable1);
+        array2.put(10, parcelable3); // Different
+
+        Bundle b1 = new Bundle();
+        b1.putSparseParcelableArray("array1", array1);
+        Bundle b1Clone = new Bundle();
+        b1Clone.putSparseParcelableArray("array1", array1Clone);
+        Bundle b2 = new Bundle();
+        b2.putSparseParcelableArray("array1", array2);
+
+        assertThat(b1).isNotEqualTo(b1Clone);
+        assertThat(BundleUtil.deepEquals(b1, b1Clone)).isTrue();
+        assertThat(BundleUtil.deepEquals(b1, b2)).isFalse();
+        assertThat(BundleUtil.deepEquals(b1Clone, b2)).isFalse();
+    }
+
+    @Test
+    public void testDeepHashCode_same() {
+        Bundle[] inputs = new Bundle[2];
+        for (int i = 0; i < 2; i++) {
+            inputs[i] = createThoroughBundle();
+        }
+        assertThat(BundleUtil.deepHashCode(inputs[0]))
+                .isEqualTo(BundleUtil.deepHashCode(inputs[1]));
+    }
+
+    @Test
+    public void testDeepHashCode_different() {
+        Bundle[] inputs = new Bundle[2];
+        for (int i = 0; i < 2; i++) {
+            Bundle b = createThoroughBundle();
+            // Create a difference
+            assertThat(b.containsKey("doubleArray")).isTrue();
+            b.putDoubleArray("doubleArray", new double[] {18., i});
+            inputs[i] = b;
+        }
+        assertThat(BundleUtil.deepHashCode(inputs[0]))
+                .isNotEqualTo(BundleUtil.deepHashCode(inputs[1]));
+    }
+
+    @Test
+    public void testHashCode_sparseArray() {
+        Parcelable parcelable1 = new ParcelUuid(UUID.randomUUID());
+        Parcelable parcelable2 = new ParcelUuid(UUID.randomUUID());
+        Parcelable parcelable3 = new ParcelUuid(UUID.randomUUID());
+
+        SparseArray<Parcelable> array1 = new SparseArray<>();
+        array1.put(1, parcelable1);
+        array1.put(10, parcelable2);
+
+        SparseArray<Parcelable> array1Clone = new SparseArray<>();
+        array1Clone.put(1, parcelable1);
+        array1Clone.put(10, parcelable2);
+
+        SparseArray<Parcelable> array2 = new SparseArray<>();
+        array2.put(1, parcelable1);
+        array2.put(10, parcelable3); // Different
+
+        Bundle b1 = new Bundle();
+        b1.putSparseParcelableArray("array1", array1);
+        Bundle b1Clone = new Bundle();
+        b1Clone.putSparseParcelableArray("array1", array1Clone);
+        Bundle b2 = new Bundle();
+        b2.putSparseParcelableArray("array1", array2);
+
+        assertThat(b1.hashCode()).isNotEqualTo(b1Clone.hashCode());
+        assertThat(BundleUtil.deepHashCode(b1)).isEqualTo(BundleUtil.deepHashCode(b1Clone));
+        assertThat(BundleUtil.deepHashCode(b1)).isNotEqualTo(BundleUtil.deepHashCode(b2));
+    }
+
+    private static Bundle createThoroughBundle() {
+        Bundle toy1 = new Bundle();
+        toy1.putString("a", "a");
+        Bundle toy2 = new Bundle();
+        toy2.putInt("b", 2);
+
+        Bundle b = new Bundle();
+        // BaseBundle stuff
+        b.putBoolean("boolean", true);
+        b.putByte("byte", (byte) 1);
+        b.putChar("char", 'a');
+        b.putShort("short", (short) 2);
+        b.putInt("int", 3);
+        b.putLong("long", 4L);
+        b.putFloat("float", 5f);
+        b.putDouble("double", 6f);
+        b.putString("string", "b");
+        b.putCharSequence("charSequence", "c");
+        b.putIntegerArrayList("integerArrayList", new ArrayList<>(ImmutableList.of(7, 8)));
+        b.putStringArrayList("stringArrayList", new ArrayList<>(ImmutableList.of("d", "e")));
+        b.putCharSequenceArrayList(
+                "charSequenceArrayList", new ArrayList<>(ImmutableList.of("f", "g")));
+        b.putSerializable("serializable", new BigDecimal(9));
+        b.putBooleanArray("booleanArray", new boolean[] {true, false, true});
+        b.putByteArray("byteArray", new byte[] {(byte) 10, (byte) 11});
+        b.putShortArray("shortArray", new short[] {(short) 12, (short) 13});
+        b.putCharArray("charArray", new char[] {'h', 'i'});
+        b.putLongArray("longArray", new long[] {14L, 15L});
+        b.putFloatArray("floatArray", new float[] {16f, 17f});
+        b.putDoubleArray("doubleArray", new double[] {18., 19.});
+        b.putStringArray("stringArray", new String[] {"j", "k"});
+        b.putCharSequenceArray("charSequenceArrayList", new CharSequence[] {"l", "m"});
+
+        // Bundle stuff
+        b.putParcelable("parcelable", toy1);
+        if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+            b.putSize("size", new Size(20, 21));
+            b.putSizeF("sizeF", new SizeF(22f, 23f));
+        }
+        b.putParcelableArray("parcelableArray", new Parcelable[] {toy1, toy2});
+        b.putParcelableArrayList(
+                "parcelableArrayList", new ArrayList<>(ImmutableList.of(toy1, toy2)));
+        SparseArray<Parcelable> sparseArray = new SparseArray<>();
+        sparseArray.put(24, toy1);
+        sparseArray.put(1025, toy2);
+        b.putSparseParcelableArray("sparceParcelableArray", sparseArray);
+        b.putBundle("bundle", toy1);
+
+        return b;
+    }
+}
diff --git a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
index 365e97d..e04d903 100644
--- a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
@@ -24,12 +24,12 @@
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.SparseArray;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
 import androidx.test.filters.LargeTest;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -308,12 +308,12 @@
 
     static class TestSerializer implements XmlSerializerAndParser<TestServiceType> {
 
-        public void writeAsXml(TestServiceType item, XmlSerializer out) throws IOException {
+        public void writeAsXml(TestServiceType item, TypedXmlSerializer out) throws IOException {
             out.attribute(null, "type", item.type);
             out.attribute(null, "value", item.value);
         }
 
-        public TestServiceType createFromXml(XmlPullParser parser)
+        public TestServiceType createFromXml(TypedXmlPullParser parser)
                 throws IOException, XmlPullParserException {
             final String type = parser.getAttributeValue(null, "type");
             final String value = parser.getAttributeValue(null, "value");
diff --git a/core/tests/coretests/src/android/database/OWNERS b/core/tests/coretests/src/android/database/OWNERS
new file mode 100644
index 0000000..bb9a2ca
--- /dev/null
+++ b/core/tests/coretests/src/android/database/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/database/OWNERS
diff --git a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
index 4370462..e750454 100644
--- a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
+++ b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
@@ -23,18 +23,16 @@
 
 import android.os.Parcel;
 import android.util.Pair;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.util.FastXmlSerializer;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -163,7 +161,7 @@
         BrightnessConfiguration config = builder.build();
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        XmlSerializer out = new FastXmlSerializer();
+        TypedXmlSerializer out = Xml.newFastSerializer();
         out.setOutput(baos, StandardCharsets.UTF_8.name());
         out.startDocument(null, true);
         config.saveToXml(out);
@@ -171,7 +169,7 @@
         baos.flush();
 
         ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray());
-        XmlPullParser parser = Xml.newPullParser();
+        TypedXmlPullParser parser = Xml.newFastPullParser();
         parser.setInput(input, StandardCharsets.UTF_8.name());
         BrightnessConfiguration loadedConfig = BrightnessConfiguration.loadFromXml(parser);
 
diff --git a/core/tests/coretests/src/android/net/OWNERS b/core/tests/coretests/src/android/net/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/core/tests/coretests/src/android/net/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/core/tests/coretests/src/android/util/BinaryXmlTest.java b/core/tests/coretests/src/android/util/BinaryXmlTest.java
index be63a0e..6fa5a23 100644
--- a/core/tests/coretests/src/android/util/BinaryXmlTest.java
+++ b/core/tests/coretests/src/android/util/BinaryXmlTest.java
@@ -20,6 +20,8 @@
 import static android.util.XmlTest.buildPersistableBundle;
 import static android.util.XmlTest.doPersistableBundleRead;
 import static android.util.XmlTest.doPersistableBundleWrite;
+import static android.util.XmlTest.doVerifyRead;
+import static android.util.XmlTest.doVerifyWrite;
 
 import static org.junit.Assert.assertEquals;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -33,6 +35,11 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 
 @RunWith(AndroidJUnit4.class)
@@ -96,4 +103,58 @@
         final PersistableBundle actual = doPersistableBundleRead(secondIn, os.toByteArray());
         assertEquals(expected.toString(), actual.toString());
     }
+
+    @Test
+    public void testResolve_File() throws Exception {
+        {
+            final File file = File.createTempFile("fast", ".xml");
+            try (OutputStream os = new FileOutputStream(file)) {
+                TypedXmlSerializer xml = Xml.newFastSerializer();
+                xml.setOutput(os, StandardCharsets.UTF_8.name());
+                doVerifyWrite(xml);
+            }
+            try (InputStream is = new FileInputStream(file)) {
+                doVerifyRead(Xml.resolvePullParser(is));
+            }
+        }
+        {
+            final File file = File.createTempFile("binary", ".xml");
+            try (OutputStream os = new FileOutputStream(file)) {
+                TypedXmlSerializer xml = Xml.newBinarySerializer();
+                xml.setOutput(os, StandardCharsets.UTF_8.name());
+                doVerifyWrite(xml);
+            }
+            try (InputStream is = new FileInputStream(file)) {
+                doVerifyRead(Xml.resolvePullParser(is));
+            }
+        }
+    }
+
+    @Test
+    public void testResolve_Memory() throws Exception {
+        {
+            final byte[] data;
+            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+                TypedXmlSerializer xml = Xml.newFastSerializer();
+                xml.setOutput(os, StandardCharsets.UTF_8.name());
+                doVerifyWrite(xml);
+                data = os.toByteArray();
+            }
+            try (InputStream is = new ByteArrayInputStream(data)) {
+                doVerifyRead(Xml.resolvePullParser(is));
+            }
+        }
+        {
+            final byte[] data;
+            try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+                TypedXmlSerializer xml = Xml.newBinarySerializer();
+                xml.setOutput(os, StandardCharsets.UTF_8.name());
+                doVerifyWrite(xml);
+                data = os.toByteArray();
+            }
+            try (InputStream is = new ByteArrayInputStream(data)) {
+                doVerifyRead(Xml.resolvePullParser(is));
+            }
+        }
+    }
 }
diff --git a/core/tests/coretests/src/android/util/XmlTest.java b/core/tests/coretests/src/android/util/XmlTest.java
index 5ae17c4..a8fc6f9 100644
--- a/core/tests/coretests/src/android/util/XmlTest.java
+++ b/core/tests/coretests/src/android/util/XmlTest.java
@@ -205,7 +205,7 @@
     private static final byte[] TEST_BYTES = new byte[] { 0, 1, 2, 3, 4, 3, 2, 1, 0 };
     private static final byte[] TEST_BYTES_EMPTY = new byte[0];
 
-    private static void doVerifyWrite(TypedXmlSerializer out) throws Exception {
+    static void doVerifyWrite(TypedXmlSerializer out) throws Exception {
         out.startDocument(StandardCharsets.UTF_8.name(), true);
         out.startTag(null, "one");
         {
@@ -244,7 +244,7 @@
         out.endDocument();
     }
 
-    private static void doVerifyRead(TypedXmlPullParser in) throws Exception {
+    static void doVerifyRead(TypedXmlPullParser in) throws Exception {
         assertEquals(START_DOCUMENT, in.getEventType());
         assertNext(in, START_TAG, "one", 1);
         {
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java
index 8e24907..75116d8 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java
@@ -38,6 +38,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.R;
 import com.android.internal.util.IntPair;
 import com.android.server.accessibility.test.MessageCapturingHandler;
 
@@ -73,12 +74,18 @@
     @Mock private IAccessibilityManager mMockService;
     private MessageCapturingHandler mHandler;
     private Instrumentation mInstrumentation;
+    private int mFocusStrokeWidthDefaultValue;
+    private int mFocusColorDefaultValue;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mHandler = new MessageCapturingHandler(null);
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mFocusStrokeWidthDefaultValue = mInstrumentation.getContext().getResources()
+                .getDimensionPixelSize(R.dimen.accessibility_focus_highlight_stroke_width);
+        mFocusColorDefaultValue = mInstrumentation.getContext().getResources().getColor(
+                R.color.accessibility_focus_highlight_color);
     }
 
     @After
@@ -94,8 +101,12 @@
         when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
                 .thenReturn(serviceReturnValue);
 
+        when(mMockService.getFocusStrokeWidth()).thenReturn(mFocusStrokeWidthDefaultValue);
+        when(mMockService.getFocusColor()).thenReturn(mFocusColorDefaultValue);
+
         AccessibilityManager manager =
-                new AccessibilityManager(mHandler, mMockService, UserHandle.USER_CURRENT);
+                new AccessibilityManager(mInstrumentation.getContext(), mHandler, mMockService,
+                        UserHandle.USER_CURRENT, true);
 
         verify(mMockService).addClient(any(IAccessibilityManagerClient.class), anyInt());
         mHandler.setCallback(manager.getCallback());
@@ -205,4 +216,16 @@
 
         verify(mMockService).setWindowMagnificationConnection(connection);
     }
+
+    @Test
+    public void testGetDefaultValueOfFocusAppearanceData() {
+        AccessibilityManager manager =
+                new AccessibilityManager(mInstrumentation.getContext(), mHandler, null,
+                        UserHandle.USER_CURRENT, false);
+
+        assertEquals(mFocusStrokeWidthDefaultValue,
+                manager.getAccessibilityFocusStrokeWidth());
+        assertEquals(mFocusColorDefaultValue,
+                manager.getAccessibilityFocusColor());
+    }
 }
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
index 75a7504..cfdb2b7 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
@@ -161,4 +161,6 @@
     public void setTouchExplorationPassthroughRegion(int displayId, Region region) {}
 
     public void setGestureDetectionPassthroughRegion(int displayId, Region region) {}
+
+    public void setFocusAppearance(int strokeWidth, int color) {}
 }
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index c17c36e..6baf305 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -68,6 +68,7 @@
 import android.view.accessibility.IAccessibilityManager;
 import android.widget.Toast;
 
+import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.R;
@@ -148,7 +149,8 @@
 
         // Use the extra level of indirection in the object to mock framework objects
         AccessibilityManager accessibilityManager =
-                new AccessibilityManager(mHandler, mAccessibilityManagerService, 0);
+                new AccessibilityManager(InstrumentationRegistry.getContext(), mHandler,
+                        mAccessibilityManagerService, 0, true);
         when(mFrameworkObjectProvider.getAccessibilityManagerInstance(mContext))
                 .thenReturn(accessibilityManager);
         when(mContext.getSystemService(Context.ACCESSIBILITY_SERVICE))
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/OWNERS b/core/tests/coretests/src/com/android/internal/accessibility/OWNERS
new file mode 100644
index 0000000..b74281e
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/accessibility/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/accessibility/OWNERS
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/OWNERS b/core/tests/coretests/src/com/android/internal/inputmethod/OWNERS
new file mode 100644
index 0000000..5deb2ce
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/inputmethod/OWNERS
diff --git a/core/tests/coretests/src/com/android/internal/policy/OWNERS b/core/tests/coretests/src/com/android/internal/policy/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/policy/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/core/tests/coretests/src/com/android/internal/power/OWNERS b/core/tests/coretests/src/com/android/internal/power/OWNERS
new file mode 100644
index 0000000..d68066b
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/power/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/power/OWNERS
diff --git a/core/tests/coretests/src/com/android/internal/statusbar/OWNERS b/core/tests/coretests/src/com/android/internal/statusbar/OWNERS
new file mode 100644
index 0000000..2e96c97
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/statusbar/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/OWNERS
diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/OWNERS b/core/tests/devicestatetests/src/android/hardware/devicestate/OWNERS
new file mode 100644
index 0000000..d9b0e2e
--- /dev/null
+++ b/core/tests/devicestatetests/src/android/hardware/devicestate/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/devicestate/OWNERS
diff --git a/core/tests/hdmitests/OWNERS b/core/tests/hdmitests/OWNERS
new file mode 100644
index 0000000..c3c47ed
--- /dev/null
+++ b/core/tests/hdmitests/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/hardware/hdmi/OWNERS
diff --git a/core/tests/hosttests/test-apps/OWNERS b/core/tests/hosttests/test-apps/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/core/tests/hosttests/test-apps/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 46695d2..a74f580 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -38,13 +38,11 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.app.Activity;
-import android.app.ActivityTaskManager;
+import android.app.ActivityClient;
 import android.app.ActivityThread;
 import android.app.ActivityThread.ActivityClientRecord;
-import android.app.IActivityTaskManager;
 import android.app.LoadedApk;
 import android.app.servertransaction.PendingTransactionActions;
 import android.content.ComponentName;
@@ -54,7 +52,6 @@
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.os.IBinder;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 import android.testing.PollingCheck;
@@ -224,18 +221,19 @@
         private MockitoSession mMockSession;
         private ActivityThread mThread;
 
-        private ClientMockSession() throws RemoteException {
+        private ClientMockSession() {
             mThread = ActivityThread.currentActivityThread();
             mMockSession = mockitoSession()
                     .strictness(Strictness.LENIENT)
-                    .spyStatic(ActivityTaskManager.class)
+                    .spyStatic(ActivityClient.class)
                     .spyStatic(WindowManagerGlobal.class)
                     .startMocking();
             doReturn(Mockito.mock(WindowManagerGlobal.class))
                     .when(WindowManagerGlobal::getInstance);
-            IActivityTaskManager mockAtm = Mockito.mock(IActivityTaskManager.class);
-            doReturn(mockAtm).when(ActivityTaskManager::getService);
-            when(mockAtm.finishActivity(any(), anyInt(), any(), anyInt())).thenReturn(true);
+            final ActivityClient mockAc = Mockito.mock(ActivityClient.class);
+            doReturn(mockAc).when(ActivityClient::getInstance);
+            doReturn(true).when(mockAc).finishActivity(any() /* token */,
+                    anyInt() /* resultCode */, any() /* resultData */, anyInt() /* finishTask */);
         }
 
         private Activity launchActivity(ActivityClientRecord r) {
diff --git a/core/tests/notificationtests/OWNERS b/core/tests/notificationtests/OWNERS
new file mode 100644
index 0000000..396fd12
--- /dev/null
+++ b/core/tests/notificationtests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/notification/OWNERS
diff --git a/core/tests/overlaytests/OWNERS b/core/tests/overlaytests/OWNERS
new file mode 100644
index 0000000..afb98d4
--- /dev/null
+++ b/core/tests/overlaytests/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/content/om/OWNERS
diff --git a/core/tests/overlaytests/remount/TEST_MAPPING b/core/tests/overlaytests/remount/TEST_MAPPING
index 54dd431..22b28b5 100644
--- a/core/tests/overlaytests/remount/TEST_MAPPING
+++ b/core/tests/overlaytests/remount/TEST_MAPPING
@@ -1,7 +1,7 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
       "name" : "OverlayRemountedTest"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/core/tests/packagemanagertests/OWNERS b/core/tests/packagemanagertests/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/core/tests/packagemanagertests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/core/tests/powertests/OWNERS b/core/tests/powertests/OWNERS
new file mode 100644
index 0000000..d68066b
--- /dev/null
+++ b/core/tests/powertests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/power/OWNERS
diff --git a/core/tests/uwbtests/Android.bp b/core/tests/uwbtests/Android.bp
index c41c346..8ee86f4 100644
--- a/core/tests/uwbtests/Android.bp
+++ b/core/tests/uwbtests/Android.bp
@@ -17,6 +17,7 @@
     static_libs: [
         "androidx.test.ext.junit",
         "androidx.test.rules",
+        "mockito-target-minus-junit4",
     ],
     libs: [
         "android.test.runner",
diff --git a/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java b/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java
new file mode 100644
index 0000000..ce67ef7
--- /dev/null
+++ b/core/tests/uwbtests/src/android/uwb/AdapterStateListenerTest.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2020 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.uwb;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+
+import android.os.RemoteException;
+import android.uwb.UwbManager.AdapterStateCallback;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Test of {@link AdapterStateListener}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AdapterStateListenerTest {
+
+    IUwbAdapter mUwbAdapter = mock(IUwbAdapter.class);
+
+    Answer mRegisterSuccessAnswer = new Answer() {
+        public Object answer(InvocationOnMock invocation) {
+            Object[] args = invocation.getArguments();
+            IUwbAdapterStateCallbacks cb = (IUwbAdapterStateCallbacks) args[0];
+            try {
+                cb.onAdapterStateChanged(false, StateChangeReason.UNKNOWN);
+            } catch (RemoteException e) {
+                // Nothing to do
+            }
+            return new Object();
+        }
+    };
+
+    Throwable mThrowRemoteException = new RemoteException("RemoteException");
+
+    private static Executor getExecutor() {
+        return new Executor() {
+            @Override
+            public void execute(Runnable command) {
+                command.run();
+            }
+        };
+    }
+
+    private static void verifyCallbackStateChangedInvoked(
+            AdapterStateCallback callback, int numTimes) {
+        verify(callback, times(numTimes)).onStateChanged(anyBoolean(), anyInt());
+    }
+
+    @Test
+    public void testRegister_RegisterUnregister() throws RemoteException {
+        doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any());
+
+        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
+        AdapterStateCallback callback1 = mock(AdapterStateCallback.class);
+        AdapterStateCallback callback2 = mock(AdapterStateCallback.class);
+
+        // Verify that the adapter state listener registered with the UWB Adapter
+        adapterStateListener.register(getExecutor(), callback1);
+        verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any());
+        verifyCallbackStateChangedInvoked(callback1, 1);
+        verifyCallbackStateChangedInvoked(callback2, 0);
+
+        // Register a second client and no new call to UWB Adapter
+        adapterStateListener.register(getExecutor(), callback2);
+        verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any());
+        verifyCallbackStateChangedInvoked(callback1, 1);
+        verifyCallbackStateChangedInvoked(callback2, 1);
+
+        // Unregister first callback
+        adapterStateListener.unregister(callback1);
+        verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any());
+        verify(mUwbAdapter, times(0)).unregisterAdapterStateCallbacks(any());
+        verifyCallbackStateChangedInvoked(callback1, 1);
+        verifyCallbackStateChangedInvoked(callback2, 1);
+
+        // Unregister second callback
+        adapterStateListener.unregister(callback2);
+        verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any());
+        verify(mUwbAdapter, times(1)).unregisterAdapterStateCallbacks(any());
+        verifyCallbackStateChangedInvoked(callback1, 1);
+        verifyCallbackStateChangedInvoked(callback2, 1);
+    }
+
+    @Test
+    public void testRegister_FirstRegisterFails() throws RemoteException {
+        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
+        AdapterStateCallback callback1 = mock(AdapterStateCallback.class);
+        AdapterStateCallback callback2 = mock(AdapterStateCallback.class);
+
+        // Throw a remote exception whenever first registering
+        doThrow(mThrowRemoteException).when(mUwbAdapter).registerAdapterStateCallbacks(any());
+
+        adapterStateListener.register(getExecutor(), callback1);
+        verify(mUwbAdapter, times(1)).registerAdapterStateCallbacks(any());
+
+        // No longer throw an exception, instead succeed
+        doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any());
+
+        // Register a different callback
+        adapterStateListener.register(getExecutor(), callback2);
+        verify(mUwbAdapter, times(2)).registerAdapterStateCallbacks(any());
+
+        // Ensure first callback was invoked again
+        verifyCallbackStateChangedInvoked(callback1, 2);
+        verifyCallbackStateChangedInvoked(callback2, 1);
+    }
+
+    @Test
+    public void testRegister_RegisterSameCallbackTwice() throws RemoteException {
+        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
+        AdapterStateCallback callback = mock(AdapterStateCallback.class);
+        doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any());
+
+        adapterStateListener.register(getExecutor(), callback);
+        verifyCallbackStateChangedInvoked(callback, 1);
+
+        adapterStateListener.register(getExecutor(), callback);
+        verifyCallbackStateChangedInvoked(callback, 1);
+
+        // Invoke a state change and ensure the callback is only called once
+        adapterStateListener.onAdapterStateChanged(false, StateChangeReason.UNKNOWN);
+        verifyCallbackStateChangedInvoked(callback, 2);
+    }
+
+    @Test
+    public void testCallback_RunViaExecutor_Success() throws RemoteException {
+        // Verify that the callbacks are invoked on the executor when successful
+        doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any());
+        runViaExecutor();
+    }
+
+    @Test
+    public void testCallback_RunViaExecutor_Failure() throws RemoteException {
+        // Verify that the callbacks are invoked on the executor when there is a remote exception
+        doThrow(mThrowRemoteException).when(mUwbAdapter).registerAdapterStateCallbacks(any());
+        runViaExecutor();
+    }
+
+    private void runViaExecutor() {
+        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
+        AdapterStateCallback callback = mock(AdapterStateCallback.class);
+
+        Executor executor = mock(Executor.class);
+
+        // Do not run commands received and ensure that the callback is not invoked
+        doAnswer(new ExecutorAnswer(false)).when(executor).execute(any());
+        adapterStateListener.register(executor, callback);
+        verify(executor, times(1)).execute(any());
+        verifyCallbackStateChangedInvoked(callback, 0);
+
+        // Manually invoke the callback and ensure callback is not invoked
+        adapterStateListener.onAdapterStateChanged(false, StateChangeReason.UNKNOWN);
+        verify(executor, times(2)).execute(any());
+        verifyCallbackStateChangedInvoked(callback, 0);
+
+        // Run the command that the executor receives
+        doAnswer(new ExecutorAnswer(true)).when(executor).execute(any());
+        adapterStateListener.onAdapterStateChanged(false, StateChangeReason.UNKNOWN);
+        verify(executor, times(3)).execute(any());
+        verifyCallbackStateChangedInvoked(callback, 1);
+    }
+
+    class ExecutorAnswer implements Answer {
+
+        final boolean mShouldRun;
+        ExecutorAnswer(boolean shouldRun) {
+            mShouldRun = shouldRun;
+        }
+
+        @Override
+        public Object answer(InvocationOnMock invocation) throws Throwable {
+            if (mShouldRun) {
+                ((Runnable) invocation.getArgument(0)).run();
+            }
+            return null;
+        }
+    }
+
+    @Test
+    public void testNotify_AllCallbacksNotified() throws RemoteException {
+        doAnswer(mRegisterSuccessAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any());
+
+        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
+        List<AdapterStateCallback> callbacks = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            AdapterStateCallback callback = mock(AdapterStateCallback.class);
+            adapterStateListener.register(getExecutor(), callback);
+            callbacks.add(callback);
+        }
+
+            // Ensure every callback got the initial state
+        for (AdapterStateCallback callback : callbacks) {
+            verifyCallbackStateChangedInvoked(callback, 1);
+        }
+
+        // Invoke a state change and ensure all callbacks are invoked
+        adapterStateListener.onAdapterStateChanged(true, StateChangeReason.ALL_SESSIONS_CLOSED);
+        for (AdapterStateCallback callback : callbacks) {
+            verifyCallbackStateChangedInvoked(callback, 2);
+        }
+    }
+
+    @Test
+    public void testStateChange_CorrectValue() {
+        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
+
+        AdapterStateCallback callback = mock(AdapterStateCallback.class);
+
+        adapterStateListener.register(getExecutor(), callback);
+
+        runStateChangeValue(StateChangeReason.ALL_SESSIONS_CLOSED,
+                AdapterStateCallback.STATE_CHANGED_REASON_ALL_SESSIONS_CLOSED);
+
+        runStateChangeValue(StateChangeReason.SESSION_STARTED,
+                AdapterStateCallback.STATE_CHANGED_REASON_SESSION_STARTED);
+
+        runStateChangeValue(StateChangeReason.SYSTEM_BOOT,
+                AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_BOOT);
+
+        runStateChangeValue(StateChangeReason.SYSTEM_POLICY,
+                AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY);
+
+        runStateChangeValue(StateChangeReason.UNKNOWN,
+                AdapterStateCallback.STATE_CHANGED_REASON_ERROR_UNKNOWN);
+    }
+
+    private void runStateChangeValue(@StateChangeReason int reasonIn,
+            @AdapterStateCallback.StateChangedReason int reasonOut) {
+        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
+        AdapterStateCallback callback = mock(AdapterStateCallback.class);
+        adapterStateListener.register(getExecutor(), callback);
+
+        adapterStateListener.onAdapterStateChanged(false, reasonIn);
+        verify(callback, times(1)).onStateChanged(false, reasonOut);
+
+        adapterStateListener.onAdapterStateChanged(true, reasonIn);
+        verify(callback, times(1)).onStateChanged(true, reasonOut);
+    }
+
+    @Test
+    public void testStateChange_FirstRegisterGetsCorrectState() throws RemoteException {
+        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
+        AdapterStateCallback callback = mock(AdapterStateCallback.class);
+
+        Answer registerAnswer = new Answer() {
+            public Object answer(InvocationOnMock invocation) {
+                Object[] args = invocation.getArguments();
+                IUwbAdapterStateCallbacks cb = (IUwbAdapterStateCallbacks) args[0];
+                try {
+                    cb.onAdapterStateChanged(true, StateChangeReason.SESSION_STARTED);
+                } catch (RemoteException e) {
+                    // Nothing to do
+                }
+                return new Object();
+            }
+        };
+
+        doAnswer(registerAnswer).when(mUwbAdapter).registerAdapterStateCallbacks(any());
+
+        adapterStateListener.register(getExecutor(), callback);
+        verify(callback).onStateChanged(true,
+                AdapterStateCallback.STATE_CHANGED_REASON_SESSION_STARTED);
+    }
+
+    @Test
+    public void testStateChange_SecondRegisterGetsCorrectState() {
+        AdapterStateListener adapterStateListener = new AdapterStateListener(mUwbAdapter);
+        AdapterStateCallback callback1 = mock(AdapterStateCallback.class);
+        AdapterStateCallback callback2 = mock(AdapterStateCallback.class);
+
+        adapterStateListener.register(getExecutor(), callback1);
+        adapterStateListener.onAdapterStateChanged(true, StateChangeReason.SYSTEM_BOOT);
+
+        adapterStateListener.register(getExecutor(), callback2);
+        verify(callback2).onStateChanged(true,
+                AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_BOOT);
+    }
+}
diff --git a/data/etc/OWNERS b/data/etc/OWNERS
index 70d4678..5efd0bd 100644
--- a/data/etc/OWNERS
+++ b/data/etc/OWNERS
@@ -1 +1,13 @@
-per-file privapp-permissions-platform.xml = hackbod@android.com, jsharkey@android.com, svetoslavganov@google.com, toddke@google.com, yamasani@google.com, cbrubaker@google.com, jeffv@google.com, moltmann@google.com, lorenzo@google.com
+cbrubaker@google.com
+hackbod@android.com
+hackbod@google.com
+jeffv@google.com
+jsharkey@android.com
+jsharkey@google.com
+lorenzo@google.com
+moltmann@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
+toddke@android.com
+toddke@google.com
+yamasani@google.com
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 1fb63f0..5f129fe 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -243,6 +243,8 @@
         <permission name="android.permission.LOG_COMPAT_CHANGE" />
         <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
         <permission name="android.permission.REGISTER_STATS_PULL_ATOM" />
+        <!-- Permissions required for reading DeviceConfig -->
+        <permission name="android.permission.READ_DEVICE_CONFIG" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.providers.telephony">
@@ -375,6 +377,7 @@
         <permission name="android.permission.SIGNAL_PERSISTENT_PROCESSES"/>
         <permission name="android.permission.STATUS_BAR"/>
         <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />
+        <permission name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND" />
         <permission name="android.permission.START_TASKS_FROM_RECENTS" />
         <permission name="android.permission.STOP_APP_SWITCHES"/>
         <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
@@ -445,6 +448,8 @@
         <!-- Permissions required for CTS test - android.server.biometrics -->
         <permission name="android.permission.USE_BIOMETRIC" />
         <permission name="android.permission.TEST_BIOMETRIC" />
+        <!-- Permissions required for CTS test - CtsContactsProviderTestCases -->
+        <permission name="android.contacts.permission.MANAGE_SIM_ACCOUNTS" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 6bcab8a..a5667b2 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -85,6 +85,12 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
+    "-2014162875": {
+      "message": "Could not register window container listener token=%s, container=%s",
+      "level": "ERROR",
+      "group": "WM_ERROR",
+      "at": "com\/android\/server\/wm\/WindowContextListenerController.java"
+    },
     "-2012562539": {
       "message": "startAnimation(): Notify animation start:",
       "level": "DEBUG",
@@ -799,12 +805,6 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimation.java"
     },
-    "-1155279885": {
-      "message": "Frontmost changed immersion: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IMMERSIVE",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
     "-1144293044": {
       "message": "SURFACE SET FREEZE LAYER: %s",
       "level": "INFO",
@@ -817,6 +817,12 @@
       "group": "WM_DEBUG_FOCUS",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
+    "-1136467585": {
+      "message": "The listener does not exist.",
+      "level": "INFO",
+      "group": "WM_DEBUG_ADD_REMOVE",
+      "at": "com\/android\/server\/wm\/WindowContextListenerController.java"
+    },
     "-1136139407": {
       "message": "no-history finish of %s",
       "level": "DEBUG",
@@ -1219,6 +1225,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/RootWindowContainer.java"
     },
+    "-655104359": {
+      "message": "Frontmost changed immersion: %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_IMMERSIVE",
+      "at": "com\/android\/server\/wm\/ActivityClientController.java"
+    },
     "-653156702": {
       "message": "createAppAnimations()",
       "level": "DEBUG",
@@ -1573,12 +1585,6 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/Task.java"
     },
-    "-272719931": {
-      "message": "startLockTaskModeLocked: %s",
-      "level": "WARN",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
     "-262984451": {
       "message": "Relaunch failed %s",
       "level": "INFO",
@@ -1825,6 +1831,18 @@
       "group": "WM_DEBUG_TASKS",
       "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
     },
+    "90764070": {
+      "message": "Could not report token removal to the window token client.",
+      "level": "WARN",
+      "group": "WM_ERROR",
+      "at": "com\/android\/server\/wm\/WindowContextListenerController.java"
+    },
+    "91350919": {
+      "message": "Attempted to set IME flag to a display that does not exist: %d",
+      "level": "WARN",
+      "group": "WM_ERROR",
+      "at": "com\/android\/server\/wm\/WindowManagerService.java"
+    },
     "94402792": {
       "message": "Moving to RESUMED: %s (in existing)",
       "level": "VERBOSE",
@@ -1969,6 +1987,12 @@
       "group": "WM_DEBUG_WINDOW_ORGANIZER",
       "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
     },
+    "236210101": {
+      "message": "registerWindowContextListener: trying to add listener to a non-existing display:%d",
+      "level": "WARN",
+      "group": "WM_ERROR",
+      "at": "com\/android\/server\/wm\/WindowManagerService.java"
+    },
     "241961619": {
       "message": "Adding %s to %s",
       "level": "VERBOSE",
@@ -2047,6 +2071,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/DisplayRotation.java"
     },
+    "295861935": {
+      "message": "startLockTaskMode: %s",
+      "level": "WARN",
+      "group": "WM_DEBUG_LOCKTASK",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
     "302969511": {
       "message": "Task info changed taskId=%d",
       "level": "VERBOSE",
@@ -2557,6 +2587,12 @@
       "group": "WM_DEBUG_TASKS",
       "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
     },
+    "883475718": {
+      "message": "Report configuration: %s %s %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONFIGURATION",
+      "at": "com\/android\/server\/wm\/ActivityClientController.java"
+    },
     "892244061": {
       "message": "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
       "level": "INFO",
@@ -3097,12 +3133,6 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "1576607724": {
-      "message": "Report configuration: %s %s %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
     "1577579529": {
       "message": "win=%s destroySurfaces: appStopped=%b win.mWindowRemovalAllowed=%b win.mRemoveOnExit=%b",
       "level": "ERROR",
@@ -3403,6 +3433,12 @@
       "group": "WM_DEBUG_TASKS",
       "at": "com\/android\/server\/wm\/RootWindowContainer.java"
     },
+    "1948483534": {
+      "message": "Could not report config changes to the window token client.",
+      "level": "WARN",
+      "group": "WM_ERROR",
+      "at": "com\/android\/server\/wm\/WindowContextListenerController.java"
+    },
     "1964565370": {
       "message": "Starting remote animation",
       "level": "INFO",
diff --git a/data/fonts/OWNERS b/data/fonts/OWNERS
new file mode 100644
index 0000000..a538331
--- /dev/null
+++ b/data/fonts/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/graphics/fonts/OWNERS
diff --git a/drm/java/android/drm/OWNERS b/drm/java/android/drm/OWNERS
new file mode 100644
index 0000000..4387100
--- /dev/null
+++ b/drm/java/android/drm/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 49079
+
+jtinker@google.com
+robertshih@google.com
diff --git a/errorprone/OWNERS b/errorprone/OWNERS
new file mode 100644
index 0000000..bddbdb3
--- /dev/null
+++ b/errorprone/OWNERS
@@ -0,0 +1,2 @@
+jsharkey@android.com
+jsharkey@google.com
diff --git a/errorprone/refaster/EfficientXml.java b/errorprone/refaster/EfficientXml.java
index bd1ddfc..ae797c4 100644
--- a/errorprone/refaster/EfficientXml.java
+++ b/errorprone/refaster/EfficientXml.java
@@ -292,6 +292,30 @@
         }
     }
 
+    class BooleanToStringTrue {
+        @BeforeTemplate
+        void before(TypedXmlSerializer out, String n) throws Exception {
+            out.attribute(null, n, "true");
+        }
+
+        @AfterTemplate
+        void after(TypedXmlSerializer out, String n) throws Exception {
+            out.attributeBoolean(null, n, true);
+        }
+    }
+
+    class BooleanToStringFalse {
+        @BeforeTemplate
+        void before(TypedXmlSerializer out, String n) throws Exception {
+            out.attribute(null, n, "false");
+        }
+
+        @AfterTemplate
+        void after(TypedXmlSerializer out, String n) throws Exception {
+            out.attributeBoolean(null, n, false);
+        }
+    }
+
     class BooleanFromString {
         @BeforeTemplate
         boolean beforeParse(TypedXmlPullParser in, String n) throws Exception {
diff --git a/errorprone/refaster/EfficientXml.java.refaster b/errorprone/refaster/EfficientXml.java.refaster
index f2974ff..750c2db 100644
--- a/errorprone/refaster/EfficientXml.java.refaster
+++ b/errorprone/refaster/EfficientXml.java.refaster
Binary files differ
diff --git a/graphics/OWNERS b/graphics/OWNERS
new file mode 100644
index 0000000..a6d1bc3
--- /dev/null
+++ b/graphics/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/graphics/OWNERS
diff --git a/graphics/java/android/graphics/OWNERS b/graphics/java/android/graphics/OWNERS
new file mode 100644
index 0000000..6196889
--- /dev/null
+++ b/graphics/java/android/graphics/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 24939
+
+romainguy@google.com
+jreck@google.com
+njawad@google.com
+sumir@google.com
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 24987da..d6b4f18 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -82,7 +82,7 @@
     private static String TAG = "Typeface";
 
     /** @hide */
-    public static final boolean ENABLE_LAZY_TYPEFACE_INITIALIZATION = false;
+    public static final boolean ENABLE_LAZY_TYPEFACE_INITIALIZATION = true;
 
     private static final NativeAllocationRegistry sRegistry =
             NativeAllocationRegistry.createMalloced(
diff --git a/graphics/java/android/graphics/drawable/OWNERS b/graphics/java/android/graphics/drawable/OWNERS
new file mode 100644
index 0000000..6196889
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 24939
+
+romainguy@google.com
+jreck@google.com
+njawad@google.com
+sumir@google.com
diff --git a/graphics/java/android/graphics/drawable/shapes/OWNERS b/graphics/java/android/graphics/drawable/shapes/OWNERS
new file mode 100644
index 0000000..6196889
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/shapes/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 24939
+
+romainguy@google.com
+jreck@google.com
+njawad@google.com
+sumir@google.com
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index e7c1582..fea756c 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -124,6 +124,19 @@
         }
 
         /**
+         * Construct a builder with a byte buffer and file path.
+         *
+         * This method is intended to be called only from SystemFonts.
+         * @param path font file path
+         * @param localeList comma concatenated BCP47 compliant language tag.
+         * @hide
+         */
+        public Builder(@NonNull File path, @NonNull String localeList) {
+            this(path);
+            mLocaleList = localeList;
+        }
+
+        /**
          * Constructs a builder with a file path.
          *
          * @param path a file path to the font file
@@ -809,29 +822,13 @@
 
             // If not found, create Font object from native object for Java API users.
             ByteBuffer buffer = NativeFontBufferHelper.refByteBuffer(ptr);
-            long packed = nGetFontInfo(ptr);
-            int weight = (int) (packed & 0x0000_0000_0000_FFFFL);
-            boolean italic = (packed & 0x0000_0000_0001_0000L) != 0;
-            int ttcIndex = (int) ((packed & 0x0000_FFFF_0000_0000L) >> 32);
-            int axisCount = (int) ((packed & 0xFFFF_0000_0000_0000L) >> 48);
-            FontVariationAxis[] axes = new FontVariationAxis[axisCount];
-            char[] charBuffer = new char[4];
-            for (int i = 0; i < axisCount; ++i) {
-                long packedAxis = nGetAxisInfo(ptr, i);
-                float value = Float.intBitsToFloat((int) (packedAxis & 0x0000_0000_FFFF_FFFFL));
-                charBuffer[0] = (char) ((packedAxis & 0xFF00_0000_0000_0000L) >> 56);
-                charBuffer[1] = (char) ((packedAxis & 0x00FF_0000_0000_0000L) >> 48);
-                charBuffer[2] = (char) ((packedAxis & 0x0000_FF00_0000_0000L) >> 40);
-                charBuffer[3] = (char) ((packedAxis & 0x0000_00FF_0000_0000L) >> 32);
-                axes[i] = new FontVariationAxis(new String(charBuffer), value);
-            }
-            String path = nGetFontPath(ptr);
-            File file = (path == null) ? null : new File(path);
-            Font.Builder builder = new Font.Builder(buffer, file, "")
-                    .setWeight(weight)
-                    .setSlant(italic ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT)
-                    .setTtcIndex(ttcIndex)
-                    .setFontVariationSettings(axes);
+            NativeFont.Font font = NativeFont.readNativeFont(ptr);
+
+            Font.Builder builder = new Font.Builder(buffer, font.getFile(), "")
+                    .setWeight(font.getStyle().getWeight())
+                    .setSlant(font.getStyle().getSlant())
+                    .setTtcIndex(font.getIndex())
+                    .setFontVariationSettings(font.getAxes());
 
             Font newFont = null;
             try {
@@ -845,15 +842,6 @@
         }
     }
 
-    @CriticalNative
-    private static native long nGetFontInfo(long ptr);
-
-    @CriticalNative
-    private static native long nGetAxisInfo(long ptr, int i);
-
-    @FastNative
-    private static native String nGetFontPath(long ptr);
-
     @FastNative
     private static native float nGetGlyphBounds(long font, int glyphId, long paint, RectF rect);
 
diff --git a/graphics/java/android/graphics/fonts/NativeFont.java b/graphics/java/android/graphics/fonts/NativeFont.java
new file mode 100644
index 0000000..9e9d76a
--- /dev/null
+++ b/graphics/java/android/graphics/fonts/NativeFont.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2020 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.graphics.fonts;
+
+import android.graphics.Typeface;
+
+import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Read native font objects.
+ *
+ * @hide
+ */
+public class NativeFont {
+
+    /**
+     * Represents native font object.
+     */
+    public static final class Font {
+        private final File mFile;
+        private final int mIndex;
+        private final FontVariationAxis[] mAxes;
+        private final FontStyle mStyle;
+
+        public Font(File file, int index, FontVariationAxis[] axes, FontStyle style) {
+            mFile = file;
+            mIndex = index;
+            mAxes = axes;
+            mStyle = style;
+        }
+
+        public File getFile() {
+            return mFile;
+        }
+
+        public FontVariationAxis[] getAxes() {
+            return mAxes;
+        }
+
+        public FontStyle getStyle() {
+            return mStyle;
+        }
+
+        public int getIndex() {
+            return mIndex;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            Font font = (Font) o;
+            return mIndex == font.mIndex && mFile.equals(font.mFile)
+                    && Arrays.equals(mAxes, font.mAxes) && mStyle.equals(font.mStyle);
+        }
+
+        @Override
+        public int hashCode() {
+            int result = Objects.hash(mFile, mIndex, mStyle);
+            result = 31 * result + Arrays.hashCode(mAxes);
+            return result;
+        }
+    }
+
+    /**
+     * Represents native font family object.
+     */
+    public static final class Family {
+        private final List<Font> mFonts;
+        private final String mLocale;
+
+        public Family(List<Font> fonts, String locale) {
+            mFonts = fonts;
+            mLocale = locale;
+        }
+
+        public List<Font> getFonts() {
+            return mFonts;
+        }
+
+        public String getLocale() {
+            return mLocale;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            Family family = (Family) o;
+            return mFonts.equals(family.mFonts) && mLocale.equals(family.mLocale);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mFonts, mLocale);
+        }
+    }
+
+    /**
+     * Get underlying font families from Typeface
+     *
+     * @param typeface a typeface
+     * @return list of family
+     */
+    public static List<Family> readTypeface(Typeface typeface) {
+        int familyCount = nGetFamilyCount(typeface.native_instance);
+        List<Family> result = new ArrayList<>(familyCount);
+        for (int i = 0; i < familyCount; ++i) {
+            result.add(readNativeFamily(nGetFamily(typeface.native_instance, i)));
+        }
+        return result;
+    }
+
+    /**
+     * Read family object from native pointer
+     *
+     * @param familyPtr a font family pointer
+     * @return a family
+     */
+    public static Family readNativeFamily(long familyPtr) {
+        int fontCount = nGetFontCount(familyPtr);
+        List<Font> result = new ArrayList<>(fontCount);
+        for (int i = 0; i < fontCount; ++i) {
+            result.add(readNativeFont(nGetFont(familyPtr, i)));
+        }
+        String localeList = nGetLocaleList(familyPtr);
+        return new Family(result, localeList);
+    }
+
+    /**
+     * Read font object from native pointer.
+     *
+     * @param ptr a font pointer
+     * @return a font
+     */
+    public static Font readNativeFont(long ptr) {
+        long packed = nGetFontInfo(ptr);
+        int weight = (int) (packed & 0x0000_0000_0000_FFFFL);
+        boolean italic = (packed & 0x0000_0000_0001_0000L) != 0;
+        int ttcIndex = (int) ((packed & 0x0000_FFFF_0000_0000L) >> 32);
+        int axisCount = (int) ((packed & 0xFFFF_0000_0000_0000L) >> 48);
+        FontVariationAxis[] axes = new FontVariationAxis[axisCount];
+        char[] charBuffer = new char[4];
+        for (int i = 0; i < axisCount; ++i) {
+            long packedAxis = nGetAxisInfo(ptr, i);
+            float value = Float.intBitsToFloat((int) (packedAxis & 0x0000_0000_FFFF_FFFFL));
+            charBuffer[0] = (char) ((packedAxis & 0xFF00_0000_0000_0000L) >> 56);
+            charBuffer[1] = (char) ((packedAxis & 0x00FF_0000_0000_0000L) >> 48);
+            charBuffer[2] = (char) ((packedAxis & 0x0000_FF00_0000_0000L) >> 40);
+            charBuffer[3] = (char) ((packedAxis & 0x0000_00FF_0000_0000L) >> 32);
+            axes[i] = new FontVariationAxis(new String(charBuffer), value);
+        }
+        String path = nGetFontPath(ptr);
+        File file = (path == null) ? null : new File(path);
+        FontStyle style = new FontStyle(weight,
+                italic ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT);
+
+        return new Font(file, ttcIndex, axes, style);
+    }
+
+    @CriticalNative
+    private static native int nGetFamilyCount(long ptr);
+
+    @CriticalNative
+    private static native long nGetFamily(long ptr, int index);
+
+    @FastNative
+    private static native String nGetLocaleList(long familyPtr);
+
+    @CriticalNative
+    private static native long nGetFont(long familyPtr, int fontIndex);
+
+    @CriticalNative
+    private static native int nGetFontCount(long familyPtr);
+
+    @CriticalNative
+    private static native long nGetFontInfo(long fontPtr);
+
+    @CriticalNative
+    private static native long nGetAxisInfo(long fontPtr, int i);
+
+    @FastNative
+    private static native String nGetFontPath(long fontPtr);
+}
diff --git a/graphics/java/android/graphics/fonts/OWNERS b/graphics/java/android/graphics/fonts/OWNERS
new file mode 100644
index 0000000..e0a354e
--- /dev/null
+++ b/graphics/java/android/graphics/fonts/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 24939
+
+romainguy@google.com
+nona@google.com
+siyamed@google.com
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index 3635adc..fb6ea99 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.FontListParser;
+import android.graphics.Typeface;
 import android.text.FontConfig;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -68,21 +69,40 @@
                 return sAvailableFonts;
             }
 
-            Set<Font> set = new HashSet<>();
-
-            for (FontFamily[] items : sFamilyMap.values()) {
-                for (FontFamily family : items) {
-                    for (int i = 0; i < family.getSize(); ++i) {
-                        set.add(family.getFont(i));
+            if (Typeface.ENABLE_LAZY_TYPEFACE_INITIALIZATION) {
+                sAvailableFonts = collectAllFonts();
+            } else {
+                Set<Font> set = new HashSet<>();
+                for (FontFamily[] items : sFamilyMap.values()) {
+                    for (FontFamily family : items) {
+                        for (int i = 0; i < family.getSize(); ++i) {
+                            set.add(family.getFont(i));
+                        }
                     }
                 }
-            }
 
-            sAvailableFonts = Collections.unmodifiableSet(set);
+                sAvailableFonts = Collections.unmodifiableSet(set);
+            }
             return sAvailableFonts;
         }
     }
 
+    private static @NonNull Set<Font> collectAllFonts() {
+        final FontCustomizationParser.Result oemCustomization =
+                readFontCustomization("/product/etc/fonts_customization.xml", "/product/fonts/");
+        Map<String, FontFamily[]> map = new ArrayMap<>();
+        buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", oemCustomization, map);
+        Set<Font> res = new HashSet<>();
+        for (FontFamily[] families : map.values()) {
+            for (FontFamily family : families) {
+                for (int i = 0; i < family.getSize(); ++i) {
+                    res.add(family.getFont(i));
+                }
+            }
+        }
+        return res;
+    }
+
     private static @Nullable ByteBuffer mmap(@NonNull String fullPath) {
         try (FileInputStream file = new FileInputStream(fullPath)) {
             final FileChannel fileChannel = file.getChannel();
diff --git a/graphics/java/android/graphics/pdf/OWNERS b/graphics/java/android/graphics/pdf/OWNERS
new file mode 100644
index 0000000..f04e200
--- /dev/null
+++ b/graphics/java/android/graphics/pdf/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 24939
+
+romainguy@google.com
+djsollen@google.com
+sumir@google.com
+svetoslavganov@android.com
+svetoslavganov@google.com
+moltmann@google.com
diff --git a/graphics/java/android/graphics/text/OWNERS b/graphics/java/android/graphics/text/OWNERS
new file mode 100644
index 0000000..e0a354e
--- /dev/null
+++ b/graphics/java/android/graphics/text/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 24939
+
+romainguy@google.com
+nona@google.com
+siyamed@google.com
diff --git a/libs/WindowManager/OWNERS b/libs/WindowManager/OWNERS
index 063d459..2c61df9 100644
--- a/libs/WindowManager/OWNERS
+++ b/libs/WindowManager/OWNERS
@@ -1,3 +1,3 @@
 set noparent
 
-include ../../services/core/java/com/android/server/wm/OWNERS
\ No newline at end of file
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 856c9c2..96e0559 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -122,6 +122,7 @@
         "kotlinx-coroutines-android",
         "kotlinx-coroutines-core",
         "iconloader_base",
+        "jsr330",
         "protolog-lib",
         "SettingsLib",
         "WindowManager-Shell-proto",
diff --git a/libs/WindowManager/Shell/res/layout/split_divider.xml b/libs/WindowManager/Shell/res/layout/split_divider.xml
index b86f36a..341fe61 100644
--- a/libs/WindowManager/Shell/res/layout/split_divider.xml
+++ b/libs/WindowManager/Shell/res/layout/split_divider.xml
@@ -14,7 +14,7 @@
   ~ limitations under the License.
   -->
 
-<com.android.wm.shell.apppairs.DividerView
+<com.android.wm.shell.common.split.DividerView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
     android:layout_width="match_parent">
@@ -24,4 +24,4 @@
         android:id="@+id/docked_divider_background"
         android:background="@color/docked_divider_background"/>
 
-</com.android.wm.shell.apppairs.DividerView>
+</com.android.wm.shell.common.split.DividerView>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java
index ada7e1a..45948dd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandler.java
@@ -19,6 +19,7 @@
 import android.view.Gravity;
 
 import com.android.wm.shell.apppairs.AppPairs;
+import com.android.wm.shell.common.annotations.ExternalThread;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
 import com.android.wm.shell.letterbox.LetterboxConfigController;
 import com.android.wm.shell.onehanded.OneHanded;
@@ -61,6 +62,7 @@
     }
 
     /** Dumps WM Shell internal state. */
+    @ExternalThread
     public void dump(PrintWriter pw) {
         mShellTaskOrganizer.dump(pw, "");
         pw.println();
@@ -76,6 +78,7 @@
 
 
     /** Returns {@code true} if command was found and executed. */
+    @ExternalThread
     public boolean handleCommand(String[] args, PrintWriter pw) {
         if (args.length < 2) {
             // Argument at position 0 is "WMShell".
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java
index 118f189..94555de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInit.java
@@ -21,6 +21,7 @@
 
 import com.android.wm.shell.apppairs.AppPairs;
 import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.annotations.ExternalThread;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.letterbox.LetterboxTaskListener;
 import com.android.wm.shell.splitscreen.SplitScreen;
@@ -56,6 +57,7 @@
         mFullscreenTaskListener = fullscreenTaskListener;
     }
 
+    @ExternalThread
     public void init() {
         // Start listening for display changes
         mDisplayImeController.startMonitorDisplays();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index beb9690..174c16a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -31,12 +31,14 @@
 import android.os.IBinder;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.view.SurfaceControl;
 import android.window.ITaskOrganizerController;
 import android.window.TaskAppearedInfo;
 import android.window.TaskOrganizer;
 
+import androidx.annotation.BinderThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
@@ -45,6 +47,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.startingsurface.StartingSurfaceDrawer;
 
 import java.io.PrintWriter;
@@ -119,7 +122,7 @@
             ShellExecutor mainExecutor, ShellExecutor animExecutor, Context context) {
         super(taskOrganizerController, mainExecutor);
         mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor);
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions);
+        if (Transitions.ENABLE_SHELL_TRANSITIONS) mTransitions.register(this);
         // TODO(b/131727939) temporarily live here, the starting surface drawer should be controlled
         //  by a controller, that class should be create while porting
         //  ActivityRecord#addStartingWindow to WMShell.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java
index 120039d..10195b6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java
@@ -23,9 +23,9 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
-import android.annotation.MainThread;
 import android.annotation.NonNull;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -35,15 +35,18 @@
 import android.window.TransitionInfo;
 import android.window.WindowOrganizer;
 
+import androidx.annotation.BinderThread;
+
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.util.ArrayList;
 
 /** Plays transition animations */
-public class Transitions extends ITransitionPlayer.Stub {
+public class Transitions {
     private static final String TAG = "ShellTransitions";
 
     /** Set to {@code true} to enable shell transitions. */
@@ -54,6 +57,7 @@
     private final TransactionPool mTransactionPool;
     private final ShellExecutor mMainExecutor;
     private final ShellExecutor mAnimExecutor;
+    private final TransitionPlayerImpl mPlayerImpl;
 
     /** Keeps track of currently tracked transitions and all the animations associated with each */
     private final ArrayMap<IBinder, ArrayList<Animator>> mActiveTransitions = new ArrayMap<>();
@@ -64,6 +68,11 @@
         mTransactionPool = pool;
         mMainExecutor = mainExecutor;
         mAnimExecutor = animExecutor;
+        mPlayerImpl = new TransitionPlayerImpl();
+    }
+
+    public void register(ShellTaskOrganizer taskOrganizer) {
+        taskOrganizer.registerTransitionPlayer(mPlayerImpl);
     }
 
     // TODO(shell-transitions): real animations
@@ -115,77 +124,73 @@
                 || type == WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
     }
 
-    @Override
-    public void onTransitionReady(@NonNull IBinder transitionToken, @NonNull TransitionInfo info,
+    private void onTransitionReady(@NonNull IBinder transitionToken, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction t) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "onTransitionReady %s: %s",
                 transitionToken, info);
         // start task
-        mMainExecutor.execute(() -> {
-            if (!mActiveTransitions.containsKey(transitionToken)) {
-                Slog.e(TAG, "Got transitionReady for non-active transition " + transitionToken
-                        + " expecting one of " + mActiveTransitions.keySet());
-            }
-            if (mActiveTransitions.get(transitionToken) != null) {
-                throw new IllegalStateException("Got a duplicate onTransitionReady call for "
-                        + transitionToken);
-            }
-            mActiveTransitions.put(transitionToken, new ArrayList<>());
-            boolean isOpening = isOpeningType(info.getType());
-            if (info.getRootLeash().isValid()) {
-                t.show(info.getRootLeash());
-            }
-            // changes should be ordered top-to-bottom in z
-            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
-                final TransitionInfo.Change change = info.getChanges().get(i);
-                final SurfaceControl leash = change.getLeash();
-                final int mode = info.getChanges().get(i).getMode();
+        if (!mActiveTransitions.containsKey(transitionToken)) {
+            Slog.e(TAG, "Got transitionReady for non-active transition " + transitionToken
+                    + " expecting one of " + mActiveTransitions.keySet());
+        }
+        if (mActiveTransitions.get(transitionToken) != null) {
+            throw new IllegalStateException("Got a duplicate onTransitionReady call for "
+                    + transitionToken);
+        }
+        mActiveTransitions.put(transitionToken, new ArrayList<>());
+        boolean isOpening = isOpeningType(info.getType());
+        if (info.getRootLeash().isValid()) {
+            t.show(info.getRootLeash());
+        }
+        // changes should be ordered top-to-bottom in z
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            final TransitionInfo.Change change = info.getChanges().get(i);
+            final SurfaceControl leash = change.getLeash();
+            final int mode = info.getChanges().get(i).getMode();
 
-                // Don't animate anything with an animating parent
-                if (change.getParent() != null) {
-                    if (mode == TRANSIT_OPEN || mode == TRANSIT_SHOW) {
-                        t.show(leash);
-                        t.setMatrix(leash, 1, 0, 0, 1);
-                    }
-                    continue;
-                }
-
-                t.reparent(leash, info.getRootLeash());
-                t.setPosition(leash, change.getEndAbsBounds().left - info.getRootOffset().x,
-                        change.getEndAbsBounds().top - info.getRootOffset().y);
-                // Put all the OPEN/SHOW on top
+            // Don't animate anything with an animating parent
+            if (change.getParent() != null) {
                 if (mode == TRANSIT_OPEN || mode == TRANSIT_SHOW) {
                     t.show(leash);
                     t.setMatrix(leash, 1, 0, 0, 1);
-                    if (isOpening) {
-                        // put on top and fade in
-                        t.setLayer(leash, info.getChanges().size() - i);
-                        t.setAlpha(leash, 0.f);
-                        startExampleAnimation(transitionToken, leash, true /* show */);
-                    } else {
-                        // put on bottom and leave it visible without fade
-                        t.setLayer(leash, -i);
-                        t.setAlpha(leash, 1.f);
-                    }
-                } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_HIDE) {
-                    if (isOpening) {
-                        // put on bottom and leave visible without fade
-                        t.setLayer(leash, -i);
-                    } else {
-                        // put on top and fade out
-                        t.setLayer(leash, info.getChanges().size() - i);
-                        startExampleAnimation(transitionToken, leash, false /* show */);
-                    }
-                } else {
-                    t.setLayer(leash, info.getChanges().size() - i);
                 }
+                continue;
             }
-            t.apply();
-            onFinish(transitionToken);
-        });
+
+            t.reparent(leash, info.getRootLeash());
+            t.setPosition(leash, change.getEndAbsBounds().left - info.getRootOffset().x,
+                    change.getEndAbsBounds().top - info.getRootOffset().y);
+            // Put all the OPEN/SHOW on top
+            if (mode == TRANSIT_OPEN || mode == TRANSIT_SHOW) {
+                t.show(leash);
+                t.setMatrix(leash, 1, 0, 0, 1);
+                if (isOpening) {
+                    // put on top and fade in
+                    t.setLayer(leash, info.getChanges().size() - i);
+                    t.setAlpha(leash, 0.f);
+                    startExampleAnimation(transitionToken, leash, true /* show */);
+                } else {
+                    // put on bottom and leave it visible without fade
+                    t.setLayer(leash, -i);
+                    t.setAlpha(leash, 1.f);
+                }
+            } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_HIDE) {
+                if (isOpening) {
+                    // put on bottom and leave visible without fade
+                    t.setLayer(leash, -i);
+                } else {
+                    // put on top and fade out
+                    t.setLayer(leash, info.getChanges().size() - i);
+                    startExampleAnimation(transitionToken, leash, false /* show */);
+                }
+            } else {
+                t.setLayer(leash, info.getChanges().size() - i);
+            }
+        }
+        t.apply();
+        onFinish(transitionToken);
     }
 
-    @MainThread
     private void onFinish(IBinder transition) {
         if (!mActiveTransitions.get(transition).isEmpty()) return;
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
@@ -194,16 +199,32 @@
         mOrganizer.finishTransition(transition, null, null);
     }
 
-    @Override
-    public void requestStartTransition(int type, @NonNull IBinder transitionToken) {
+    private void requestStartTransition(int type, @NonNull IBinder transitionToken) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition requested: type=%d %s",
                 type, transitionToken);
-        mMainExecutor.execute(() -> {
-            if (mActiveTransitions.containsKey(transitionToken)) {
-                throw new RuntimeException("Transition already started " + transitionToken);
-            }
-            IBinder transition = mOrganizer.startTransition(type, transitionToken, null /* wct */);
-            mActiveTransitions.put(transition, null);
-        });
+
+        if (mActiveTransitions.containsKey(transitionToken)) {
+            throw new RuntimeException("Transition already started " + transitionToken);
+        }
+        IBinder transition = mOrganizer.startTransition(type, transitionToken, null /* wct */);
+        mActiveTransitions.put(transition, null);
+    }
+
+    @BinderThread
+    private class TransitionPlayerImpl extends ITransitionPlayer.Stub {
+        @Override
+        public void onTransitionReady(IBinder iBinder, TransitionInfo transitionInfo,
+                SurfaceControl.Transaction transaction) throws RemoteException {
+            mMainExecutor.execute(() -> {
+                Transitions.this.onTransitionReady(iBinder, transitionInfo, transaction);
+            });
+        }
+
+        @Override
+        public void requestStartTransition(int i, IBinder iBinder) throws RemoteException {
+            mMainExecutor.execute(() -> {
+                Transitions.this.requestStartTransition(i, iBinder);
+            });
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java
index acb9a5da..834de3f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java
@@ -18,11 +18,11 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
-import android.app.WindowConfiguration;
 import android.os.RemoteException;
-import android.view.WindowManagerGlobal;
 
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.pip.PinnedStackListenerForwarder;
+import com.android.wm.shell.pip.PinnedStackListenerForwarder.PinnedStackListener;
 
 /**
  * The singleton wrapper to communicate between WindowManagerService and WMShell features
@@ -31,32 +31,30 @@
 public class WindowManagerShellWrapper {
     private static final String TAG = WindowManagerShellWrapper.class.getSimpleName();
 
-    public static final int WINDOWING_MODE_PINNED = WindowConfiguration.WINDOWING_MODE_PINNED;
-
     /**
      * Forwarder to which we can add multiple pinned stack listeners. Each listener will receive
      * updates from the window manager service.
      */
-    private PinnedStackListenerForwarder mPinnedStackListenerForwarder =
-            new PinnedStackListenerForwarder();
+    private final PinnedStackListenerForwarder mPinnedStackListenerForwarder;
+
+    public WindowManagerShellWrapper(ShellExecutor shellMainExecutor) {
+        mPinnedStackListenerForwarder = new PinnedStackListenerForwarder(shellMainExecutor);
+    }
 
     /**
      * Adds a pinned stack listener, which will receive updates from the window manager service
      * along with any other pinned stack listeners that were added via this method.
      */
-    public void addPinnedStackListener(PinnedStackListenerForwarder.PinnedStackListener listener)
-            throws
-            RemoteException {
+    public void addPinnedStackListener(PinnedStackListener listener)
+            throws RemoteException {
         mPinnedStackListenerForwarder.addListener(listener);
-        WindowManagerGlobal.getWindowManagerService().registerPinnedStackListener(
-                DEFAULT_DISPLAY, mPinnedStackListenerForwarder);
+        mPinnedStackListenerForwarder.register(DEFAULT_DISPLAY);
     }
 
     /**
      * Removes a pinned stack listener.
      */
-    public void removePinnedStackListener(
-            PinnedStackListenerForwarder.PinnedStackListener listener) {
+    public void removePinnedStackListener(PinnedStackListener listener) {
         mPinnedStackListenerForwarder.removeListener(listener);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
index d3032f8..cfbf845 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
@@ -29,11 +29,13 @@
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.split.SplitLayout;
 
 import java.io.PrintWriter;
 
@@ -42,7 +44,7 @@
  * {@link #mTaskInfo1} and {@link #mTaskInfo2} in the pair.
  * Also includes all UI for managing the pair like the divider.
  */
-class AppPair implements ShellTaskOrganizer.TaskListener {
+class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChangeListener {
     private static final String TAG = AppPair.class.getSimpleName();
 
     private ActivityManager.RunningTaskInfo mRootTaskInfo;
@@ -55,7 +57,7 @@
     private final AppPairsController mController;
     private final SyncTransactionQueue mSyncQueue;
     private final DisplayController mDisplayController;
-    private AppPairLayout mAppPairLayout;
+    private SplitLayout mSplitLayout;
 
     AppPair(AppPairsController controller) {
         mController = controller;
@@ -92,11 +94,9 @@
 
         mTaskInfo1 = task1;
         mTaskInfo2 = task2;
-        mAppPairLayout = new AppPairLayout(
+        mSplitLayout = new SplitLayout(
                 mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
-                mDisplayController.getDisplay(mRootTaskInfo.displayId),
-                mRootTaskInfo.configuration,
-                mRootTaskLeash);
+                mRootTaskInfo.configuration, this, mRootTaskLeash);
 
         final WindowContainerToken token1 = task1.token;
         final WindowContainerToken token2 = task2.token;
@@ -107,8 +107,8 @@
                 .reparent(token2, mRootTaskInfo.token, true /* onTop */)
                 .setWindowingMode(token1, WINDOWING_MODE_MULTI_WINDOW)
                 .setWindowingMode(token2, WINDOWING_MODE_MULTI_WINDOW)
-                .setBounds(token1, mAppPairLayout.getBounds1())
-                .setBounds(token2, mAppPairLayout.getBounds2())
+                .setBounds(token1, mSplitLayout.getBounds1())
+                .setBounds(token2, mSplitLayout.getBounds2())
                 // Moving the root task to top after the child tasks were repareted , or the root
                 // task cannot be visible and focused.
                 .reorder(mRootTaskInfo.token, true);
@@ -117,6 +117,10 @@
     }
 
     void unpair() {
+        unpair(null /* toTopToken */);
+    }
+
+    private void unpair(@Nullable WindowContainerToken toTopToken) {
         final WindowContainerToken token1 = mTaskInfo1.token;
         final WindowContainerToken token2 = mTaskInfo2.token;
         final WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -124,16 +128,16 @@
         // Reparent out of this container and reset windowing mode.
         wct.setHidden(mRootTaskInfo.token, true)
                 .reorder(mRootTaskInfo.token, false)
-                .reparent(token1, null, false /* onTop */)
-                .reparent(token2, null, false /* onTop */)
+                .reparent(token1, null, token1 == toTopToken /* onTop */)
+                .reparent(token2, null, token2 == toTopToken /* onTop */)
                 .setWindowingMode(token1, WINDOWING_MODE_UNDEFINED)
                 .setWindowingMode(token2, WINDOWING_MODE_UNDEFINED);
         mController.getTaskOrganizer().applyTransaction(wct);
 
         mTaskInfo1 = null;
         mTaskInfo2 = null;
-        mAppPairLayout.release();
-        mAppPairLayout = null;
+        mSplitLayout.release();
+        mSplitLayout = null;
     }
 
     @Override
@@ -153,17 +157,17 @@
 
         if (mTaskLeash1 == null || mTaskLeash2 == null) return;
 
-        mAppPairLayout.init();
-        final SurfaceControl dividerLeash = mAppPairLayout.getDividerLeash();
-        final Rect dividerBounds = mAppPairLayout.getDividerBounds();
+        mSplitLayout.init();
+        final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
+        final Rect dividerBounds = mSplitLayout.getDividerBounds();
 
         // TODO: Is there more we need to do here?
         mSyncQueue.runInSync(t -> {
-            t.setPosition(mTaskLeash1, mTaskInfo1.positionInParent.x,
-                    mTaskInfo1.positionInParent.y)
+            t.setLayer(dividerLeash, Integer.MAX_VALUE)
+                    .setPosition(mTaskLeash1, mTaskInfo1.positionInParent.x,
+                            mTaskInfo1.positionInParent.y)
                     .setPosition(mTaskLeash2, mTaskInfo2.positionInParent.x,
                             mTaskInfo2.positionInParent.y)
-                    .setLayer(dividerLeash, Integer.MAX_VALUE)
                     .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
                     .show(mRootTaskLeash)
                     .show(mTaskLeash1)
@@ -185,14 +189,14 @@
             }
             mRootTaskInfo = taskInfo;
 
-            if (mAppPairLayout != null
-                    && mAppPairLayout.updateConfiguration(mRootTaskInfo.configuration)) {
+            if (mSplitLayout != null
+                    && mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)) {
                 // Update bounds when root bounds or its orientation changed.
                 final WindowContainerTransaction wct = new WindowContainerTransaction();
-                final SurfaceControl dividerLeash = mAppPairLayout.getDividerLeash();
-                final Rect dividerBounds = mAppPairLayout.getDividerBounds();
-                final Rect bounds1 = mAppPairLayout.getBounds1();
-                final Rect bounds2 = mAppPairLayout.getBounds2();
+                final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
+                final Rect dividerBounds = mSplitLayout.getDividerBounds();
+                final Rect bounds1 = mSplitLayout.getBounds1();
+                final Rect bounds2 = mSplitLayout.getBounds2();
 
                 wct.setBounds(mTaskInfo1.token, bounds1)
                         .setBounds(mTaskInfo2.token, bounds2);
@@ -200,7 +204,9 @@
                 mSyncQueue.runInSync(t -> t
                         .setPosition(mTaskLeash1, bounds1.left, bounds1.top)
                         .setPosition(mTaskLeash2, bounds2.left, bounds2.top)
-                        .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top));
+                        .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
+                        // Resets layer to divider bar to make sure it is always on top.
+                        .setLayer(dividerLeash, Integer.MAX_VALUE));
             }
         } else if (taskInfo.taskId == getTaskId1()) {
             mTaskInfo1 = taskInfo;
@@ -242,4 +248,39 @@
     public String toString() {
         return TAG + "#" + getRootTaskId();
     }
+
+    @Override
+    public void onSnappedToDismiss(boolean snappedToEnd) {
+        unpair(snappedToEnd ? mTaskInfo1.token : mTaskInfo2.token /* toTopToken */);
+    }
+
+    @Override
+    public void onBoundsChanging(SplitLayout layout) {
+        final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
+        if (dividerLeash == null) return;
+        final Rect dividerBounds = layout.getDividerBounds();
+        final Rect bounds1 = layout.getBounds1();
+        final Rect bounds2 = layout.getBounds2();
+        mSyncQueue.runInSync(t -> t
+                .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
+                .setPosition(mTaskLeash1, bounds1.left, bounds1.top)
+                .setPosition(mTaskLeash2, bounds2.left, bounds2.top));
+    }
+
+    @Override
+    public void onBoundsChanged(SplitLayout layout) {
+        final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
+        if (dividerLeash == null) return;
+        final Rect dividerBounds = layout.getDividerBounds();
+        final Rect bounds1 = layout.getBounds1();
+        final Rect bounds2 = layout.getBounds2();
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.setBounds(mTaskInfo1.token, bounds1)
+                .setBounds(mTaskInfo2.token, bounds2);
+        mController.getTaskOrganizer().applyTransaction(wct);
+        mSyncQueue.runInSync(t -> t
+                .setPosition(dividerLeash, dividerBounds.left, dividerBounds.top)
+                .setPosition(mTaskLeash1, bounds1.left, bounds1.top)
+                .setPosition(mTaskLeash2, bounds2.left, bounds2.top));
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairLayout.java
deleted file mode 100644
index 8c8655e..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairLayout.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2020 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 com.android.wm.shell.apppairs;
-
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
-import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
-import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.Binder;
-import android.os.IBinder;
-import android.view.Display;
-import android.view.IWindow;
-import android.view.LayoutInflater;
-import android.view.SurfaceControl;
-import android.view.SurfaceControlViewHost;
-import android.view.WindowManager;
-import android.view.WindowlessWindowManager;
-
-import com.android.wm.shell.R;
-
-/**
- * Records and handles layout of a pair of apps.
- */
-final class AppPairLayout {
-    private static final String DIVIDER_WINDOW_TITLE = "AppPairDivider";
-    private final Display mDisplay;
-    private final int mDividerWindowWidth;
-    private final int mDividerWindowInsets;
-    private final AppPairWindowManager mAppPairWindowManager;
-
-    private Context mContext;
-    private Rect mRootBounds;
-    private DIVIDE_POLICY mDividePolicy;
-
-    private SurfaceControlViewHost mViewHost;
-    private SurfaceControl mDividerLeash;
-
-    AppPairLayout(
-            Context context,
-            Display display,
-            Configuration configuration,
-            SurfaceControl rootLeash) {
-        mContext = context.createConfigurationContext(configuration);
-        mDisplay = display;
-        mRootBounds = configuration.windowConfiguration.getBounds();
-        mDividerWindowWidth = mContext.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.docked_stack_divider_thickness);
-        mDividerWindowInsets = mContext.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.docked_stack_divider_insets);
-
-        mAppPairWindowManager = new AppPairWindowManager(configuration, rootLeash);
-        mDividePolicy = DIVIDE_POLICY.MIDDLE;
-        mDividePolicy.update(mRootBounds, mDividerWindowWidth, mDividerWindowInsets);
-    }
-
-    boolean updateConfiguration(Configuration configuration) {
-        mAppPairWindowManager.setConfiguration(configuration);
-        final Rect rootBounds = configuration.windowConfiguration.getBounds();
-        if (isIdenticalBounds(mRootBounds, rootBounds)) {
-            return false;
-        }
-
-        mContext = mContext.createConfigurationContext(configuration);
-        mRootBounds = rootBounds;
-        mDividePolicy.update(mRootBounds, mDividerWindowWidth, mDividerWindowInsets);
-        release();
-        init();
-        return true;
-    }
-
-    Rect getBounds1() {
-        return mDividePolicy.mBounds1;
-    }
-
-    Rect getBounds2() {
-        return mDividePolicy.mBounds2;
-    }
-
-    Rect getDividerBounds() {
-        return mDividePolicy.mDividerBounds;
-    }
-
-    SurfaceControl getDividerLeash() {
-        return mDividerLeash;
-    }
-
-    void release() {
-        if (mViewHost == null) {
-            return;
-        }
-        mViewHost.release();
-        mDividerLeash = null;
-        mViewHost = null;
-    }
-
-    void init() {
-        if (mViewHost == null) {
-            mViewHost = new SurfaceControlViewHost(mContext, mDisplay, mAppPairWindowManager);
-        }
-
-        final DividerView dividerView = (DividerView) LayoutInflater.from(mContext)
-                .inflate(R.layout.split_divider, null);
-
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                mDividePolicy.mDividerBounds.width(),
-                mDividePolicy.mDividerBounds.height(),
-                TYPE_DOCK_DIVIDER,
-                FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_WATCH_OUTSIDE_TOUCH
-                        | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY,
-                PixelFormat.TRANSLUCENT);
-        lp.token = new Binder();
-        lp.setTitle(DIVIDER_WINDOW_TITLE);
-        lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
-
-        mViewHost.setView(dividerView, lp);
-        mDividerLeash = mAppPairWindowManager.getSurfaceControl(mViewHost.getWindowToken());
-    }
-
-    private static boolean isIdenticalBounds(Rect bounds1, Rect bounds2) {
-        return bounds1.left == bounds2.left && bounds1.top == bounds2.top
-                && bounds1.right == bounds2.right && bounds1.bottom == bounds2.bottom;
-    }
-
-    /**
-     * Indicates the policy of placing divider bar and corresponding split-screens.
-     */
-    // TODO(172704238): add more divide policy and provide snap to resize feature for divider bar.
-    enum DIVIDE_POLICY {
-        MIDDLE;
-
-        void update(Rect rootBounds, int dividerWindowWidth, int dividerWindowInsets) {
-            final int dividerOffset = dividerWindowWidth / 2;
-            final int boundsOffset = dividerOffset - dividerWindowInsets;
-
-            mDividerBounds = new Rect(rootBounds);
-            mBounds1 = new Rect(rootBounds);
-            mBounds2 = new Rect(rootBounds);
-
-            switch (this) {
-                case MIDDLE:
-                default:
-                    if (isLandscape(rootBounds)) {
-                        mDividerBounds.left = rootBounds.width() / 2 - dividerOffset;
-                        mDividerBounds.right = rootBounds.width() / 2 + dividerOffset;
-                        mBounds1.left = rootBounds.width() / 2 + boundsOffset;
-                        mBounds2.right = rootBounds.width() / 2 - boundsOffset;
-                    } else {
-                        mDividerBounds.top = rootBounds.height() / 2 - dividerOffset;
-                        mDividerBounds.bottom = rootBounds.height() / 2 + dividerOffset;
-                        mBounds1.bottom = rootBounds.height() / 2 - boundsOffset;
-                        mBounds2.top = rootBounds.height() / 2 + boundsOffset;
-                    }
-            }
-        }
-
-        private boolean isLandscape(Rect bounds) {
-            return bounds.width() > bounds.height();
-        }
-
-        Rect mDividerBounds;
-        Rect mBounds1;
-        Rect mBounds2;
-    }
-
-    /**
-     * WindowManger for app pair. Holds view hierarchy for the root task.
-     */
-    private static final class AppPairWindowManager extends WindowlessWindowManager {
-        AppPairWindowManager(Configuration config, SurfaceControl rootSurface) {
-            super(config, rootSurface, null /* hostInputToken */);
-        }
-
-        @Override
-        public void setTouchRegion(IBinder window, Region region) {
-            super.setTouchRegion(window, region);
-        }
-
-        @Override
-        public SurfaceControl getSurfaceControl(IWindow window) {
-            return super.getSurfaceControl(window);
-        }
-
-        @Override
-        public void setConfiguration(Configuration configuration) {
-            super.setConfiguration(configuration);
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java
index ef3e3e0..f5aa852 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java
@@ -20,11 +20,14 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.wm.shell.common.annotations.ExternalThread;
+
 import java.io.PrintWriter;
 
 /**
  * Interface to engage app pairs feature.
  */
+@ExternalThread
 public interface AppPairs {
     /** Pairs indicated tasks. */
     boolean pair(int task1, int task2);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/DividerView.java
deleted file mode 100644
index 41b5e47..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/DividerView.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2020 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 com.android.wm.shell.apppairs;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Stack divider for app pair.
- */
-public class DividerView extends FrameLayout {
-    public DividerView(@NonNull Context context) {
-        super(context);
-    }
-
-    public DividerView(@NonNull Context context,
-            @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DividerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public DividerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    void show() {
-        post(() -> setVisibility(View.VISIBLE));
-    }
-
-    void hide() {
-        post(() -> setVisibility(View.INVISIBLE));
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index aa7355b..40b41e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -1213,7 +1213,7 @@
         @Override
         public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
             if (mStackView != null) {
-                mStackView.post(() -> mStackView.onImeVisibilityChanged(imeVisible, imeHeight));
+                mStackView.onImeVisibilityChanged(imeVisible, imeHeight);
             }
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 92d15c5..fa5ac44 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -30,6 +30,8 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
 
+import com.android.wm.shell.common.annotations.ExternalThread;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -40,6 +42,7 @@
 /**
  * Interface to engage bubbles feature.
  */
+@ExternalThread
 public interface Bubbles {
 
     @Retention(SOURCE)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/AnimationThread.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/AnimationThread.java
deleted file mode 100644
index 96b9f86..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/AnimationThread.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2020 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 com.android.wm.shell.common;
-
-import static android.os.Process.THREAD_PRIORITY_DISPLAY;
-
-import android.annotation.NonNull;
-import android.os.HandlerThread;
-import android.util.Singleton;
-
-/**
- * A singleton thread for Shell to run animations on.
- */
-public class AnimationThread extends HandlerThread {
-    private ShellExecutor mExecutor;
-
-    private AnimationThread() {
-        super("wmshell.anim", THREAD_PRIORITY_DISPLAY);
-    }
-
-    /** Get the singleton instance of this thread */
-    public static AnimationThread instance() {
-        return sAnimationThreadSingleton.get();
-    }
-
-    /**
-     * @return a shared {@link ShellExecutor} associated with this thread
-     * @hide
-     */
-    @NonNull
-    public ShellExecutor getExecutor() {
-        if (mExecutor == null) {
-            mExecutor = new HandlerExecutor(getThreadHandler());
-        }
-        return mExecutor;
-    }
-
-    private static final Singleton<AnimationThread> sAnimationThreadSingleton =
-            new Singleton<AnimationThread>() {
-                @Override
-                protected AnimationThread create() {
-                    final AnimationThread animThread = new AnimationThread();
-                    animThread.start();
-                    return animThread;
-                }
-            };
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java
index 3263f79..cb4584c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java
@@ -23,6 +23,10 @@
 import android.view.IWindowManager;
 import android.window.WindowContainerTransaction;
 
+import androidx.annotation.BinderThread;
+
+import com.android.wm.shell.common.annotations.ShellMainThread;
+
 import java.util.ArrayList;
 
 /**
@@ -35,39 +39,18 @@
 
     private final Handler mHandler;
     private final IWindowManager mWmService;
+    private final IDisplayWindowRotationController mControllerImpl;
 
     private final ArrayList<OnDisplayChangingListener> mRotationListener =
             new ArrayList<>();
     private final ArrayList<OnDisplayChangingListener> mTmpListeners = new ArrayList<>();
 
-    private final IDisplayWindowRotationController mDisplayRotationController =
-            new IDisplayWindowRotationController.Stub() {
-                @Override
-                public void onRotateDisplay(int displayId, final int fromRotation,
-                        final int toRotation, IDisplayWindowRotationCallback callback) {
-                    mHandler.post(() -> {
-                        WindowContainerTransaction t = new WindowContainerTransaction();
-                        synchronized (mRotationListener) {
-                            mTmpListeners.clear();
-                            // Make a local copy in case the handlers add/remove themselves.
-                            mTmpListeners.addAll(mRotationListener);
-                        }
-                        for (OnDisplayChangingListener c : mTmpListeners) {
-                            c.onRotateDisplay(displayId, fromRotation, toRotation, t);
-                        }
-                        try {
-                            callback.continueRotateDisplay(toRotation, t);
-                        } catch (RemoteException e) {
-                        }
-                    });
-                }
-            };
-
     public DisplayChangeController(Handler mainHandler, IWindowManager wmService) {
         mHandler = mainHandler;
         mWmService = wmService;
+        mControllerImpl = new DisplayWindowRotationControllerImpl();
         try {
-            mWmService.setDisplayWindowRotationController(mDisplayRotationController);
+            mWmService.setDisplayWindowRotationController(mControllerImpl);
         } catch (RemoteException e) {
             throw new RuntimeException("Unable to register rotation controller");
         }
@@ -91,10 +74,41 @@
         }
     }
 
+    private void onRotateDisplay(int displayId, final int fromRotation, final int toRotation,
+            IDisplayWindowRotationCallback callback) {
+        WindowContainerTransaction t = new WindowContainerTransaction();
+        synchronized (mRotationListener) {
+            mTmpListeners.clear();
+            // Make a local copy in case the handlers add/remove themselves.
+            mTmpListeners.addAll(mRotationListener);
+        }
+        for (OnDisplayChangingListener c : mTmpListeners) {
+            c.onRotateDisplay(displayId, fromRotation, toRotation, t);
+        }
+        try {
+            callback.continueRotateDisplay(toRotation, t);
+        } catch (RemoteException e) {
+        }
+    }
+
+    @BinderThread
+    private class DisplayWindowRotationControllerImpl
+            extends IDisplayWindowRotationController.Stub {
+        @Override
+        public void onRotateDisplay(int displayId, final int fromRotation,
+                final int toRotation, IDisplayWindowRotationCallback callback) {
+            mHandler.post(() -> {
+                DisplayChangeController.this.onRotateDisplay(displayId, fromRotation, toRotation,
+                        callback);
+            });
+        }
+    }
+
     /**
      * Give a listener a chance to queue up configuration changes to execute as part of a
      * display rotation. The contents of {@link #onRotateDisplay} must run synchronously.
      */
+    @ShellMainThread
     public interface OnDisplayChangingListener {
         /**
          * Called before the display is rotated. Contents of this method must run synchronously.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
index 4189732..a413c05 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
@@ -28,7 +28,10 @@
 import android.view.IDisplayWindowListener;
 import android.view.IWindowManager;
 
+import androidx.annotation.BinderThread;
+
 import com.android.wm.shell.common.DisplayChangeController.OnDisplayChangingListener;
+import com.android.wm.shell.common.annotations.ShellMainThread;
 
 import java.util.ArrayList;
 
@@ -45,6 +48,7 @@
     private final Context mContext;
     private final IWindowManager mWmService;
     private final DisplayChangeController mChangeController;
+    private final IDisplayWindowListener mDisplayContainerListener;
 
     private final SparseArray<DisplayRecord> mDisplays = new SparseArray<>();
     private final ArrayList<OnDisplaysChangedListener> mDisplayChangedListeners = new ArrayList<>();
@@ -57,119 +61,13 @@
         return displayManager.getDisplay(displayId);
     }
 
-    private final IDisplayWindowListener mDisplayContainerListener =
-            new IDisplayWindowListener.Stub() {
-                @Override
-                public void onDisplayAdded(int displayId) {
-                    mHandler.post(() -> {
-                        synchronized (mDisplays) {
-                            if (mDisplays.get(displayId) != null) {
-                                return;
-                            }
-                            Display display = getDisplay(displayId);
-                            if (display == null) {
-                                // It's likely that the display is private to some app and thus not
-                                // accessible by system-ui.
-                                return;
-                            }
-                            DisplayRecord record = new DisplayRecord();
-                            record.mDisplayId = displayId;
-                            record.mContext = (displayId == Display.DEFAULT_DISPLAY) ? mContext
-                                    : mContext.createDisplayContext(display);
-                            record.mDisplayLayout = new DisplayLayout(record.mContext, display);
-                            mDisplays.put(displayId, record);
-                            for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
-                                mDisplayChangedListeners.get(i).onDisplayAdded(displayId);
-                            }
-                        }
-                    });
-                }
-
-                @Override
-                public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
-                    mHandler.post(() -> {
-                        synchronized (mDisplays) {
-                            DisplayRecord dr = mDisplays.get(displayId);
-                            if (dr == null) {
-                                Slog.w(TAG, "Skipping Display Configuration change on non-added"
-                                        + " display.");
-                                return;
-                            }
-                            Display display = getDisplay(displayId);
-                            if (display == null) {
-                                Slog.w(TAG, "Skipping Display Configuration change on invalid"
-                                        + " display. It may have been removed.");
-                                return;
-                            }
-                            Context perDisplayContext = mContext;
-                            if (displayId != Display.DEFAULT_DISPLAY) {
-                                perDisplayContext = mContext.createDisplayContext(display);
-                            }
-                            dr.mContext = perDisplayContext.createConfigurationContext(newConfig);
-                            dr.mDisplayLayout = new DisplayLayout(dr.mContext, display);
-                            for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
-                                mDisplayChangedListeners.get(i).onDisplayConfigurationChanged(
-                                        displayId, newConfig);
-                            }
-                        }
-                    });
-                }
-
-                @Override
-                public void onDisplayRemoved(int displayId) {
-                    mHandler.post(() -> {
-                        synchronized (mDisplays) {
-                            if (mDisplays.get(displayId) == null) {
-                                return;
-                            }
-                            for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
-                                mDisplayChangedListeners.get(i).onDisplayRemoved(displayId);
-                            }
-                            mDisplays.remove(displayId);
-                        }
-                    });
-                }
-
-                @Override
-                public void onFixedRotationStarted(int displayId, int newRotation) {
-                    mHandler.post(() -> {
-                        synchronized (mDisplays) {
-                            if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
-                                Slog.w(TAG, "Skipping onFixedRotationStarted on unknown"
-                                        + " display, displayId=" + displayId);
-                                return;
-                            }
-                            for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
-                                mDisplayChangedListeners.get(i).onFixedRotationStarted(
-                                        displayId, newRotation);
-                            }
-                        }
-                    });
-                }
-
-                @Override
-                public void onFixedRotationFinished(int displayId) {
-                    mHandler.post(() -> {
-                        synchronized (mDisplays) {
-                            if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
-                                Slog.w(TAG, "Skipping onFixedRotationFinished on unknown"
-                                        + " display, displayId=" + displayId);
-                                return;
-                            }
-                            for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
-                                mDisplayChangedListeners.get(i).onFixedRotationFinished(displayId);
-                            }
-                        }
-                    });
-                }
-            };
-
     public DisplayController(Context context, Handler handler,
             IWindowManager wmService) {
         mHandler = handler;
         mContext = context;
         mWmService = wmService;
         mChangeController = new DisplayChangeController(mHandler, mWmService);
+        mDisplayContainerListener = new DisplayWindowListenerImpl();
         try {
             mWmService.registerDisplayWindowListener(mDisplayContainerListener);
         } catch (RemoteException e) {
@@ -232,18 +130,146 @@
         mChangeController.removeRotationListener(controller);
     }
 
+    private void onDisplayAdded(int displayId) {
+        synchronized (mDisplays) {
+            if (mDisplays.get(displayId) != null) {
+                return;
+            }
+            Display display = getDisplay(displayId);
+            if (display == null) {
+                // It's likely that the display is private to some app and thus not
+                // accessible by system-ui.
+                return;
+            }
+            DisplayRecord record = new DisplayRecord();
+            record.mDisplayId = displayId;
+            record.mContext = (displayId == Display.DEFAULT_DISPLAY) ? mContext
+                    : mContext.createDisplayContext(display);
+            record.mDisplayLayout = new DisplayLayout(record.mContext, display);
+            mDisplays.put(displayId, record);
+            for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
+                mDisplayChangedListeners.get(i).onDisplayAdded(displayId);
+            }
+        }
+    }
+
+    private void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
+        synchronized (mDisplays) {
+            DisplayRecord dr = mDisplays.get(displayId);
+            if (dr == null) {
+                Slog.w(TAG, "Skipping Display Configuration change on non-added"
+                        + " display.");
+                return;
+            }
+            Display display = getDisplay(displayId);
+            if (display == null) {
+                Slog.w(TAG, "Skipping Display Configuration change on invalid"
+                        + " display. It may have been removed.");
+                return;
+            }
+            Context perDisplayContext = mContext;
+            if (displayId != Display.DEFAULT_DISPLAY) {
+                perDisplayContext = mContext.createDisplayContext(display);
+            }
+            dr.mContext = perDisplayContext.createConfigurationContext(newConfig);
+            dr.mDisplayLayout = new DisplayLayout(dr.mContext, display);
+            for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
+                mDisplayChangedListeners.get(i).onDisplayConfigurationChanged(
+                        displayId, newConfig);
+            }
+        }
+    }
+
+    private void onDisplayRemoved(int displayId) {
+        synchronized (mDisplays) {
+            if (mDisplays.get(displayId) == null) {
+                return;
+            }
+            for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
+                mDisplayChangedListeners.get(i).onDisplayRemoved(displayId);
+            }
+            mDisplays.remove(displayId);
+        }
+    }
+
+    private void onFixedRotationStarted(int displayId, int newRotation) {
+        synchronized (mDisplays) {
+            if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
+                Slog.w(TAG, "Skipping onFixedRotationStarted on unknown"
+                        + " display, displayId=" + displayId);
+                return;
+            }
+            for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
+                mDisplayChangedListeners.get(i).onFixedRotationStarted(
+                        displayId, newRotation);
+            }
+        }
+    }
+
+    private void onFixedRotationFinished(int displayId) {
+        synchronized (mDisplays) {
+            if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
+                Slog.w(TAG, "Skipping onFixedRotationFinished on unknown"
+                        + " display, displayId=" + displayId);
+                return;
+            }
+            for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
+                mDisplayChangedListeners.get(i).onFixedRotationFinished(displayId);
+            }
+        }
+    }
+
     private static class DisplayRecord {
         int mDisplayId;
         Context mContext;
         DisplayLayout mDisplayLayout;
     }
 
+    @BinderThread
+    private class DisplayWindowListenerImpl extends IDisplayWindowListener.Stub {
+        @Override
+        public void onDisplayAdded(int displayId) {
+            mHandler.post(() -> {
+                DisplayController.this.onDisplayAdded(displayId);
+            });
+        }
+
+        @Override
+        public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
+            mHandler.post(() -> {
+                DisplayController.this.onDisplayConfigurationChanged(displayId, newConfig);
+            });
+        }
+
+        @Override
+        public void onDisplayRemoved(int displayId) {
+            mHandler.post(() -> {
+                DisplayController.this.onDisplayRemoved(displayId);
+            });
+        }
+
+        @Override
+        public void onFixedRotationStarted(int displayId, int newRotation) {
+            mHandler.post(() -> {
+                DisplayController.this.onFixedRotationStarted(displayId, newRotation);
+            });
+        }
+
+        @Override
+        public void onFixedRotationFinished(int displayId) {
+            mHandler.post(() -> {
+                DisplayController.this.onFixedRotationFinished(displayId);
+            });
+        }
+    }
+
     /**
      * Gets notified when a display is added/removed to the WM hierarchy and when a display's
      * window-configuration changes.
      *
      * @see IDisplayWindowListener
      */
+    @ShellMainThread
     public interface OnDisplaysChangedListener {
         /**
          * Called when a display has been added to the WM hierarchy.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index ea18a19..3fbd7ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -24,7 +24,6 @@
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.os.Handler;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Slog;
@@ -40,6 +39,8 @@
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
+import androidx.annotation.BinderThread;
+
 import com.android.internal.view.IInputMethodManager;
 
 import java.util.ArrayList;
@@ -197,6 +198,7 @@
             mRotation = initialRotation;
         }
 
+        @BinderThread
         @Override
         public void insetsChanged(InsetsState insetsState) {
             mExecutor.execute(() -> {
@@ -204,6 +206,8 @@
                     return;
                 }
 
+                mImeShowing = insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME);
+
                 final InsetsSource newSource = insetsState.getSource(InsetsState.ITYPE_IME);
                 final Rect newFrame = newSource.getFrame();
                 final Rect oldFrame = mInsetsState.getSource(InsetsState.ITYPE_IME).getFrame();
@@ -216,6 +220,7 @@
             });
         }
 
+        @BinderThread
         @Override
         public void insetsControlChanged(InsetsState insetsState,
                 InsetsSourceControl[] activeControls) {
@@ -266,6 +271,7 @@
             }
         }
 
+        @BinderThread
         @Override
         public void showInsets(int types, boolean fromIme) {
             if ((types & WindowInsets.Type.ime()) == 0) {
@@ -275,6 +281,7 @@
             mExecutor.execute(() -> startAnimation(true /* show */, false /* forceRestart */));
         }
 
+        @BinderThread
         @Override
         public void hideInsets(int types, boolean fromIme) {
             if ((types & WindowInsets.Type.ime()) == 0) {
@@ -284,6 +291,7 @@
             mExecutor.execute(() -> startAnimation(false /* show */, false /* forceRestart */));
         }
 
+        @BinderThread
         @Override
         public void topFocusedWindowChanged(String packageName) {
             // no-op
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java
index cd75840..fa0a75c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java
@@ -28,6 +28,17 @@
     }
 
     @Override
+    public void execute(@NonNull Runnable command) {
+        if (mHandler.getLooper().isCurrentThread()) {
+            command.run();
+            return;
+        }
+        if (!mHandler.post(command)) {
+            throw new RuntimeException(mHandler + " is probably exiting");
+        }
+    }
+
+    @Override
     public void executeDelayed(@NonNull Runnable r, long delayMillis) {
         if (!mHandler.postDelayed(r, delayMillis)) {
             throw new RuntimeException(mHandler + " is probably exiting");
@@ -38,11 +49,4 @@
     public void removeCallbacks(@NonNull Runnable r) {
         mHandler.removeCallbacks(r);
     }
-
-    @Override
-    public void execute(@NonNull Runnable command) {
-        if (!mHandler.post(command)) {
-            throw new RuntimeException(mHandler + " is probably exiting");
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/PipInputConsumer.java
deleted file mode 100644
index 87ddb18..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/PipInputConsumer.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2020 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 com.android.wm.shell.common;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.INPUT_CONSUMER_PIP;
-import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.BatchedInputEventReceiver;
-import android.view.Choreographer;
-import android.view.IWindowManager;
-import android.view.InputChannel;
-import android.view.InputEvent;
-import android.view.WindowManagerGlobal;
-
-import java.io.PrintWriter;
-
-/**
- * Manages the input consumer that allows the Shell to directly receive input.
- */
-public class PipInputConsumer {
-
-    private static final String TAG = PipInputConsumer.class.getSimpleName();
-
-    /**
-     * Listener interface for callers to subscribe to input events.
-     */
-    public interface InputListener {
-        /** Handles any input event. */
-        boolean onInputEvent(InputEvent ev);
-    }
-
-    /**
-     * Listener interface for callers to learn when this class is registered or unregistered with
-     * window manager
-     */
-    public interface RegistrationListener {
-        void onRegistrationChanged(boolean isRegistered);
-    }
-
-    /**
-     * Input handler used for the input consumer. Input events are batched and consumed with the
-     * SurfaceFlinger vsync.
-     */
-    private final class InputEventReceiver extends BatchedInputEventReceiver {
-
-        InputEventReceiver(InputChannel inputChannel, Looper looper,
-                Choreographer choreographer) {
-            super(inputChannel, looper, choreographer);
-        }
-
-        @Override
-        public void onInputEvent(InputEvent event) {
-            boolean handled = true;
-            try {
-                if (mListener != null) {
-                    handled = mListener.onInputEvent(event);
-                }
-            } finally {
-                finishInputEvent(event, handled);
-            }
-        }
-    }
-
-    private final IWindowManager mWindowManager;
-    private final IBinder mToken;
-    private final String mName;
-
-    private InputEventReceiver mInputEventReceiver;
-    private InputListener mListener;
-    private RegistrationListener mRegistrationListener;
-
-    /**
-     * @param name the name corresponding to the input consumer that is defined in the system.
-     */
-    public PipInputConsumer(IWindowManager windowManager, String name) {
-        mWindowManager = windowManager;
-        mToken = new Binder();
-        mName = name;
-    }
-
-    /**
-     * Sets the input listener.
-     */
-    public void setInputListener(InputListener listener) {
-        mListener = listener;
-    }
-
-    /**
-     * Sets the registration listener.
-     */
-    public void setRegistrationListener(RegistrationListener listener) {
-        mRegistrationListener = listener;
-        if (mRegistrationListener != null) {
-            mRegistrationListener.onRegistrationChanged(mInputEventReceiver != null);
-        }
-    }
-
-    /**
-     * Check if the InputConsumer is currently registered with WindowManager
-     *
-     * @return {@code true} if registered, {@code false} if not.
-     */
-    public boolean isRegistered() {
-        return mInputEventReceiver != null;
-    }
-
-    /**
-     * Registers the input consumer.
-     */
-    public void registerInputConsumer() {
-        registerInputConsumer(false);
-    }
-
-    /**
-     * Registers the input consumer.
-     * @param withSfVsync the flag set using sf vsync signal or no
-     */
-    public void registerInputConsumer(boolean withSfVsync) {
-        if (mInputEventReceiver != null) {
-            return;
-        }
-        final InputChannel inputChannel = new InputChannel();
-        try {
-            // TODO(b/113087003): Support Picture-in-picture in multi-display.
-            mWindowManager.destroyInputConsumer(mName, DEFAULT_DISPLAY);
-            mWindowManager.createInputConsumer(mToken, mName, DEFAULT_DISPLAY, inputChannel);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to create input consumer", e);
-        }
-        mInputEventReceiver = new InputEventReceiver(inputChannel, Looper.myLooper(),
-                withSfVsync ? Choreographer.getSfInstance() : Choreographer.getInstance());
-        if (mRegistrationListener != null) {
-            mRegistrationListener.onRegistrationChanged(true /* isRegistered */);
-        }
-    }
-
-    /**
-     * Unregisters the input consumer.
-     */
-    public void unregisterInputConsumer() {
-        if (mInputEventReceiver == null) {
-            return;
-        }
-        try {
-            // TODO(b/113087003): Support Picture-in-picture in multi-display.
-            mWindowManager.destroyInputConsumer(mName, DEFAULT_DISPLAY);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to destroy input consumer", e);
-        }
-        mInputEventReceiver.dispose();
-        mInputEventReceiver = null;
-        if (mRegistrationListener != null) {
-            mRegistrationListener.onRegistrationChanged(false /* isRegistered */);
-        }
-    }
-
-    public void dump(PrintWriter pw, String prefix) {
-        final String innerPrefix = prefix + "  ";
-        pw.println(prefix + TAG);
-        pw.println(innerPrefix + "registered=" + (mInputEventReceiver != null));
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
index aafe240..22b831b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
@@ -16,13 +16,40 @@
 
 package com.android.wm.shell.common;
 
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Super basic Executor interface that adds support for delayed execution and removing callbacks.
  * Intended to wrap Handler while better-supporting testing.
  */
 public interface ShellExecutor extends Executor {
+
+    /**
+     * Executes the given runnable. If the caller is running on the same looper as this executor,
+     * the runnable must be executed immediately.
+     */
+    @Override
+    void execute(Runnable runnable);
+
+    /**
+     * Executes the given runnable in a blocking call. If the caller is running on the same looper
+     * as this executor, the runnable must be executed immediately.
+     *
+     * @throws InterruptedException if runnable does not return in the time specified by
+     *                              {@param waitTimeout}
+     */
+    default void executeBlocking(Runnable runnable, int waitTimeout, TimeUnit waitTimeUnit)
+            throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        execute(() -> {
+            runnable.run();
+            latch.countDown();
+        });
+        latch.await(waitTimeout, waitTimeUnit);
+    }
+
     /**
      * See {@link android.os.Handler#postDelayed(Runnable, long)}.
      */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
index 9cb1250..7321dc8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
@@ -24,6 +24,10 @@
 import android.window.WindowContainerTransactionCallback;
 import android.window.WindowOrganizer;
 
+import androidx.annotation.BinderThread;
+
+import com.android.wm.shell.common.annotations.ShellMainThread;
+
 import java.util.ArrayList;
 
 /**
@@ -151,6 +155,7 @@
             mHandler.postDelayed(mOnReplyTimeout, REPLY_TIMEOUT);
         }
 
+        @BinderThread
         @Override
         public void onTransactionReady(int id,
                 @NonNull SurfaceControl.Transaction t) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
index 0f6dd93..5e07718 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
@@ -19,12 +19,10 @@
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ITaskStackListener;
-import android.app.TaskInfo;
 import android.content.ComponentName;
 import android.os.IBinder;
 
 import androidx.annotation.BinderThread;
-import androidx.annotation.MainThread;
 
 /**
  * An interface to track task stack changes. Classes should implement this instead of
@@ -32,85 +30,61 @@
  */
 public interface TaskStackListenerCallback {
 
-    @MainThread
     default void onRecentTaskListUpdated() { }
 
-    @MainThread
     default void onRecentTaskListFrozenChanged(boolean frozen) { }
 
     @BinderThread
     default void onTaskStackChangedBackground() { }
 
-    @MainThread
     default void onTaskStackChanged() { }
 
-    @MainThread
     default void onTaskProfileLocked(int taskId, int userId) { }
 
-    @MainThread
     default void onTaskDisplayChanged(int taskId, int newDisplayId) { }
 
-    @MainThread
     default void onTaskCreated(int taskId, ComponentName componentName) { }
 
-    @MainThread
     default void onTaskRemoved(int taskId) { }
 
-    @MainThread
     default void onTaskMovedToFront(int taskId) { }
 
-    @MainThread
     default void onTaskMovedToFront(RunningTaskInfo taskInfo) {
         onTaskMovedToFront(taskInfo.taskId);
     }
 
-    @MainThread
     default void onTaskDescriptionChanged(RunningTaskInfo taskInfo) { }
 
-    @MainThread
     default void onTaskSnapshotChanged(int taskId, ActivityManager.TaskSnapshot snapshot) { }
 
-    @MainThread
     default void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { }
 
-    @MainThread
     default void onActivityRestartAttempt(RunningTaskInfo task, boolean homeTaskVisible,
             boolean clearedTask, boolean wasVisible) { }
 
-    @MainThread
     default void onActivityPinned(String packageName, int userId, int taskId, int stackId) { }
 
-    @MainThread
     default void onActivityUnpinned() { }
 
-    @MainThread
     default void onActivityForcedResizable(String packageName, int taskId, int reason) { }
 
-    @MainThread
     default void onActivityDismissingDockedStack() { }
 
-    @MainThread
     default void onActivityLaunchOnSecondaryDisplayFailed() { }
 
-    @MainThread
     default void onActivityLaunchOnSecondaryDisplayFailed(RunningTaskInfo taskInfo) {
         onActivityLaunchOnSecondaryDisplayFailed();
     }
 
-    @MainThread
     default void onActivityLaunchOnSecondaryDisplayRerouted() { }
 
-    @MainThread
     default void onActivityLaunchOnSecondaryDisplayRerouted(RunningTaskInfo taskInfo) {
         onActivityLaunchOnSecondaryDisplayRerouted();
     }
 
-    @MainThread
     default void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) { }
 
-    @MainThread
     default void onActivityRotation(int displayId) { }
 
-    @MainThread
     default void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken) { }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ChoreographerSfVsync.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ChoreographerSfVsync.java
new file mode 100644
index 0000000..4009ad2
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ChoreographerSfVsync.java
@@ -0,0 +1,18 @@
+package com.android.wm.shell.common.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Qualifier;
+
+/**
+ * Annotates a method that or qualifies a provider runs aligned to the Choreographer SF vsync
+ * instead of the app vsync.
+ */
+@Documented
+@Inherited
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ChoreographerSfVsync {}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ExternalThread.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ExternalThread.java
new file mode 100644
index 0000000..7560f71
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ExternalThread.java
@@ -0,0 +1,15 @@
+package com.android.wm.shell.common.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Qualifier;
+
+/** Annotates a method or class that is called from an external thread to the Shell threads. */
+@Documented
+@Inherited
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExternalThread {}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ShellAnimationThread.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ShellAnimationThread.java
new file mode 100644
index 0000000..0479f87
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ShellAnimationThread.java
@@ -0,0 +1,15 @@
+package com.android.wm.shell.common.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Qualifier;
+
+/** Annotates a method or qualifies a provider that runs on the Shell animation-thread */
+@Documented
+@Inherited
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ShellAnimationThread {}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ShellMainThread.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ShellMainThread.java
new file mode 100644
index 0000000..423f4ce
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/annotations/ShellMainThread.java
@@ -0,0 +1,15 @@
+package com.android.wm.shell.common.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Qualifier;
+
+/** Annotates a method or qualifies a provider that runs on the Shell main-thread */
+@Documented
+@Inherited
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ShellMainThread {}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
new file mode 100644
index 0000000..50d9fe8
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2020 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 com.android.wm.shell.common.split;
+
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.SurfaceControlViewHost;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.internal.policy.DividerSnapAlgorithm;
+
+/**
+ * Stack divider for app pair.
+ */
+// TODO(b/172704238): add handle view to indicate touching status.
+public class DividerView extends FrameLayout implements View.OnTouchListener {
+    private final int mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
+
+    private SplitLayout mSplitLayout;
+    private SurfaceControlViewHost mViewHost;
+    private DragListener mDragListener;
+
+    private VelocityTracker mVelocityTracker;
+    private boolean mMoving;
+    private int mStartPos;
+
+    public DividerView(@NonNull Context context) {
+        super(context);
+    }
+
+    public DividerView(@NonNull Context context,
+            @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public DividerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public DividerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    /** Sets up essential dependencies of the divider bar. */
+    public void setup(
+            SplitLayout layout,
+            SurfaceControlViewHost viewHost,
+            @Nullable DragListener dragListener) {
+        mSplitLayout = layout;
+        mViewHost = viewHost;
+        mDragListener = dragListener;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        setOnTouchListener(this);
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        if (mSplitLayout == null) {
+            return false;
+        }
+
+        final int action = event.getAction() & MotionEvent.ACTION_MASK;
+        final boolean isLandscape = isLandscape();
+        // Using raw xy to prevent lost track of motion events while moving divider bar.
+        final int touchPos = isLandscape ? (int) event.getRawX() : (int) event.getRawY();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mVelocityTracker = VelocityTracker.obtain();
+                mVelocityTracker.addMovement(event);
+                setSlippery(false);
+                mStartPos = touchPos;
+                mMoving = false;
+                break;
+            case MotionEvent.ACTION_MOVE:
+                mVelocityTracker.addMovement(event);
+                if (!mMoving && Math.abs(touchPos - mStartPos) > mTouchSlop) {
+                    mStartPos = touchPos;
+                    mMoving = true;
+                    if (mDragListener != null) {
+                        mDragListener.onDragStart();
+                    }
+                }
+                if (mMoving) {
+                    final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
+                    mSplitLayout.updateDividePosition(position);
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mVelocityTracker.addMovement(event);
+                mVelocityTracker.computeCurrentVelocity(1000 /* units */);
+                final float velocity = isLandscape
+                        ? mVelocityTracker.getXVelocity()
+                        : mVelocityTracker.getYVelocity();
+                setSlippery(true);
+                mMoving = false;
+                if (mDragListener != null) {
+                    mDragListener.onDragEnd();
+                }
+
+                final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
+                final DividerSnapAlgorithm.SnapTarget snapTarget =
+                        mSplitLayout.findSnapTarget(position, velocity);
+                mSplitLayout.setSnapTarget(snapTarget);
+                break;
+        }
+        return true;
+    }
+
+    private void setSlippery(boolean slippery) {
+        if (mViewHost == null) {
+            return;
+        }
+
+        final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
+        final boolean isSlippery = (lp.flags & FLAG_SLIPPERY) != 0;
+        if (isSlippery == slippery) {
+            return;
+        }
+
+        if (slippery) {
+            lp.flags |= FLAG_SLIPPERY;
+        } else {
+            lp.flags &= ~FLAG_SLIPPERY;
+        }
+        mViewHost.relayout(lp);
+    }
+
+    private boolean isLandscape() {
+        return getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE;
+    }
+
+    /** Monitors dragging action of the divider bar. */
+    // TODO(b/172704238): add listeners to deal with resizing state of the app windows.
+    public interface DragListener {
+        /** Called when start dragging. */
+        void onDragStart();
+        /** Called when stop dragging. */
+        void onDragEnd();
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
new file mode 100644
index 0000000..e11037f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2020 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 com.android.wm.shell.common.split;
+
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_TOP;
+
+import static com.android.internal.policy.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END;
+import static com.android.internal.policy.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.view.SurfaceControl;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.policy.DividerSnapAlgorithm;
+
+/**
+ * Records and handles layout of splits. Helps to calculate proper bounds when configuration or
+ * divide position changes.
+ */
+public class SplitLayout {
+    private final int mDividerWindowWidth;
+    private final int mDividerInsets;
+    private final int mDividerSize;
+
+    private final Rect mRootBounds = new Rect();
+    private final Rect mDividerBounds = new Rect();
+    private final Rect mBounds1 = new Rect();
+    private final Rect mBounds2 = new Rect();
+    private final LayoutChangeListener mLayoutChangeListener;
+    private final SplitWindowManager mSplitWindowManager;
+
+    private Context mContext;
+    private DividerSnapAlgorithm mDividerSnapAlgorithm;
+    private int mDividePosition;
+
+    public SplitLayout(Context context, Configuration configuration,
+            LayoutChangeListener layoutChangeListener, SurfaceControl rootLeash) {
+        mContext = context.createConfigurationContext(configuration);
+        mLayoutChangeListener = layoutChangeListener;
+        mSplitWindowManager = new SplitWindowManager(mContext, configuration, rootLeash);
+
+        mDividerWindowWidth = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_divider_thickness);
+        mDividerInsets = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.docked_stack_divider_insets);
+        mDividerSize = mDividerWindowWidth - mDividerInsets * 2;
+
+        mRootBounds.set(configuration.windowConfiguration.getBounds());
+        mDividerSnapAlgorithm = getSnapAlgorithm(context.getResources(), mRootBounds);
+        mDividePosition = mDividerSnapAlgorithm.getMiddleTarget().position;
+        updateBounds(mDividePosition);
+    }
+
+    /** Gets bounds of the primary split. */
+    public Rect getBounds1() {
+        return mBounds1;
+    }
+
+    /** Gets bounds of the secondary split. */
+    public Rect getBounds2() {
+        return mBounds2;
+    }
+
+    /** Gets bounds of divider window. */
+    public Rect getDividerBounds() {
+        return mDividerBounds;
+    }
+
+    /** Returns leash of the current divider bar. */
+    @Nullable
+    public SurfaceControl getDividerLeash() {
+        return mSplitWindowManager == null ? null : mSplitWindowManager.getSurfaceControl();
+    }
+
+    int getDividePosition() {
+        return mDividePosition;
+    }
+
+    /** Applies new configuration, returns {@code false} if there's no effect to the layout. */
+    public boolean updateConfiguration(Configuration configuration) {
+        final Rect rootBounds = configuration.windowConfiguration.getBounds();
+        if (mRootBounds.equals(rootBounds)) {
+            return false;
+        }
+
+        mContext = mContext.createConfigurationContext(configuration);
+        mSplitWindowManager.setConfiguration(configuration);
+        mRootBounds.set(rootBounds);
+        mDividerSnapAlgorithm = getSnapAlgorithm(mContext.getResources(), mRootBounds);
+        mDividePosition = mDividerSnapAlgorithm.getMiddleTarget().position;
+        updateBounds(mDividePosition);
+        release();
+        init();
+        return true;
+    }
+
+    /** Updates recording bounds of divider window and both of the splits. */
+    private void updateBounds(int position) {
+        mDividerBounds.set(mRootBounds);
+        mBounds1.set(mRootBounds);
+        mBounds2.set(mRootBounds);
+        if (isLandscape(mRootBounds)) {
+            mDividerBounds.left = position - mDividerInsets;
+            mDividerBounds.right = mDividerBounds.left + mDividerWindowWidth;
+            mBounds1.right = mBounds1.left + position;
+            mBounds2.left = mBounds1.right + mDividerSize;
+        } else {
+            mDividerBounds.top = position - mDividerInsets;
+            mDividerBounds.bottom = mDividerBounds.top + mDividerWindowWidth;
+            mBounds1.bottom = mBounds1.top + position;
+            mBounds2.top = mBounds1.bottom + mDividerSize;
+        }
+    }
+
+    /** Inflates {@link DividerView} on the root surface. */
+    public void init() {
+        mSplitWindowManager.init(this);
+    }
+
+    /** Releases the surface holding the current {@link DividerView}. */
+    public void release() {
+        mSplitWindowManager.release();
+    }
+
+    /**
+     * Updates bounds with the passing position. Usually used to update recording bounds while
+     * performing animation or dragging divider bar to resize the splits.
+     */
+    public void updateDividePosition(int position) {
+        updateBounds(position);
+        mLayoutChangeListener.onBoundsChanging(this);
+    }
+
+    /**
+     * Sets new divide position and updates bounds correspondingly. Notifies listener if the new
+     * target indicates dismissing split.
+     */
+    public void setSnapTarget(DividerSnapAlgorithm.SnapTarget snapTarget) {
+        switch(snapTarget.flag) {
+            case FLAG_DISMISS_START:
+                mLayoutChangeListener.onSnappedToDismiss(false /* snappedToEnd */);
+                break;
+            case FLAG_DISMISS_END:
+                mLayoutChangeListener.onSnappedToDismiss(true /* snappedToEnd */);
+                break;
+            default:
+                mDividePosition = snapTarget.position;
+                updateBounds(mDividePosition);
+                mLayoutChangeListener.onBoundsChanged(this);
+                break;
+        }
+    }
+
+    /**
+     * Returns {@link DividerSnapAlgorithm.SnapTarget} which matches passing position and velocity.
+     */
+    public DividerSnapAlgorithm.SnapTarget findSnapTarget(int position, float velocity) {
+        return mDividerSnapAlgorithm.calculateSnapTarget(position, velocity);
+    }
+
+    private DividerSnapAlgorithm getSnapAlgorithm(Resources resources, Rect rootBounds) {
+        final boolean isLandscape = isLandscape(rootBounds);
+        return new DividerSnapAlgorithm(
+                resources,
+                rootBounds.width(),
+                rootBounds.height(),
+                mDividerSize,
+                !isLandscape,
+                new Rect() /* insets */,
+                isLandscape ? DOCKED_LEFT : DOCKED_TOP /* dockSide */);
+    }
+
+    private static boolean isLandscape(Rect bounds) {
+        return bounds.width() > bounds.height();
+    }
+
+    /** Listens layout change event. */
+    public interface LayoutChangeListener {
+        /** Calls when dismissing split. */
+        void onSnappedToDismiss(boolean snappedToEnd);
+        /** Calls when the bounds is changing due to animation or dragging divider bar. */
+        void onBoundsChanging(SplitLayout layout);
+        /** Calls when the target bounds changed. */
+        void onBoundsChanged(SplitLayout layout);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
new file mode 100644
index 0000000..e412198
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2020 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 com.android.wm.shell.common.split;
+
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
+import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
+import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Binder;
+import android.os.IBinder;
+import android.view.IWindow;
+import android.view.LayoutInflater;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
+import android.view.WindowManager;
+import android.view.WindowlessWindowManager;
+
+import androidx.annotation.Nullable;
+
+import com.android.wm.shell.R;
+
+/**
+ * Holds view hierarchy of a root surface and helps to inflate {@link DividerView} for a split.
+ */
+public final class SplitWindowManager extends WindowlessWindowManager {
+    private static final String DIVIDER_WINDOW_TITLE = "SplitDivider";
+
+    private Context mContext;
+    private SurfaceControlViewHost mViewHost;
+
+    public SplitWindowManager(Context context, Configuration config, SurfaceControl rootSurface) {
+        super(config, rootSurface, null /* hostInputToken */);
+        mContext = context.createConfigurationContext(config);
+    }
+
+    @Override
+    public void setTouchRegion(IBinder window, Region region) {
+        super.setTouchRegion(window, region);
+    }
+
+    @Override
+    public SurfaceControl getSurfaceControl(IWindow window) {
+        return super.getSurfaceControl(window);
+    }
+
+    @Override
+    public void setConfiguration(Configuration configuration) {
+        super.setConfiguration(configuration);
+        mContext = mContext.createConfigurationContext(configuration);
+    }
+
+    /** Inflates {@link DividerView} on to the root surface. */
+    void init(SplitLayout splitLayout) {
+        if (mViewHost == null) {
+            mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
+        }
+
+        final Rect dividerBounds = splitLayout.getDividerBounds();
+        final DividerView dividerView = (DividerView) LayoutInflater.from(mContext)
+                .inflate(R.layout.split_divider, null /* root */);
+
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                dividerBounds.width(), dividerBounds.height(), TYPE_DOCK_DIVIDER,
+                FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_WATCH_OUTSIDE_TOUCH
+                        | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY,
+                PixelFormat.TRANSLUCENT);
+        lp.token = new Binder();
+        lp.setTitle(DIVIDER_WINDOW_TITLE);
+        lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
+        mViewHost.setView(dividerView, lp);
+        dividerView.setup(splitLayout, mViewHost, null /* dragListener */);
+    }
+
+    /**
+     * Releases the surface control of the current {@link DividerView} and tear down the view
+     * hierarchy.
+     */
+    void release() {
+        if (mViewHost == null) return;
+        mViewHost.release();
+        mViewHost = null;
+    }
+
+    /**
+     * Gets {@link SurfaceControl} of the surface holding divider view. @return {@code null} if not
+     * feasible.
+     */
+    @Nullable
+    SurfaceControl getSurfaceControl() {
+        return mViewHost == null ? null : getSurfaceControl(mViewHost.getWindowToken());
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java
index 38e0519..3a2f0da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutout.java
@@ -20,11 +20,14 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.wm.shell.common.annotations.ExternalThread;
+
 import java.io.PrintWriter;
 
 /**
  * Interface to engage hide display cutout feature.
  */
+@ExternalThread
 public interface HideDisplayCutout {
     /**
      * Notifies {@link Configuration} changed.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
index 9bb709f..821a007 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java
@@ -18,6 +18,7 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.wm.shell.common.annotations.ExternalThread;
 import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback;
 
 import java.io.PrintWriter;
@@ -25,6 +26,7 @@
 /**
  * Interface to engage one handed feature.
  */
+@ExternalThread
 public interface OneHanded {
     /**
      * Return one handed settings enabled or not.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
index 993e0e7..5593268 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
@@ -19,12 +19,16 @@
 import android.app.RemoteAction;
 import android.content.ComponentName;
 import android.content.pm.ParceledListSlice;
+import android.os.RemoteException;
 import android.view.DisplayInfo;
-import android.view.IPinnedStackController;
 import android.view.IPinnedStackListener;
+import android.view.WindowManagerGlobal;
+
+import androidx.annotation.BinderThread;
+
+import com.android.wm.shell.common.ShellExecutor;
 
 import java.util.ArrayList;
-import java.util.List;
 
 /**
  * PinnedStackListener that simply forwards all calls to each listener added via
@@ -32,8 +36,15 @@
  * {@link com.android.server.wm.WindowManagerService#registerPinnedStackListener} replaces any
  * previously set listener.
  */
-public class PinnedStackListenerForwarder extends IPinnedStackListener.Stub {
-    private List<PinnedStackListener> mListeners = new ArrayList<>();
+public class PinnedStackListenerForwarder {
+
+    private final IPinnedStackListener mListenerImpl = new PinnedStackListenerImpl();
+    private final ShellExecutor mShellMainExecutor;
+    private final ArrayList<PinnedStackListener> mListeners = new ArrayList<>();
+
+    public PinnedStackListenerForwarder(ShellExecutor shellMainExecutor) {
+        mShellMainExecutor = shellMainExecutor;
+    }
 
     /** Adds a listener to receive updates from the WindowManagerService. */
     public void addListener(PinnedStackListener listener) {
@@ -45,69 +56,110 @@
         mListeners.remove(listener);
     }
 
-    @Override
-    public void onListenerRegistered(IPinnedStackController controller) {
-        for (PinnedStackListener listener : mListeners) {
-            listener.onListenerRegistered(controller);
-        }
+    public void register(int displayId) throws RemoteException {
+        WindowManagerGlobal.getWindowManagerService().registerPinnedStackListener(
+                displayId, mListenerImpl);
     }
 
-    @Override
-    public void onMovementBoundsChanged(boolean fromImeAdjustment) {
+    private void onMovementBoundsChanged(boolean fromImeAdjustment) {
         for (PinnedStackListener listener : mListeners) {
             listener.onMovementBoundsChanged(fromImeAdjustment);
         }
     }
 
-    @Override
-    public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+    private void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
         for (PinnedStackListener listener : mListeners) {
             listener.onImeVisibilityChanged(imeVisible, imeHeight);
         }
     }
 
-    @Override
-    public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
+    private void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
         for (PinnedStackListener listener : mListeners) {
             listener.onActionsChanged(actions);
         }
     }
 
-    @Override
-    public void onActivityHidden(ComponentName componentName) {
+    private void onActivityHidden(ComponentName componentName) {
         for (PinnedStackListener listener : mListeners) {
             listener.onActivityHidden(componentName);
         }
     }
 
-    @Override
-    public void onDisplayInfoChanged(DisplayInfo displayInfo) {
+    private void onDisplayInfoChanged(DisplayInfo displayInfo) {
         for (PinnedStackListener listener : mListeners) {
             listener.onDisplayInfoChanged(displayInfo);
         }
     }
 
-    @Override
-    public void onConfigurationChanged() {
+    private void onConfigurationChanged() {
         for (PinnedStackListener listener : mListeners) {
             listener.onConfigurationChanged();
         }
     }
 
-    @Override
-    public void onAspectRatioChanged(float aspectRatio) {
+    private void onAspectRatioChanged(float aspectRatio) {
         for (PinnedStackListener listener : mListeners) {
             listener.onAspectRatioChanged(aspectRatio);
         }
     }
 
+    @BinderThread
+    private class PinnedStackListenerImpl extends IPinnedStackListener.Stub {
+        @Override
+        public void onMovementBoundsChanged(boolean fromImeAdjustment) {
+            mShellMainExecutor.execute(() -> {
+                PinnedStackListenerForwarder.this.onMovementBoundsChanged(fromImeAdjustment);
+            });
+        }
+
+        @Override
+        public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+            mShellMainExecutor.execute(() -> {
+                PinnedStackListenerForwarder.this.onImeVisibilityChanged(imeVisible, imeHeight);
+            });
+        }
+
+        @Override
+        public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
+            mShellMainExecutor.execute(() -> {
+                PinnedStackListenerForwarder.this.onActionsChanged(actions);
+            });
+        }
+
+        @Override
+        public void onActivityHidden(ComponentName componentName) {
+            mShellMainExecutor.execute(() -> {
+                PinnedStackListenerForwarder.this.onActivityHidden(componentName);
+            });
+        }
+
+        @Override
+        public void onDisplayInfoChanged(DisplayInfo displayInfo) {
+            mShellMainExecutor.execute(() -> {
+                PinnedStackListenerForwarder.this.onDisplayInfoChanged(displayInfo);
+            });
+        }
+
+        @Override
+        public void onConfigurationChanged() {
+            mShellMainExecutor.execute(() -> {
+                PinnedStackListenerForwarder.this.onConfigurationChanged();
+            });
+        }
+
+        @Override
+        public void onAspectRatioChanged(float aspectRatio) {
+            mShellMainExecutor.execute(() -> {
+                PinnedStackListenerForwarder.this.onAspectRatioChanged(aspectRatio);
+            });
+        }
+    }
+
     /**
      * A counterpart of {@link IPinnedStackListener} with empty implementations.
      * Subclasses can ignore those methods they do not intend to take action upon.
      */
     public static class PinnedStackListener {
-        public void onListenerRegistered(IPinnedStackController controller) {}
-
         public void onMovementBoundsChanged(boolean fromImeAdjustment) {}
 
         public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
index 9fa222a..da9ce0a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
@@ -17,12 +17,12 @@
 package com.android.wm.shell.pip;
 
 import android.annotation.Nullable;
-import android.app.ActivityManager;
 import android.app.PictureInPictureParams;
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
 import android.graphics.Rect;
 
+import com.android.wm.shell.common.annotations.ExternalThread;
 import com.android.wm.shell.pip.phone.PipTouchHandler;
 
 import java.io.PrintWriter;
@@ -31,6 +31,7 @@
 /**
  * Interface to engage picture in picture feature.
  */
+@ExternalThread
 public interface Pip {
     /**
      * Closes PIP (PIPed activity and PIP system UI).
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index d829462..fe01811 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -54,6 +54,7 @@
     public static final int TRANSITION_DIRECTION_LEAVE_PIP = 3;
     public static final int TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN = 4;
     public static final int TRANSITION_DIRECTION_REMOVE_STACK = 5;
+    public static final int TRANSITION_DIRECTION_SNAP_AFTER_RESIZE = 6;
 
     @IntDef(prefix = { "TRANSITION_DIRECTION_" }, value = {
             TRANSITION_DIRECTION_NONE,
@@ -61,7 +62,8 @@
             TRANSITION_DIRECTION_TO_PIP,
             TRANSITION_DIRECTION_LEAVE_PIP,
             TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN,
-            TRANSITION_DIRECTION_REMOVE_STACK
+            TRANSITION_DIRECTION_REMOVE_STACK,
+            TRANSITION_DIRECTION_SNAP_AFTER_RESIZE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface TransitionDirection {}
@@ -109,13 +111,27 @@
     }
 
     @SuppressWarnings("unchecked")
+    /**
+     * Construct and return an animator that animates from the {@param startBounds} to the
+     * {@param endBounds} with the given {@param direction}. If {@param direction} is type
+     * {@link ANIM_TYPE_BOUNDS}, then {@param sourceHintRect} will be used to animate
+     * in a better, more smooth manner.
+     *
+     * In the case where one wants to start animation during an intermediate animation (for example,
+     * if the user is currently doing a pinch-resize, and upon letting go now PiP needs to animate
+     * to the correct snap fraction region), then provide the base bounds, which is current PiP
+     * leash bounds before transformation/any animation. This is so when we try to construct
+     * the different transformation matrices for the animation, we are constructing this based off
+     * the PiP original bounds, rather than the {@param startBounds}, which is post-transformed.
+     */
     @VisibleForTesting
-    public PipTransitionAnimator getAnimator(SurfaceControl leash, Rect startBounds, Rect endBounds,
-            Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction) {
+    public PipTransitionAnimator getAnimator(SurfaceControl leash, Rect baseBounds,
+            Rect startBounds, Rect endBounds, Rect sourceHintRect,
+            @PipAnimationController.TransitionDirection int direction) {
         if (mCurrentAnimator == null) {
             mCurrentAnimator = setupPipTransitionAnimator(
-                    PipTransitionAnimator.ofBounds(leash, startBounds, endBounds, sourceHintRect,
-                            direction));
+                    PipTransitionAnimator.ofBounds(leash, startBounds, startBounds, endBounds,
+                            sourceHintRect, direction));
         } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA
                 && mCurrentAnimator.isRunning()) {
             // If we are still animating the fade into pip, then just move the surface and ensure
@@ -130,8 +146,8 @@
         } else {
             mCurrentAnimator.cancel();
             mCurrentAnimator = setupPipTransitionAnimator(
-                    PipTransitionAnimator.ofBounds(leash, startBounds, endBounds, sourceHintRect,
-                            direction));
+                    PipTransitionAnimator.ofBounds(leash, baseBounds, startBounds, endBounds,
+                            sourceHintRect, direction));
         }
         return mCurrentAnimator;
     }
@@ -180,6 +196,7 @@
         private final @AnimationType int mAnimationType;
         private final Rect mDestinationBounds = new Rect();
 
+        private T mBaseValue;
         protected T mCurrentValue;
         protected T mStartValue;
         private T mEndValue;
@@ -190,10 +207,11 @@
         private @TransitionDirection int mTransitionDirection;
 
         private PipTransitionAnimator(SurfaceControl leash, @AnimationType int animationType,
-                Rect destinationBounds, T startValue, T endValue) {
+                Rect destinationBounds, T baseValue, T startValue, T endValue) {
             mLeash = leash;
             mAnimationType = animationType;
             mDestinationBounds.set(destinationBounds);
+            mBaseValue = baseValue;
             mStartValue = startValue;
             mEndValue = endValue;
             addListener(this);
@@ -263,6 +281,10 @@
             return mStartValue;
         }
 
+        T getBaseValue() {
+            return mBaseValue;
+        }
+
         @VisibleForTesting
         public T getEndValue() {
             return mEndValue;
@@ -334,7 +356,7 @@
         static PipTransitionAnimator<Float> ofAlpha(SurfaceControl leash,
                 Rect destinationBounds, float startValue, float endValue) {
             return new PipTransitionAnimator<Float>(leash, ANIM_TYPE_ALPHA,
-                    destinationBounds, startValue, endValue) {
+                    destinationBounds, startValue, startValue, endValue) {
                 @Override
                 void applySurfaceControlTransaction(SurfaceControl leash,
                         SurfaceControl.Transaction tx, float fraction) {
@@ -367,7 +389,7 @@
         }
 
         static PipTransitionAnimator<Rect> ofBounds(SurfaceControl leash,
-                Rect startValue, Rect endValue, Rect sourceHintRect,
+                Rect baseValue, Rect startValue, Rect endValue, Rect sourceHintRect,
                 @PipAnimationController.TransitionDirection int direction) {
             // Just for simplicity we'll interpolate between the source rect hint insets and empty
             // insets to calculate the window crop
@@ -375,7 +397,7 @@
             if (isOutPipDirection(direction)) {
                 initialSourceValue = new Rect(endValue);
             } else {
-                initialSourceValue = new Rect(startValue);
+                initialSourceValue = new Rect(baseValue);
             }
 
             final Rect sourceHintRectInsets;
@@ -391,22 +413,24 @@
 
             // construct new Rect instances in case they are recycled
             return new PipTransitionAnimator<Rect>(leash, ANIM_TYPE_BOUNDS,
-                    endValue, new Rect(startValue), new Rect(endValue)) {
+                    endValue, new Rect(baseValue), new Rect(startValue), new Rect(endValue)) {
                 private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
                 private final RectEvaluator mInsetsEvaluator = new RectEvaluator(new Rect());
 
                 @Override
                 void applySurfaceControlTransaction(SurfaceControl leash,
                         SurfaceControl.Transaction tx, float fraction) {
+                    final Rect base = getBaseValue();
                     final Rect start = getStartValue();
                     final Rect end = getEndValue();
                     Rect bounds = mRectEvaluator.evaluate(fraction, start, end);
                     setCurrentValue(bounds);
                     if (inScaleTransition() || sourceHintRect == null) {
+
                         if (isOutPipDirection(direction)) {
                             getSurfaceTransactionHelper().scale(tx, leash, end, bounds);
                         } else {
-                            getSurfaceTransactionHelper().scale(tx, leash, start, bounds);
+                            getSurfaceTransactionHelper().scale(tx, leash, base, bounds);
                         }
                     } else {
                         final Rect insets;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 98ed822..167b9f9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -30,6 +30,7 @@
 import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_NONE;
 import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_REMOVE_STACK;
 import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_SAME;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_SNAP_AFTER_RESIZE;
 import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
 import static com.android.wm.shell.pip.PipAnimationController.isInPipDirection;
 import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection;
@@ -814,6 +815,20 @@
                 TRANSITION_DIRECTION_NONE, duration, updateBoundsCallback);
     }
 
+    /**
+     * Animates resizing of the pinned stack given the duration and start bounds.
+     * This is used when the starting bounds is not the current PiP bounds.
+     */
+    public void scheduleAnimateResizePip(Rect fromBounds, Rect toBounds, int duration,
+            Consumer<Rect> updateBoundsCallback) {
+        if (mShouldDeferEnteringPip) {
+            Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
+            return;
+        }
+        scheduleAnimateResizePip(fromBounds, toBounds, null /* sourceHintRect */,
+                TRANSITION_DIRECTION_SNAP_AFTER_RESIZE, duration, updateBoundsCallback);
+    }
+
     private void scheduleAnimateResizePip(Rect currentBounds, Rect destinationBounds,
             Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction,
             int durationMs, Consumer<Rect> updateBoundsCallback) {
@@ -1073,8 +1088,11 @@
             Log.w(TAG, "Abort animation, invalid leash");
             return;
         }
+        Rect baseBounds = direction == TRANSITION_DIRECTION_SNAP_AFTER_RESIZE
+                ? mPipBoundsState.getBounds() : currentBounds;
         mPipAnimationController
-                .getAnimator(mLeash, currentBounds, destinationBounds, sourceHintRect, direction)
+                .getAnimator(mLeash, baseBounds, currentBounds, destinationBounds, sourceHintRect,
+                        direction)
                 .setTransitionDirection(direction)
                 .setPipAnimationCallback(mPipAnimationCallback)
                 .setDuration(durationMs)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java
index f153aa5..7194fc7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java
@@ -20,15 +20,18 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.RemoteException;
 import android.view.MagnificationSpec;
+import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 
+import androidx.annotation.BinderThread;
+
 import com.android.wm.shell.R;
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.pip.PipBoundsState;
 import com.android.wm.shell.pip.PipSnapAlgorithm;
 import com.android.wm.shell.pip.PipTaskOrganizer;
@@ -40,8 +43,7 @@
  * Expose the touch actions to accessibility as if this object were a window with a single view.
  * That pseudo-view exposes all of the actions this object can perform.
  */
-public class PipAccessibilityInteractionConnection
-        extends IAccessibilityInteractionConnection.Stub {
+public class PipAccessibilityInteractionConnection {
 
     public interface AccessibilityCallbacks {
         void onAccessibilityShowMenu();
@@ -50,14 +52,15 @@
     private static final long ACCESSIBILITY_NODE_ID = 1;
     private List<AccessibilityNodeInfo> mAccessibilityNodeInfoList;
 
-    private Context mContext;
-    private Handler mHandler;
+    private final Context mContext;
+    private final ShellExecutor mShellMainExcutor;
     private final @NonNull PipBoundsState mPipBoundsState;
-    private PipMotionHelper mMotionHelper;
-    private PipTaskOrganizer mTaskOrganizer;
-    private PipSnapAlgorithm mSnapAlgorithm;
-    private Runnable mUpdateMovementBoundCallback;
-    private AccessibilityCallbacks mCallbacks;
+    private final PipMotionHelper mMotionHelper;
+    private final PipTaskOrganizer mTaskOrganizer;
+    private final PipSnapAlgorithm mSnapAlgorithm;
+    private final Runnable mUpdateMovementBoundCallback;
+    private final AccessibilityCallbacks mCallbacks;
+    private final IAccessibilityInteractionConnection mConnectionImpl;
 
     private final Rect mNormalBounds = new Rect();
     private final Rect mExpandedBounds = new Rect();
@@ -69,19 +72,23 @@
             @NonNull PipBoundsState pipBoundsState, PipMotionHelper motionHelper,
             PipTaskOrganizer taskOrganizer, PipSnapAlgorithm snapAlgorithm,
             AccessibilityCallbacks callbacks, Runnable updateMovementBoundCallback,
-            Handler handler) {
+            ShellExecutor shellMainExcutor) {
         mContext = context;
-        mHandler = handler;
+        mShellMainExcutor = shellMainExcutor;
         mPipBoundsState = pipBoundsState;
         mMotionHelper = motionHelper;
         mTaskOrganizer = taskOrganizer;
         mSnapAlgorithm = snapAlgorithm;
         mUpdateMovementBoundCallback = updateMovementBoundCallback;
         mCallbacks = callbacks;
+        mConnectionImpl = new PipAccessibilityInteractionConnectionImpl();
     }
 
-    @Override
-    public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId,
+    public void register(AccessibilityManager am) {
+        am.setPictureInPictureActionReplacingConnection(mConnectionImpl);
+    }
+
+    private void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId,
             Region interactiveRegion, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags,
             int interrogatingPid, long interrogatingTid, MagnificationSpec spec, Bundle args) {
@@ -94,8 +101,7 @@
         }
     }
 
-    @Override
-    public void performAccessibilityAction(long accessibilityNodeId, int action,
+    private void performAccessibilityAction(long accessibilityNodeId, int action,
             Bundle arguments, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags,
             int interrogatingPid, long interrogatingTid) {
@@ -115,9 +121,7 @@
             } else {
                 switch (action) {
                     case AccessibilityNodeInfo.ACTION_CLICK:
-                        mHandler.post(() -> {
-                            mCallbacks.onAccessibilityShowMenu();
-                        });
+                        mCallbacks.onAccessibilityShowMenu();
                         result = true;
                         break;
                     case AccessibilityNodeInfo.ACTION_DISMISS:
@@ -172,8 +176,7 @@
         });
     }
 
-    @Override
-    public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
+    private void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
             String viewId, Region interactiveRegion, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags,
             int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
@@ -185,8 +188,7 @@
         }
     }
 
-    @Override
-    public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text,
+    private void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text,
             Region interactiveRegion, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags,
             int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
@@ -198,8 +200,7 @@
         }
     }
 
-    @Override
-    public void findFocus(long accessibilityNodeId, int focusType, Region interactiveRegion,
+    private void findFocus(long accessibilityNodeId, int focusType, Region interactiveRegion,
             int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
             int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
         // We have no view that can take focus
@@ -210,8 +211,7 @@
         }
     }
 
-    @Override
-    public void focusSearch(long accessibilityNodeId, int direction, Region interactiveRegion,
+    private void focusSearch(long accessibilityNodeId, int direction, Region interactiveRegion,
             int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
             int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
         // We have no view that can take focus
@@ -222,16 +222,6 @@
         }
     }
 
-    @Override
-    public void clearAccessibilityFocus() {
-        // We should not be here.
-    }
-
-    @Override
-    public void notifyOutsideTouch() {
-        // Do nothing.
-    }
-
     /**
      * Update the normal and expanded bounds so they can be used for Resize.
      */
@@ -271,4 +261,95 @@
         mAccessibilityNodeInfoList.add(info);
         return mAccessibilityNodeInfoList;
     }
+
+    @BinderThread
+    private class PipAccessibilityInteractionConnectionImpl
+            extends IAccessibilityInteractionConnection.Stub {
+        @Override
+        public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId,
+                Region bounds, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec,
+                Bundle arguments) throws RemoteException {
+            mShellMainExcutor.execute(() -> {
+                PipAccessibilityInteractionConnection.this
+                        .findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId, bounds,
+                                interactionId, callback, flags, interrogatingPid, interrogatingTid,
+                                spec, arguments);
+            });
+        }
+
+        @Override
+        public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId,
+                Region bounds, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec)
+                throws RemoteException {
+            mShellMainExcutor.execute(() -> {
+                PipAccessibilityInteractionConnection.this.findAccessibilityNodeInfosByViewId(
+                        accessibilityNodeId, viewId, bounds, interactionId, callback, flags,
+                        interrogatingPid, interrogatingTid, spec);
+            });
+        }
+
+        @Override
+        public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text,
+                Region bounds, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec)
+                throws RemoteException {
+            mShellMainExcutor.execute(() -> {
+                PipAccessibilityInteractionConnection.this.findAccessibilityNodeInfosByText(
+                        accessibilityNodeId, text, bounds, interactionId, callback, flags,
+                        interrogatingPid, interrogatingTid, spec);
+            });
+        }
+
+        @Override
+        public void findFocus(long accessibilityNodeId, int focusType, Region bounds,
+                int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec)
+                throws RemoteException {
+            mShellMainExcutor.execute(() -> {
+                PipAccessibilityInteractionConnection.this.findFocus(accessibilityNodeId, focusType,
+                        bounds, interactionId, callback, flags, interrogatingPid, interrogatingTid,
+                        spec);
+            });
+        }
+
+        @Override
+        public void focusSearch(long accessibilityNodeId, int direction, Region bounds,
+                int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec)
+                throws RemoteException {
+            mShellMainExcutor.execute(() -> {
+                PipAccessibilityInteractionConnection.this.focusSearch(accessibilityNodeId,
+                        direction,
+                        bounds, interactionId, callback, flags, interrogatingPid, interrogatingTid,
+                        spec);
+            });
+        }
+
+        @Override
+        public void performAccessibilityAction(long accessibilityNodeId, int action,
+                Bundle arguments, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid) throws RemoteException {
+            mShellMainExcutor.execute(() -> {
+                PipAccessibilityInteractionConnection.this.performAccessibilityAction(
+                        accessibilityNodeId, action, arguments, interactionId, callback, flags,
+                        interrogatingPid, interrogatingTid);
+            });
+        }
+
+        @Override
+        public void clearAccessibilityFocus() throws RemoteException {
+            // Do nothing
+        }
+
+        @Override
+        public void notifyOutsideTouch() throws RemoteException {
+            // Do nothing
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index db02e28..3234ef6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -41,7 +41,6 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.view.DisplayInfo;
-import android.view.IPinnedStackController;
 import android.view.WindowManagerGlobal;
 import android.window.WindowContainerTransaction;
 
@@ -52,7 +51,6 @@
 import com.android.wm.shell.common.DisplayChangeController;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.PipInputConsumer;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TaskStackListenerCallback;
 import com.android.wm.shell.common.TaskStackListenerImpl;
@@ -163,63 +161,50 @@
     private class PipControllerPinnedStackListener extends
             PinnedStackListenerForwarder.PinnedStackListener {
         @Override
-        public void onListenerRegistered(IPinnedStackController controller) {
-            mMainExecutor.execute(() -> mTouchHandler.setPinnedStackController(controller));
-        }
-
-        @Override
         public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
-            mMainExecutor.execute(() -> {
-                mPipBoundsState.setImeVisibility(imeVisible, imeHeight);
-                mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
-            });
+            mPipBoundsState.setImeVisibility(imeVisible, imeHeight);
+            mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
         }
 
         @Override
         public void onMovementBoundsChanged(boolean fromImeAdjustment) {
-            mMainExecutor.execute(() -> updateMovementBounds(null /* toBounds */,
+            updateMovementBounds(null /* toBounds */,
                     false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */,
-                    null /* windowContainerTransaction */));
+                    null /* windowContainerTransaction */);
         }
 
         @Override
         public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
-            mMainExecutor.execute(() -> mMenuController.setAppActions(actions));
+            mMenuController.setAppActions(actions);
         }
 
         @Override
         public void onActivityHidden(ComponentName componentName) {
-            mMainExecutor.execute(() -> {
-                if (componentName.equals(mPipBoundsState.getLastPipComponentName())) {
-                    // The activity was removed, we don't want to restore to the reentry state
-                    // saved for this component anymore.
-                    mPipBoundsState.setLastPipComponentName(null);
-                }
-            });
+            if (componentName.equals(mPipBoundsState.getLastPipComponentName())) {
+                // The activity was removed, we don't want to restore to the reentry state
+                // saved for this component anymore.
+                mPipBoundsState.setLastPipComponentName(null);
+            }
         }
 
         @Override
         public void onDisplayInfoChanged(DisplayInfo displayInfo) {
-            mMainExecutor.execute(() -> mPipBoundsState.setDisplayInfo(displayInfo));
+            mPipBoundsState.setDisplayInfo(displayInfo);
         }
 
         @Override
         public void onConfigurationChanged() {
-            mMainExecutor.execute(() -> {
-                mPipBoundsAlgorithm.onConfigurationChanged(mContext);
-                mTouchHandler.onConfigurationChanged();
-                mPipBoundsState.onConfigurationChanged();
-            });
+            mPipBoundsAlgorithm.onConfigurationChanged(mContext);
+            mTouchHandler.onConfigurationChanged();
+            mPipBoundsState.onConfigurationChanged();
         }
 
         @Override
         public void onAspectRatioChanged(float aspectRatio) {
             // TODO(b/169373982): Remove this callback as it is redundant with PipTaskOrg params
             // change.
-            mMainExecutor.execute(() -> {
-                mPipBoundsState.setAspectRatio(aspectRatio);
-                mTouchHandler.onAspectRatioChanged();
-            });
+            mPipBoundsState.setAspectRatio(aspectRatio);
+            mTouchHandler.onAspectRatioChanged();
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
new file mode 100644
index 0000000..0c64c8c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2020 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 com.android.wm.shell.pip.phone;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.BatchedInputEventReceiver;
+import android.view.Choreographer;
+import android.view.IWindowManager;
+import android.view.InputChannel;
+import android.view.InputEvent;
+
+import java.io.PrintWriter;
+
+/**
+ * Manages the input consumer that allows the Shell to directly receive input.
+ */
+public class PipInputConsumer {
+
+    private static final String TAG = PipInputConsumer.class.getSimpleName();
+
+    /**
+     * Listener interface for callers to subscribe to input events.
+     */
+    public interface InputListener {
+        /** Handles any input event. */
+        boolean onInputEvent(InputEvent ev);
+    }
+
+    /**
+     * Listener interface for callers to learn when this class is registered or unregistered with
+     * window manager
+     */
+    public interface RegistrationListener {
+        void onRegistrationChanged(boolean isRegistered);
+    }
+
+    /**
+     * Input handler used for the input consumer. Input events are batched and consumed with the
+     * SurfaceFlinger vsync.
+     */
+    private final class InputEventReceiver extends BatchedInputEventReceiver {
+
+        InputEventReceiver(InputChannel inputChannel, Looper looper,
+                Choreographer choreographer) {
+            super(inputChannel, looper, choreographer);
+        }
+
+        @Override
+        public void onInputEvent(InputEvent event) {
+            boolean handled = true;
+            try {
+                if (mListener != null) {
+                    handled = mListener.onInputEvent(event);
+                }
+            } finally {
+                finishInputEvent(event, handled);
+            }
+        }
+    }
+
+    private final IWindowManager mWindowManager;
+    private final IBinder mToken;
+    private final String mName;
+
+    private InputEventReceiver mInputEventReceiver;
+    private InputListener mListener;
+    private RegistrationListener mRegistrationListener;
+
+    /**
+     * @param name the name corresponding to the input consumer that is defined in the system.
+     */
+    public PipInputConsumer(IWindowManager windowManager, String name) {
+        mWindowManager = windowManager;
+        mToken = new Binder();
+        mName = name;
+    }
+
+    /**
+     * Sets the input listener.
+     */
+    public void setInputListener(InputListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Sets the registration listener.
+     */
+    public void setRegistrationListener(RegistrationListener listener) {
+        mRegistrationListener = listener;
+        if (mRegistrationListener != null) {
+            mRegistrationListener.onRegistrationChanged(mInputEventReceiver != null);
+        }
+    }
+
+    /**
+     * Check if the InputConsumer is currently registered with WindowManager
+     *
+     * @return {@code true} if registered, {@code false} if not.
+     */
+    public boolean isRegistered() {
+        return mInputEventReceiver != null;
+    }
+
+    /**
+     * Registers the input consumer.
+     */
+    public void registerInputConsumer() {
+        registerInputConsumer(false);
+    }
+
+    /**
+     * Registers the input consumer.
+     * @param withSfVsync the flag set using sf vsync signal or no
+     */
+    public void registerInputConsumer(boolean withSfVsync) {
+        if (mInputEventReceiver != null) {
+            return;
+        }
+        final InputChannel inputChannel = new InputChannel();
+        try {
+            // TODO(b/113087003): Support Picture-in-picture in multi-display.
+            mWindowManager.destroyInputConsumer(mName, DEFAULT_DISPLAY);
+            mWindowManager.createInputConsumer(mToken, mName, DEFAULT_DISPLAY, inputChannel);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to create input consumer", e);
+        }
+        mInputEventReceiver = new InputEventReceiver(inputChannel, Looper.myLooper(),
+                withSfVsync ? Choreographer.getSfInstance() : Choreographer.getInstance());
+        if (mRegistrationListener != null) {
+            mRegistrationListener.onRegistrationChanged(true /* isRegistered */);
+        }
+    }
+
+    /**
+     * Unregisters the input consumer.
+     */
+    public void unregisterInputConsumer() {
+        if (mInputEventReceiver == null) {
+            return;
+        }
+        try {
+            // TODO(b/113087003): Support Picture-in-picture in multi-display.
+            mWindowManager.destroyInputConsumer(mName, DEFAULT_DISPLAY);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to destroy input consumer", e);
+        }
+        mInputEventReceiver.dispose();
+        mInputEventReceiver = null;
+        if (mRegistrationListener != null) {
+            mRegistrationListener.onRegistrationChanged(false /* isRegistered */);
+        }
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "registered=" + (mInputEventReceiver != null));
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 4e991f2..2e10fc9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -475,7 +475,7 @@
             final Intent settingsIntent = new Intent(ACTION_PICTURE_IN_PICTURE_SETTINGS,
                     Uri.fromParts("package", topPipActivityInfo.first.getPackageName(), null));
             settingsIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
-            mContext.startActivityAsUser(settingsIntent, UserHandle.CURRENT);
+            mContext.startActivityAsUser(settingsIntent, UserHandle.of(topPipActivityInfo.second));
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java
new file mode 100644
index 0000000..28cbe35
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2020 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 com.android.wm.shell.pip.phone;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+
+/**
+ * Helper class to calculate the new size given two-fingers pinch to resize.
+ */
+public class PipPinchResizingAlgorithm {
+    private static final Rect TMP_RECT = new Rect();
+    /**
+     * Given inputs and requirements and current PiP bounds, return the new size.
+     *
+     * @param x0 x-coordinate of the primary input.
+     * @param y0 y-coordinate of the primary input.
+     * @param x1 x-coordinate of the secondary input.
+     * @param y1 y-coordinate of the secondary input.
+     * @param downx0 x-coordinate of the original down point of the primary input.
+     * @param downy0 y-coordinate of the original down ponit of the primary input.
+     * @param downx1 x-coordinate of the original down point of the secondary input.
+     * @param downy1 y-coordinate of the original down point of the secondary input.
+     * @param currentPipBounds current PiP bounds.
+     * @param minVisibleWidth minimum visible width.
+     * @param minVisibleHeight minimum visible height.
+     * @param maxSize max size.
+     * @return The new resized PiP bounds, sharing the same center.
+     */
+    public static Rect pinchResize(float x0, float y0, float x1, float y1,
+            float downx0, float downy0, float downx1, float downy1, Rect currentPipBounds,
+            int minVisibleWidth, int minVisibleHeight, Point maxSize) {
+
+        int width = currentPipBounds.width();
+        int height = currentPipBounds.height();
+        int left = currentPipBounds.left;
+        int top = currentPipBounds.top;
+        int right = currentPipBounds.right;
+        int bottom = currentPipBounds.bottom;
+        final float aspect = (float) width / (float) height;
+        final int widthDelta = Math.round(Math.abs(x0 - x1) - Math.abs(downx0 - downx1));
+        final int heightDelta = Math.round(Math.abs(y0 - y1) - Math.abs(downy0 - downy1));
+
+        width = Math.max(minVisibleWidth, Math.min(width + widthDelta, maxSize.x));
+        height = Math.max(minVisibleHeight, Math.min(height + heightDelta, maxSize.y));
+
+        // Calculate 2 rectangles fulfilling all requirements for either X or Y being the major
+        // drag axis. What ever is producing the bigger rectangle will be chosen.
+        int width1;
+        int width2;
+        int height1;
+        int height2;
+        if (aspect > 1.0f) {
+            // Assuming that the width is our target we calculate the height.
+            width1 = Math.max(minVisibleWidth, Math.min(maxSize.x, width));
+            height1 = Math.round((float) width1 / aspect);
+            if (height1 < minVisibleHeight) {
+                // If the resulting height is too small we adjust to the minimal size.
+                height1 = minVisibleHeight;
+                width1 = Math.max(minVisibleWidth,
+                        Math.min(maxSize.x, Math.round((float) height1 * aspect)));
+            }
+            // Assuming that the height is our target we calculate the width.
+            height2 = Math.max(minVisibleHeight, Math.min(maxSize.y, height));
+            width2 = Math.round((float) height2 * aspect);
+            if (width2 < minVisibleWidth) {
+                // If the resulting width is too small we adjust to the minimal size.
+                width2 = minVisibleWidth;
+                height2 = Math.max(minVisibleHeight,
+                        Math.min(maxSize.y, Math.round((float) width2 / aspect)));
+            }
+        } else {
+            // Assuming that the width is our target we calculate the height.
+            width1 = Math.max(minVisibleWidth, Math.min(maxSize.x, width));
+            height1 = Math.round((float) width1 * aspect);
+            if (height1 < minVisibleHeight) {
+                // If the resulting height is too small we adjust to the minimal size.
+                height1 = minVisibleHeight;
+                width1 = Math.max(minVisibleWidth,
+                        Math.min(maxSize.x, Math.round((float) height1 / aspect)));
+            }
+            // Assuming that the height is our target we calculate the width.
+            height2 = Math.max(minVisibleHeight, Math.min(maxSize.y, height));
+            width2 = Math.round((float) height2 / aspect);
+            if (width2 < minVisibleWidth) {
+                // If the resulting width is too small we adjust to the minimal size.
+                width2 = minVisibleWidth;
+                height2 = Math.max(minVisibleHeight,
+                        Math.min(maxSize.y, Math.round((float) width2 * aspect)));
+            }
+        }
+
+        // Use the bigger of the two rectangles if the major change was positive, otherwise
+        // do the opposite.
+        final boolean grows = width > (right - left) || height > (bottom - top);
+        if (grows == (width1 * height1 > width2 * height2)) {
+            width = width1;
+            height = height1;
+        } else {
+            width = width2;
+            height = height2;
+        }
+
+        TMP_RECT.set(currentPipBounds.centerX() - width / 2,
+                currentPipBounds.centerY() - height / 2,
+                currentPipBounds.centerX() + width / 2,
+                currentPipBounds.centerY() + height / 2);
+        return TMP_RECT;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index bb545bd..88a1168 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -39,7 +39,6 @@
 import android.view.InputEventReceiver;
 import android.view.InputMonitor;
 import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
 import android.view.ViewConfiguration;
 
 import androidx.annotation.VisibleForTesting;
@@ -62,19 +61,21 @@
 public class PipResizeGestureHandler {
 
     private static final String TAG = "PipResizeGestureHandler";
-    private static final float PINCH_THRESHOLD = 0.05f;
-    private static final float STARTING_SCALE_FACTOR = 1.0f;
+    private static final int PINCH_RESIZE_SNAP_DURATION = 250;
 
     private final Context mContext;
     private final PipBoundsAlgorithm mPipBoundsAlgorithm;
     private final PipMotionHelper mMotionHelper;
     private final PipBoundsState mPipBoundsState;
+    private final PipTaskOrganizer mPipTaskOrganizer;
+    private final PhonePipMenuController mPhonePipMenuController;
+    private final PipUiEventLogger mPipUiEventLogger;
     private final int mDisplayId;
     private final Executor mMainExecutor;
-    private final ScaleGestureDetector mScaleGestureDetector;
     private final Region mTmpRegion = new Region();
 
     private final PointF mDownPoint = new PointF();
+    private final PointF mDownSecondaryPoint = new PointF();
     private final Point mMaxSize = new Point();
     private final Point mMinSize = new Point();
     private final Rect mLastResizeBounds = new Rect();
@@ -88,6 +89,7 @@
     private final Rect mDisplayBounds = new Rect();
     private final Function<Rect, Rect> mMovementBoundsSupplier;
     private final Runnable mUpdateMovementBoundsRunnable;
+    private final Handler mHandler;
 
     private int mDelta;
     private float mTouchSlop;
@@ -96,15 +98,17 @@
     private boolean mIsEnabled;
     private boolean mEnablePinchResize;
     private boolean mIsSysUiStateValid;
+    // For drag-resize
     private boolean mThresholdCrossed;
+    // For pinch-resize
+    private boolean mThresholdCrossed0;
+    private boolean mThresholdCrossed1;
     private boolean mUsingPinchToZoom = false;
-    private float mScaleFactor = STARTING_SCALE_FACTOR;
+    int mFirstIndex = -1;
+    int mSecondIndex = -1;
 
     private InputMonitor mInputMonitor;
     private InputEventReceiver mInputEventReceiver;
-    private PipTaskOrganizer mPipTaskOrganizer;
-    private PhonePipMenuController mPhonePipMenuController;
-    private PipUiEventLogger mPipUiEventLogger;
 
     private int mCtrlType;
 
@@ -124,66 +128,11 @@
         mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
         mPhonePipMenuController = menuActivityController;
         mPipUiEventLogger = pipUiEventLogger;
+        mHandler = new Handler(Looper.getMainLooper());
 
         context.getDisplay().getRealSize(mMaxSize);
         reloadResources();
 
-        mScaleGestureDetector = new ScaleGestureDetector(context,
-                new ScaleGestureDetector.OnScaleGestureListener() {
-                    @Override
-                    public boolean onScale(ScaleGestureDetector detector) {
-                        mScaleFactor *= detector.getScaleFactor();
-
-                        if (!mThresholdCrossed
-                                && (mScaleFactor > (STARTING_SCALE_FACTOR + PINCH_THRESHOLD)
-                                || mScaleFactor < (STARTING_SCALE_FACTOR - PINCH_THRESHOLD))) {
-                            mThresholdCrossed = true;
-                            mInputMonitor.pilferPointers();
-                        }
-                        if (mThresholdCrossed) {
-                            int height = Math.min(mMaxSize.y, Math.max(mMinSize.y,
-                                    (int) (mScaleFactor * mLastDownBounds.height())));
-                            int width = Math.min(mMaxSize.x, Math.max(mMinSize.x,
-                                    (int) (mScaleFactor * mLastDownBounds.width())));
-                            int top, bottom, left, right;
-
-                            if ((mCtrlType & CTRL_TOP) != 0) {
-                                top = mLastDownBounds.bottom - height;
-                                bottom = mLastDownBounds.bottom;
-                            } else {
-                                top = mLastDownBounds.top;
-                                bottom = mLastDownBounds.top + height;
-                            }
-
-                            if ((mCtrlType & CTRL_LEFT) != 0) {
-                                left = mLastDownBounds.right - width;
-                                right = mLastDownBounds.right;
-                            } else {
-                                left = mLastDownBounds.left;
-                                right = mLastDownBounds.left + width;
-                            }
-
-                            mLastResizeBounds.set(left, top, right, bottom);
-                            mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds,
-                                    mLastResizeBounds,
-                                    null);
-                        }
-                        return true;
-                    }
-
-                    @Override
-                    public boolean onScaleBegin(ScaleGestureDetector detector) {
-                        setCtrlTypeForPinchToZoom();
-                        return true;
-                    }
-
-                    @Override
-                    public void onScaleEnd(ScaleGestureDetector detector) {
-                        mScaleFactor = STARTING_SCALE_FACTOR;
-                        finishResize();
-                    }
-                });
-
         mEnablePinchResize = DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_SYSTEMUI,
                 PIP_PINCH_RESIZE,
@@ -274,7 +223,7 @@
 
         if (ev instanceof MotionEvent) {
             if (mUsingPinchToZoom) {
-                mScaleGestureDetector.onTouchEvent((MotionEvent) ev);
+                onPinchResize((MotionEvent) ev);
             } else {
                 onDragCornerResize((MotionEvent) ev);
             }
@@ -282,6 +231,13 @@
     }
 
     /**
+     * Checks if there is currently an on-going gesture, either drag-resize or pinch-resize.
+     */
+    public boolean hasOngoingGesture() {
+        return mCtrlType != CTRL_NONE || mUsingPinchToZoom;
+    }
+
+    /**
      * Check whether the current x,y coordinate is within the region in which drag-resize should
      * start.
      * This consists of 4 small squares on the 4 corners of the PIP window, a quarter of which
@@ -295,7 +251,7 @@
      * |_|_|_________|_|_|
      * |_|_|         |_|_|
      */
-    public boolean isWithinTouchRegion(int x, int y) {
+    public boolean isWithinDragResizeRegion(int x, int y) {
         final Rect currentPipBounds = mPipBoundsState.getBounds();
         if (currentPipBounds == null) {
             return false;
@@ -327,15 +283,14 @@
         if (isInValidSysUiState()) {
             switch (ev.getActionMasked()) {
                 case MotionEvent.ACTION_DOWN:
-                    // Always pass the DOWN event to the ScaleGestureDetector
-                    mScaleGestureDetector.onTouchEvent(ev);
-                    if (isWithinTouchRegion((int) ev.getRawX(), (int) ev.getRawY())) {
+                    if (isWithinDragResizeRegion((int) ev.getRawX(), (int) ev.getRawY())) {
                         return true;
                     }
                     break;
 
                 case MotionEvent.ACTION_POINTER_DOWN:
                     if (mEnablePinchResize && ev.getPointerCount() == 2) {
+                        onPinchResize(ev);
                         mUsingPinchToZoom = true;
                         return true;
                     }
@@ -348,33 +303,11 @@
         return false;
     }
 
-    private void setCtrlTypeForPinchToZoom() {
-        final Rect currentPipBounds = mPipBoundsState.getBounds();
-        mLastDownBounds.set(mPipBoundsState.getBounds());
-
-        Rect movementBounds = mMovementBoundsSupplier.apply(currentPipBounds);
-        mDisplayBounds.set(movementBounds.left,
-                movementBounds.top,
-                movementBounds.right + currentPipBounds.width(),
-                movementBounds.bottom + currentPipBounds.height());
-
-        if (currentPipBounds.left == mDisplayBounds.left) {
-            mCtrlType |= CTRL_RIGHT;
-        } else {
-            mCtrlType |= CTRL_LEFT;
-        }
-
-        if (currentPipBounds.top > mDisplayBounds.top + mDisplayBounds.height()) {
-            mCtrlType |= CTRL_TOP;
-        } else {
-            mCtrlType |= CTRL_BOTTOM;
-        }
-    }
-
     private void setCtrlType(int x, int y) {
         final Rect currentPipBounds = mPipBoundsState.getBounds();
 
         Rect movementBounds = mMovementBoundsSupplier.apply(currentPipBounds);
+
         mDisplayBounds.set(movementBounds.left,
                 movementBounds.top,
                 movementBounds.right + currentPipBounds.width(),
@@ -408,6 +341,78 @@
         return mIsSysUiStateValid;
     }
 
+    private void onPinchResize(MotionEvent ev) {
+        int action = ev.getActionMasked();
+
+        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+            mFirstIndex = -1;
+            mSecondIndex = -1;
+            finishResize();
+        }
+
+        if (ev.getPointerCount() != 2) {
+            return;
+        }
+
+        if (action == MotionEvent.ACTION_POINTER_DOWN) {
+            if (mFirstIndex == -1 && mSecondIndex == -1) {
+                mFirstIndex = 0;
+                mSecondIndex = 1;
+                mLastResizeBounds.setEmpty();
+                mDownPoint.set(ev.getRawX(mFirstIndex), ev.getRawY(mFirstIndex));
+                mDownSecondaryPoint.set(ev.getRawX(mSecondIndex), ev.getRawY(mSecondIndex));
+
+                mLastResizeBounds.setEmpty();
+                mLastDownBounds.set(mPipBoundsState.getBounds());
+            }
+        }
+
+        if (action == MotionEvent.ACTION_MOVE) {
+            if (mFirstIndex == -1 || mSecondIndex == -1) {
+                return;
+            }
+
+            float x0 = ev.getRawX(mFirstIndex);
+            float y0 = ev.getRawY(mFirstIndex);
+            float x1 = ev.getRawX(mSecondIndex);
+            float y1 = ev.getRawY(mSecondIndex);
+
+            double hypot0 = Math.hypot(x0 - mDownPoint.x, y0 - mDownPoint.y);
+            double hypot1 = Math.hypot(x1 - mDownSecondaryPoint.x, y1 - mDownSecondaryPoint.y);
+            // Capture inputs
+            if (hypot0 > mTouchSlop && !mThresholdCrossed0) {
+                mInputMonitor.pilferPointers();
+                mThresholdCrossed0 = true;
+                // Reset the down to begin resizing from this point
+                mDownPoint.set(x0, y0);
+            }
+            if (hypot1 > mTouchSlop && !mThresholdCrossed1) {
+                mInputMonitor.pilferPointers();
+                mThresholdCrossed1 = true;
+                // Reset the down to begin resizing from this point
+                mDownSecondaryPoint.set(x1, y1);
+            }
+            if (mThresholdCrossed0 || mThresholdCrossed1) {
+                if (mPhonePipMenuController.isMenuVisible()) {
+                    mPhonePipMenuController.hideMenu();
+                }
+
+                x0 = mThresholdCrossed0 ? x0 : mDownPoint.x;
+                y0 = mThresholdCrossed0 ? y0 : mDownPoint.y;
+                x1 = mThresholdCrossed1 ? x1 : mDownSecondaryPoint.x;
+                y1 = mThresholdCrossed1 ? y1 : mDownSecondaryPoint.y;
+
+                final Rect currentPipBounds = mPipBoundsState.getBounds();
+                mLastResizeBounds.set(PipPinchResizingAlgorithm.pinchResize(x0, y0, x1, y1,
+                        mDownPoint.x, mDownPoint.y, mDownSecondaryPoint.x, mDownSecondaryPoint.y,
+                        currentPipBounds, mMinSize.x, mMinSize.y, mMaxSize));
+
+                mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,
+                        null);
+            }
+        }
+    }
+
     private void onDragCornerResize(MotionEvent ev) {
         int action = ev.getActionMasked();
         float x = ev.getX();
@@ -415,7 +420,7 @@
         if (action == MotionEvent.ACTION_DOWN) {
             final Rect currentPipBounds = mPipBoundsState.getBounds();
             mLastResizeBounds.setEmpty();
-            mAllowGesture = isInValidSysUiState() && isWithinTouchRegion((int) x, (int) y);
+            mAllowGesture = isInValidSysUiState() && isWithinDragResizeRegion((int) x, (int) y);
             if (mAllowGesture) {
                 setCtrlType((int) x, (int) y);
                 mDownPoint.set(x, y);
@@ -468,15 +473,30 @@
 
     private void finishResize() {
         if (!mLastResizeBounds.isEmpty()) {
-            mUserResizeBounds.set(mLastResizeBounds);
-            mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
-                    (Rect bounds) -> {
-                        new Handler(Looper.getMainLooper()).post(() -> {
-                            mMotionHelper.synchronizePinnedStackBounds();
-                            mUpdateMovementBoundsRunnable.run();
-                            resetState();
+            final Runnable callback = () -> {
+                mUserResizeBounds.set(mLastResizeBounds);
+                mMotionHelper.synchronizePinnedStackBounds();
+                mUpdateMovementBoundsRunnable.run();
+                resetState();
+            };
+
+            // Pinch-to-resize needs to re-calculate snap fraction and animate to the snapped
+            // position correctly. Drag-resize does not need to move, so just finalize resize.
+            if (mUsingPinchToZoom) {
+                final Rect startBounds = new Rect(mLastResizeBounds);
+                mPipBoundsAlgorithm.applySnapFraction(mLastResizeBounds,
+                        mPipBoundsAlgorithm.getSnapFraction(mPipBoundsState.getBounds()));
+                mPipTaskOrganizer.scheduleAnimateResizePip(startBounds, mLastResizeBounds,
+                        PINCH_RESIZE_SNAP_DURATION,
+                        (Rect rect) -> {
+                            mHandler.post(callback);
                         });
-                    });
+            } else {
+                mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
+                        (Rect bounds) -> {
+                            mHandler.post(callback);
+                        });
+            }
             mPipUiEventLogger.log(
                     PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE);
         } else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 9917701..9281f58 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -31,11 +31,8 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.Handler;
-import android.os.RemoteException;
 import android.provider.DeviceConfig;
-import android.util.Log;
 import android.util.Size;
-import android.view.IPinnedStackController;
 import android.view.InputEvent;
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
@@ -47,6 +44,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.pip.PipAnimationController;
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.pip.PipBoundsState;
@@ -75,7 +73,6 @@
     private final PipDismissTargetHandler mPipDismissTargetHandler;
 
     private PipResizeGestureHandler mPipResizeGestureHandler;
-    private IPinnedStackController mPinnedStackController;
     private WeakReference<Consumer<Rect>> mPipExclusionBoundsChangeListener;
 
     private final PhonePipMenuController mMenuController;
@@ -157,7 +154,8 @@
             @NonNull PipBoundsState pipBoundsState,
             PipTaskOrganizer pipTaskOrganizer,
             FloatingContentCoordinator floatingContentCoordinator,
-            PipUiEventLogger pipUiEventLogger) {
+            PipUiEventLogger pipUiEventLogger,
+            ShellExecutor shellMainExecutor) {
         // Initialize the Pip input consumer
         mContext = context;
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
@@ -188,7 +186,7 @@
         mFloatingContentCoordinator = floatingContentCoordinator;
         mConnection = new PipAccessibilityInteractionConnection(mContext, pipBoundsState,
                 mMotionHelper, pipTaskOrganizer, mPipBoundsAlgorithm.getSnapAlgorithm(),
-                this::onAccessibilityShowMenu, this::updateMovementBounds, mHandler);
+                this::onAccessibilityShowMenu, this::updateMovementBounds, shellMainExecutor);
 
         mPipUiEventLogger = pipUiEventLogger;
 
@@ -436,8 +434,11 @@
      * TODO Add appropriate description
      */
     public void onRegistrationChanged(boolean isRegistered) {
-        mAccessibilityManager.setPictureInPictureActionReplacingConnection(isRegistered
-                ? mConnection : null);
+        if (isRegistered) {
+            mConnection.register(mAccessibilityManager);
+        } else {
+            mAccessibilityManager.setPictureInPictureActionReplacingConnection(null);
+        }
         if (!isRegistered && mTouchState.isUserInteracting()) {
             // If the input consumer is unregistered while the user is interacting, then we may not
             // get the final TOUCH_UP event, so clean up the dismiss target as well
@@ -459,10 +460,6 @@
         if (!(inputEvent instanceof MotionEvent)) {
             return true;
         }
-        // Skip touch handling until we are bound to the controller
-        if (mPinnedStackController == null) {
-            return true;
-        }
 
         MotionEvent ev = (MotionEvent) inputEvent;
         if (!mPipBoundsState.isStashed() && mPipResizeGestureHandler.willStartResizeGesture(ev)) {
@@ -473,6 +470,11 @@
             return true;
         }
 
+        if (mPipResizeGestureHandler.hasOngoingGesture()) {
+            mPipDismissTargetHandler.hideDismissTargetMaybe();
+            return true;
+        }
+
         if ((ev.getAction() == MotionEvent.ACTION_DOWN || mTouchState.isUserInteracting())
                 && mPipDismissTargetHandler.maybeConsumeMotionEvent(ev)) {
             // If the first touch event occurs within the magnetic field, pass the ACTION_DOWN event
@@ -586,13 +588,6 @@
     }
 
     /**
-     * Sets the controller to update the system of changes from user interaction.
-     */
-    void setPinnedStackController(IPinnedStackController controller) {
-        mPinnedStackController = controller;
-    }
-
-    /**
      * Sets the menu visibility.
      */
     private void setMenuState(int menuState, boolean resize, Runnable callback) {
@@ -620,13 +615,9 @@
                     // bounds which are now stale.  In such a case we defer the animation to the
                     // normal bounds until after the next onMovementBoundsChanged() call to get the
                     // bounds in the new orientation
-                    try {
-                        int displayRotation = mPinnedStackController.getDisplayRotation();
-                        if (mDisplayRotation != displayRotation) {
-                            mDeferResizeToNormalBoundsUntilRotation = displayRotation;
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Could not get display rotation from controller");
+                    int displayRotation = mContext.getDisplay().getRotation();
+                    if (mDisplayRotation != displayRotation) {
+                        mDeferResizeToNormalBoundsUntilRotation = displayRotation;
                     }
                 }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
index 21715077..5f2327c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
@@ -19,6 +19,7 @@
 import android.graphics.PointF;
 import android.os.Handler;
 import android.util.Log;
+import android.view.Display;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.ViewConfiguration;
@@ -64,6 +65,7 @@
     private boolean mStartedDragging = false;
     private boolean mAllowDraggingOffscreen = false;
     private int mActivePointerId;
+    private int mLastTouchDisplayId = Display.INVALID_DISPLAY;
 
     public PipTouchState(ViewConfiguration viewConfig, Handler handler,
             Runnable doubleTapTimeoutCallback, Runnable hoverExitTimeoutCallback) {
@@ -81,12 +83,14 @@
         mIsDragging = false;
         mStartedDragging = false;
         mIsUserInteracting = false;
+        mLastTouchDisplayId = Display.INVALID_DISPLAY;
     }
 
     /**
      * Processes a given touch event and updates the state.
      */
     public void onTouchEvent(MotionEvent ev) {
+        mLastTouchDisplayId = ev.getDisplayId();
         switch (ev.getActionMasked()) {
             case MotionEvent.ACTION_DOWN: {
                 if (!mAllowTouches) {
@@ -266,6 +270,13 @@
     }
 
     /**
+     * @return Display ID of the last touch event.
+     */
+    public int getLastTouchDisplayId() {
+        return mLastTouchDisplayId;
+    }
+
+    /**
      * Sets whether touching is currently allowed.
      */
     public void setAllowTouches(boolean allowTouches) {
@@ -378,6 +389,7 @@
         pw.println(prefix + TAG);
         pw.println(innerPrefix + "mAllowTouches=" + mAllowTouches);
         pw.println(innerPrefix + "mActivePointerId=" + mActivePointerId);
+        pw.println(innerPrefix + "mLastTouchDisplayId=" + mLastTouchDisplayId);
         pw.println(innerPrefix + "mDownTouch=" + mDownTouch);
         pw.println(innerPrefix + "mDownDelta=" + mDownDelta);
         pw.println(innerPrefix + "mLastTouch=" + mLastTouch);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
index 5d8d5e6..763370b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
@@ -179,40 +179,33 @@
             PinnedStackListenerForwarder.PinnedStackListener {
         @Override
         public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
-            mHandler.post(() -> {
-                mPipBoundsState.setImeVisibility(imeVisible, imeHeight);
-                if (mState == STATE_PIP) {
-                    if (mImeVisible != imeVisible) {
-                        if (imeVisible) {
-                            // Save the IME height adjustment, and offset to not occlude the IME
-                            mPipBoundsState.getNormalBounds().offset(0, -imeHeight);
-                            mImeHeightAdjustment = imeHeight;
-                        } else {
-                            // Apply the inverse adjustment when the IME is hidden
-                            mPipBoundsState.getNormalBounds().offset(0, mImeHeightAdjustment);
-                        }
-                        mImeVisible = imeVisible;
-                        resizePinnedStack(STATE_PIP);
+            mPipBoundsState.setImeVisibility(imeVisible, imeHeight);
+            if (mState == STATE_PIP) {
+                if (mImeVisible != imeVisible) {
+                    if (imeVisible) {
+                        // Save the IME height adjustment, and offset to not occlude the IME
+                        mPipBoundsState.getNormalBounds().offset(0, -imeHeight);
+                        mImeHeightAdjustment = imeHeight;
+                    } else {
+                        // Apply the inverse adjustment when the IME is hidden
+                        mPipBoundsState.getNormalBounds().offset(0, mImeHeightAdjustment);
                     }
+                    mImeVisible = imeVisible;
+                    resizePinnedStack(STATE_PIP);
                 }
-            });
+            }
         }
 
         @Override
         public void onMovementBoundsChanged(boolean fromImeAdjustment) {
-            mHandler.post(() -> {
-                mTmpDisplayInfo.copyFrom(mPipBoundsState.getDisplayInfo());
-
-                mPipBoundsAlgorithm.getInsetBounds(mTmpInsetBounds);
-            });
+            mTmpDisplayInfo.copyFrom(mPipBoundsState.getDisplayInfo());
+            mPipBoundsAlgorithm.getInsetBounds(mTmpInsetBounds);
         }
 
         @Override
         public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
             mCustomActions = actions;
-            mHandler.post(() -> {
-                mTvPipMenuController.setAppActions(mCustomActions);
-            });
+            mTvPipMenuController.setAppActions(mCustomActions);
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerWindowManager.java
index f2becc9..5078371 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/DividerWindowManager.java
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.SHELL_ROOT_LAYER_DIVIDER;
 
@@ -59,7 +60,7 @@
                 PixelFormat.TRANSLUCENT);
         mLp.token = new Binder();
         mLp.setTitle(WINDOW_TITLE);
-        mLp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
+        mLp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
         mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
         view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index e55f065..7c70a4efa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -19,6 +19,8 @@
 import android.graphics.Rect;
 import android.window.WindowContainerToken;
 
+import com.android.wm.shell.common.annotations.ExternalThread;
+
 import java.io.PrintWriter;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
@@ -26,6 +28,7 @@
 /**
  * Interface to engage split screen feature.
  */
+@ExternalThread
 public interface SplitScreen {
     /** Called when keyguard showing state changed. */
     void onKeyguardVisibilityChanged(boolean isShowing);
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
index 101b5bf..1054c43 100644
--- a/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidManifest.xml
@@ -21,6 +21,8 @@
     <!-- Read and write traces from external storage -->
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <!-- Allow the test to write directly to /sdcard/ -->
+    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
     <!-- Write secure settings -->
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <!-- Capture screen contents -->
@@ -38,7 +40,8 @@
     <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
     <!-- ATM.removeRootTasksWithActivityTypes() -->
     <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />
-    <application>
+    <!-- Allow the test to write directly to /sdcard/ -->
+    <application android:requestLegacyExternalStorage="true">
         <uses-library android:name="android.test.runner"/>
 
         <service android:name=".NotificationListener"
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTestPhysicalDevices.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTestPhysicalDevices.xml
index 9dd9f42..23d7021 100644
--- a/libs/WindowManager/Shell/tests/flicker/AndroidTestPhysicalDevices.xml
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidTestPhysicalDevices.xml
@@ -34,7 +34,7 @@
         <option name="hidden-api-checks" value="false" />
     </test>
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
-        <option name="directory-keys" value="/storage/emulated/0/Android/data/com.android.wm.shell.flicker/files" />
+        <option name="directory-keys" value="/sdcard/flicker" />
         <option name="collect-on-run-ended-only" value="true" />
         <option name="clean-up" value="true" />
     </metrics_collector>
diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTestVirtualDevices.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTestVirtualDevices.xml
index afb1166..0738608 100644
--- a/libs/WindowManager/Shell/tests/flicker/AndroidTestVirtualDevices.xml
+++ b/libs/WindowManager/Shell/tests/flicker/AndroidTestVirtualDevices.xml
@@ -34,7 +34,7 @@
         <option name="hidden-api-checks" value="false" />
     </test>
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
-        <option name="directory-keys" value="/storage/emulated/0/Android/data/com.android.wm.shell.flicker/files" />
+        <option name="directory-keys" value="/sdcard/flicker" />
         <option name="collect-on-run-ended-only" value="true" />
         <option name="clean-up" value="true" />
     </metrics_collector>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index 0fb43e2..3ed53fb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -18,78 +18,6 @@
 
 import com.android.server.wm.flicker.dsl.EventLogAssertion
 import com.android.server.wm.flicker.dsl.LayersAssertion
-import com.android.server.wm.flicker.dsl.WmAssertion
-import com.android.server.wm.flicker.helpers.WindowUtils
-
-@JvmOverloads
-fun WmAssertion.statusBarWindowIsAlwaysVisible(
-    bugId: Int = 0,
-    enabled: Boolean = bugId == 0
-) {
-    all("statusBarWindowIsAlwaysVisible", bugId, enabled) {
-        this.showsAboveAppWindow(FlickerTestBase.STATUS_BAR_WINDOW_TITLE)
-    }
-}
-
-@JvmOverloads
-fun WmAssertion.navBarWindowIsAlwaysVisible(
-    bugId: Int = 0,
-    enabled: Boolean = bugId == 0
-) {
-    all("navBarWindowIsAlwaysVisible", bugId, enabled) {
-        this.showsAboveAppWindow(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE)
-    }
-}
-
-@JvmOverloads
-fun LayersAssertion.noUncoveredRegions(
-    beginRotation: Int,
-    endRotation: Int = beginRotation,
-    allStates: Boolean = true,
-    bugId: Int = 0,
-    enabled: Boolean = bugId == 0
-) {
-    val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
-    val endingBounds = WindowUtils.getDisplayBounds(endRotation)
-    if (allStates) {
-        all("noUncoveredRegions", bugId, enabled) {
-            if (startingBounds == endingBounds) {
-                this.coversAtLeastRegion(startingBounds)
-            } else {
-                this.coversAtLeastRegion(startingBounds)
-                        .then()
-                        .coversAtLeastRegion(endingBounds)
-            }
-        }
-    } else {
-        start("noUncoveredRegions_StartingPos") {
-            this.coversAtLeastRegion(startingBounds)
-        }
-        end("noUncoveredRegions_EndingPos") {
-            this.coversAtLeastRegion(endingBounds)
-        }
-    }
-}
-
-@JvmOverloads
-fun LayersAssertion.statusBarLayerIsAlwaysVisible(
-    bugId: Int = 0,
-    enabled: Boolean = bugId == 0
-) {
-    all("statusBarLayerIsAlwaysVisible", bugId, enabled) {
-        this.showsLayer(FlickerTestBase.STATUS_BAR_WINDOW_TITLE)
-    }
-}
-
-@JvmOverloads
-fun LayersAssertion.navBarLayerIsAlwaysVisible(
-    bugId: Int = 0,
-    enabled: Boolean = bugId == 0
-) {
-    all("navBarLayerIsAlwaysVisible", bugId, enabled) {
-        this.showsLayer(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE)
-    }
-}
 
 @JvmOverloads
 fun LayersAssertion.appPairsDividerIsVisible(
@@ -131,48 +59,6 @@
     }
 }
 
-@JvmOverloads
-fun LayersAssertion.navBarLayerRotatesAndScales(
-    beginRotation: Int,
-    endRotation: Int = beginRotation,
-    bugId: Int = 0,
-    enabled: Boolean = bugId == 0
-) {
-    val startingPos = WindowUtils.getNavigationBarPosition(beginRotation)
-    val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
-
-    start("navBarLayerRotatesAndScales_StartingPos", bugId, enabled) {
-        this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-    }
-    end("navBarLayerRotatesAndScales_EndingPost", bugId, enabled) {
-        this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, endingPos)
-    }
-
-    if (startingPos == endingPos) {
-        all("navBarLayerRotatesAndScales", bugId, enabled) {
-            this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-        }
-    }
-}
-
-@JvmOverloads
-fun LayersAssertion.statusBarLayerRotatesScales(
-    beginRotation: Int,
-    endRotation: Int = beginRotation,
-    bugId: Int = 0,
-    enabled: Boolean = bugId == 0
-) {
-    val startingPos = WindowUtils.getStatusBarPosition(beginRotation)
-    val endingPos = WindowUtils.getStatusBarPosition(endRotation)
-
-    start("statusBarLayerRotatesScales_StartingPos", bugId, enabled) {
-        this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, startingPos)
-    }
-    end("statusBarLayerRotatesScales_EndingPos", bugId, enabled) {
-        this.hasVisibleRegion(FlickerTestBase.STATUS_BAR_WINDOW_TITLE, endingPos)
-    }
-}
-
 fun EventLogAssertion.focusChanges(
     vararg windows: String,
     bugId: Int = 0,
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt
index ced99de..7ac91b0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTest.kt
@@ -29,10 +29,10 @@
 import com.android.wm.shell.flicker.helpers.AppPairsHelper.Companion.TEST_REPETITIONS
 import com.android.wm.shell.flicker.appPairsDividerIsInvisible
 import com.android.wm.shell.flicker.appPairsDividerIsVisible
-import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt
index 0663eb3..c9396aa 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterExitPipTest.kt
@@ -23,10 +23,10 @@
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
 import com.android.wm.shell.flicker.helpers.PipAppHelper
-import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
 import org.junit.FixMethodOrder
 import org.junit.Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipOrientationTest.kt
index 322034c..76aabc1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipOrientationTest.kt
@@ -24,10 +24,10 @@
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
 import com.android.wm.shell.flicker.helpers.PipAppHelper
-import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_ENTER_PIP
 import com.android.wm.shell.flicker.testapp.Components.PipActivity.ACTION_SET_REQUESTED_ORIENTATION
 import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index 96d98d5..a67b3b7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -31,13 +31,13 @@
 import com.android.server.wm.flicker.startRotation
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
 import com.android.wm.shell.flicker.helpers.PipAppHelper
-import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.navBarLayerRotatesAndScales
-import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.noUncoveredRegions
-import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarLayerRotatesScales
-import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.noUncoveredRegions
+import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.statusBarLayerRotatesScales
 import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
 import org.junit.FixMethodOrder
 import org.junit.runner.RunWith
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipSplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipSplitScreenTest.kt
index d20552f..f79b21f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipSplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipSplitScreenTest.kt
@@ -28,10 +28,10 @@
 import com.android.wm.shell.flicker.helpers.ImeAppHelper
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
 import com.android.wm.shell.flicker.helpers.PipAppHelper
-import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
 import org.junit.FixMethodOrder
 import org.junit.Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenTest.kt
index c61a0f1..5570a56 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenTest.kt
@@ -25,10 +25,10 @@
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
 import com.android.wm.shell.flicker.dockedStackDividerIsVisible
 import com.android.wm.shell.flicker.helpers.SplitScreenHelper.Companion.TEST_REPETITIONS
-import com.android.wm.shell.flicker.navBarLayerIsAlwaysVisible
-import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/ExitSplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/ExitSplitScreenTest.kt
index bf92869..7c47d1f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/ExitSplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/ExitSplitScreenTest.kt
@@ -29,8 +29,8 @@
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
 import com.android.wm.shell.flicker.dockedStackDividerIsInvisible
 import com.android.wm.shell.flicker.helpers.SplitScreenHelper.Companion.TEST_REPETITIONS
-import com.android.wm.shell.flicker.navBarWindowIsAlwaysVisible
-import com.android.wm.shell.flicker.statusBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
+import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairLayoutTests.java
deleted file mode 100644
index c9d32c4..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairLayoutTests.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2020 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 com.android.wm.shell.apppairs;
-
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.view.Display;
-import android.view.SurfaceControl;
-
-import androidx.test.annotation.UiThreadTest;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.ShellTestCase;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/** Tests for {@link AppPairLayout} */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class AppPairLayoutTests extends ShellTestCase {
-    @Mock SurfaceControl mSurfaceControl;
-    private Display mDisplay;
-    private Configuration mConfiguration;
-    private AppPairLayout mAppPairLayout;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mConfiguration = getConfiguration(false);
-        mDisplay = mContext.getDisplay();
-        mAppPairLayout = new AppPairLayout(mContext, mDisplay, mConfiguration, mSurfaceControl);
-    }
-
-    @After
-    @UiThreadTest
-    public void tearDown() {
-        mAppPairLayout.release();
-    }
-
-    @Test
-    @UiThreadTest
-    public void testUpdateConfiguration() {
-        assertThat(mAppPairLayout.updateConfiguration(getConfiguration(false))).isFalse();
-        assertThat(mAppPairLayout.updateConfiguration(getConfiguration(true))).isTrue();
-    }
-
-    @Test
-    @UiThreadTest
-    public void testInitRelease() {
-        mAppPairLayout.init();
-        assertThat(mAppPairLayout.getDividerLeash()).isNotNull();
-        mAppPairLayout.release();
-        assertThat(mAppPairLayout.getDividerLeash()).isNull();
-    }
-
-    private static Configuration getConfiguration(boolean isLandscape) {
-        final Configuration configuration = new Configuration();
-        configuration.unset();
-        configuration.orientation = isLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
-        configuration.windowConfiguration.setBounds(
-                new Rect(0, 0, isLandscape ? 2160 : 1080, isLandscape ? 1080 : 2160));
-        return configuration;
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java
index f12648a..8dbc1d5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java
@@ -55,13 +55,13 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
+        when(mDisplayController.getDisplay(anyInt())).thenReturn(
+                mContext.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY));
         mController = new TestAppPairsController(
                 mTaskOrganizer,
                 mSyncQueue,
                 mDisplayController);
-        when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
-        when(mDisplayController.getDisplay(anyInt())).thenReturn(
-                mContext.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY));
     }
 
     @After
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java
index f8c68d2..fada694 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java
@@ -55,14 +55,14 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
+        when(mDisplayController.getDisplay(anyInt())).thenReturn(
+                mContext.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY));
         mController = new TestAppPairsController(
                 mTaskOrganizer,
                 mSyncQueue,
                 mDisplayController);
         mPool = mController.getPool();
-        when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
-        when(mDisplayController.getDisplay(anyInt())).thenReturn(
-                mContext.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY));
     }
 
     @After
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java
index 8ece913..a3f134e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java
@@ -18,10 +18,14 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.SyncTransactionQueue;
 
@@ -35,7 +39,7 @@
 /** Tests for {@link AppPairsPool} */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class AppPairsPoolTests {
+public class AppPairsPoolTests extends ShellTestCase {
     private TestAppPairsController mController;
     private TestAppPairsPool mPool;
     @Mock private SyncTransactionQueue mSyncQueue;
@@ -45,6 +49,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
         mController = new TestAppPairsController(
                 mTaskOrganizer,
                 mSyncQueue,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
index 080cddc..5e0d518 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
@@ -20,12 +20,15 @@
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.Surface.ROTATION_0;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.graphics.Point;
+import android.view.InsetsSource;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 import android.view.SurfaceControl;
@@ -68,19 +71,31 @@
     @Test
     public void reappliesVisibilityToChangedLeash() {
         verifyZeroInteractions(mT);
+        mPerDisplay.mImeShowing = true;
 
-        mPerDisplay.mImeShowing = false;
-        mPerDisplay.insetsControlChanged(new InsetsState(), new InsetsSourceControl[] {
-                new InsetsSourceControl(ITYPE_IME, mock(SurfaceControl.class), new Point(0, 0))
-        });
+        mPerDisplay.insetsControlChanged(insetsStateWithIme(false), insetsSourceControl());
 
+        assertFalse(mPerDisplay.mImeShowing);
         verify(mT).hide(any());
 
         mPerDisplay.mImeShowing = true;
-        mPerDisplay.insetsControlChanged(new InsetsState(), new InsetsSourceControl[] {
-                new InsetsSourceControl(ITYPE_IME, mock(SurfaceControl.class), new Point(0, 0))
-        });
+        mPerDisplay.insetsControlChanged(insetsStateWithIme(true), insetsSourceControl());
 
+        assertTrue(mPerDisplay.mImeShowing);
         verify(mT).show(any());
     }
+
+    private InsetsSourceControl[] insetsSourceControl() {
+        return new InsetsSourceControl[]{
+                new InsetsSourceControl(ITYPE_IME, mock(SurfaceControl.class), new Point(0, 0))
+        };
+    }
+
+    private InsetsState insetsStateWithIme(boolean visible) {
+        InsetsState state = new InsetsState();
+        state.addSource(new InsetsSource(ITYPE_IME));
+        state.setSourceVisible(ITYPE_IME, visible);
+        return state;
+    }
+
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
new file mode 100644
index 0000000..d87f4c6
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2020 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 com.android.wm.shell.common.split;
+
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.view.SurfaceControl;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.policy.DividerSnapAlgorithm;
+import com.android.wm.shell.ShellTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Tests for {@link SplitLayout} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SplitLayoutTests extends ShellTestCase {
+    @Mock SplitLayout.LayoutChangeListener mLayoutChangeListener;
+    @Mock SurfaceControl mRootLeash;
+    private SplitLayout mSplitLayout;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mSplitLayout = new SplitLayout(
+                mContext,
+                getConfiguration(false),
+                mLayoutChangeListener,
+                mRootLeash);
+    }
+
+    @Test
+    @UiThreadTest
+    public void testUpdateConfiguration() {
+        assertThat(mSplitLayout.updateConfiguration(getConfiguration(false))).isFalse();
+        assertThat(mSplitLayout.updateConfiguration(getConfiguration(true))).isTrue();
+    }
+
+    @Test
+    public void testUpdateDividePosition() {
+        mSplitLayout.updateDividePosition(anyInt());
+        verify(mLayoutChangeListener).onBoundsChanging(any(SplitLayout.class));
+    }
+
+    @Test
+    public void testSetSnapTarget() {
+        DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0,
+                DividerSnapAlgorithm.SnapTarget.FLAG_NONE);
+        mSplitLayout.setSnapTarget(snapTarget);
+        verify(mLayoutChangeListener).onBoundsChanged(any(SplitLayout.class));
+
+        // verify it callbacks properly when the snap target indicates dismissing split.
+        snapTarget = getSnapTarget(0, DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START);
+        mSplitLayout.setSnapTarget(snapTarget);
+        verify(mLayoutChangeListener).onSnappedToDismiss(eq(false));
+        snapTarget = getSnapTarget(0, DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END);
+        mSplitLayout.setSnapTarget(snapTarget);
+        verify(mLayoutChangeListener).onSnappedToDismiss(eq(true));
+    }
+
+    private static Configuration getConfiguration(boolean isLandscape) {
+        final Configuration configuration = new Configuration();
+        configuration.unset();
+        configuration.orientation = isLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
+        configuration.windowConfiguration.setBounds(
+                new Rect(0, 0, isLandscape ? 2160 : 1080, isLandscape ? 1080 : 2160));
+        return configuration;
+    }
+
+    private static DividerSnapAlgorithm.SnapTarget getSnapTarget(int position, int flag) {
+        return new DividerSnapAlgorithm.SnapTarget(
+                position /* position */, position /* taskPosition */, flag);
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java
new file mode 100644
index 0000000..aa0eb2f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitWindowManagerTests.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 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 com.android.wm.shell.common.split;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.view.SurfaceControl;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Tests for {@link SplitWindowManager} */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SplitWindowManagerTests extends ShellTestCase {
+    @Mock SurfaceControl mSurfaceControl;
+    @Mock SplitLayout mSplitLayout;
+    private SplitWindowManager mSplitWindowManager;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        final Configuration configuration = new Configuration();
+        configuration.setToDefaults();
+        mSplitWindowManager = new SplitWindowManager(mContext, configuration, mSurfaceControl);
+        when(mSplitLayout.getDividerBounds()).thenReturn(
+                new Rect(0, 0, configuration.windowConfiguration.getBounds().width(),
+                        configuration.windowConfiguration.getBounds().height()));
+    }
+
+    @Test
+    @UiThreadTest
+    public void testInitRelease() {
+        mSplitWindowManager.init(mSplitLayout);
+        assertThat(mSplitWindowManager.getSurfaceControl()).isNotNull();
+        mSplitWindowManager.release();
+        assertThat(mSplitWindowManager.getSurfaceControl()).isNull();
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
index 55e7a35..7f280cd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -79,7 +79,8 @@
     @Test
     public void getAnimator_withBounds_returnBoundsAnimator() {
         final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
-                .getAnimator(mLeash, new Rect(), new Rect(), null, TRANSITION_DIRECTION_TO_PIP);
+                .getAnimator(mLeash, new Rect(), new Rect(), new Rect(), null,
+                        TRANSITION_DIRECTION_TO_PIP);
 
         assertEquals("Expect ANIM_TYPE_BOUNDS animation",
                 animator.getAnimationType(), PipAnimationController.ANIM_TYPE_BOUNDS);
@@ -87,16 +88,19 @@
 
     @Test
     public void getAnimator_whenSameTypeRunning_updateExistingAnimator() {
+        final Rect baseValue = new Rect(0, 0, 100, 100);
         final Rect startValue = new Rect(0, 0, 100, 100);
         final Rect endValue1 = new Rect(100, 100, 200, 200);
         final Rect endValue2 = new Rect(200, 200, 300, 300);
         final PipAnimationController.PipTransitionAnimator oldAnimator = mPipAnimationController
-                .getAnimator(mLeash, startValue, endValue1, null, TRANSITION_DIRECTION_TO_PIP);
+                .getAnimator(mLeash, baseValue, startValue, endValue1, null,
+                        TRANSITION_DIRECTION_TO_PIP);
         oldAnimator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new);
         oldAnimator.start();
 
         final PipAnimationController.PipTransitionAnimator newAnimator = mPipAnimationController
-                .getAnimator(mLeash, startValue, endValue2, null, TRANSITION_DIRECTION_TO_PIP);
+                .getAnimator(mLeash, baseValue, startValue, endValue2, null,
+                        TRANSITION_DIRECTION_TO_PIP);
 
         assertEquals("getAnimator with same type returns same animator",
                 oldAnimator, newAnimator);
@@ -122,11 +126,13 @@
     @Test
     @SuppressWarnings("unchecked")
     public void pipTransitionAnimator_updateEndValue() {
+        final Rect baseValue = new Rect(0, 0, 100, 100);
         final Rect startValue = new Rect(0, 0, 100, 100);
         final Rect endValue1 = new Rect(100, 100, 200, 200);
         final Rect endValue2 = new Rect(200, 200, 300, 300);
         final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
-                .getAnimator(mLeash, startValue, endValue1, null, TRANSITION_DIRECTION_TO_PIP);
+                .getAnimator(mLeash, baseValue, startValue, endValue1, null,
+                        TRANSITION_DIRECTION_TO_PIP);
 
         animator.updateEndValue(endValue2);
 
@@ -135,10 +141,12 @@
 
     @Test
     public void pipTransitionAnimator_setPipAnimationCallback() {
+        final Rect baseValue = new Rect(0, 0, 100, 100);
         final Rect startValue = new Rect(0, 0, 100, 100);
         final Rect endValue = new Rect(100, 100, 200, 200);
         final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
-                .getAnimator(mLeash, startValue, endValue, null, TRANSITION_DIRECTION_TO_PIP);
+                .getAnimator(mLeash, baseValue, startValue, endValue, null,
+                        TRANSITION_DIRECTION_TO_PIP);
         animator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new);
 
         animator.setPipAnimationCallback(mPipAnimationCallback);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index e602219..4efaebf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -33,6 +33,7 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.pip.PipBoundsState;
 import com.android.wm.shell.pip.PipSnapAlgorithm;
@@ -71,6 +72,9 @@
     @Mock
     private PipUiEventLogger mPipUiEventLogger;
 
+    @Mock
+    private ShellExecutor mShellMainExecutor;
+
     private PipBoundsState mPipBoundsState;
     private PipBoundsAlgorithm mPipBoundsAlgorithm;
     private PipSnapAlgorithm mPipSnapAlgorithm;
@@ -94,7 +98,7 @@
         mPipSnapAlgorithm = new PipSnapAlgorithm();
         mPipTouchHandler = new PipTouchHandler(mContext, mPhonePipMenuController,
                 mPipBoundsAlgorithm, mPipBoundsState, mPipTaskOrganizer,
-                mFloatingContentCoordinator, mPipUiEventLogger);
+                mFloatingContentCoordinator, mPipUiEventLogger, mShellMainExecutor);
         mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper());
         mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler());
         mPipTouchHandler.setPipMotionHelper(mMotionHelper);
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index cd53217..1ff1978 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -333,6 +333,7 @@
         "jni/YuvToJpegEncoder.cpp",
         "jni/fonts/Font.cpp",
         "jni/fonts/FontFamily.cpp",
+        "jni/fonts/NativeFont.cpp",
         "jni/text/LineBreaker.cpp",
         "jni/text/MeasuredText.cpp",
         "jni/text/TextShaper.cpp",
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index c174c24..f4c633f 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -18,6 +18,7 @@
 
 #include "renderstate/RenderState.h"
 #include "utils/Color.h"
+#include "utils/MathUtils.h"
 
 namespace android {
 namespace uirenderer {
@@ -52,5 +53,90 @@
     }
 }
 
+static inline SkScalar isIntegerAligned(SkScalar x) {
+    return fabsf(roundf(x) - x) <= NON_ZERO_EPSILON;
+}
+
+// Disable filtering when there is no scaling in screen coordinates and the corners have the same
+// fraction (for translate) or zero fraction (for any other rect-to-rect transform).
+static bool shouldFilterRect(const SkMatrix& matrix, const SkRect& srcRect, const SkRect& dstRect) {
+    if (!matrix.rectStaysRect()) return true;
+    SkRect dstDevRect = matrix.mapRect(dstRect);
+    float dstW, dstH;
+    if (MathUtils::isZero(matrix.getScaleX()) && MathUtils::isZero(matrix.getScaleY())) {
+        // Has a 90 or 270 degree rotation, although total matrix may also have scale factors
+        // in m10 and m01. Those scalings are automatically handled by mapRect so comparing
+        // dimensions is sufficient, but swap width and height comparison.
+        dstW = dstDevRect.height();
+        dstH = dstDevRect.width();
+    } else {
+        // Handle H/V flips or 180 rotation matrices. Axes may have been mirrored, but
+        // dimensions are still safe to compare directly.
+        dstW = dstDevRect.width();
+        dstH = dstDevRect.height();
+    }
+    if (!(MathUtils::areEqual(dstW, srcRect.width()) &&
+          MathUtils::areEqual(dstH, srcRect.height()))) {
+        return true;
+    }
+    // Device rect and source rect should be integer aligned to ensure there's no difference
+    // in how nearest-neighbor sampling is resolved.
+    return !(isIntegerAligned(srcRect.x()) &&
+             isIntegerAligned(srcRect.y()) &&
+             isIntegerAligned(dstDevRect.x()) &&
+             isIntegerAligned(dstDevRect.y()));
+}
+
+void Layer::draw(SkCanvas* canvas) {
+    GrRecordingContext* context = canvas->recordingContext();
+    if (context == nullptr) {
+        SkDEBUGF(("Attempting to draw LayerDrawable into an unsupported surface"));
+        return;
+    }
+    SkMatrix layerTransform = getTransform();
+    //sk_sp<SkImage> layerImage = getImage();
+    const int layerWidth = getWidth();
+    const int layerHeight = getHeight();
+    if (layerImage) {
+        SkMatrix textureMatrixInv;
+        textureMatrixInv = getTexTransform();
+        // TODO: after skia bug https://bugs.chromium.org/p/skia/issues/detail?id=7075 is fixed
+        // use bottom left origin and remove flipV and invert transformations.
+        SkMatrix flipV;
+        flipV.setAll(1, 0, 0, 0, -1, 1, 0, 0, 1);
+        textureMatrixInv.preConcat(flipV);
+        textureMatrixInv.preScale(1.0f / layerWidth, 1.0f / layerHeight);
+        textureMatrixInv.postScale(layerImage->width(), layerImage->height());
+        SkMatrix textureMatrix;
+        if (!textureMatrixInv.invert(&textureMatrix)) {
+            textureMatrix = textureMatrixInv;
+        }
+
+        SkMatrix matrix;
+        matrix = SkMatrix::Concat(layerTransform, textureMatrix);
+
+        SkPaint paint;
+        paint.setAlpha(getAlpha());
+        paint.setBlendMode(getMode());
+        paint.setColorFilter(getColorFilter());
+        const bool nonIdentityMatrix = !matrix.isIdentity();
+        if (nonIdentityMatrix) {
+            canvas->save();
+            canvas->concat(matrix);
+        }
+        const SkMatrix& totalMatrix = canvas->getTotalMatrix();
+
+        SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height());
+        if (getForceFilter() || shouldFilterRect(totalMatrix, imageRect, imageRect)) {
+            paint.setFilterQuality(kLow_SkFilterQuality);
+        }
+        canvas->drawImage(layerImage.get(), 0, 0, &paint);
+        // restore the original matrix
+        if (nonIdentityMatrix) {
+            canvas->restore();
+        }
+    }
+}
+
 }  // namespace uirenderer
 }  // namespace android
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index ea3bfc9..e99e762 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -21,6 +21,7 @@
 #include <SkBlendMode.h>
 #include <SkColorFilter.h>
 #include <SkColorSpace.h>
+#include <SkCanvas.h>
 #include <SkPaint.h>
 #include <SkImage.h>
 #include <SkMatrix.h>
@@ -87,6 +88,8 @@
 
     inline sk_sp<SkImage> getImage() const { return this->layerImage; }
 
+    void draw(SkCanvas* canvas);
+
 protected:
 
     RenderState& mRenderState;
diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp
index e1f5abd7..0fad2d5 100644
--- a/libs/hwui/apex/jni_runtime.cpp
+++ b/libs/hwui/apex/jni_runtime.cpp
@@ -69,6 +69,7 @@
 extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
 extern int register_android_graphics_fonts_Font(JNIEnv* env);
 extern int register_android_graphics_fonts_FontFamily(JNIEnv* env);
+extern int register_android_graphics_fonts_NativeFont(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
@@ -135,6 +136,7 @@
     REG_JNI(register_android_graphics_drawable_VectorDrawable),
     REG_JNI(register_android_graphics_fonts_Font),
     REG_JNI(register_android_graphics_fonts_FontFamily),
+    REG_JNI(register_android_graphics_fonts_NativeFont),
     REG_JNI(register_android_graphics_pdf_PdfDocument),
     REG_JNI(register_android_graphics_pdf_PdfEditor),
     REG_JNI(register_android_graphics_pdf_PdfRenderer),
diff --git a/libs/hwui/canvas/CanvasOpRasterizer.cpp b/libs/hwui/canvas/CanvasOpRasterizer.cpp
index 25129f6..0093c38 100644
--- a/libs/hwui/canvas/CanvasOpRasterizer.cpp
+++ b/libs/hwui/canvas/CanvasOpRasterizer.cpp
@@ -33,7 +33,11 @@
     SkMatrix& currentGlobalTransform = globalMatrixStack.emplace_back(SkMatrix::I());
 
     source.for_each([&]<CanvasOpType T>(const CanvasOpContainer<T> * op) {
-        if constexpr (T == CanvasOpType::BeginZ || T == CanvasOpType::EndZ) {
+        if constexpr (
+            T == CanvasOpType::BeginZ ||
+            T == CanvasOpType::EndZ   ||
+            T == CanvasOpType::DrawLayer
+        ) {
             // Do beginZ or endZ
             LOG_ALWAYS_FATAL("TODO");
             return;
diff --git a/libs/hwui/canvas/CanvasOpTypes.h b/libs/hwui/canvas/CanvasOpTypes.h
index f9df2f7..f0aa777 100644
--- a/libs/hwui/canvas/CanvasOpTypes.h
+++ b/libs/hwui/canvas/CanvasOpTypes.h
@@ -47,14 +47,17 @@
     DrawArc,
     DrawPaint,
     DrawPoint,
+    DrawPoints,
     DrawPath,
     DrawLine,
+    DrawLines,
     DrawVertices,
     DrawImage,
     DrawImageRect,
     // DrawImageLattice also used to draw 9 patches
     DrawImageLattice,
     DrawPicture,
+    DrawLayer,
 
     // TODO: Rest
 
diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h
index 8c7113d..242dbdb 100644
--- a/libs/hwui/canvas/CanvasOps.h
+++ b/libs/hwui/canvas/CanvasOps.h
@@ -26,8 +26,10 @@
 #include <hwui/Bitmap.h>
 #include <log/log.h>
 #include "CanvasProperty.h"
+#include "Points.h"
 
 #include "CanvasOpTypes.h"
+#include "Layer.h"
 
 #include <experimental/type_traits>
 #include <utility>
@@ -165,6 +167,22 @@
 };
 
 template <>
+struct CanvasOp<CanvasOpType::DrawPoints> {
+    size_t count;
+    SkPaint paint;
+    sk_sp<Points> points;
+    void draw(SkCanvas* canvas) const {
+        canvas->drawPoints(
+            SkCanvas::kPoints_PointMode,
+            count,
+            points->data(),
+            paint
+        );
+    }
+    ASSERT_DRAWABLE()
+};
+
+template <>
 struct CanvasOp<CanvasOpType::DrawRect> {
     SkRect rect;
     SkPaint paint;
@@ -263,6 +281,22 @@
 };
 
 template<>
+struct CanvasOp<CanvasOpType::DrawLines> {
+    size_t count;
+    SkPaint paint;
+    sk_sp<Points> points;
+    void draw(SkCanvas* canvas) const {
+        canvas->drawPoints(
+            SkCanvas::kLines_PointMode,
+            count,
+            points->data(),
+            paint
+        );
+    }
+    ASSERT_DRAWABLE()
+};
+
+template<>
 struct CanvasOp<CanvasOpType::DrawVertices> {
     sk_sp<SkVertices> vertices;
     SkBlendMode mode;
@@ -364,6 +398,11 @@
     }
 };
 
+template<>
+struct CanvasOp<CanvasOpType::DrawLayer> {
+    sp<Layer> layer;
+};
+
 // cleanup our macros
 #undef ASSERT_DRAWABLE
 
diff --git a/libs/hwui/canvas/Points.h b/libs/hwui/canvas/Points.h
new file mode 100644
index 0000000..05e6a7d
--- /dev/null
+++ b/libs/hwui/canvas/Points.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+#include <ui/FatVector.h>
+#include "SkPoint.h"
+#include "SkRefCnt.h"
+
+/**
+ * Collection of points that are ref counted and to be used with
+ * various drawing calls that consume SkPoint as inputs like
+ * drawLines/drawPoints
+ */
+class Points: public SkNVRefCnt<SkPoint> {
+public:
+  Points(int size){
+      skPoints.resize(size);
+  }
+
+  Points(std::initializer_list<SkPoint> init): skPoints(init) { }
+
+  SkPoint& operator[](int index) {
+      return skPoints[index];
+  }
+
+  const SkPoint* data() const {
+      return skPoints.data();
+  }
+
+  size_t size() const {
+      return skPoints.size();
+  }
+private:
+  // Initialize the size to contain 2 SkPoints on the stack for optimized
+  // drawLine calls that require 2 SkPoints for start/end points of the line
+  android::FatVector<SkPoint, 2> skPoints;
+};
diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp
index f0c7793..f612bce 100644
--- a/libs/hwui/jni/fonts/Font.cpp
+++ b/libs/hwui/jni/fonts/Font.cpp
@@ -187,38 +187,6 @@
 }
 
 // Critical Native
-static jlong Font_getFontInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
-    const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
-    MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
-
-    uint64_t result = font->style().weight();
-    result |= font->style().slant() == minikin::FontStyle::Slant::ITALIC ? 0x10000 : 0x00000;
-    result |= ((static_cast<uint64_t>(minikinSkia->GetFontIndex())) << 32);
-    result |= ((static_cast<uint64_t>(minikinSkia->GetAxes().size())) << 48);
-    return result;
-}
-
-// Critical Native
-static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle, jint index) {
-    const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
-    MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
-    const minikin::FontVariation& var = minikinSkia->GetAxes().at(index);
-    uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
-    return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
-}
-
-// FastNative
-static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontHandle) {
-    const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
-    MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
-    const std::string& filePath = minikinSkia->getFilePath();
-    if (filePath.empty()) {
-        return nullptr;
-    }
-    return env->NewStringUTF(filePath.c_str());
-}
-
-// Critical Native
 static jlong Font_getNativeFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
     FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
     return reinterpret_cast<jlong>(font->font.get());
@@ -276,9 +244,6 @@
 static const JNINativeMethod gFontMethods[] = {
     { "nGetGlyphBounds", "(JIJLandroid/graphics/RectF;)F", (void*) Font_getGlyphBounds },
     { "nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F", (void*) Font_getFontMetrics },
-    { "nGetFontInfo", "(J)J", (void*) Font_getFontInfo },
-    { "nGetAxisInfo", "(JI)J", (void*) Font_getAxisInfo },
-    { "nGetFontPath", "(J)Ljava/lang/String;", (void*) Font_getFontPath },
     { "nGetNativeFontPtr", "(J)J", (void*) Font_getNativeFontPtr },
     { "nGetFontBufferAddress", "(J)J", (void*) Font_GetBufferAddress },
 };
diff --git a/libs/hwui/jni/fonts/NativeFont.cpp b/libs/hwui/jni/fonts/NativeFont.cpp
new file mode 100644
index 0000000..c5c5d46
--- /dev/null
+++ b/libs/hwui/jni/fonts/NativeFont.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "Minikin"
+
+#include "Font.h"
+#include "SkData.h"
+#include "SkFont.h"
+#include "SkFontMetrics.h"
+#include "SkFontMgr.h"
+#include "SkRefCnt.h"
+#include "SkTypeface.h"
+#include "GraphicsJNI.h"
+#include <nativehelper/ScopedUtfChars.h>
+#include "Utils.h"
+#include "FontUtils.h"
+
+#include <hwui/MinikinSkia.h>
+#include <hwui/Paint.h>
+#include <hwui/Typeface.h>
+#include <minikin/FontFamily.h>
+#include <minikin/LocaleList.h>
+#include <ui/FatVector.h>
+
+#include <memory>
+
+namespace android {
+
+// Critical Native
+static jint NativeFont_getFamilyCount(CRITICAL_JNI_PARAMS_COMMA jlong typefaceHandle) {
+    Typeface* tf = reinterpret_cast<Typeface*>(typefaceHandle);
+    return tf->fFontCollection->getFamilies().size();
+}
+
+// Critical Native
+static jlong NativeFont_getFamily(CRITICAL_JNI_PARAMS_COMMA jlong typefaceHandle, jint index) {
+    Typeface* tf = reinterpret_cast<Typeface*>(typefaceHandle);
+    return reinterpret_cast<jlong>(tf->fFontCollection->getFamilies()[index].get());
+
+}
+
+// Fast Native
+static jstring NativeFont_getLocaleList(JNIEnv* env, jobject, jlong familyHandle) {
+    minikin::FontFamily* family = reinterpret_cast<minikin::FontFamily*>(familyHandle);
+    uint32_t localeListId = family->localeListId();
+    return env->NewStringUTF(minikin::getLocaleString(localeListId).c_str());
+}
+
+// Critical Native
+static jint NativeFont_getFontCount(CRITICAL_JNI_PARAMS_COMMA jlong familyHandle) {
+    minikin::FontFamily* family = reinterpret_cast<minikin::FontFamily*>(familyHandle);
+    return family->getNumFonts();
+}
+
+// Critical Native
+static jlong NativeFont_getFont(CRITICAL_JNI_PARAMS_COMMA jlong familyHandle, jint index) {
+    minikin::FontFamily* family = reinterpret_cast<minikin::FontFamily*>(familyHandle);
+    return reinterpret_cast<jlong>(family->getFont(index));
+}
+
+// Critical Native
+static jlong NativeFont_getFontInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
+    const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
+    MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
+
+    uint64_t result = font->style().weight();
+    result |= font->style().slant() == minikin::FontStyle::Slant::ITALIC ? 0x10000 : 0x00000;
+    result |= ((static_cast<uint64_t>(minikinSkia->GetFontIndex())) << 32);
+    result |= ((static_cast<uint64_t>(minikinSkia->GetAxes().size())) << 48);
+    return result;
+}
+
+// Critical Native
+static jlong NativeFont_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle, jint index) {
+    const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
+    MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
+    const minikin::FontVariation& var = minikinSkia->GetAxes().at(index);
+    uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
+    return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
+}
+
+// FastNative
+static jstring NativeFont_getFontPath(JNIEnv* env, jobject, jlong fontHandle) {
+    const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
+    MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
+    const std::string& filePath = minikinSkia->getFilePath();
+    if (filePath.empty()) {
+        return nullptr;
+    }
+    return env->NewStringUTF(filePath.c_str());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static const JNINativeMethod gNativeFontMethods[] = {
+    { "nGetFamilyCount", "(J)I", (void*) NativeFont_getFamilyCount },
+    { "nGetFamily", "(JI)J", (void*) NativeFont_getFamily },
+    { "nGetLocaleList", "(J)Ljava/lang/String;", (void*) NativeFont_getLocaleList },
+    { "nGetFontCount", "(J)I", (void*) NativeFont_getFontCount },
+    { "nGetFont", "(JI)J", (void*) NativeFont_getFont },
+    { "nGetFontInfo", "(J)J", (void*) NativeFont_getFontInfo },
+    { "nGetAxisInfo", "(JI)J", (void*) NativeFont_getAxisInfo },
+    { "nGetFontPath", "(J)Ljava/lang/String;", (void*) NativeFont_getFontPath },
+};
+
+int register_android_graphics_fonts_NativeFont(JNIEnv* env) {
+    return RegisterMethodsOrDie(env, "android/graphics/fonts/NativeFont", gNativeFontMethods,
+            NELEM(gNativeFontMethods));
+}
+
+}  // namespace android
diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp
index f186e55..033a587 100644
--- a/libs/hwui/tests/unit/CanvasOpTests.cpp
+++ b/libs/hwui/tests/unit/CanvasOpTests.cpp
@@ -245,6 +245,31 @@
     EXPECT_EQ(1, canvas.sumTotalDrawCalls());
 }
 
+TEST(CanvasOp, simpleDrawPoints) {
+    CanvasOpBuffer buffer;
+    EXPECT_EQ(buffer.size(), 0);
+    size_t numPts = 3;
+    auto pts = sk_ref_sp(
+          new Points({
+              {32, 16},
+              {48, 48},
+              {16, 32}
+          })
+    );
+
+    buffer.push(CanvasOp<Op::DrawPoints> {
+        .count = numPts,
+        .paint = SkPaint{},
+        .points = pts
+    });
+
+    CallCountingCanvas canvas;
+    EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+    rasterizeCanvasBuffer(buffer, &canvas);
+    EXPECT_EQ(1, canvas.drawPoints);
+    EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
 TEST(CanvasOp, simpleDrawLine) {
     CanvasOpBuffer buffer;
     EXPECT_EQ(buffer.size(), 0);
@@ -263,6 +288,30 @@
     EXPECT_EQ(1, canvas.sumTotalDrawCalls());
 }
 
+TEST(CanvasOp, simpleDrawLines) {
+    CanvasOpBuffer buffer;
+    EXPECT_EQ(buffer.size(), 0);
+    size_t numPts = 3;
+    auto pts = sk_ref_sp(
+        new Points({
+               {32, 16},
+               {48, 48},
+               {16, 32}
+          })
+        );
+    buffer.push(CanvasOp<Op::DrawLines> {
+        .count = numPts,
+        .paint = SkPaint{},
+        .points = pts
+    });
+
+    CallCountingCanvas canvas;
+    EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+    rasterizeCanvasBuffer(buffer, &canvas);
+    EXPECT_EQ(1, canvas.drawPoints);
+    EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
 TEST(CanvasOp, simpleDrawRect) {
     CanvasOpBuffer buffer;
     EXPECT_EQ(buffer.size(), 0);
diff --git a/libs/incident/OWNERS b/libs/incident/OWNERS
new file mode 100644
index 0000000..f766115
--- /dev/null
+++ b/libs/incident/OWNERS
@@ -0,0 +1 @@
+include /cmds/incidentd/OWNERS
diff --git a/libs/input/OWNERS b/libs/input/OWNERS
new file mode 100644
index 0000000..d701f23
--- /dev/null
+++ b/libs/input/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/hardware/input/OWNERS
diff --git a/libs/storage/OWNERS b/libs/storage/OWNERS
new file mode 100644
index 0000000..6f9dbea
--- /dev/null
+++ b/libs/storage/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/os/storage/OWNERS
diff --git a/libs/usb/OWNERS b/libs/usb/OWNERS
new file mode 100644
index 0000000..f7b2a37
--- /dev/null
+++ b/libs/usb/OWNERS
@@ -0,0 +1 @@
+include /services/usb/OWNERS
diff --git a/location/OWNERS b/location/OWNERS
new file mode 100644
index 0000000..5ac6028
--- /dev/null
+++ b/location/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/location/OWNERS
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index d3dc3b3..92e2136 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -30,6 +30,7 @@
 import android.location.IGnssNavigationMessageListener;
 import android.location.ILocationCallback;
 import android.location.ILocationListener;
+import android.location.LastLocationRequest;
 import android.location.Location;
 import android.location.LocationRequest;
 import android.location.LocationTime;
@@ -45,7 +46,7 @@
  */
 interface ILocationManager
 {
-    @nullable Location getLastLocation(String provider, String packageName, String attributionTag);
+    @nullable Location getLastLocation(String provider, in LastLocationRequest request, String packageName, String attributionTag);
     @nullable ICancellationSignal getCurrentLocation(String provider, in LocationRequest request, in ILocationCallback callback, String packageName, String attributionTag, String listenerId);
 
     void registerLocationListener(String provider, in LocationRequest request, in ILocationListener listener, String packageName, String attributionTag, String listenerId);
diff --git a/location/java/android/location/LastLocationRequest.aidl b/location/java/android/location/LastLocationRequest.aidl
new file mode 100644
index 0000000..30c90a9
--- /dev/null
+++ b/location/java/android/location/LastLocationRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2012, 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.location;
+
+parcelable LastLocationRequest;
diff --git a/location/java/android/location/LastLocationRequest.java b/location/java/android/location/LastLocationRequest.java
new file mode 100644
index 0000000..9ea8048
--- /dev/null
+++ b/location/java/android/location/LastLocationRequest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2020 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.location;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * An encapsulation of various parameters for requesting last location via {@link LocationManager}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class LastLocationRequest implements Parcelable {
+
+    private final boolean mHiddenFromAppOps;
+    private final boolean mLocationSettingsIgnored;
+
+    private LastLocationRequest(
+            boolean hiddenFromAppOps,
+            boolean locationSettingsIgnored) {
+        mHiddenFromAppOps = hiddenFromAppOps;
+        mLocationSettingsIgnored = locationSettingsIgnored;
+    }
+
+    /**
+     * Returns true if this last location request should be ignored while updating app ops with
+     * location usage. This implies that someone else (usually the creator of the last location
+     * request) is responsible for updating app ops.
+     *
+     * @return true if this request should be ignored while updating app ops with location usage
+     *
+     */
+    public boolean isHiddenFromAppOps() {
+        return mHiddenFromAppOps;
+    }
+
+    /**
+     * Returns true if location settings, throttling, background location limits, and any other
+     * possible limiting factors will be ignored in order to satisfy this last location request.
+     *
+     * @return true if all limiting factors will be ignored to satisfy this request
+     */
+    public boolean isLocationSettingsIgnored() {
+        return mLocationSettingsIgnored;
+    }
+
+    public static final @NonNull Parcelable.Creator<LastLocationRequest> CREATOR =
+            new Parcelable.Creator<LastLocationRequest>() {
+                @Override
+                public LastLocationRequest createFromParcel(Parcel in) {
+                    return new LastLocationRequest(
+                            /* hiddenFromAppOps= */ in.readBoolean(),
+                            /* locationSettingsIgnored= */ in.readBoolean());
+                }
+                @Override
+                public LastLocationRequest[] newArray(int size) {
+                    return new LastLocationRequest[size];
+                }
+            };
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeBoolean(mHiddenFromAppOps);
+        parcel.writeBoolean(mLocationSettingsIgnored);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        LastLocationRequest that = (LastLocationRequest) o;
+        return mHiddenFromAppOps == that.mHiddenFromAppOps
+                && mLocationSettingsIgnored == that.mLocationSettingsIgnored;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mHiddenFromAppOps, mLocationSettingsIgnored);
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("LastLocationRequest[");
+        if (mHiddenFromAppOps) {
+            s.append("hiddenFromAppOps, ");
+        }
+        if (mLocationSettingsIgnored) {
+            s.append("locationSettingsIgnored, ");
+        }
+        if (s.length() > "LastLocationRequest[".length()) {
+            s.setLength(s.length() - 2);
+        }
+        s.append(']');
+        return s.toString();
+    }
+
+    /**
+     * A builder class for {@link LastLocationRequest}.
+     */
+    public static final class Builder {
+
+        private boolean mHiddenFromAppOps;
+        private boolean mLocationSettingsIgnored;
+
+        /**
+         * Creates a new Builder.
+         */
+        public Builder() {
+            mHiddenFromAppOps = false;
+            mLocationSettingsIgnored = false;
+        }
+
+        /**
+         * Creates a new Builder with all parameters copied from the given last location request.
+         */
+        public Builder(@NonNull LastLocationRequest lastLocationRequest) {
+            mHiddenFromAppOps = lastLocationRequest.mHiddenFromAppOps;
+            mLocationSettingsIgnored = lastLocationRequest.mLocationSettingsIgnored;
+        }
+
+        /**
+         * If set to true, indicates that app ops should not be updated with location usage due to
+         * this request. This implies that someone else (usually the creator of the last location
+         * request) is responsible for updating app ops as appropriate. Defaults to false.
+         *
+         * <p>Permissions enforcement occurs when resulting last location request is actually used,
+         * not when this method is invoked.
+         */
+        @RequiresPermission(Manifest.permission.UPDATE_APP_OPS_STATS)
+        public @NonNull Builder setHiddenFromAppOps(boolean hiddenFromAppOps) {
+            mHiddenFromAppOps = hiddenFromAppOps;
+            return this;
+        }
+
+        /**
+         * If set to true, indicates that location settings, throttling, background location limits,
+         * and any other possible limiting factors should be ignored in order to satisfy this
+         * last location request. This is only intended for use in user initiated emergency
+         * situations, and should be used extremely cautiously. Defaults to false.
+         *
+         * <p>Permissions enforcement occurs when resulting last location request is actually used,
+         * not when this method is invoked.
+         */
+        @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+        public @NonNull Builder setLocationSettingsIgnored(boolean locationSettingsIgnored) {
+            mLocationSettingsIgnored = locationSettingsIgnored;
+            return this;
+        }
+
+        /**
+         * Builds a last location request from this builder.
+         *
+         * @return a new last location request
+         */
+        public @NonNull LastLocationRequest build() {
+            return new LastLocationRequest(
+                    mHiddenFromAppOps,
+                    mLocationSettingsIgnored);
+        }
+    }
+}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 047b809..7085a75 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -683,6 +683,7 @@
      * location should always be checked.
      *
      * @return the last known location, or null if not available
+     *
      * @throws SecurityException if no suitable location permission is present
      *
      * @hide
@@ -706,18 +707,50 @@
      * in the course of the attempt as compared to this method.
      *
      * @param provider a provider listed by {@link #getAllProviders()}
+     *
      * @return the last known location for the given provider, or null if not available
+     *
      * @throws SecurityException if no suitable permission is present
      * @throws IllegalArgumentException if provider is null or doesn't exist
      */
     @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
     @Nullable
     public Location getLastKnownLocation(@NonNull String provider) {
+        return getLastKnownLocation(provider, new LastLocationRequest.Builder().build());
+    }
+
+    /**
+     * Gets the last known location from the given provider, or null if there is no last known
+     * location.
+     *
+     * <p>See {@link LastLocationRequest} documentation for an explanation of various request
+     * parameters and how they can affect the returned location.
+     *
+     * <p>See {@link #getLastKnownLocation(String)} for more detail on how this method works.
+     *
+     * @param provider            a provider listed by {@link #getAllProviders()}
+     * @param lastLocationRequest the last location request containing location parameters
+     *
+     * @return the last known location for the given provider, or null if not available
+     *
+     * @throws SecurityException if no suitable permission is present
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if lastLocationRequest is null
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    @Nullable
+    public Location getLastKnownLocation(@NonNull String provider,
+            @NonNull LastLocationRequest lastLocationRequest) {
         Preconditions.checkArgument(provider != null, "invalid null provider");
+        Preconditions.checkArgument(lastLocationRequest != null,
+                "invalid null last location request");
 
         try {
-            return mService.getLastLocation(provider, mContext.getPackageName(),
-                    mContext.getAttributionTag());
+            return mService.getLastLocation(provider, lastLocationRequest,
+                    mContext.getPackageName(), mContext.getAttributionTag());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1509,8 +1542,15 @@
     }
 
     /**
-     * Removes location updates for the specified {@link LocationListener}. Following this call,
-     * the listener will not receive any more invocations of any kind.
+     * Removes all location updates for the specified {@link LocationListener}. The given listener
+     * is guaranteed not to receive any invocations that <b>happens-after</b> this method is
+     * invoked.
+     *
+     * <p>If the given listener has any batched requests, this method will not flush any incomplete
+     * location batches before stopping location updates. If you wish to flush any pending locations
+     * before stopping, you must first call {@link #requestFlush(String, LocationListener, int)} and
+     * then call this method once the flush is complete. If this method is invoked before the flush
+     * is complete, you may not receive the flushed locations.
      *
      * @param listener listener that no longer needs location updates
      *
@@ -1537,6 +1577,8 @@
      * Removes location updates for the specified {@link PendingIntent}. Following this call, the
      * PendingIntent will no longer receive location updates.
      *
+     * <p>See {@link #removeUpdates(LocationListener)} for more detail on how this method works.
+     *
      * @param pendingIntent pending intent that no longer needs location updates
      *
      * @throws IllegalArgumentException if pendingIntent is null
diff --git a/location/java/android/location/OWNERS b/location/java/android/location/OWNERS
new file mode 100644
index 0000000..383321b
--- /dev/null
+++ b/location/java/android/location/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 880425
+
+mstogaitis@google.com
+wyattriley@google.com
+etn@google.com
+weiwa@google.com
diff --git a/media/OWNERS b/media/OWNERS
index e741490..b2875e7 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -10,7 +10,7 @@
 jaewan@google.com
 jinpark@google.com
 jmtrivi@google.com
-jsharkey@android.com
+jsharkey@google.com
 klhyun@google.com
 lajos@google.com
 marcone@google.com
diff --git a/media/java/android/media/AudioPlaybackConfiguration.java b/media/java/android/media/AudioPlaybackConfiguration.java
index 515e9d0..17305a5 100644
--- a/media/java/android/media/AudioPlaybackConfiguration.java
+++ b/media/java/android/media/AudioPlaybackConfiguration.java
@@ -89,9 +89,8 @@
     /**
      * @hide
      * Player backed an AAudio player.
-     * Note this type is not in System API so it will not be returned in public API calls
      */
-    // TODO unhide for SystemApi, update getPlayerType()
+    @SystemApi
     public static final int PLAYER_TYPE_AAUDIO = 13;
 
     /**
@@ -280,10 +279,7 @@
 
     /**
      * @hide
-     * Return the type of player linked to this configuration. The return value is one of
-     * {@link #PLAYER_TYPE_JAM_AUDIOTRACK}, {@link #PLAYER_TYPE_JAM_MEDIAPLAYER},
-     * {@link #PLAYER_TYPE_JAM_SOUNDPOOL}, {@link #PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE},
-     * {@link #PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD}, or {@link #PLAYER_TYPE_UNKNOWN}.
+     * Return the type of player linked to this configuration.
      * <br>Note that player types not exposed in the system API will be represented as
      * {@link #PLAYER_TYPE_UNKNOWN}.
      * @return the type of the player.
@@ -291,7 +287,6 @@
     @SystemApi
     public @PlayerType int getPlayerType() {
         switch (mPlayerType) {
-            case PLAYER_TYPE_AAUDIO:
             case PLAYER_TYPE_HW_SOURCE:
             case PLAYER_TYPE_EXTERNAL_PROXY:
                 return PLAYER_TYPE_UNKNOWN;
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 39bdf95..bd27f6d 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.TestApi;
 import android.bluetooth.BluetoothCodecConfig;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -1550,9 +1551,11 @@
 
     /** @hide returns master balance value in range -1.f -> 1.f, where 0.f is dead center. */
     @TestApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS)
     public static native float getMasterBalance();
     /** @hide Changes the audio balance of the device. */
     @TestApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS)
     public static native int setMasterBalance(float balance);
 
     // helpers for android.media.AudioManager.getProperty(), see description there for meaning
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 4b11e32..f8311cd 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -4232,8 +4232,10 @@
      * @see OnRtpRxNoticeListener
      *
      * @param listener the listener called after a notice from RTP Rx
-     * @param handler the {@link Handler} that receives RTP Tx events
-     *
+     * @param handler the {@link Handler} that receives RTP Tx events. If null is passed,
+     *                notifications will be posted on the thread that created this MediaPlayer
+     *                instance. If the creating thread does not have a {@link Looper}, then
+     *                notifications will be posted on the main thread.
      * @hide
      */
     @SystemApi
diff --git a/media/java/android/media/OWNERS b/media/java/android/media/OWNERS
new file mode 100644
index 0000000..cbc9ab7
--- /dev/null
+++ b/media/java/android/media/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 1344
+
+fgoldfain@google.com
+elaurent@google.com
+lajos@google.com
+olly@google.com
+andrewlewis@google.com
+sungsoo@google.com
diff --git a/media/java/android/media/audiofx/OWNERS b/media/java/android/media/audiofx/OWNERS
new file mode 100644
index 0000000..189fe0f
--- /dev/null
+++ b/media/java/android/media/audiofx/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 48436
+
+elaurent@google.com
diff --git a/media/java/android/media/audiopolicy/OWNERS b/media/java/android/media/audiopolicy/OWNERS
new file mode 100644
index 0000000..189fe0f
--- /dev/null
+++ b/media/java/android/media/audiopolicy/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 48436
+
+elaurent@google.com
diff --git a/media/java/android/media/browse/OWNERS b/media/java/android/media/browse/OWNERS
new file mode 100644
index 0000000..916fc36
--- /dev/null
+++ b/media/java/android/media/browse/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 137631
+
+hdmoon@google.com
+insun@google.com
+jaewan@google.com
+jinpark@google.com
+klhyun@google.com
+gyumin@google.com
diff --git a/media/java/android/media/midi/OWNERS b/media/java/android/media/midi/OWNERS
new file mode 100644
index 0000000..6a351d3
--- /dev/null
+++ b/media/java/android/media/midi/OWNERS
@@ -0,0 +1 @@
+elaurent@google.com
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index e9bb7f8..1da41fb 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -46,6 +46,8 @@
 import android.util.Log;
 import android.view.KeyEvent;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
@@ -437,7 +439,7 @@
         }
 
         if (mSessionInfo == null) {
-            Log.w(TAG, "sessionInfo shouldn't be null.");
+            Log.d(TAG, "sessionInfo is not set.");
             mSessionInfo = Bundle.EMPTY;
         } else if (MediaSession.hasCustomParcelable(mSessionInfo)) {
             Log.w(TAG, "sessionInfo contains custom parcelable. Ignoring.");
@@ -514,6 +516,17 @@
         return success;
     }
 
+    /**
+     * Gets associated handler for the given callback.
+     * @hide
+     */
+    @VisibleForTesting
+    public Handler getHandlerForCallback(Callback cb) {
+        synchronized (mLock) {
+            return getHandlerForCallbackLocked(cb);
+        }
+    }
+
     private MessageHandler getHandlerForCallbackLocked(Callback cb) {
         if (cb == null) {
             throw new IllegalArgumentException("Callback cannot be null");
diff --git a/media/java/android/media/session/OWNERS b/media/java/android/media/session/OWNERS
new file mode 100644
index 0000000..916fc36
--- /dev/null
+++ b/media/java/android/media/session/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 137631
+
+hdmoon@google.com
+insun@google.com
+jaewan@google.com
+jinpark@google.com
+klhyun@google.com
+gyumin@google.com
diff --git a/media/java/android/media/soundtrigger/OWNERS b/media/java/android/media/soundtrigger/OWNERS
new file mode 100644
index 0000000..6a351d3
--- /dev/null
+++ b/media/java/android/media/soundtrigger/OWNERS
@@ -0,0 +1 @@
+elaurent@google.com
diff --git a/media/java/android/media/tv/OWNERS b/media/java/android/media/tv/OWNERS
index a891154..8bccc9a 100644
--- a/media/java/android/media/tv/OWNERS
+++ b/media/java/android/media/tv/OWNERS
@@ -1,9 +1,6 @@
-amyjojo@google.com
 nchalko@google.com
-shubang@google.com
 quxiangfang@google.com
 
 # For android remote service
 per-file ITvRemoteServiceInput.aidl = file:/media/lib/tvremote/OWNERS
 per-file ITvRemoteProvider.aidl = file:/media/lib/tvremote/OWNERS
-
diff --git a/media/java/android/media/tv/tuner/Descrambler.java b/media/java/android/media/tv/tuner/Descrambler.java
index 2217eb3..700e7be 100644
--- a/media/java/android/media/tv/tuner/Descrambler.java
+++ b/media/java/android/media/tv/tuner/Descrambler.java
@@ -110,14 +110,16 @@
     }
 
     /**
-     * Set a key token to link descrambler to a key slot
+     * Set a key token to link descrambler to a key slot. Use {@link isValidKeyToken(byte[])} to
+     * validate the key token format. Invalid key token would cause no-op and return
+     * {@link Tuner.RESULT_INVALID_ARGUMENT}.
      *
      * <p>A descrambler instance can have only one key slot to link, but a key slot can hold a few
-     * keys for different purposes.
+     * keys for different purposes. {@link Tuner.VOID_KEYTOKEN} is considered valid.
      *
-     * @param keyToken the token to be used to link the key slot. Use {@link Tuner.INVALID_KEYTOKEN}
+     * @param keyToken the token to be used to link the key slot. Use {@link Tuner.VOID_KEYTOKEN}
      *        to remove the current key from descrambler. If the current keyToken comes from a
-     *        MediaCas session, use {@link Tuner.INVALID_KEYTOKEN} to remove current key before
+     *        MediaCas session, use {@link Tuner.VOID_KEYTOKEN} to remove current key before
      *        closing the MediaCas session.
      * @return result status of the operation.
      */
@@ -134,6 +136,22 @@
     }
 
     /**
+     * Validate the key token format as the parameter of {@link setKeyToken(byte[])}.
+     *
+     * <p>The key token is expected to be less than 128 bits.
+     *
+     * @param keyToken the token to be validated.
+     * @return true if the given key token is a valid one.
+     */
+    public static boolean isValidKeyToken(@NonNull byte[] keyToken) {
+        if (keyToken.length == 0 || keyToken.length > 16) {
+            Log.d(TAG, "Invalid key token size: " + (keyToken.length * 8) + " bit.");
+            return false;
+        }
+        return true;
+    }
+
+    /**
      * Release the descrambler instance.
      */
     @Override
@@ -150,18 +168,4 @@
             }
         }
     }
-
-    private boolean isValidKeyToken(byte[] keyToken) {
-        if (keyToken.length == 0 || keyToken.length > 16) {
-            Log.d(TAG, "Invalid key token size: " + (keyToken.length * 8) + " bit.");
-            return false;
-        }
-        for (int i = 0; i < keyToken.length; i++) {
-            if (keyToken[i] < 0) {
-                Log.d(TAG, "Invalid key token.");
-                return false;
-            }
-        }
-        return true;
-    }
 }
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index c261371..d094c2c 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -60,6 +60,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -166,13 +167,13 @@
     public static final int INVALID_LNB_ID =
             android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_LNB_ID;
     /**
-     * Invalid key token. It is used to remove the current key from descrambler.
+     * A void key token. It is used to remove the current key from descrambler.
      *
      * <p>If the current keyToken comes from a MediaCas session, App is recommended to
      * to use this constant to remove current key before closing MediaCas session.
      */
     @NonNull
-    public static final byte[] INVALID_KEYTOKEN =
+    public static final byte[] VOID_KEYTOKEN =
             {android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_KEYTOKEN};
 
     /** @hide */
@@ -296,8 +297,8 @@
     private Executor mOnResourceLostListenerExecutor;
 
     private Integer mDemuxHandle;
-    private Map<Integer, Descrambler> mDescramblers = new HashMap<>();
-    private List<Filter> mFilters = new ArrayList<>();
+    private Map<Integer, WeakReference<Descrambler>> mDescramblers = new HashMap<>();
+    private List<WeakReference<Filter>> mFilters = new ArrayList<WeakReference<Filter>>();
 
     private final TunerResourceManager.ResourcesReclaimListener mResourceListener =
             new TunerResourceManager.ResourcesReclaimListener() {
@@ -486,18 +487,28 @@
         if (mLnb != null) {
             mLnb.close();
         }
-        if (!mDescramblers.isEmpty()) {
-            for (Map.Entry<Integer, Descrambler> d : mDescramblers.entrySet()) {
-                d.getValue().close();
-                mTunerResourceManager.releaseDescrambler(d.getKey(), mClientId);
+        synchronized (mDescramblers) {
+            if (!mDescramblers.isEmpty()) {
+                for (Map.Entry<Integer, WeakReference<Descrambler>> d : mDescramblers.entrySet()) {
+                    Descrambler descrambler = d.getValue().get();
+                    if (descrambler != null) {
+                        descrambler.close();
+                    }
+                    mTunerResourceManager.releaseDescrambler(d.getKey(), mClientId);
+                }
+                mDescramblers.clear();
             }
-            mDescramblers.clear();
         }
-        if (!mFilters.isEmpty()) {
-            for (Filter f : mFilters) {
-                f.close();
+        synchronized (mFilters) {
+            if (!mFilters.isEmpty()) {
+                for (WeakReference<Filter> weakFilter : mFilters) {
+                    Filter filter = weakFilter.get();
+                    if (filter != null) {
+                        filter.close();
+                    }
+                }
+                mFilters.clear();
             }
-            mFilters.clear();
         }
         if (mDemuxHandle != null) {
             int res = nativeCloseDemux(mDemuxHandle);
@@ -1183,7 +1194,10 @@
             if (mHandler == null) {
                 mHandler = createEventHandler();
             }
-            mFilters.add(filter);
+            synchronized (mFilters) {
+                WeakReference<Filter> weakFilter = new WeakReference<Filter>(filter);
+                mFilters.add(weakFilter);
+            }
         }
         return filter;
     }
@@ -1351,7 +1365,10 @@
         int handle = descramblerHandle[0];
         Descrambler descrambler = nativeOpenDescramblerByHandle(handle);
         if (descrambler != null) {
-            mDescramblers.put(handle, descrambler);
+            synchronized (mDescramblers) {
+                WeakReference weakDescrambler = new WeakReference<Descrambler>(descrambler);
+                mDescramblers.put(handle, weakDescrambler);
+            }
         } else {
             mTunerResourceManager.releaseDescrambler(handle, mClientId);
         }
diff --git a/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
index 98f8096..a2a602a 100644
--- a/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
@@ -341,13 +341,13 @@
         return mScanType;
     }
     /**
-     * Get if the client could handle the Diseqc Rx Message or not. Default value is false.
+     * Get if the client can handle the Diseqc Rx Message or not. Default value is false.
      *
-     * The setter {@link Builder#setCouldHandleDiseqcRxMessage(boolean)} is only supported with
+     * The setter {@link Builder#setCanHandleDiseqcRxMessage(boolean)} is only supported with
      * Tuner HAL 1.1 or higher. Use {@link TunerVersionChecker.getTunerVersion()} to check the
      * version.
      */
-    public boolean getCouldHandleDiseqcRxMessage() {
+    public boolean canHandleDiseqcRxMessage() {
         return mIsDiseqcRxMessage;
     }
 
@@ -409,7 +409,7 @@
         }
 
         /**
-         * Set true to indicate the client could handle the Diseqc Messages. Note that it's still
+         * Set true to indicate the client can handle the Diseqc Messages. Note that it's still
          * possible that the client won't receive the messages when HAL is not able to setup Rx
          * channel in the hardware layer.
          *
@@ -417,10 +417,10 @@
          * no-op. Use {@link TunerVersionChecker.getTunerVersion()} to check the version.
          */
         @NonNull
-        public Builder setCouldHandleDiseqcRxMessage(boolean couldReceiveDiseqcMessage) {
+        public Builder setCanHandleDiseqcRxMessage(boolean canHandleDiseqcMessage) {
             if (TunerVersionChecker.checkHigherOrEqualVersionTo(
-                        TunerVersionChecker.TUNER_VERSION_1_1, "setCouldHandleDiseqcRxMessage")) {
-                mIsDiseqcRxMessage = couldReceiveDiseqcMessage;
+                        TunerVersionChecker.TUNER_VERSION_1_1, "setCanHandleDiseqcRxMessage")) {
+                mIsDiseqcRxMessage = canHandleDiseqcMessage;
             }
             return this;
         }
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
index af1ff01..c762da6 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
@@ -28,7 +28,7 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * Frontend status.
+ * A Frontend Status class that contains the metrics of the active frontend.
  *
  * @hide
  */
@@ -461,7 +461,7 @@
     }
 
     /**
-     * Lock status for Demod.
+     * Gets if the demod is currently locked or not.
      */
     public boolean isDemodLocked() {
         if (mIsDemodLocked == null) {
@@ -470,7 +470,7 @@
         return mIsDemodLocked;
     }
     /**
-     * Gets Signal to Noise Ratio in thousandths of a deciBel (0.001dB).
+     * Gets the current Signal to Noise Ratio in thousandths of a deciBel (0.001dB).
      */
     public int getSnr() {
         if (mSnr == null) {
@@ -479,7 +479,7 @@
         return mSnr;
     }
     /**
-     * Gets Bit Error Ratio.
+     * Gets the current Bit Error Ratio.
      *
      * <p>The number of error bit per 1 billion bits.
      */
@@ -491,7 +491,7 @@
     }
 
     /**
-     * Gets Packages Error Ratio.
+     * Gets the current Packages Error Ratio.
      *
      * <p>The number of error package per 1 billion packages.
      */
@@ -502,7 +502,7 @@
         return mPer;
     }
     /**
-     * Gets Bit Error Ratio before Forward Error Correction (FEC).
+     * Gets the current Bit Error Ratio before Forward Error Correction (FEC).
      *
      * <p>The number of error bit per 1 billion bits before FEC.
      */
@@ -513,7 +513,7 @@
         return mPerBer;
     }
     /**
-     * Gets Signal Quality in percent.
+     * Gets the current Signal Quality in percent.
      */
     public int getSignalQuality() {
         if (mSignalQuality == null) {
@@ -522,7 +522,7 @@
         return mSignalQuality;
     }
     /**
-     * Gets Signal Strength in thousandths of a dBm (0.001dBm).
+     * Gets the current Signal Strength in thousandths of a dBm (0.001dBm).
      */
     public int getSignalStrength() {
         if (mSignalStrength == null) {
@@ -531,7 +531,7 @@
         return mSignalStrength;
     }
     /**
-     * Gets symbol rate in symbols per second.
+     * Gets the current symbol rate in symbols per second.
      */
     public int getSymbolRate() {
         if (mSymbolRate == null) {
@@ -540,7 +540,7 @@
         return mSymbolRate;
     }
     /**
-     *  Gets Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1
+     *  Gets the current Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1
      *  and ETSI EN 302 307-2 V1.1.1.
      */
     @FrontendSettings.InnerFec
@@ -551,7 +551,7 @@
         return mInnerFec;
     }
     /**
-     * Gets modulation.
+     * Gets the currently modulation information.
      */
     @FrontendModulation
     public int getModulation() {
@@ -561,7 +561,7 @@
         return mModulation;
     }
     /**
-     * Gets Spectral Inversion for DVBC.
+     * Gets the currently Spectral Inversion information for DVBC.
      */
     @FrontendSettings.FrontendSpectralInversion
     public int getSpectralInversion() {
@@ -571,7 +571,7 @@
         return mInversion;
     }
     /**
-     * Gets Power Voltage Type for LNB.
+     * Gets the current Power Voltage Type for LNB.
      */
     @Lnb.Voltage
     public int getLnbVoltage() {
@@ -581,7 +581,7 @@
         return mLnbVoltage;
     }
     /**
-     * Gets Physical Layer Pipe ID.
+     * Gets the current Physical Layer Pipe ID.
      */
     public int getPlpId() {
         if (mPlpId == null) {
@@ -599,7 +599,7 @@
         return mIsEwbs;
     }
     /**
-     * Gets Automatic Gain Control value which is normalized from 0 to 255.
+     * Gets the current Automatic Gain Control value which is normalized from 0 to 255.
      */
     public int getAgc() {
         if (mAgc == null) {
@@ -617,7 +617,7 @@
         return mIsLnaOn;
     }
     /**
-     * Gets Error status by layer.
+     * Gets the current Error information by layer.
      */
     @NonNull
     public boolean[] getLayerErrors() {
@@ -627,7 +627,7 @@
         return mIsLayerErrors;
     }
     /**
-     * Gets Modulation Error Ratio in thousandths of a deciBel (0.001dB).
+     * Gets the current Modulation Error Ratio in thousandths of a deciBel (0.001dB).
      */
     public int getMer() {
         if (mMer == null) {
@@ -636,7 +636,7 @@
         return mMer;
     }
     /**
-     * Gets frequency difference in Hz.
+     * Gets the current frequency difference in Hz.
      *
      * <p>Difference between tuning frequency and actual locked frequency.
      */
@@ -647,7 +647,7 @@
         return mFreqOffset;
     }
     /**
-     * Gets hierarchy Type for DVBT.
+     * Gets the current hierarchy Type for DVBT.
      */
     @DvbtFrontendSettings.Hierarchy
     public int getHierarchy() {
@@ -657,7 +657,7 @@
         return mHierarchy;
     }
     /**
-     * Gets lock status for RF.
+     * Gets if the RF is locked or not.
      */
     public boolean isRfLocked() {
         if (mIsRfLocked == null) {
@@ -666,7 +666,7 @@
         return mIsRfLocked;
     }
     /**
-     * Gets an array of PLP status for tuned PLPs for ATSC3 frontend.
+     * Gets an array of the current tuned PLPs information of ATSC3 frontend.
      */
     @NonNull
     public Atsc3PlpTuningInfo[] getAtsc3PlpTuningInfo() {
@@ -677,9 +677,9 @@
     }
 
     /**
-     * Gets an array of extended bit error ratio status.
+     * Gets an array of the current extended bit error ratio.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
@@ -693,10 +693,9 @@
     }
 
     /**
-     * Gets an array of code rates status. The {@link FrontendSettings.InnerFec} would be used to
-     * show the code rate.
+     * Gets an array of the current code rates.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
@@ -711,9 +710,9 @@
     }
 
     /**
-     * Gets bandwidth status.
+     * Gets the current bandwidth information.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @FrontendBandwidth
@@ -727,9 +726,9 @@
     }
 
     /**
-     * Gets guard interval status.
+     * Gets the current guard interval information.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @FrontendGuardInterval
@@ -743,9 +742,9 @@
     }
 
     /**
-     * Gets tansmission mode status.
+     * Gets the current transmission mode information.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @FrontendTransmissionMode
@@ -759,10 +758,10 @@
     }
 
     /**
-     * Gets the Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP) since the
-     * last tune operation.
+     * Gets the current Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP)
+     * since the last tune operation.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     public int getUec() {
@@ -775,9 +774,9 @@
     }
 
     /**
-     * Gets the current DVB-T2 system id status.
+     * Gets the current DVB-T2 system id.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @IntRange(from = 0, to = 0xffff)
@@ -791,10 +790,9 @@
     }
 
     /**
-     * Gets an array of interleaving status. Array value should be within {@link
-     * FrontendInterleaveMode}.
+     * Gets an array of the current interleaving mode information.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
@@ -809,9 +807,10 @@
     }
 
     /**
-     * Gets an array of the segments status in ISDB-T Specification of all the channels.
+     * Gets an array of the current segments information in ISDB-T Specification of all the
+     * channels.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
@@ -828,7 +827,7 @@
     /**
      * Gets an array of the Transport Stream Data Rate in BPS of the current channel.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
@@ -842,13 +841,13 @@
     }
 
     /**
-     * Gets an array of the extended modulations status. Array value should be withink {@link
-     * FrontendModulation}.
+     * Gets an array of the current extended modulations information.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
+    @FrontendModulation
     public int[] getExtendedModulations() {
         TunerVersionChecker.checkHigherOrEqualVersionTo(
                 TunerVersionChecker.TUNER_VERSION_1_1, "getExtendedModulations status");
@@ -859,9 +858,9 @@
     }
 
     /**
-     * Gets roll off status.
+     * Gets the current roll off information.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @FrontendRollOff
@@ -875,9 +874,9 @@
     }
 
     /**
-     * Gets is MISO enabled status.
+     * Gets is MISO enabled or not.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     public boolean isMisoEnabled() {
@@ -890,9 +889,9 @@
     }
 
     /**
-     * Gets is the Code Rate of the frontend is linear or not status.
+     * Gets is the Code Rate of the frontend is linear or not.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     public boolean isLinear() {
@@ -905,9 +904,9 @@
     }
 
     /**
-     * Gets is the Short Frames enabled or not status.
+     * Gets is the Short Frames enabled or not.
      *
-     * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     public boolean isShortFramesEnabled() {
@@ -920,7 +919,7 @@
     }
 
     /**
-     * Status for each tuning Physical Layer Pipes.
+     * Information of each tuning Physical Layer Pipes.
      */
     public static class Atsc3PlpTuningInfo {
         private final int mPlpId;
diff --git a/media/java/android/mtp/OWNERS b/media/java/android/mtp/OWNERS
index 1928ba8..e27d06f 100644
--- a/media/java/android/mtp/OWNERS
+++ b/media/java/android/mtp/OWNERS
@@ -1,7 +1,7 @@
 set noparent
 
 marcone@google.com
-jsharkey@android.com
+jsharkey@google.com
 jameswei@google.com
 rmojumder@google.com
 
diff --git a/media/jni/OWNERS b/media/jni/OWNERS
index f1b0237..e6e4f86 100644
--- a/media/jni/OWNERS
+++ b/media/jni/OWNERS
@@ -1,5 +1,5 @@
 # extra for MTP related files
-per-file android_mtp_*.cpp=marcone@google.com,jsharkey@android.com,jameswei@google.com,rmojumder@google.com
+per-file android_mtp_*.cpp=marcone@google.com,jsharkey@google.com,jameswei@google.com,rmojumder@google.com
 
 # extra for TV related files
 per-file android_media_tv_*=nchalko@google.com,quxiangfang@google.com
diff --git a/media/jni/android_media_MediaCodecLinearBlock.h b/media/jni/android_media_MediaCodecLinearBlock.h
index 8f1d2fa..ae2d3a2 100644
--- a/media/jni/android_media_MediaCodecLinearBlock.h
+++ b/media/jni/android_media_MediaCodecLinearBlock.h
@@ -49,7 +49,14 @@
             if (offset == 0 && size == block.capacity()) {
                 return mBuffer;
             }
-            return C2Buffer::CreateLinearBuffer(block.subBlock(offset, size));
+
+            std::shared_ptr<C2Buffer> buffer =
+                C2Buffer::CreateLinearBuffer(block.subBlock(offset, size));
+            for (const std::shared_ptr<const C2Info> &info : mBuffer->info()) {
+                std::shared_ptr<C2Param> param = std::move(C2Param::Copy(*info));
+                buffer->setInfo(std::static_pointer_cast<C2Info>(param));
+            }
+            return buffer;
         }
         if (mBlock) {
             return C2Buffer::CreateLinearBuffer(mBlock->share(offset, size, C2Fence{}));
diff --git a/media/mca/effect/java/android/media/effect/OWNERS b/media/mca/effect/java/android/media/effect/OWNERS
new file mode 100644
index 0000000..6a351d3
--- /dev/null
+++ b/media/mca/effect/java/android/media/effect/OWNERS
@@ -0,0 +1 @@
+elaurent@google.com
diff --git a/media/mca/effect/java/android/media/effect/effects/OWNERS b/media/mca/effect/java/android/media/effect/effects/OWNERS
new file mode 100644
index 0000000..6a351d3
--- /dev/null
+++ b/media/mca/effect/java/android/media/effect/effects/OWNERS
@@ -0,0 +1 @@
+elaurent@google.com
diff --git a/media/mca/filterfw/java/android/filterfw/OWNERS b/media/mca/filterfw/java/android/filterfw/OWNERS
new file mode 100644
index 0000000..5d351ef
--- /dev/null
+++ b/media/mca/filterfw/java/android/filterfw/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 50018
+
+elaurent@google.com
diff --git a/media/mca/filterfw/java/android/filterfw/samples/OWNERS b/media/mca/filterfw/java/android/filterfw/samples/OWNERS
new file mode 100644
index 0000000..5d351ef
--- /dev/null
+++ b/media/mca/filterfw/java/android/filterfw/samples/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 50018
+
+elaurent@google.com
diff --git a/media/tests/MtpTests/OWNERS b/media/tests/MtpTests/OWNERS
index 1928ba8..e27d06f 100644
--- a/media/tests/MtpTests/OWNERS
+++ b/media/tests/MtpTests/OWNERS
@@ -1,7 +1,7 @@
 set noparent
 
 marcone@google.com
-jsharkey@android.com
+jsharkey@google.com
 jameswei@google.com
 rmojumder@google.com
 
diff --git a/mime/OWNERS b/mime/OWNERS
new file mode 100644
index 0000000..6f9dbea
--- /dev/null
+++ b/mime/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/os/storage/OWNERS
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 7793d6c..6db4da9 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -36,6 +36,7 @@
     defaults: ["libandroid_defaults"],
 
     srcs: [
+        "activity_manager.cpp",
         "asset_manager.cpp",
         "choreographer.cpp",
         "configuration.cpp",
@@ -95,6 +96,10 @@
 
     include_dirs: ["bionic/libc/dns/include"],
 
+    local_include_dirs: [ "include_platform", ],
+
+    export_include_dirs: [ "include_platform", ],
+
     version_script: "libandroid.map.txt",
     stubs: {
         symbol_file: "libandroid.map.txt",
diff --git a/native/android/activity_manager.cpp b/native/android/activity_manager.cpp
new file mode 100644
index 0000000..82f4569
--- /dev/null
+++ b/native/android/activity_manager.cpp
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "AActivityManager"
+#include <utils/Log.h>
+
+#include <android/activity_manager.h>
+#include <binder/ActivityManager.h>
+
+namespace android {
+namespace activitymanager {
+
+// Global instance of ActivityManager, service is obtained only on first use.
+static ActivityManager gAm;
+// String tag used with ActivityManager.
+static const String16& getTag() {
+    static String16 tag("libandroid");
+    return tag;
+}
+
+struct UidObserver : public BnUidObserver, public virtual IBinder::DeathRecipient {
+    explicit UidObserver(const AActivityManager_onUidImportance& cb,
+                         int32_t cutpoint, void* cookie)
+          : mCallback(cb), mImportanceCutpoint(cutpoint), mCookie(cookie), mRegistered(false) {}
+    bool registerSelf();
+    void unregisterSelf();
+
+    // IUidObserver
+    void onUidGone(uid_t uid, bool disabled) override;
+    void onUidActive(uid_t uid) override;
+    void onUidIdle(uid_t uid, bool disabled) override;
+    void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
+                           int32_t capability) override;
+
+    // IBinder::DeathRecipient implementation
+    void binderDied(const wp<IBinder>& who) override;
+
+    static int32_t procStateToImportance(int32_t procState);
+    static int32_t importanceToProcState(int32_t importance);
+
+    AActivityManager_onUidImportance mCallback;
+    int32_t mImportanceCutpoint;
+    void* mCookie;
+    std::mutex mRegisteredLock;
+    bool mRegistered GUARDED_BY(mRegisteredLock);
+};
+
+//static
+int32_t UidObserver::procStateToImportance(int32_t procState) {
+    // TODO: remove this after adding Importance to onUidStateChanged callback.
+    if (procState == ActivityManager::PROCESS_STATE_NONEXISTENT) {
+        return AACTIVITYMANAGER_IMPORTANCE_GONE;
+    } else if (procState >= ActivityManager::PROCESS_STATE_HOME) {
+        return AACTIVITYMANAGER_IMPORTANCE_CACHED;
+    } else if (procState == ActivityManager::PROCESS_STATE_HEAVY_WEIGHT) {
+        return AACTIVITYMANAGER_IMPORTANCE_CANT_SAVE_STATE;
+    } else if (procState >= ActivityManager::PROCESS_STATE_TOP_SLEEPING) {
+        return AACTIVITYMANAGER_IMPORTANCE_TOP_SLEEPING;
+    } else if (procState >= ActivityManager::PROCESS_STATE_SERVICE) {
+        return AACTIVITYMANAGER_IMPORTANCE_SERVICE;
+    } else if (procState >= ActivityManager::PROCESS_STATE_TRANSIENT_BACKGROUND) {
+        return AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE;
+    } else if (procState >= ActivityManager::PROCESS_STATE_IMPORTANT_FOREGROUND) {
+        return AACTIVITYMANAGER_IMPORTANCE_VISIBLE;
+    } else if (procState >= ActivityManager::PROCESS_STATE_FOREGROUND_SERVICE) {
+        return AACTIVITYMANAGER_IMPORTANCE_FOREGROUND_SERVICE;
+    } else {
+        return AACTIVITYMANAGER_IMPORTANCE_FOREGROUND;
+    }
+}
+
+//static
+int32_t UidObserver::importanceToProcState(int32_t importance) {
+    // TODO: remove this after adding Importance to onUidStateChanged callback.
+    if (importance == AACTIVITYMANAGER_IMPORTANCE_GONE) {
+        return ActivityManager::PROCESS_STATE_NONEXISTENT;
+    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_CACHED) {
+        return ActivityManager::PROCESS_STATE_HOME;
+    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_CANT_SAVE_STATE) {
+        return ActivityManager::PROCESS_STATE_HEAVY_WEIGHT;
+    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_TOP_SLEEPING) {
+        return ActivityManager::PROCESS_STATE_TOP_SLEEPING;
+    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_SERVICE) {
+        return ActivityManager::PROCESS_STATE_SERVICE;
+    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE) {
+        return ActivityManager::PROCESS_STATE_TRANSIENT_BACKGROUND;
+    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_VISIBLE) {
+        return ActivityManager::PROCESS_STATE_IMPORTANT_FOREGROUND;
+    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_FOREGROUND_SERVICE) {
+        return ActivityManager::PROCESS_STATE_FOREGROUND_SERVICE;
+    } else {
+        return ActivityManager::PROCESS_STATE_TOP;
+    }
+}
+
+
+void UidObserver::onUidGone(uid_t uid, bool disabled __unused) {
+    std::scoped_lock lock{mRegisteredLock};
+
+    if (mRegistered && mCallback) {
+        mCallback(uid, AACTIVITYMANAGER_IMPORTANCE_GONE, mCookie);
+    }
+}
+
+void UidObserver::onUidActive(uid_t uid __unused) {}
+
+void UidObserver::onUidIdle(uid_t uid __unused, bool disabled __unused) {}
+
+void UidObserver::onUidStateChanged(uid_t uid, int32_t procState,
+                                    int64_t procStateSeq __unused,
+                                    int32_t capability __unused) {
+    std::scoped_lock lock{mRegisteredLock};
+
+    if (mRegistered && mCallback) {
+        mCallback(uid, procStateToImportance(procState), mCookie);
+    }
+}
+
+void UidObserver::binderDied(const wp<IBinder>& /*who*/) {
+    // ActivityManager is dead, try to re-register.
+    {
+        std::scoped_lock lock{mRegisteredLock};
+        // If client already unregistered, don't try to re-register.
+        if (!mRegistered) {
+            return;
+        }
+        // Clear mRegistered to re-register.
+        mRegistered = false;
+    }
+    registerSelf();
+}
+
+bool UidObserver::registerSelf() {
+    std::scoped_lock lock{mRegisteredLock};
+    if (mRegistered) {
+        return true;
+    }
+
+    status_t res = gAm.linkToDeath(this);
+    if (res != OK) {
+        ALOGE("UidObserver: Failed to linkToDeath with ActivityManager (err %d)", res);
+        return false;
+    }
+
+    // TODO: it seems only way to get all changes is to set cutoff to PROCESS_STATE_UNKNOWN.
+    // But there is no equivalent of PROCESS_STATE_UNKNOWN in the UidImportance.
+    // If mImportanceCutpoint is < 0, use PROCESS_STATE_UNKNOWN instead.
+    res = gAm.registerUidObserver(
+            this,
+            ActivityManager::UID_OBSERVER_GONE | ActivityManager::UID_OBSERVER_PROCSTATE,
+            (mImportanceCutpoint < 0) ? ActivityManager::PROCESS_STATE_UNKNOWN
+                                      : importanceToProcState(mImportanceCutpoint),
+            getTag());
+    if (res != OK) {
+        ALOGE("UidObserver: Failed to register with ActivityManager (err %d)", res);
+        gAm.unlinkToDeath(this);
+        return false;
+    }
+
+    mRegistered = true;
+    ALOGV("UidObserver: Registered with ActivityManager");
+    return true;
+}
+
+void UidObserver::unregisterSelf() {
+    std::scoped_lock lock{mRegisteredLock};
+
+    if (mRegistered) {
+        gAm.unregisterUidObserver(this);
+        gAm.unlinkToDeath(this);
+        mRegistered = false;
+    }
+
+    ALOGV("UidObserver: Unregistered with ActivityManager");
+}
+
+} // activitymanager
+} // android
+
+using namespace android;
+using namespace activitymanager;
+
+struct AActivityManager_UidImportanceListener : public UidObserver {
+};
+
+AActivityManager_UidImportanceListener* AActivityManager_addUidImportanceListener(
+        AActivityManager_onUidImportance onUidImportance, int32_t importanceCutpoint, void* cookie) {
+    sp<UidObserver> observer(new UidObserver(onUidImportance, importanceCutpoint, cookie));
+    if (observer == nullptr || !observer->registerSelf()) {
+        return nullptr;
+    }
+    observer->incStrong((void *)AActivityManager_addUidImportanceListener);
+    return static_cast<AActivityManager_UidImportanceListener*>(observer.get());
+}
+
+void AActivityManager_removeUidImportanceListener(
+        AActivityManager_UidImportanceListener* listener) {
+    if (listener != nullptr) {
+        UidObserver* observer = static_cast<UidObserver*>(listener);
+        observer->unregisterSelf();
+        observer->decStrong((void *)AActivityManager_addUidImportanceListener);
+    }
+}
+
+bool AActivityManager_isUidActive(uid_t uid) {
+    return gAm.isUidActive(uid, getTag());
+}
+
+int32_t AActivityManager_getUidImportance(uid_t uid) {
+    return UidObserver::procStateToImportance(gAm.getUidProcessState(uid, getTag()));
+}
+
diff --git a/native/android/aidl/com/android/internal/compat/OWNERS b/native/android/aidl/com/android/internal/compat/OWNERS
new file mode 100644
index 0000000..f8c3520
--- /dev/null
+++ b/native/android/aidl/com/android/internal/compat/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/compat/OWNERS
diff --git a/native/android/include_platform/android/activity_manager.h b/native/android/include_platform/android/activity_manager.h
new file mode 100644
index 0000000..0ecd56d
--- /dev/null
+++ b/native/android/include_platform/android/activity_manager.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef __AACTIVITYMANAGER_H__
+#define __AACTIVITYMANAGER_H__
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+struct AActivityManager_UidImportanceListener;
+typedef struct AActivityManager_UidImportanceListener AActivityManager_UidImportanceListener;
+
+/**
+ * Callback interface when Uid Importance has changed for a uid.
+ *
+ * This callback will be called on an arbitrary thread. Calls to a given listener will be
+ * serialized.
+ *
+ * @param uid the uid for which the importance has changed.
+ * @param uidImportance the new uidImportance for the uid.
+ * @cookie the same cookie when the UidImportanceListener was added.
+ *
+ * Introduced in API 31.
+ */
+typedef void (*AActivityManager_onUidImportance)(uid_t uid, int32_t uidImportance, void* cookie);
+
+/**
+ * ActivityManager Uid Importance constants.
+ *
+ * Introduced in API 31.
+ */
+enum {
+    /**
+     * Constant for Uid Importance: This process is running the
+     * foreground UI; that is, it is the thing currently at the top of the screen
+     * that the user is interacting with.
+     */
+    AACTIVITYMANAGER_IMPORTANCE_FOREGROUND = 100,
+
+    /**
+     * Constant for Uid Importance: This process is running a foreground
+     * service, for example to perform music playback even while the user is
+     * not immediately in the app.  This generally indicates that the process
+     * is doing something the user actively cares about.
+     */
+    AACTIVITYMANAGER_IMPORTANCE_FOREGROUND_SERVICE = 125,
+
+    /**
+     * Constant for Uid Importance: This process is running something
+     * that is actively visible to the user, though not in the immediate
+     * foreground.  This may be running a window that is behind the current
+     * foreground (so paused and with its state saved, not interacting with
+     * the user, but visible to them to some degree); it may also be running
+     * other services under the system's control that it inconsiders important.
+     */
+    AACTIVITYMANAGER_IMPORTANCE_VISIBLE = 200,
+
+    /**
+     * Constant for Uid Importance: This process is not something the user
+     * is directly aware of, but is otherwise perceptible to them to some degree.
+     */
+    AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE = 230,
+
+    /**
+     * Constant for Uid Importance: This process contains services
+     * that should remain running.  These are background services apps have
+     * started, not something the user is aware of, so they may be killed by
+     * the system relatively freely (though it is generally desired that they
+     * stay running as long as they want to).
+     */
+    AACTIVITYMANAGER_IMPORTANCE_SERVICE = 300,
+
+    /**
+     * Constant for Uid Importance: This process is running the foreground
+     * UI, but the device is asleep so it is not visible to the user.  Though the
+     * system will try hard to keep its process from being killed, in all other
+     * ways we consider it a kind of cached process, with the limitations that go
+     * along with that state: network access, running background services, etc.
+     */
+    AACTIVITYMANAGER_IMPORTANCE_TOP_SLEEPING = 325,
+
+    /**
+     * Constant for Uid Importance: This process is running an
+     * application that can not save its state, and thus can't be killed
+     * while in the background.  This will be used with apps that have
+     * {@link android.R.attr#cantSaveState} set on their application tag.
+     */
+    AACTIVITYMANAGER_IMPORTANCE_CANT_SAVE_STATE = 350,
+
+    /**
+     * Constant for Uid Importance: This process process contains
+     * cached code that is expendable, not actively running any app components
+     * we care about.
+     */
+    AACTIVITYMANAGER_IMPORTANCE_CACHED = 400,
+
+    /**
+     * Constant for Uid Importance: This process does not exist.
+     */
+    AACTIVITYMANAGER_IMPORTANCE_GONE = 1000,
+};
+
+#if __ANDROID_API__ >= 31
+
+/**
+ * Adds a UidImportanceListener to the ActivityManager.
+ *
+ * This API requires android.Manifest.permission.PACKAGE_USAGE_STATS permission.
+ *
+ * @param onUidImportance the listener callback that will receive change reports.
+ *
+ * @param importanceCutpoint the level of importance in which the caller is interested
+ * in differences. For example, if AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE is used
+ * here, you will receive a call each time a uid's importance transitions between being
+ * <= AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE and > AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE.
+ *
+ * @param cookie a cookie that will be passed back to the listener callback.
+ *
+ * @return an opaque pointer of AActivityManager_UidImportanceListener, or nullptr
+ * upon failure. Upon success, the returned AActivityManager_UidImportanceListener pointer
+ * must be removed and released through AActivityManager_removeUidImportanceListener.
+ */
+AActivityManager_UidImportanceListener* AActivityManager_addUidImportanceListener(
+        AActivityManager_onUidImportance onUidImportance,
+        int32_t importanceCutpoint,
+        void* cookie) __INTRODUCED_IN(31);
+
+/**
+ * Removes a UidImportanceListener that was added with AActivityManager_addUidImportanceListener.
+ *
+ * When this returns, it's guaranteed the listener callback will no longer be invoked.
+ *
+ * @param listener the UidImportanceListener to be removed.
+ */
+void AActivityManager_removeUidImportanceListener(
+        AActivityManager_UidImportanceListener* listener) __INTRODUCED_IN(31);
+
+/**
+ * Queries if a uid is currently active.
+ *
+ * This API requires android.Manifest.permission.PACKAGE_USAGE_STATS permission.
+ *
+ * @return true if the uid is active, false otherwise.
+ */
+bool AActivityManager_isUidActive(uid_t uid) __INTRODUCED_IN(31);
+
+/**
+ * Queries the current Uid Importance value of a uid.
+ *
+ * This API requires android.Manifest.permission.PACKAGE_USAGE_STATS permission.
+ *
+ * @param uid the uid for which the importance value is queried.
+ * @return the current uid importance value for uid.
+ */
+int32_t AActivityManager_getUidImportance(uid_t uid) __INTRODUCED_IN(31);
+
+#endif // __ANDROID_API__ >= 31
+
+__END_DECLS
+
+#endif  // __AACTIVITYMANAGER_H__
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index eca67bd..8fa3acf 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -1,5 +1,9 @@
 LIBANDROID {
   global:
+    AActivityManager_addUidImportanceListener; # apex # introduced=31
+    AActivityManager_removeUidImportanceListener; # apex # introduced=31
+    AActivityManager_isUidActive; # apex # introduced=31
+    AActivityManager_getUidImportance; # apex # introduced=31
     AAssetDir_close;
     AAssetDir_getNextFileName;
     AAssetDir_rewind;
diff --git a/native/android/tests/activitymanager/UidImportanceHelperApps/Android.bp b/native/android/tests/activitymanager/UidImportanceHelperApps/Android.bp
new file mode 100644
index 0000000..1a51218
--- /dev/null
+++ b/native/android/tests/activitymanager/UidImportanceHelperApps/Android.bp
@@ -0,0 +1,11 @@
+android_test_helper_app {
+    name: "UidImportanceHelperApp",
+    manifest: "HelperAppManifest.xml",
+    static_libs: ["androidx.test.rules"],
+    sdk_version: "test_current",
+    srcs: ["src/**/*.java"],
+    test_suites: [
+        "general-tests",
+    ],
+}
+
diff --git a/native/android/tests/activitymanager/UidImportanceHelperApps/HelperAppManifest.xml b/native/android/tests/activitymanager/UidImportanceHelperApps/HelperAppManifest.xml
new file mode 100644
index 0000000..3583b33
--- /dev/null
+++ b/native/android/tests/activitymanager/UidImportanceHelperApps/HelperAppManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.tests.UidImportanceHelper"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <application android:label="UidImportanceHelper">
+        <activity android:name="com.android.tests.UidImportanceHelper.MainActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
+
diff --git a/native/android/tests/activitymanager/UidImportanceHelperApps/src/com/android/tests/UidImportanceHelper/MainActivity.java b/native/android/tests/activitymanager/UidImportanceHelperApps/src/com/android/tests/UidImportanceHelper/MainActivity.java
new file mode 100644
index 0000000..db0f2b5
--- /dev/null
+++ b/native/android/tests/activitymanager/UidImportanceHelperApps/src/com/android/tests/UidImportanceHelper/MainActivity.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 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 com.android.tests.UidImportanceHelper;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * This is an empty activity for testing the UID policy of media transcoding service.
+ */
+public class MainActivity extends Activity {
+    private static final String TAG = "MainActivity";
+
+    // Called at the start of the full lifetime.
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // Initialize Activity and inflate the UI.
+    }
+
+    // Called after onCreate has finished, use to restore UI state
+    @Override
+    public void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        // Restore UI state from the savedInstanceState.
+        // This bundle has also been passed to onCreate.
+        // Will only be called if the Activity has been
+        // killed by the system since it was last visible.
+    }
+
+    // Called before subsequent visible lifetimes
+    // for an activity process.
+    @Override
+    public void onRestart() {
+        super.onRestart();
+        // Load changes knowing that the Activity has already
+        // been visible within this process.
+    }
+
+    // Called at the start of the visible lifetime.
+    @Override
+    public void onStart() {
+        super.onStart();
+        // Apply any required UI change now that the Activity is visible.
+    }
+
+    // Called at the start of the active lifetime.
+    @Override
+    public void onResume() {
+        super.onResume();
+        // Resume any paused UI updates, threads, or processes required
+        // by the Activity but suspended when it was inactive.
+    }
+
+    // Called to save UI state changes at the
+    // end of the active lifecycle.
+    @Override
+    public void onSaveInstanceState(Bundle savedInstanceState) {
+        // Save UI state changes to the savedInstanceState.
+        // This bundle will be passed to onCreate and
+        // onRestoreInstanceState if the process is
+        // killed and restarted by the run time.
+        super.onSaveInstanceState(savedInstanceState);
+    }
+
+    // Called at the end of the active lifetime.
+    @Override
+    public void onPause() {
+        // Suspend UI updates, threads, or CPU intensive processes
+        // that don't need to be updated when the Activity isn't
+        // the active foreground Activity.
+        super.onPause();
+    }
+
+    // Called at the end of the visible lifetime.
+    @Override
+    public void onStop() {
+        // Suspend remaining UI updates, threads, or processing
+        // that aren't required when the Activity isn't visible.
+        // Persist all edits or state changes
+        // as after this call the process is likely to be killed.
+        super.onStop();
+    }
+
+    // Sometimes called at the end of the full lifetime.
+    @Override
+    public void onDestroy() {
+        // Clean up any resources including ending threads,
+        // closing database connections etc.
+        super.onDestroy();
+    }
+}
diff --git a/native/android/tests/activitymanager/nativeTests/Android.bp b/native/android/tests/activitymanager/nativeTests/Android.bp
new file mode 100644
index 0000000..d4b5015
--- /dev/null
+++ b/native/android/tests/activitymanager/nativeTests/Android.bp
@@ -0,0 +1,39 @@
+cc_test {
+    name: "ActivityManagerNativeTestCases",
+
+    multilib: {
+        lib32: {
+            suffix: "32",
+        },
+        lib64: {
+            suffix: "64",
+        },
+    },
+
+    srcs: ["src/ActivityManagerNativeTest.cpp"],
+
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libandroid",
+        "libbinder",
+    ],
+
+    static_libs: [
+        "libbase",
+        "libgtest",
+    ],
+    stl: "c++_shared",
+
+    test_suites: [
+        "general-tests",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+    required: [
+        "UidImportanceHelperApp",
+    ],
+}
diff --git a/native/android/tests/activitymanager/nativeTests/AndroidTest.xml b/native/android/tests/activitymanager/nativeTests/AndroidTest.xml
new file mode 100644
index 0000000..bf6287ad
--- /dev/null
+++ b/native/android/tests/activitymanager/nativeTests/AndroidTest.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for ActivityManager native test cases">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="component" value="framework" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+
+    <!-- Force root to allow registering UidImportanceListener from native test -->
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+        <option name="force-root" value="true" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
+        <option name="run-command" value="wm dismiss-keyguard" />
+    </target_preparer>
+    <!-- Install the helper apk -->
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="UidImportanceHelperApp.apk" />
+    </target_preparer>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="ActivityManagerNativeTestCases->/data/local/tmp/ActivityManagerNativeTestCases" />
+        <option name="append-bitness" value="true" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="ActivityManagerNativeTestCases" />
+        <option name="runtime-hint" value="1m" />
+    </test>
+
+    <!-- Controller that will skip the module if a native bridge situation is detected -->
+    <!-- For example: module wants to run arm and device is x86 -->
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
+</configuration>
diff --git a/native/android/tests/activitymanager/nativeTests/src/ActivityManagerNativeTest.cpp b/native/android/tests/activitymanager/nativeTests/src/ActivityManagerNativeTest.cpp
new file mode 100644
index 0000000..75ba0ff
--- /dev/null
+++ b/native/android/tests/activitymanager/nativeTests/src/ActivityManagerNativeTest.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "ActivityManagerNativeTest"
+
+#include <android-base/logging.h>
+#include <android/activity_manager.h>
+#include <binder/PermissionController.h>
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+
+constexpr const char* kTestPackage = "com.android.tests.UidImportanceHelper";
+constexpr const char* kTestActivity = "com.android.tests.UidImportanceHelper.MainActivity";
+constexpr int64_t kEventTimeoutUs = 500000;
+
+//-----------------------------------------------------------------
+class ActivityManagerNativeTest : public ::testing::Test {
+protected:
+    ActivityManagerNativeTest() : mUidObserver(nullptr), mTestAppUid(-1), mLastUidImportance(-1) {}
+
+    virtual ~ActivityManagerNativeTest() {}
+
+    /* Test setup*/
+    virtual void SetUp() { android::ProcessState::self()->startThreadPool(); }
+
+    /* Test tear down */
+    virtual void TearDown() {}
+
+    bool waitForImportance(int32_t val, int64_t timeoutUs) {
+        std::unique_lock lock(mLock);
+
+        if (mLastUidImportance != val && timeoutUs > 0) {
+            mCondition.wait_for(lock, std::chrono::microseconds(timeoutUs));
+        }
+
+        return mLastUidImportance == val;
+    }
+
+    void onUidImportanceChanged(uid_t uid, int32_t uidImportance) {
+        LOG(ERROR) << "OnUidImportance: uid " << uid << ", importance " << uidImportance;
+        std::unique_lock lock(mLock);
+
+        if (uid == mTestAppUid) {
+            mLastUidImportance = uidImportance;
+            mCondition.notify_one();
+        }
+    }
+
+    static void OnUidImportance(uid_t uid, int32_t uidImportance, void* cookie) {
+        ActivityManagerNativeTest* owner = reinterpret_cast<ActivityManagerNativeTest*>(cookie);
+        owner->onUidImportanceChanged(uid, uidImportance);
+    }
+
+    AActivityManager_UidImportanceListener* mUidObserver;
+    uid_t mTestAppUid;
+    std::mutex mLock;
+    std::condition_variable mCondition;
+    int32_t mLastUidImportance;
+};
+
+static bool getUidForPackage(const char* packageName, /*inout*/ uid_t& uid) {
+    android::PermissionController pc;
+    uid = pc.getPackageUid(android::String16(packageName), 0);
+    if (uid <= 0) {
+        ALOGE("Unknown package: '%s'", packageName);
+        return false;
+    }
+    return true;
+}
+
+struct ShellHelper {
+    static bool RunCmd(const std::string& cmdStr) {
+        int ret = system(cmdStr.c_str());
+        if (ret != 0) {
+            LOG(ERROR) << "Failed to run cmd: " << cmdStr << ", exitcode " << ret;
+            return false;
+        }
+        return true;
+    }
+
+    static bool Start(const char* packageName, const char* activityName) {
+        return RunCmd("am start -W " + std::string(packageName) + "/" + std::string(activityName) +
+                      " &> /dev/null");
+    }
+
+    static bool Stop(const char* packageName) {
+        return RunCmd("am force-stop " + std::string(packageName));
+    }
+};
+
+//-------------------------------------------------------------------------------------------------
+TEST_F(ActivityManagerNativeTest, testUidImportance) {
+    pid_t selfPid = ::getpid();
+    uid_t selfUid = ::getuid();
+
+    uid_t testAppUid;
+    EXPECT_TRUE(getUidForPackage(kTestPackage, testAppUid));
+    LOG(INFO) << "testUidImportance: uidselfUid" << selfUid << ", selfPid " << selfPid
+              << ", testAppUid " << testAppUid;
+    mTestAppUid = testAppUid;
+
+    // Expect the initial UidImportance to be GONE.
+    EXPECT_FALSE(AActivityManager_isUidActive(testAppUid));
+    EXPECT_EQ(AActivityManager_getUidImportance(testAppUid), AACTIVITYMANAGER_IMPORTANCE_GONE);
+
+    mUidObserver = AActivityManager_addUidImportanceListener(&OnUidImportance,
+                                                             AACTIVITYMANAGER_IMPORTANCE_FOREGROUND,
+                                                             (void*)this);
+    EXPECT_TRUE(mUidObserver != nullptr);
+
+    // Start the test activity, and expect to receive UidImportance change to FOREGROUND.
+    EXPECT_TRUE(ShellHelper::Start(kTestPackage, kTestActivity));
+    EXPECT_TRUE(waitForImportance(AACTIVITYMANAGER_IMPORTANCE_FOREGROUND, kEventTimeoutUs));
+    EXPECT_TRUE(AActivityManager_isUidActive(testAppUid));
+    EXPECT_EQ(AActivityManager_getUidImportance(testAppUid),
+              AACTIVITYMANAGER_IMPORTANCE_FOREGROUND);
+
+    // Stop the test activity, and expect to receive UidImportance change to GONE.
+    EXPECT_TRUE(ShellHelper::Stop(kTestPackage));
+    EXPECT_TRUE(waitForImportance(AACTIVITYMANAGER_IMPORTANCE_GONE, kEventTimeoutUs));
+    EXPECT_FALSE(AActivityManager_isUidActive(testAppUid));
+    EXPECT_EQ(AActivityManager_getUidImportance(testAppUid), AACTIVITYMANAGER_IMPORTANCE_GONE);
+
+    AActivityManager_removeUidImportanceListener(mUidObserver);
+    mUidObserver = nullptr;
+}
diff --git a/native/graphics/OWNERS b/native/graphics/OWNERS
new file mode 100644
index 0000000..a6d1bc3
--- /dev/null
+++ b/native/graphics/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/graphics/OWNERS
diff --git a/opengl/java/android/opengl/OWNERS b/opengl/java/android/opengl/OWNERS
new file mode 100644
index 0000000..9c6c610
--- /dev/null
+++ b/opengl/java/android/opengl/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 25421
+
+sumir@google.com
+prahladk@google.com
diff --git a/packages/AppPredictionLib/OWNERS b/packages/AppPredictionLib/OWNERS
new file mode 100644
index 0000000..3a5d23d
--- /dev/null
+++ b/packages/AppPredictionLib/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/appprediction/OWNERS
diff --git a/packages/Backup/OWNERS b/packages/Backup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/packages/Backup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/packages/BackupEncryption/OWNERS b/packages/BackupEncryption/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/packages/BackupEncryption/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/packages/BackupRestoreConfirmation/OWNERS b/packages/BackupRestoreConfirmation/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
index 5247ac9..91bad7b 100644
--- a/packages/CompanionDeviceManager/AndroidManifest.xml
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -31,6 +31,7 @@
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
     <uses-permission android:name="android.permission.RADIO_SCAN_WITHOUT_LOCATION"/>
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
+    <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"/>
 
     <application
         android:allowClearUserData="true"
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index 2fe351e..fd71670 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -321,7 +321,8 @@
     }
 
     void onDeviceSelected(String callingPackage, String deviceAddress) {
-        mServiceCallback.complete(new Association(getUserId(), deviceAddress, callingPackage));
+        mServiceCallback.complete(new Association(
+                getUserId(), deviceAddress, callingPackage, mRequest.getDeviceProfile(), false));
     }
 
     void onCancel() {
diff --git a/packages/EasterEgg/OWNERS b/packages/EasterEgg/OWNERS
new file mode 100644
index 0000000..2e96c97
--- /dev/null
+++ b/packages/EasterEgg/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/OWNERS
diff --git a/packages/ExternalStorageProvider/OWNERS b/packages/ExternalStorageProvider/OWNERS
new file mode 100644
index 0000000..6f9dbea
--- /dev/null
+++ b/packages/ExternalStorageProvider/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/os/storage/OWNERS
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 11d1b0a..087275e 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -322,6 +322,11 @@
                 return true;
             }
 
+            if (TextUtils.equals(Environment.DIRECTORY_ANDROID.toLowerCase(),
+                    path.toLowerCase())) {
+                return true;
+            }
+
             return false;
         } catch (IOException e) {
             throw new IllegalArgumentException(
diff --git a/packages/FusedLocation/OWNERS b/packages/FusedLocation/OWNERS
new file mode 100644
index 0000000..5ac6028
--- /dev/null
+++ b/packages/FusedLocation/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/location/OWNERS
diff --git a/packages/MtpDocumentsProvider/OWNERS b/packages/MtpDocumentsProvider/OWNERS
new file mode 100644
index 0000000..6f9dbea
--- /dev/null
+++ b/packages/MtpDocumentsProvider/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/os/storage/OWNERS
diff --git a/packages/PrintRecommendationService/OWNERS b/packages/PrintRecommendationService/OWNERS
new file mode 100644
index 0000000..2c7b881
--- /dev/null
+++ b/packages/PrintRecommendationService/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/print/OWNERS
diff --git a/packages/PrintSpooler/OWNERS b/packages/PrintSpooler/OWNERS
new file mode 100644
index 0000000..2c7b881
--- /dev/null
+++ b/packages/PrintSpooler/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/print/OWNERS
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index e6492aa..23cb36f 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -54,6 +54,7 @@
         "SettingsLibEmergencyNumber",
         "SettingsLibTopIntroPreference",
         "SettingsLibBannerMessagePreference",
+        "SettingsLibFooterPreference",
     ],
 }
 
diff --git a/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java b/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java
index 12d21ca..1c0e718 100644
--- a/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java
+++ b/packages/SettingsLib/EmergencyNumber/src/com/android/settingslib/emergencynumber/EmergencyNumberUtils.java
@@ -84,8 +84,9 @@
     }
 
     private List<EmergencyNumber> getPromotedEmergencyNumbers(int categories) {
-        Map<Integer, List<EmergencyNumber>> allLists = mTelephonyManager.getEmergencyNumberList(
-                categories);
+        // TODO(b/171542607): Use platform API when its bug is fixed.
+        Map<Integer, List<EmergencyNumber>> allLists = filterEmergencyNumbersByCategories(
+                mTelephonyManager.getEmergencyNumberList(), categories);
         if (allLists == null || allLists.isEmpty()) {
             Log.w(TAG, "Unable to retrieve emergency number lists!");
             return new ArrayList<>();
@@ -130,4 +131,28 @@
         }
         return promotedEmergencyNumberLists.get(SubscriptionManager.getDefaultSubscriptionId());
     }
+
+    /**
+     * Filter emergency numbers with categories.
+     */
+    private Map<Integer, List<EmergencyNumber>> filterEmergencyNumbersByCategories(
+            Map<Integer, List<EmergencyNumber>> emergencyNumberList, int categories) {
+        Map<Integer, List<EmergencyNumber>> filteredMap = new ArrayMap<>();
+        if (emergencyNumberList == null) {
+            return filteredMap;
+        }
+        for (Integer subscriptionId : emergencyNumberList.keySet()) {
+            List<EmergencyNumber> allNumbersForSub = emergencyNumberList.get(
+                    subscriptionId);
+            List<EmergencyNumber> numbersForCategoriesPerSub = new ArrayList<>();
+            for (EmergencyNumber number : allNumbersForSub) {
+                if (number.isInEmergencyServiceCategories(categories)) {
+                    numbersForCategoriesPerSub.add(number);
+                }
+            }
+            filteredMap.put(
+                    subscriptionId, numbersForCategoriesPerSub);
+        }
+        return filteredMap;
+    }
 }
diff --git a/packages/SettingsLib/FooterPreference/Android.bp b/packages/SettingsLib/FooterPreference/Android.bp
new file mode 100644
index 0000000..30d9bd2
--- /dev/null
+++ b/packages/SettingsLib/FooterPreference/Android.bp
@@ -0,0 +1,13 @@
+android_library {
+    name: "SettingsLibFooterPreference",
+
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+
+    static_libs: [
+        "androidx.annotation_annotation",
+        "androidx.preference_preference",
+    ],
+    sdk_version: "system_current",
+    min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/FooterPreference/AndroidManifest.xml b/packages/SettingsLib/FooterPreference/AndroidManifest.xml
new file mode 100644
index 0000000..96d9e51
--- /dev/null
+++ b/packages/SettingsLib/FooterPreference/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.settingslib.widget">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
diff --git a/packages/SettingsLib/FooterPreference/res/drawable/ic_info_outline_24.xml b/packages/SettingsLib/FooterPreference/res/drawable/ic_info_outline_24.xml
new file mode 100644
index 0000000..d9afeb0
--- /dev/null
+++ b/packages/SettingsLib/FooterPreference/res/drawable/ic_info_outline_24.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2020 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
+</vector>
diff --git a/packages/SettingsLib/FooterPreference/res/values/attrs.xml b/packages/SettingsLib/FooterPreference/res/values/attrs.xml
new file mode 100644
index 0000000..deba3af
--- /dev/null
+++ b/packages/SettingsLib/FooterPreference/res/values/attrs.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<resources>
+    <attr name="footerPreferenceStyle" format="reference" />
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
new file mode 100644
index 0000000..15301f6
--- /dev/null
+++ b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2020 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 com.android.settingslib.widget;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+import androidx.core.content.res.TypedArrayUtils;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+/**
+ * A custom preference acting as "footer" of a page. It has a field for icon and text. It is added
+ * to screen as the last preference.
+ */
+public class FooterPreference extends Preference {
+
+    public static final String KEY_FOOTER = "footer_preference";
+    static final int ORDER_FOOTER = Integer.MAX_VALUE - 1;
+
+    public FooterPreference(Context context, AttributeSet attrs) {
+        super(context, attrs, TypedArrayUtils.getAttr(
+                context, R.attr.footerPreferenceStyle, android.R.attr.preferenceStyle));
+        init();
+    }
+
+    public FooterPreference(Context context) {
+        this(context, null);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        TextView title = holder.itemView.findViewById(android.R.id.title);
+        title.setMovementMethod(new LinkMovementMethod());
+        title.setClickable(false);
+        title.setLongClickable(false);
+    }
+
+    @Override
+    public void setSummary(CharSequence summary) {
+        setTitle(summary);
+    }
+
+    @Override
+    public void setSummary(int summaryResId) {
+        setTitle(summaryResId);
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        return getTitle();
+    }
+
+    private void init() {
+        if (getIcon() == null) {
+            setIcon(R.drawable.ic_info_outline_24);
+        }
+        setOrder(ORDER_FOOTER);
+        if (TextUtils.isEmpty(getKey())) {
+            setKey(KEY_FOOTER);
+        }
+    }
+
+    /**
+     * The builder is convenient to creat a dynamic FooterPreference.
+     */
+    public static class Builder {
+        private Context mContext;
+        private String mKey;
+        private CharSequence mTitle;
+
+        public Builder(@NonNull Context context) {
+            mContext = context;
+        }
+
+        /**
+         * To set the key value of the {@link FooterPreference}.
+         * @param key The key value.
+         */
+        public Builder setKey(@NonNull String key) {
+            mKey = key;
+            return this;
+        }
+
+        /**
+         * To set the title of the {@link FooterPreference}.
+         * @param title The title.
+         */
+        public Builder setTitle(CharSequence title) {
+            mTitle = title;
+            return this;
+        }
+
+        /**
+         * To set the title of the {@link FooterPreference}.
+         * @param titleResId The resource id of the title.
+         */
+        public Builder setTitle(@StringRes int titleResId) {
+            mTitle = mContext.getText(titleResId);
+            return this;
+        }
+
+        /**
+         * To generate the {@link FooterPreference}.
+         */
+        public FooterPreference build() {
+            final FooterPreference footerPreference = new FooterPreference(mContext);
+            footerPreference.setSelectable(false);
+            if (TextUtils.isEmpty(mTitle)) {
+                throw new IllegalArgumentException("Footer title cannot be empty!");
+            }
+            footerPreference.setTitle(mTitle);
+            if (!TextUtils.isEmpty(mKey)) {
+                footerPreference.setKey(mKey);
+            }
+            return footerPreference;
+        }
+    }
+}
diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS
index 8eafbdf..30c10d3 100644
--- a/packages/SettingsLib/OWNERS
+++ b/packages/SettingsLib/OWNERS
@@ -1,5 +1,5 @@
 # People who can approve changes for submission
-dsandler@android.com
+dsandler@google.com
 edgarwang@google.com
 emilychuang@google.com
 evanlaird@google.com
diff --git a/packages/SettingsLib/res/drawable/ic_info_outline_24.xml b/packages/SettingsLib/res/drawable/ic_info_outline_24.xml
deleted file mode 100644
index 317e43b..0000000
--- a/packages/SettingsLib/res/drawable/ic_info_outline_24.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 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.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
-</vector>
diff --git a/packages/SettingsLib/res/values/attrs.xml b/packages/SettingsLib/res/values/attrs.xml
index 9aed54e..1e6cb33 100644
--- a/packages/SettingsLib/res/values/attrs.xml
+++ b/packages/SettingsLib/res/values/attrs.xml
@@ -46,8 +46,6 @@
     <attr name="wifi_signal" format="reference" />
     <attr name="wifi_friction" format="reference" />
 
-    <attr name="footerPreferenceStyle" format="reference" />
-
     <!-- Workaround for b/74248169. These are duplicates of attrs in AndroidX preferences. -->
     <attr name="preferenceStyle" format="reference" />
     <attr name="switchPreferenceStyle" format="reference" />
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 9f1c96d..22213cb 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -995,8 +995,14 @@
     <!-- Settings item title for media transcoding settings. [CHAR LIMIT=85] -->
     <string name="transcode_settings_title">Media transcoding settings</string>
 
-    <!-- Settings item title to disable transcoding globally. [CHAR LIMIT=85] -->
-    <string name="transcode_enable_all">Disable transcoding</string>
+    <!-- Settings item title to enable user's control over further transcoding preferences. [CHAR LIMIT=85] -->
+    <string name="transcode_user_control">Override transcoding defaults</string>
+
+    <!-- Settings item title to enable transcoding globally. [CHAR LIMIT=85] -->
+    <string name="transcode_enable_all">Enable transcoding</string>
+
+    <!-- Settings item title to select the default behavior for transcoding if an encodig is not supported by an app. [CHAR LIMIT=85] -->
+    <string name="transcode_default">Assume apps support modern formats</string>
 
     <!-- Settings category title for selecting apps to be enabled for transcoding. [CHAR LIMIT=85] -->
     <string name="transcode_skip_apps">Enable transcoding for apps</string>
@@ -1110,7 +1116,7 @@
     <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
     <string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> until charged</string>
     <!-- [CHAR_LIMIT=40] Label for battery level chart when charge been limited -->
-    <string name="power_charging_limited"><xliff:g id="level">%1$s</xliff:g> - Battery limited temporarily</string>
+    <string name="power_charging_limited"><xliff:g id="level">%1$s</xliff:g> - Optimizing for battery health</string>
 
     <!-- Battery Info screen. Value for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="battery_info_status_unknown">Unknown</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
index f9bb90e..b3205d7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.fuelgauge;
 
+import static android.os.BatteryManager.BATTERY_HEALTH_OVERHEAT;
 import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
 import static android.os.BatteryManager.BATTERY_STATUS_FULL;
 import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
@@ -128,6 +129,15 @@
     }
 
     /**
+     * Whether battery is overheated.
+     *
+     * @return true if battery is overheated
+     */
+    public boolean isOverheated() {
+        return health == BATTERY_HEALTH_OVERHEAT;
+    }
+
+    /**
      * Return current chargin speed is fast, slow or normal.
      *
      * @return the charing speed
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 41d6afc..f21c359 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -38,6 +38,7 @@
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2Manager;
 import android.text.TextUtils;
+import android.util.Log;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.VisibleForTesting;
@@ -46,6 +47,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -199,6 +201,10 @@
      */
 
     public void requestSetVolume(int volume) {
+        if (mRouteInfo == null) {
+            Log.w(TAG, "Unable to set volume. RouteInfo is empty");
+            return;
+        }
         mRouterManager.setRouteVolume(mRouteInfo, volume);
     }
 
@@ -208,6 +214,10 @@
      * @return max volume.
      */
     public int getMaxVolume() {
+        if (mRouteInfo == null) {
+            Log.w(TAG, "Unable to get max volume. RouteInfo is empty");
+            return 0;
+        }
         return mRouteInfo.getVolumeMax();
     }
 
@@ -217,6 +227,10 @@
      * @return current volume.
      */
     public int getCurrentVolume() {
+        if (mRouteInfo == null) {
+            Log.w(TAG, "Unable to get current volume. RouteInfo is empty");
+            return 0;
+        }
         return mRouteInfo.getVolume();
     }
 
@@ -226,6 +240,10 @@
      * @return package name.
      */
     public String getClientPackageName() {
+        if (mRouteInfo == null) {
+            Log.w(TAG, "Unable to get client package name. RouteInfo is empty");
+            return null;
+        }
         return mRouteInfo.getClientPackageName();
     }
 
@@ -244,6 +262,10 @@
      * @return result of transfer media
      */
     public boolean connect() {
+        if (mRouteInfo == null) {
+            Log.w(TAG, "Unable to connect. RouteInfo is empty");
+            return false;
+        }
         setConnectedRecord();
         mRouterManager.selectRoute(mPackageName, mRouteInfo);
         return true;
@@ -358,6 +380,10 @@
      * Gets the supported features of the route.
      */
     public List<String> getFeatures() {
+        if (mRouteInfo == null) {
+            Log.w(TAG, "Unable to get features. RouteInfo is empty");
+            return new ArrayList<>();
+        }
         return mRouteInfo.getFeatures();
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
deleted file mode 100644
index 1557618..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.settingslib.widget;
-
-import android.annotation.StringRes;
-import android.content.Context;
-import android.text.TextUtils;
-import android.text.method.LinkMovementMethod;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.core.content.res.TypedArrayUtils;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settingslib.R;
-
-/**
- * A custom preference acting as "footer" of a page. It has a field for icon and text. It is added
- * to screen as the last preference.
- */
-public class FooterPreference extends Preference {
-
-    static final int ORDER_FOOTER = Integer.MAX_VALUE - 1;
-    public static final String KEY_FOOTER = "footer_preference";
-
-    public FooterPreference(Context context, AttributeSet attrs) {
-        super(context, attrs, TypedArrayUtils.getAttr(
-                context, R.attr.footerPreferenceStyle, android.R.attr.preferenceStyle));
-        init();
-    }
-
-    public FooterPreference(Context context) {
-        this(context, null);
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-        TextView title = holder.itemView.findViewById(android.R.id.title);
-        title.setMovementMethod(new LinkMovementMethod());
-        title.setClickable(false);
-        title.setLongClickable(false);
-    }
-
-    @Override
-    public void setSummary(CharSequence summary) {
-        setTitle(summary);
-    }
-
-    @Override
-    public void setSummary(int summaryResId) {
-        setTitle(summaryResId);
-    }
-
-    @Override
-    public CharSequence getSummary() {
-        return getTitle();
-    }
-
-    private void init() {
-        if (getIcon() == null) {
-            setIcon(R.drawable.ic_info_outline_24);
-        }
-        setOrder(ORDER_FOOTER);
-        if (TextUtils.isEmpty(getKey())) {
-            setKey(KEY_FOOTER);
-        }
-    }
-
-    /**
-     * The builder is convenient to creat a dynamic FooterPreference.
-     */
-    public static class Builder {
-        private Context mContext;
-        private String mKey;
-        private CharSequence mTitle;
-
-        public Builder(@NonNull Context context) {
-            mContext = context;
-        }
-
-        /**
-         * To set the key value of the {@link FooterPreference}.
-         * @param key The key value.
-         */
-        public Builder setKey(@NonNull String key) {
-            mKey = key;
-            return this;
-        }
-
-        /**
-         * To set the title of the {@link FooterPreference}.
-         * @param title The title.
-         */
-        public Builder setTitle(CharSequence title) {
-            mTitle = title;
-            return this;
-        }
-
-        /**
-         * To set the title of the {@link FooterPreference}.
-         * @param titleResId The resource id of the title.
-         */
-        public Builder setTitle(@StringRes int titleResId) {
-            mTitle = mContext.getText(titleResId);
-            return this;
-        }
-
-        /**
-         * To generate the {@link FooterPreference}.
-         */
-        public FooterPreference build() {
-            final FooterPreference footerPreference = new FooterPreference(mContext);
-            footerPreference.setSelectable(false);
-            if (TextUtils.isEmpty(mTitle)) {
-                throw new IllegalArgumentException("Footer title cannot be empty!");
-            }
-            footerPreference.setTitle(mTitle);
-            if (!TextUtils.isEmpty(mKey)) {
-                footerPreference.setKey(mKey);
-            }
-            return footerPreference;
-        }
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
index 47d4beb..6f7f73a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
@@ -465,4 +465,12 @@
         assertThat(mInfoMediaDevice1.getState()).isEqualTo(
                 LocalMediaManager.MediaDeviceState.STATE_CONNECTING_FAILED);
     }
+
+    @Test
+    public void getFeatures_noRouteInfo_returnEmptyList() {
+        mBluetoothMediaDevice1 = new BluetoothMediaDevice(mContext, mCachedDevice1,
+                mMediaRouter2Manager, null /* MediaRoute2Info */, TEST_PACKAGE_NAME);
+
+        assertThat(mBluetoothMediaDevice1.getFeatures().size()).isEqualTo(0);
+    }
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/DiscreteValueValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/DiscreteValueValidator.java
index 183651f..e7d870e 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/DiscreteValueValidator.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/DiscreteValueValidator.java
@@ -34,6 +34,6 @@
 
     @Override
     public boolean validate(@Nullable String value) {
-        return ArrayUtils.contains(mValues, value);
+        return value == null || ArrayUtils.contains(mValues, value);
     }
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index a02d67f..668e267 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -34,10 +34,6 @@
  * Validators for Global settings
  */
 public class GlobalSettingsValidators {
-    /**
-     * All settings in {@link Global.SETTINGS_TO_BACKUP} array *must* have a non-null validator,
-     * otherwise they won't be restored.
-     */
     public static final Map<String, Validator> VALIDATORS = new ArrayMap<>();
 
     static {
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveFloatRangeValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveFloatRangeValidator.java
index 1a0b88c..58620b5 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveFloatRangeValidator.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveFloatRangeValidator.java
@@ -34,6 +34,9 @@
 
     @Override
     public boolean validate(@Nullable String value) {
+        if (value == null) {
+            return true;
+        }
         try {
             final float floatValue = Float.parseFloat(value);
             return floatValue >= mMin && floatValue <= mMax;
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveIntegerRangeValidator.java b/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveIntegerRangeValidator.java
index f9f8ce8..aa27c877 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveIntegerRangeValidator.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/InclusiveIntegerRangeValidator.java
@@ -34,6 +34,9 @@
 
     @Override
     public boolean validate(@Nullable String value) {
+        if (value == null) {
+            return true;
+        }
         try {
             final int intValue = Integer.parseInt(value);
             return intValue >= mMin && intValue <= mMax;
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 9331b5e..517fa54 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -42,11 +42,6 @@
  * Validators for the Secure Settings.
  */
 public class SecureSettingsValidators {
-    /**
-     * All settings in {@link Secure.SETTINGS_TO_BACKUP} and {@link
-     * DeviceSpecificSettings.DEVICE_SPECIFIC_SETTINGS_TO_BACKUP} array *must* have a non-null
-     * validator, otherwise they won't be restored.
-     */
     public static final Map<String, Validator> VALIDATORS = new ArrayMap<>();
 
     static {
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java
index 8d5c6e6..97e1d68 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SettingsValidators.java
@@ -16,6 +16,7 @@
 
 package android.provider.settings.validators;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.net.Uri;
@@ -48,6 +49,9 @@
     public static final Validator NON_NEGATIVE_INTEGER_VALIDATOR = new Validator() {
         @Override
         public boolean validate(@Nullable String value) {
+            if (value == null) {
+                return true;
+            }
             try {
                 return Integer.parseInt(value) >= 0;
             } catch (NumberFormatException e) {
@@ -59,6 +63,9 @@
     public static final Validator ANY_INTEGER_VALIDATOR = new Validator() {
         @Override
         public boolean validate(@Nullable String value) {
+            if (value == null) {
+                return true;
+            }
             try {
                 Integer.parseInt(value);
                 return true;
@@ -71,6 +78,9 @@
     public static final Validator URI_VALIDATOR = new Validator() {
         @Override
         public boolean validate(@Nullable String value) {
+            if (value == null) {
+                return true;
+            }
             try {
                 Uri.decode(value);
                 return true;
@@ -87,7 +97,7 @@
      */
     public static final Validator COMPONENT_NAME_VALIDATOR = new Validator() {
         @Override
-        public boolean validate(@Nullable String value) {
+        public boolean validate(@NonNull String value) {
             return value != null && ComponentName.unflattenFromString(value) != null;
         }
     };
@@ -104,18 +114,15 @@
 
     public static final Validator PACKAGE_NAME_VALIDATOR = new Validator() {
         @Override
-        public boolean validate(@Nullable String value) {
+        public boolean validate(@NonNull String value) {
             return value != null && isStringPackageName(value);
         }
 
-        private boolean isStringPackageName(String value) {
+        private boolean isStringPackageName(@NonNull String value) {
             // The name may contain uppercase or lowercase letters ('A' through 'Z'), numbers,
             // and underscores ('_'). However, individual package name parts may only
             // start with letters.
             // (https://developer.android.com/guide/topics/manifest/manifest-element.html#package)
-            if (value == null) {
-                return false;
-            }
             String[] subparts = value.split("\\.");
             boolean isValidPackageName = true;
             for (String subpart : subparts) {
@@ -143,7 +150,7 @@
         @Override
         public boolean validate(@Nullable String value) {
             if (value == null) {
-                return false;
+                return true;
             }
             return value.length() <= MAX_IPV6_LENGTH;
         }
@@ -153,7 +160,7 @@
         @Override
         public boolean validate(@Nullable String value) {
             if (value == null) {
-                return false;
+                return true;
             }
             Locale[] validLocales = Locale.getAvailableLocales();
             for (Locale locale : validLocales) {
@@ -167,6 +174,9 @@
 
     /** {@link Validator} that checks whether a value is a valid {@link JSONObject}. */
     public static final Validator JSON_OBJECT_VALIDATOR = (value) -> {
+        if (value == null) {
+            return true;
+        }
         if (TextUtils.isEmpty(value)) {
             return false;
         }
@@ -184,6 +194,9 @@
 
     static final Validator DATE_FORMAT_VALIDATOR = value -> {
         try {
+            if (value == null) {
+                return true;
+            }
             new SimpleDateFormat(value);
             return true;
         } catch (IllegalArgumentException | NullPointerException e) {
@@ -211,6 +224,9 @@
     static final Validator NONE_NEGATIVE_LONG_VALIDATOR = new Validator() {
         @Override
         public boolean validate(String value) {
+            if (value == null) {
+                return true;
+            }
             try {
                 return Long.parseLong(value) >= 0;
             } catch (NumberFormatException e) {
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index c5d4fa9..d278c59 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -38,12 +38,6 @@
  * Validators for System settings
  */
 public class SystemSettingsValidators {
-    /**
-     * These are all public system settings
-     *
-     * <p>All settings in {@link System.SETTINGS_TO_BACKUP} array *must* have a non-null validator,
-     * otherwise they won't be restored.
-     */
     @UnsupportedAppUsage
     public static final Map<String, Validator> VALIDATORS = new ArrayMap<>();
 
@@ -89,15 +83,7 @@
                         return value == null || value.length() < MAX_LENGTH;
                     }
                 });
-        VALIDATORS.put(
-                System.FONT_SCALE,
-                value -> {
-                    try {
-                        return Float.parseFloat(value) >= 0;
-                    } catch (NumberFormatException | NullPointerException e) {
-                        return false;
-                    }
-                });
+        VALIDATORS.put(System.FONT_SCALE, new InclusiveFloatRangeValidator(0.85f, 1.3f));
         VALIDATORS.put(System.DIM_SCREEN, BOOLEAN_VALIDATOR);
         VALIDATORS.put(
                 System.DISPLAY_COLOR_MODE,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index a61e3cd..c9e3b6f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -3342,7 +3342,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 195;
+            private static final int SETTINGS_VERSION = 196;
 
             private final int mUserId;
 
@@ -4777,6 +4777,15 @@
                     currentVersion = 195;
                 }
 
+                if (currentVersion == 195) {
+                    // Version 195: delete obsolete manged services settings
+                    getSecureSettingsLocked(userId).deleteSettingLocked(
+                            Secure.ENABLED_NOTIFICATION_ASSISTANT);
+                    getSecureSettingsLocked(userId).deleteSettingLocked(
+                            Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES);
+                    currentVersion = 196;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 75eea8d..c740bac 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -146,7 +146,6 @@
                     Settings.Global.BROADCAST_OFFLOAD_CONSTANTS,
                     Settings.Global.BATTERY_DISCHARGE_DURATION_THRESHOLD,
                     Settings.Global.BATTERY_DISCHARGE_THRESHOLD,
-                    Settings.Global.BATTERY_SAVER_ADAPTIVE_DEVICE_SPECIFIC_CONSTANTS,
                     Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS,
                     Settings.Global.BATTERY_STATS_CONSTANTS,
                     Settings.Global.BINDER_CALLS_STATS,
@@ -232,7 +231,6 @@
                     Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR,
                     Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH,
                     Settings.Global.DEVICE_DEMO_MODE,
-                    Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS,
                     Settings.Global.BATTERY_SAVER_CONSTANTS,
                     Settings.Global.BATTERY_TIP_CONSTANTS,
                     Settings.Global.DEFAULT_SM_DP_PLUS,
diff --git a/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java b/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java
index 9134d87..e5d148c 100644
--- a/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/settings/validators/SettingsValidatorsTest.java
@@ -56,8 +56,8 @@
     }
 
     @Test
-    public void testNonNegativeIntegerValidator_onNullValue_returnsFalse() {
-        assertFalse(SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR.validate(null));
+    public void testNonNegativeIntegerValidator_onNullValue_returnsTrue() {
+        assertTrue(SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR.validate(null));
     }
 
     @Test
@@ -69,8 +69,8 @@
     }
 
     @Test
-    public void testAnyIntegerValidator_onNullValue_returnsFalse() {
-        assertFalse(SettingsValidators.ANY_INTEGER_VALIDATOR.validate(null));
+    public void testAnyIntegerValidator_onNullValue_returnsTrue() {
+        assertTrue(SettingsValidators.ANY_INTEGER_VALIDATOR.validate(null));
     }
 
     @Test
@@ -91,8 +91,8 @@
     }
 
     @Test
-    public void testLenientIpAddressValidator_onNullValue_returnsFalse() {
-        assertFalse(SettingsValidators.LENIENT_IP_ADDRESS_VALIDATOR.validate(null));
+    public void testLenientIpAddressValidator_onNullValue_returnsTrue() {
+        assertTrue(SettingsValidators.LENIENT_IP_ADDRESS_VALIDATOR.validate(null));
     }
 
     @Test
@@ -120,8 +120,8 @@
     }
 
     @Test
-    public void testLocaleValidator_onNullValue_returnsFalse() {
-        assertFalse(SettingsValidators.LOCALE_VALIDATOR.validate(null));
+    public void testLocaleValidator_onNullValue_returnsTrue() {
+        assertTrue(SettingsValidators.LOCALE_VALIDATOR.validate(null));
     }
 
     @Test
@@ -149,11 +149,11 @@
     }
 
     @Test
-    public void testDiscreteValueValidator_onNullValue_returnsFalse() {
+    public void testDiscreteValueValidator_onNullValue_returnsTrue() {
         String[] discreteTypes = new String[]{"Type1", "Type2"};
         Validator v = new DiscreteValueValidator(discreteTypes);
 
-        assertFalse(v.validate(null));
+        assertTrue(v.validate(null));
     }
 
     @Test
@@ -167,10 +167,10 @@
     }
 
     @Test
-    public void testInclusiveIntegerRangeValidator_onNullValue_returnsFalse() {
+    public void testInclusiveIntegerRangeValidator_onNullValue_returnsTrue() {
         Validator v = new InclusiveIntegerRangeValidator(0, 5);
 
-        assertFalse(v.validate(null));
+        assertTrue(v.validate(null));
     }
 
     @Test
@@ -184,10 +184,10 @@
     }
 
     @Test
-    public void testInclusiveFloatRangeValidator_onNullValue_returnsFalse() {
+    public void testInclusiveFloatRangeValidator_onNullValue_returnsTrue() {
         Validator v = new InclusiveFloatRangeValidator(0.0f, 5.0f);
 
-        assertFalse(v.validate(null));
+        assertTrue(v.validate(null));
     }
 
     @Test
@@ -220,8 +220,8 @@
     }
 
     @Test
-    public void dateFormatValidator_onNullValue_returnsFalse() {
-        assertFalse(SettingsValidators.DATE_FORMAT_VALIDATOR.validate(null));
+    public void dateFormatValidator_onNullValue_returnsTrue() {
+        assertTrue(SettingsValidators.DATE_FORMAT_VALIDATOR.validate(null));
     }
 
     @Test
@@ -240,8 +240,8 @@
     }
 
     @Test
-    public void testJSONObjectValidator_onNullValue_returnsFalse() {
-        assertFalse(SettingsValidators.JSON_OBJECT_VALIDATOR.validate(null));
+    public void testJSONObjectValidator_onNullValue_returnsTrue() {
+        assertTrue(SettingsValidators.JSON_OBJECT_VALIDATOR.validate(null));
     }
 
     @Test
diff --git a/packages/SharedStorageBackup/OWNERS b/packages/SharedStorageBackup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/packages/SharedStorageBackup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 92b1ca7..7b1257b0 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -281,6 +281,9 @@
     <uses-permission android:name="android.permission.MANAGE_NOTIFICATIONS"/>
     <uses-permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"/>
 
+    <!-- Permission needed for CTS test - MusicRecognitionManagerTest -->
+    <uses-permission android:name="android.permission.MANAGE_MUSIC_RECOGNITION" />
+
     <!-- Permissions required to test ambient display. -->
     <uses-permission android:name="android.permission.READ_DREAM_STATE"/>
     <uses-permission android:name="android.permission.WRITE_DREAM_STATE"/>
@@ -347,9 +350,18 @@
     <!-- Permissions required for CTS test - NotificationManagerTest -->
     <uses-permission android:name="android.permission.MANAGE_NOTIFICATION_LISTENERS" />
 
+    <!-- Permissions required for CTS test - CtsContactsProviderTestCases -->
+    <uses-permission android:name="android.contacts.permission.MANAGE_SIM_ACCOUNTS" />
+
+    <!-- Permissions required for CTS test - CarrierMessagingServiceWrapprTest -->
+    <uses-permission android:name="android.permission.BIND_CARRIER_SERVICES" />
+
     <!-- Allows overriding the system's device state from the shell -->
     <uses-permission android:name="android.permission.CONTROL_DEVICE_STATE"/>
 
+    <!-- Permissions required for CTS tests to close system dialogs -->
+    <uses-permission android:name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS" />
+
     <application android:label="@string/app_label"
                 android:theme="@android:style/Theme.DeviceDefault.DayNight"
                 android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS
index 6ba1fcb..2d7a3e6 100644
--- a/packages/Shell/OWNERS
+++ b/packages/Shell/OWNERS
@@ -1,6 +1,6 @@
 set noparent
 
-jsharkey@android.com
+jsharkey@google.com
 felipeal@google.com
 nandana@google.com
 svetoslavganov@google.com
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 2da958f..285c4a1 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -576,6 +576,7 @@
             android:launchMode="singleInstance">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
+                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index f884270..3bda710 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -1,6 +1,6 @@
 set noparent
 
-dsandler@android.com
+dsandler@google.com
 
 aaliomer@google.com
 adamcohen@google.com
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
index 6c6c927..3058d94 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
@@ -127,6 +127,13 @@
     default void onTimeZoneChanged(TimeZone timeZone) {}
 
     /**
+     * Notifies that the time format has changed.
+     *
+     * @param timeFormat "12" for 12-hour format, "24" for 24-hour format
+     */
+    default void onTimeFormatChanged(String timeFormat) {}
+
+    /**
      * Indicates whether the keyguard status area (date) should be shown below
      * the clock.
      */
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index c82bda6..19f8248 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -73,13 +73,15 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:gravity="right"
-            android:textSize="80dp"
+            android:textSize="100dp"
             android:letterSpacing="0.02"
             android:lineSpacingMultiplier=".8"
             android:includeFontPadding="false"
             android:fontFamily="@font/clock"
             android:typeface="monospace"
             android:elegantTextHeight="false"
+            dozeWeight="200"
+            lockScreenWeight="300"
         />
     </FrameLayout>
     <FrameLayout
@@ -95,13 +97,15 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:gravity="center_horizontal"
-            android:textSize="180dp"
+            android:textSize="200dp"
             android:letterSpacing="0.02"
             android:lineSpacingMultiplier=".8"
             android:includeFontPadding="false"
             android:fontFamily="@font/clock"
             android:typeface="monospace"
             android:elegantTextHeight="false"
+            dozeWeight="100"
+            lockScreenWeight="400"
         />
     </FrameLayout>
     <include layout="@layout/keyguard_status_area"
diff --git a/packages/SystemUI/res-keyguard/values/attrs.xml b/packages/SystemUI/res-keyguard/values/attrs.xml
index 293b683..bfcc56c 100644
--- a/packages/SystemUI/res-keyguard/values/attrs.xml
+++ b/packages/SystemUI/res-keyguard/values/attrs.xml
@@ -39,4 +39,9 @@
     </declare-styleable>
 
     <attr name="passwordStyle" format="reference" />
+
+    <declare-styleable name="AnimatableClockView">
+        <attr name="dozeWeight" format="integer" />
+        <attr name="lockScreenWeight" format="integer" />
+    </declare-styleable>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index d95ab37..4b662137 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -79,8 +79,8 @@
          is not fully charged, and it's plugged into a slow charger, say that it's charging slowly.  -->
     <string name="keyguard_plugged_in_charging_slowly"><xliff:g id="percentage">%s</xliff:g> • Charging slowly</string>
 
-    <!-- When the lock screen is showing and the phone plugged in, and the defend mode is triggered, say that it's limited temporarily.  -->
-    <string name="keyguard_plugged_in_charging_limited"><xliff:g id="percentage">%s</xliff:g> • Battery limited temporarily</string>
+    <!-- When the lock screen is showing and the phone plugged in, and the defend mode is triggered, say that it's optimizing for battery health.  -->
+    <string name="keyguard_plugged_in_charging_limited"><xliff:g id="percentage">%s</xliff:g> • Optimizing for battery health</string>
 
     <!-- When the lock screen is showing and the battery is low, warn user to plug
          in the phone soon. -->
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index bc48e8f..71a1cc2 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -137,5 +137,4 @@
         <item name="android:shadowColor">@color/keyguard_shadow_color</item>
         <item name="android:shadowRadius">?attr/shadowRadius</item>
     </style>
-
 </resources>
diff --git a/packages/SystemUI/res/color/qs_background_dark.xml b/packages/SystemUI/res/color/qs_background_dark.xml
deleted file mode 100644
index c47959a..0000000
--- a/packages/SystemUI/res/color/qs_background_dark.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:alpha="1"
-          android:color="?android:attr/colorBackground"/>
-</selector>
diff --git a/packages/SystemUI/res/drawable/brightness_mirror_background.xml b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
index 43c9b73..02261b2 100644
--- a/packages/SystemUI/res/drawable/brightness_mirror_background.xml
+++ b/packages/SystemUI/res/drawable/brightness_mirror_background.xml
@@ -15,6 +15,6 @@
   ~ limitations under the License
   -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="@color/qs_background_dark" />
+    <solid android:color="?android:attr/colorBackground" />
     <corners android:radius="8dp" />
 </shape>
diff --git a/packages/SystemUI/res/drawable/people_space_activity_card.xml b/packages/SystemUI/res/drawable/people_space_activity_card.xml
new file mode 100644
index 0000000..81162d2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/people_space_activity_card.xml
@@ -0,0 +1,19 @@
+<!--
+  ~ Copyright (C) 2020 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.
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="?android:attr/colorAccent" />
+    <corners android:radius="@dimen/people_space_widget_radius" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_background_primary.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
deleted file mode 100644
index dd74cadd..0000000
--- a/packages/SystemUI/res/drawable/qs_background_primary.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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.
--->
-<inset xmlns:android="http://schemas.android.com/apk/res/android">
-    <shape>
-        <solid android:color="@color/qs_background_dark"/>
-        <corners android:radius="?android:attr/dialogCornerRadius" />
-    </shape>
-</inset>
diff --git a/packages/SystemUI/res/drawable/qs_footer_drag_handle.xml b/packages/SystemUI/res/drawable/qs_footer_drag_handle.xml
index 509cd1f..59dad0e 100644
--- a/packages/SystemUI/res/drawable/qs_footer_drag_handle.xml
+++ b/packages/SystemUI/res/drawable/qs_footer_drag_handle.xml
@@ -17,6 +17,6 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:shape="rectangle" >
     <solid
-        android:color="#e5e5e5" />
+        android:color="?android:attr/textColorPrimary" />
     <corners android:radius="2dp" />
 </shape>
diff --git a/packages/SystemUI/res/layout/people_space_activity.xml b/packages/SystemUI/res/layout/people_space_activity.xml
index 67ecdaa..07af01b 100644
--- a/packages/SystemUI/res/layout/people_space_activity.xml
+++ b/packages/SystemUI/res/layout/people_space_activity.xml
@@ -17,8 +17,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/scroll"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@android:color/holo_blue_light">
+    android:layout_height="match_parent">
 
     <LinearLayout
         android:id="@+id/people_space_layout"
@@ -30,16 +29,15 @@
         android:clipChildren="false"
         android:clipToPadding="false">
 
-        <ImageView
-            android:id="@+id/people_space_cloud"
-            android:layout_width="67dp"
-            android:layout_height="67dp"
+        <TextView
+            android:id="@+id/select_conversation"
+            android:text="@string/select_conversation_text"
+            android:layout_width="match_parent"
+            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+            android:textSize="24sp"
+            android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
-            android:scaleType="fitCenter"
-            android:focusable="false"
-            android:paddingBottom="16dp"
-            android:tint="?android:attr/colorControlNormal"
-            android:src="@drawable/cloud" />
+            android:paddingBottom="16dp" />
 
     </LinearLayout>
 </androidx.core.widget.NestedScrollView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_space_tile_view.xml b/packages/SystemUI/res/layout/people_space_tile_view.xml
index 80bb070..c751e7d 100644
--- a/packages/SystemUI/res/layout/people_space_tile_view.xml
+++ b/packages/SystemUI/res/layout/people_space_tile_view.xml
@@ -20,46 +20,53 @@
     android:orientation="vertical">
 
     <LinearLayout
-        android:background="@drawable/people_space_tile_view_card"
         android:orientation="vertical"
-        android:padding="16dp"
-        android:layout_marginBottom="24dp"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:background="@drawable/people_space_activity_card"
+        android:padding="12dp"
         android:elevation="4dp"
-        android:gravity="start">
+        android:layout_marginBottom="12dp"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
 
-        <ImageView
-            android:id="@+id/tile_view_package_icon"
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:layout_gravity="end" />
-
-        <ImageView
-            android:id="@+id/tile_view_person_icon"
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:layout_gravity="start" />
-
-        <TextView
-            android:id="@+id/tile_view_name"
-            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
-            android:paddingVertical="4dp"
-            android:textSize="22sp"
-            android:textColor="?android:attr/textColorPrimary"
-            android:layout_width="wrap_content"
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="start" />
+            android:gravity="start">
 
-        <TextView
-            android:id="@+id/tile_view_status"
-            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
-            android:paddingVertical="4dp"
-            android:textSize="16sp"
-            android:textColor="?android:attr/textColorSecondary"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:ellipsize="end"
-            android:layout_gravity="start" />
+            <ImageView
+                android:id="@+id/tile_view_person_icon"
+                android:layout_width="48dp"
+                android:layout_height="48dp" />
+
+            <ImageView
+                android:id="@+id/tile_view_package_icon"
+                android:layout_width="16dp"
+                android:layout_marginStart="-8dp"
+                android:layout_height="16dp" />
+
+            <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <TextView
+                    android:id="@+id/tile_view_name"
+                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+                    android:paddingHorizontal="16dp"
+                    android:textSize="22sp"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content" />
+
+                <TextView
+                    android:id="@+id/tile_view_status"
+                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+                    android:paddingVertical="4dp"
+                    android:textSize="12sp"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:ellipsize="end" />
+            </LinearLayout>
+        </LinearLayout>
     </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_space_widget.xml b/packages/SystemUI/res/layout/people_space_widget.xml
index b417fcf..f4db321 100644
--- a/packages/SystemUI/res/layout/people_space_widget.xml
+++ b/packages/SystemUI/res/layout/people_space_widget.xml
@@ -22,6 +22,6 @@
     android:background="@drawable/people_space_widget_background"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:padding="5dp"
+    android:padding="2dp"
     android:divider="@null"
     android:dividerHeight="0dp"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/people_space_widget_item.xml b/packages/SystemUI/res/layout/people_space_widget_item.xml
index e4de6f9..95de6d6 100644
--- a/packages/SystemUI/res/layout/people_space_widget_item.xml
+++ b/packages/SystemUI/res/layout/people_space_widget_item.xml
@@ -22,38 +22,57 @@
         android:background="@drawable/people_space_tile_view_card"
         android:id="@+id/item"
         android:orientation="vertical"
-        android:padding="6dp"
-        android:layout_marginBottom="6dp"
+        android:padding="4dp"
+        android:layout_marginBottom="2dp"
         android:elevation="4dp"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="start">
-        <ImageView
-            android:id="@+id/package_icon"
-            android:layout_width="30dp"
-            android:layout_height="30dp"
-            android:layout_gravity="end" />
-        <ImageView
-            android:id="@+id/person_icon"
-            android:layout_width="30dp"
-            android:layout_height="30dp"
-            android:layout_gravity="start" />
-        <TextView
-            android:id="@+id/name"
-            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
-            android:textSize="18sp"
-            android:textColor="?android:attr/textColorPrimary"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="start" />
-        <TextView
-            android:id="@+id/status"
-            android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
-            android:paddingVertical="2dp"
-            android:textSize="14sp"
-            android:textColor="?android:attr/textColorSecondary"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="start" />
+        android:layout_height="wrap_content">
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:gravity="center_vertical"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <ImageView
+                android:id="@+id/person_icon"
+                android:layout_width="42dp"
+                android:layout_height="42dp" />
+
+            <ImageView
+                android:id="@+id/package_icon"
+                android:gravity="bottom|end"
+                android:layout_width="14dp"
+                android:layout_marginStart="-8dp"
+                android:layout_height="14dp" />
+
+            <LinearLayout
+                android:orientation="vertical"
+                android:paddingStart="4dp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <TextView
+                    android:id="@+id/name"
+                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+                    android:textColor="?android:attr/textColorPrimary"
+                    android:textSize="16sp"
+                    android:maxLines="1"
+                    android:ellipsize="end"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content" />
+
+                <TextView
+                    android:id="@+id/status"
+                    android:textColor="?android:attr/textColorSecondary"
+                    android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+                    android:paddingVertical="2dp"
+                    android:textSize="12sp"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:maxLines="3"
+                    android:ellipsize="end" />
+            </LinearLayout>
+        </LinearLayout>
     </LinearLayout>
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 89bf12d..387f2f2 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -25,9 +25,7 @@
     <View
         android:id="@+id/quick_settings_background"
         android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:elevation="4dp"
-        android:background="@drawable/qs_background_primary" />
+        android:layout_height="0dp" />
 
     <com.android.systemui.qs.NonInterceptingScrollView
         android:id="@+id/expanded_qs_scroll_view"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
index 69beffe..6f9d745 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
@@ -25,5 +25,4 @@
     android:layout_marginTop="@dimen/notification_side_paddings"
     android:layout_marginLeft="@dimen/notification_side_paddings"
     android:layout_marginRight="@dimen/notification_side_paddings"
-    android:visibility="gone"
-    android:background="@drawable/qs_background_primary"/>
+    android:visibility="gone"/>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 01b55b7..880dd378 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -357,6 +357,9 @@
          the notification is not swiped enough to dismiss it. -->
     <bool name="config_showNotificationGear">true</bool>
 
+    <!-- Whether or not a background should be drawn behind a notification. -->
+    <bool name="config_drawNotificationBackground">true</bool>
+
     <!-- Whether or the notifications can be shown and dismissed with a drag. -->
     <bool name="config_enableNotificationShadeDrag">true</bool>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 5b74687..7989b7a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2824,13 +2824,15 @@
     <string name="build_number_copy_toast">Build number copied to clipboard.</string>
 
     <!-- Status for last interaction with exact time [CHAR LIMIT=120] -->
-    <string name="last_interaction_status" translatable="false">You last chatted <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
+    <string name="last_interaction_status" translatable="false">Last chatted <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
     <!-- Status for last interaction when less than a certain time window [CHAR LIMIT=120] -->
-    <string name="last_interaction_status_less_than" translatable="false">You last chatted less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
+    <string name="last_interaction_status_less_than" translatable="false">Last chatted less than <xliff:g id="duration" example="5 hours">%1$s</xliff:g> ago</string>
     <!-- Status for last interaction when over a certain time window [CHAR LIMIT=120] -->
-    <string name="last_interaction_status_over" translatable="false">You last chatted over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
+    <string name="last_interaction_status_over" translatable="false">Last chatted over <xliff:g id="duration" example="1 week">%1$s</xliff:g> ago</string>
     <!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
     <string name="basic_status" translatable="false">Open conversation</string>
+    <!-- Status for conversation without interaction data [CHAR LIMIT=120] -->
+    <string name="select_conversation_text" translatable="false">Select one conversation to show in your widget:</string>
 
     <!-- Title to display in a notification when ACTION_BATTERY_CHANGED.EXTRA_PRESENT field is false
     [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/res/xml/people_space_widget_info.xml b/packages/SystemUI/res/xml/people_space_widget_info.xml
index f08c8c8..10e28c4 100644
--- a/packages/SystemUI/res/xml/people_space_widget_info.xml
+++ b/packages/SystemUI/res/xml/people_space_widget_info.xml
@@ -15,10 +15,11 @@
   -->
 
 <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
-    android:minWidth="72dp"
-    android:minHeight="150dp"
+    android:minWidth="180dp"
+    android:minHeight="40dp"
     android:updatePeriodMillis="60000"
-    android:previewImage="@drawable/cloud"
+    android:previewImage="@drawable/ic_android"
     android:resizeMode="horizontal|vertical"
+    android:configure="com.android.systemui.people.PeopleSpaceActivity"
     android:initialLayout="@layout/people_space_widget">
 </appwidget-provider>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
index c8607df..ee7030a8 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
@@ -386,7 +386,10 @@
                     }
                     Intent i = new Intent(PluginManagerImpl.DISABLE_PLUGIN).setData(
                             Uri.parse("package://" + component.flattenToString()));
-                    PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, 0);
+                    // TODO(b/174161910) Please replace FLAG_MUTABLE_UNAUDITED below
+                    // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+                    PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i,
+                            PendingIntent.FLAG_MUTABLE_UNAUDITED);
                     nb.addAction(new Action.Builder(null, "Disable plugin", pi).build());
                     mContext.getSystemService(NotificationManager.class)
                             .notify(SystemMessage.NOTE_PLUGIN, nb.build());
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
index 3157a5a..7c6a274 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockController.java
@@ -24,6 +24,8 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.util.ViewController;
 
+import java.util.TimeZone;
+
 /**
  * Controls the color of a GradientTextClock.
  */
@@ -62,12 +64,26 @@
     }
 
     /**
-     * Updates the time for this view.
+     * Updates the time for the view.
      */
     public void refreshTime() {
         mView.refreshTime();
     }
 
+    /**
+     * Updates the timezone for the view.
+     */
+    public void onTimeZoneChanged(TimeZone timeZone) {
+        mView.onTimeZoneChanged(timeZone);
+    }
+
+    /**
+     * Trigger a time format update
+     */
+    public void refreshFormat() {
+        mView.refreshFormat();
+    }
+
     private void initColors() {
         mLockScreenColors[0] = Utils.getColorAttrDefaultColor(getContext(),
                 com.android.systemui.R.attr.wallpaperTextColor);
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
index 6d1d42e..ca99563 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
@@ -19,13 +19,17 @@
 import android.annotation.FloatRange;
 import android.annotation.IntRange;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.icu.text.DateTimePatternGenerator;
 import android.text.format.DateFormat;
 import android.util.AttributeSet;
 import android.widget.TextView;
 
+import com.android.systemui.R;
+
 import java.util.Calendar;
+import java.util.TimeZone;
 
 import kotlin.Unit;
 
@@ -38,11 +42,14 @@
     private static final CharSequence FORMAT_24_HOUR = "HH\nmm";
     private static final long ANIM_DURATION = 300;
 
+    private final Calendar mTime = Calendar.getInstance();
+
     private CharSequence mFormat;
     private CharSequence mDescFormat;
-    private Calendar mTime = Calendar.getInstance();
     private int[] mDozingColors;
     private int[] mLockScreenColors;
+    private final int mDozingWeight;
+    private final int mLockScreenWeight;
 
     private TextAnimator mTextAnimator = null;
     private Runnable mOnTextAnimatorInitialized;
@@ -62,13 +69,21 @@
     public AnimatableClockView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        updateTimeFormat();
+        TypedArray ta = context.obtainStyledAttributes(
+                attrs, R.styleable.AnimatableClockView, defStyleAttr, defStyleRes);
+        try {
+            mDozingWeight = ta.getInt(R.styleable.AnimatableClockView_dozeWeight, 100);
+            mLockScreenWeight = ta.getInt(R.styleable.AnimatableClockView_lockScreenWeight, 300);
+        } finally {
+            ta.recycle();
+        }
+        refreshFormat();
     }
 
     @Override
     public void onAttachedToWindow() {
         super.onAttachedToWindow();
-        updateTimeFormat();
+        refreshFormat();
     }
 
     @Override
@@ -82,6 +97,11 @@
         setContentDescription(DateFormat.format(mDescFormat, mTime));
     }
 
+    void onTimeZoneChanged(TimeZone timeZone) {
+        mTime.setTimeZone(timeZone);
+        refreshFormat();
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -113,7 +133,7 @@
     }
 
     void animateDoze(boolean isDozing, boolean animate) {
-        setTextStyle(isDozing ? 100 : 300 /* weight */,
+        setTextStyle(isDozing ? mDozingWeight : mLockScreenWeight /* weight */,
                 -1,
                 isDozing ? mDozingColors : mLockScreenColors,
                 animate);
@@ -144,10 +164,11 @@
         }
     }
 
-    private void updateTimeFormat() {
+    void refreshFormat() {
         final boolean use24HourFormat = DateFormat.is24HourFormat(getContext());
         mFormat =  use24HourFormat ? FORMAT_24_HOUR : FORMAT_12_HOUR;
         mDescFormat = getBestDateTimePattern(getContext(), use24HourFormat ? "Hm" : "hm");
+        refreshTime();
     }
 
     private static String getBestDateTimePattern(Context context, String skeleton) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 68405a1..ab7ba8a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -156,13 +156,17 @@
 
             statusAreaLP.removeRule(RelativeLayout.BELOW);
             statusAreaLP.addRule(RelativeLayout.ALIGN_PARENT_START);
+            statusAreaLP.addRule(RelativeLayout.START_OF, R.id.new_lockscreen_clock_view);
+            statusAreaLP.width = 0;
         } else {
             setPaddingRelative(0, 0, 0, 0);
             mSmallClockFrame.setVisibility(VISIBLE);
             mNewLockscreenClockFrame.setVisibility(GONE);
 
             statusAreaLP.removeRule(RelativeLayout.ALIGN_PARENT_START);
+            statusAreaLP.removeRule(RelativeLayout.START_OF);
             statusAreaLP.addRule(RelativeLayout.BELOW, R.id.clock_view);
+            statusAreaLP.width = ViewGroup.LayoutParams.WRAP_CONTENT;
         }
 
         requestLayout();
@@ -401,6 +405,17 @@
         }
     }
 
+    /**
+     * Notifies that the time format has changed.
+     *
+     * @param timeFormat "12" for 12-hour format, "24" for 24-hour format
+     */
+    public void onTimeFormatChanged(String timeFormat) {
+        if (mClockPlugin != null) {
+            mClockPlugin.onTimeFormatChanged(timeFormat);
+        }
+    }
+
     void updateColors(ColorExtractor.GradientColors colors) {
         mSupportsDarkText = colors.supportsDarkText();
         mColorPalette = colors.getColorPalette();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 829ff97..4d6e8a9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -17,7 +17,9 @@
 package com.android.keyguard;
 
 import android.app.WallpaperManager;
+import android.content.ContentResolver;
 import android.content.res.Resources;
+import android.provider.Settings;
 import android.text.format.DateFormat;
 import android.util.TypedValue;
 import android.view.View;
@@ -90,6 +92,7 @@
     };
 
     private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
+    private String mTimeFormat;
 
     @Inject
     public KeyguardClockSwitchController(
@@ -98,7 +101,8 @@
             StatusBarStateController statusBarStateController,
             SysuiColorExtractor colorExtractor, ClockManager clockManager,
             KeyguardSliceViewController keyguardSliceViewController,
-            NotificationIconAreaController notificationIconAreaController) {
+            NotificationIconAreaController notificationIconAreaController,
+            ContentResolver contentResolver) {
         super(keyguardClockSwitch);
         mResources = resources;
         mStatusBarStateController = statusBarStateController;
@@ -106,6 +110,7 @@
         mClockManager = clockManager;
         mKeyguardSliceViewController = keyguardSliceViewController;
         mNotificationIconAreaController = notificationIconAreaController;
+        mTimeFormat = Settings.System.getString(contentResolver, Settings.System.TIME_12_24);
     }
 
     /**
@@ -246,12 +251,26 @@
 
     void updateTimeZone(TimeZone timeZone) {
         mView.onTimeZoneChanged(timeZone);
+        if (mNewLockScreenClockViewController != null) {
+            mNewLockScreenClockViewController.onTimeZoneChanged(timeZone);
+            mNewLockScreenLargeClockViewController.onTimeZoneChanged(timeZone);
+        }
     }
 
-    void refreshFormat() {
+    void refreshFormat(String timeFormat) {
+        mTimeFormat = timeFormat;
         Patterns.update(mResources);
         mView.setFormat12Hour(Patterns.sClockView12);
         mView.setFormat24Hour(Patterns.sClockView24);
+        mView.onTimeFormatChanged(mTimeFormat);
+        if (mNewLockScreenClockViewController != null) {
+            mNewLockScreenClockViewController.refreshFormat();
+            mNewLockScreenLargeClockViewController.refreshFormat();
+        }
+    }
+
+    void refreshFormat() {
+        refreshFormat(mTimeFormat);
     }
 
     float getClockTextTopPadding() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index bc81a198..826020c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -329,6 +329,11 @@
         }
 
         @Override
+        public void onTimeFormatChanged(String timeFormat) {
+            mKeyguardClockSwitchController.refreshFormat(timeFormat);
+        }
+
+        @Override
         public void onKeyguardVisibilityChanged(boolean showing) {
             if (showing) {
                 if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a7e5195..2071cfa 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -182,6 +182,7 @@
     private static final int MSG_USER_REMOVED = 341;
     private static final int MSG_KEYGUARD_GOING_AWAY = 342;
     private static final int MSG_LOCK_SCREEN_MODE = 343;
+    private static final int MSG_TIME_FORMAT_UPDATE = 344;
 
     public static final int LOCK_SCREEN_MODE_NORMAL = 0;
     public static final int LOCK_SCREEN_MODE_LAYOUT_1 = 1;
@@ -280,6 +281,7 @@
             mCallbacks = Lists.newArrayList();
     private ContentObserver mDeviceProvisionedObserver;
     private ContentObserver mLockScreenModeObserver;
+    private ContentObserver mTimeFormatChangeObserver;
 
     private boolean mSwitchingUser;
 
@@ -1721,6 +1723,9 @@
                     case MSG_LOCK_SCREEN_MODE:
                         handleLockScreenMode();
                         break;
+                    case MSG_TIME_FORMAT_UPDATE:
+                        handleTimeFormatUpdate((String) msg.obj);
+                        break;
                     default:
                         super.handleMessage(msg);
                         break;
@@ -1866,12 +1871,25 @@
         mContext.getContentResolver().registerContentObserver(
                 Settings.Global.getUriFor(Settings.Global.SHOW_NEW_LOCKSCREEN),
                 false, mLockScreenModeObserver);
+
+        mTimeFormatChangeObserver = new ContentObserver(mHandler) {
+            @Override
+            public void onChange(boolean selfChange) {
+                mHandler.sendMessage(mHandler.obtainMessage(
+                        MSG_TIME_FORMAT_UPDATE,
+                        Settings.System.getString(
+                                mContext.getContentResolver(),
+                                Settings.System.TIME_12_24)));
+            }
+        };
+        mContext.getContentResolver().registerContentObserver(
+                Settings.System.getUriFor(Settings.System.TIME_12_24),
+                false, mTimeFormatChangeObserver, UserHandle.USER_ALL);
     }
 
     private void updateLockScreenMode() {
         final int newMode = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.SHOW_NEW_LOCKSCREEN,
-                isUdfpsEnrolled() ? 1 : 0);
+                Settings.Global.SHOW_NEW_LOCKSCREEN, LOCK_SCREEN_MODE_LAYOUT_1);
         if (newMode != mLockScreenMode) {
             mLockScreenMode = newMode;
             mHandler.sendEmptyMessage(MSG_LOCK_SCREEN_MODE);
@@ -2451,6 +2469,22 @@
     }
 
     /**
+     * Handle (@line #MSG_TIME_FORMAT_UPDATE}
+     *
+     * @param timeFormat "12" for 12-hour format, "24" for 24-hour format
+     */
+    private void handleTimeFormatUpdate(String timeFormat) {
+        Assert.isMainThread();
+        if (DEBUG) Log.d(TAG, "handleTimeFormatUpdate timeFormat=" + timeFormat);
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onTimeFormatChanged(timeFormat);
+            }
+        }
+    }
+
+    /**
      * Handle {@link #MSG_BATTERY_UPDATE}
      */
     private void handleBatteryUpdate(BatteryStatus status) {
@@ -2687,6 +2721,11 @@
             return true;
         }
 
+        // change in battery overheat
+        if (current.health != old.health) {
+            return true;
+        }
+
         return false;
     }
 
@@ -3055,6 +3094,10 @@
             mContext.getContentResolver().unregisterContentObserver(mLockScreenModeObserver);
         }
 
+        if (mTimeFormatChangeObserver != null) {
+            mContext.getContentResolver().unregisterContentObserver(mTimeFormatChangeObserver);
+        }
+
         try {
             ActivityManager.getService().unregisterUserSwitchObserver(mUserSwitchObserver);
         } catch (RemoteException e) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index b722dea..36617c2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -58,6 +58,11 @@
     public void onTimeZoneChanged(TimeZone timeZone) { }
 
     /**
+     * Called when time format changes.
+     */
+    public void onTimeFormatChanged(String timeFormat) { }
+
+    /**
      * Called when the carrier PLMN or SPN changes.
      */
     public void onRefreshCarrierInfo() { }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index e49a5be..e6ad1cb 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -400,7 +400,10 @@
                 case INTENT_ACTION_ACCESSIBILITY_SHORTCUT: {
                     Intent intent = new Intent(intentAction);
                     intent.setPackage(context.getPackageName());
-                    return PendingIntent.getBroadcast(context, 0, intent, 0);
+                    // TODO(b/173157883) Please replace FLAG_MUTABLE_UNAUDITED below
+                    // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+                    return PendingIntent.getBroadcast(context, 0, intent,
+                            PendingIntent.FLAG_MUTABLE_UNAUDITED);
                 }
                 default:
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index a330be6..ce5795c 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -103,7 +103,7 @@
 
         d.setOnShowListener(dialog -> {
             if (mBlurUtils.supportsBlursOnWindows()) {
-                background.setAlpha((int) (ScrimController.BLUR_SCRIM_ALPHA * 255));
+                background.setAlpha((int) (ScrimController.BUSY_SCRIM_ALPHA * 255));
                 mBlurUtils.applyBlur(d.getWindow().getDecorView().getViewRootImpl(),
                         mBlurUtils.blurRadiusOfRatio(1));
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
index 5cd3b33..4a633c3 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java
@@ -16,19 +16,30 @@
 
 package com.android.systemui.people;
 
+import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID;
+import static android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID;
+
 import android.app.Activity;
 import android.app.INotificationManager;
 import android.app.people.IPeopleManager;
 import android.app.people.PeopleSpaceTile;
+import android.appwidget.AppWidgetManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.ServiceManager;
+import android.provider.Settings;
 import android.util.Log;
 import android.view.ViewGroup;
 
+import androidx.preference.PreferenceManager;
+
 import com.android.systemui.R;
+import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
 
 import java.util.List;
 import java.util.Map;
@@ -46,6 +57,9 @@
     private PackageManager mPackageManager;
     private LauncherApps mLauncherApps;
     private Context mContext;
+    private AppWidgetManager mAppWidgetManager;
+    private int mAppWidgetId;
+    private boolean mShowSingleConversation;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -59,7 +73,18 @@
         mPeopleManager = IPeopleManager.Stub.asInterface(
                 ServiceManager.getService(Context.PEOPLE_SERVICE));
         mLauncherApps = mContext.getSystemService(LauncherApps.class);
+        mAppWidgetManager = AppWidgetManager.getInstance(mContext);
         setTileViewsWithPriorityConversations();
+        mAppWidgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID,
+                INVALID_APPWIDGET_ID);
+        mShowSingleConversation = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
+        // Finish the configuration activity immediately if a widget is added for multiple
+        // conversations. If the mAppWidgetId is INVALID, then the activity wasn't launched as a
+        // widget configuration activity.
+        if (!mShowSingleConversation && mAppWidgetId != INVALID_APPWIDGET_ID) {
+            finishActivity();
+        }
     }
 
     /**
@@ -93,12 +118,39 @@
             tileView.setName(tile.getUserName().toString());
             tileView.setPackageIcon(mPackageManager.getApplicationIcon(pkg));
             tileView.setPersonIcon(tile.getUserIcon());
-            tileView.setOnClickListener(mLauncherApps, tile);
+            tileView.setOnClickListener(v -> storeWidgetConfiguration(tile));
         } catch (Exception e) {
             Log.e(TAG, "Couldn't retrieve shortcut information", e);
         }
     }
 
+    /** Stores the user selected configuration for {@code mAppWidgetId}. */
+    private void storeWidgetConfiguration(PeopleSpaceTile tile) {
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+        SharedPreferences.Editor editor = sp.edit();
+        if (PeopleSpaceUtils.DEBUG) {
+            Log.d(TAG, "Put " + tile.getUserName() + "'s shortcut ID: "
+                    + tile.getId() + " for widget ID: "
+                    + mAppWidgetId);
+        }
+        editor.putString(String.valueOf(mAppWidgetId), tile.getId());
+        editor.commit();
+        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
+        int[] widgetIds = appWidgetManager.getAppWidgetIds(
+                new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
+        PeopleSpaceUtils.updateSingleConversationWidgets(mContext, widgetIds, mAppWidgetManager,
+                mNotificationManager);
+        finishActivity();
+    }
+
+    /** Finish activity with a successful widget configuration result. */
+    private void finishActivity() {
+        Intent resultValue = new Intent();
+        resultValue.putExtra(EXTRA_APPWIDGET_ID, mAppWidgetId);
+        setResult(RESULT_OK, resultValue);
+        finish();
+    }
+
     @Override
     protected void onResume() {
         super.onResume();
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java
index 4aea5b8..9ae7847 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceTileView.java
@@ -84,4 +84,9 @@
                 launcherApps.startShortcut(tile.getPackageName(), tile.getId(), null, null,
                         UserHandle.getUserHandleForUid(tile.getUid())));
     }
+
+    /** Sets the click listener of the tile directly. */
+    public void setOnClickListener(OnClickListener onClickListener) {
+        mTileView.setOnClickListener(onClickListener);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index fe262b4..5f3ceb1 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -17,11 +17,17 @@
 package com.android.systemui.people;
 
 import android.app.INotificationManager;
+import android.app.PendingIntent;
 import android.app.people.ConversationChannel;
 import android.app.people.IPeopleManager;
 import android.app.people.PeopleSpaceTile;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetManager;
 import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.BitmapDrawable;
@@ -29,17 +35,24 @@
 import android.icu.text.MeasureFormat;
 import android.icu.util.Measure;
 import android.icu.util.MeasureUnit;
+import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.ConversationChannelWrapper;
 import android.util.Log;
+import android.widget.RemoteViews;
+
+import androidx.preference.PreferenceManager;
 
 import com.android.systemui.R;
+import com.android.systemui.people.widget.LaunchConversationActivity;
+import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
 
 import java.time.Duration;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -57,14 +70,15 @@
             Context context, INotificationManager notificationManager, IPeopleManager peopleManager,
             LauncherApps launcherApps)
             throws Exception {
-        boolean showAllConversations = Settings.Global.getInt(context.getContentResolver(),
-                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
+        boolean showOnlyPriority = Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 1;
         List<ConversationChannelWrapper> conversations = notificationManager.getConversations(
                 true).getList();
         List<Map.Entry<Long, PeopleSpaceTile>> tiles = getSortedTiles(peopleManager,
                 conversations.stream().map(c ->
                         new PeopleSpaceTile.Builder(c.getShortcutInfo(), launcherApps).build()));
-        if (showAllConversations) {
+        if (!showOnlyPriority) {
+            if (DEBUG) Log.d(TAG, "Add recent conversations");
             List<ConversationChannel> recentConversations =
                     peopleManager.getRecentConversations().getList();
             List<Map.Entry<Long, PeopleSpaceTile>> recentTiles =
@@ -77,6 +91,73 @@
         return tiles;
     }
 
+    /** Updates {@code appWidgetIds} with their associated conversation stored. */
+    public static void updateSingleConversationWidgets(Context context, int[] appWidgetIds,
+            AppWidgetManager appWidgetManager, INotificationManager notificationManager) {
+        PackageManager mPackageManager = context.getPackageManager();
+        IPeopleManager mPeopleManager = IPeopleManager.Stub.asInterface(
+                ServiceManager.getService(Context.PEOPLE_SERVICE));
+        LauncherApps mLauncherApps = context.getSystemService(LauncherApps.class);
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
+        Intent activityIntent = new Intent(context, LaunchConversationActivity.class);
+        activityIntent.addFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_CLEAR_TASK
+                        | Intent.FLAG_ACTIVITY_NO_HISTORY
+                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        try {
+            List<Map.Entry<Long, PeopleSpaceTile>> shortcutInfos =
+                    PeopleSpaceUtils.getTiles(
+                            context, notificationManager,
+                            mPeopleManager, mLauncherApps);
+            for (int appWidgetId : appWidgetIds) {
+                RemoteViews views = new RemoteViews(context.getPackageName(),
+                        R.layout.people_space_widget_item);
+                String shortcutId = sp.getString(String.valueOf(appWidgetId), null);
+                if (DEBUG) {
+                    Log.d(TAG, "Set widget: " + appWidgetId + " with shortcut ID: " + shortcutId);
+                }
+
+                Optional<Map.Entry<Long, PeopleSpaceTile>> entry = shortcutInfos.stream().filter(
+                        e -> e.getValue().getId().equals(shortcutId)).findFirst();
+                if (!entry.isPresent() || shortcutId == null) {
+                    if (DEBUG) Log.d(TAG, "Matching conversation not found for shortcut ID");
+                    AppWidgetHost host = new AppWidgetHost(context, 0);
+                    host.deleteAppWidgetId(appWidgetId);
+                    continue;
+                }
+                PeopleSpaceTile tile = entry.get().getValue();
+
+                String status = PeopleSpaceUtils.getLastInteractionString(context,
+                        entry.get().getKey());
+                views.setTextViewText(R.id.status, status);
+                views.setTextViewText(R.id.name, tile.getUserName().toString());
+
+                activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, tile.getId());
+                activityIntent.putExtra(
+                        PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, tile.getPackageName());
+                activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_UID, tile.getUid());
+                views.setOnClickPendingIntent(R.id.item, PendingIntent.getActivity(
+                        context,
+                        appWidgetId,
+                        activityIntent,
+                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE));
+
+                views.setImageViewBitmap(
+                        R.id.package_icon,
+                        PeopleSpaceUtils.convertDrawableToBitmap(
+                                mPackageManager.getApplicationIcon(tile.getPackageName())
+                        )
+                );
+                views.setImageViewIcon(R.id.person_icon, tile.getUserIcon());
+                // Tell the AppWidgetManager to perform an update on the current app widget.
+                appWidgetManager.updateAppWidget(appWidgetId, views);
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to retrieve conversations to set tiles");
+        }
+    }
+
     /** Returns a list sorted by ascending last interaction time from {@code stream}. */
     private static List<Map.Entry<Long, PeopleSpaceTile>> getSortedTiles(
             IPeopleManager peopleManager, Stream<PeopleSpaceTile> stream) {
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 9b7cf6e..ac32e19 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -16,11 +16,14 @@
 
 package com.android.systemui.people.widget;
 
+import android.app.INotificationManager;
 import android.app.NotificationChannel;
+import android.appwidget.AppWidgetManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.util.Log;
@@ -42,13 +45,18 @@
     private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
 
     private final Context mContext;
-    private IAppWidgetService mAppWidgetManager;
+    private IAppWidgetService mAppWidgetService;
+    private AppWidgetManager mAppWidgetManager;
+    private INotificationManager mNotificationManager;
 
     @Inject
     public PeopleSpaceWidgetManager(Context context, IAppWidgetService appWidgetService) {
         if (DEBUG) Log.d(TAG, "constructor");
         mContext = context;
-        mAppWidgetManager = appWidgetService;
+        mAppWidgetService = appWidgetService;
+        mAppWidgetManager = AppWidgetManager.getInstance(context);
+        mNotificationManager = INotificationManager.Stub.asInterface(
+                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
     }
 
     /** Constructor used for testing. */
@@ -56,21 +64,24 @@
     protected PeopleSpaceWidgetManager(Context context) {
         if (DEBUG) Log.d(TAG, "constructor");
         mContext = context;
-        mAppWidgetManager = IAppWidgetService.Stub.asInterface(
+        mAppWidgetService = IAppWidgetService.Stub.asInterface(
                 ServiceManager.getService(Context.APPWIDGET_SERVICE));
     }
 
     /** AppWidgetManager setter used for testing. */
     @VisibleForTesting
-    protected void setAppWidgetManager(IAppWidgetService appWidgetService) {
-        mAppWidgetManager = appWidgetService;
+    protected void setAppWidgetManager(IAppWidgetService appWidgetService,
+            AppWidgetManager appWidgetManager, INotificationManager notificationManager) {
+        mAppWidgetService = appWidgetService;
+        mAppWidgetManager = appWidgetManager;
+        mNotificationManager = notificationManager;
     }
 
     /** Updates People Space widgets. */
     public void updateWidgets() {
         try {
             if (DEBUG) Log.d(TAG, "updateWidgets called");
-            int[] widgetIds = mAppWidgetManager.getAppWidgetIds(
+            int[] widgetIds = mAppWidgetService.getAppWidgetIds(
                     new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
             );
 
@@ -80,9 +91,16 @@
             }
 
             if (DEBUG) Log.d(TAG, "updating " + widgetIds.length + " widgets");
-            mAppWidgetManager
-                    .notifyAppWidgetViewDataChanged(mContext.getOpPackageName(), widgetIds,
-                            R.id.widget_list_view);
+            boolean showSingleConversation = Settings.Global.getInt(mContext.getContentResolver(),
+                    Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
+            if (showSingleConversation) {
+                PeopleSpaceUtils.updateSingleConversationWidgets(mContext, widgetIds,
+                        mAppWidgetManager, mNotificationManager);
+            } else {
+                mAppWidgetService
+                        .notifyAppWidgetViewDataChanged(mContext.getOpPackageName(), widgetIds,
+                                R.id.widget_list_view);
+            }
         } catch (Exception e) {
             Log.e(TAG, "Exception: " + e);
         }
@@ -125,7 +143,8 @@
 
         @Override
         public void onNotificationRankingUpdate(
-                NotificationListenerService.RankingMap rankingMap) { }
+                NotificationListenerService.RankingMap rankingMap) {
+        }
 
         @Override
         public void onNotificationsInitialized() {
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
index 9f84514..1ee9e0e 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
@@ -16,11 +16,14 @@
 
 package com.android.systemui.people.widget;
 
+import android.app.INotificationManager;
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProvider;
 import android.content.Context;
 import android.content.Intent;
+import android.os.ServiceManager;
+import android.provider.Settings;
 import android.util.Log;
 import android.widget.RemoteViews;
 
@@ -41,6 +44,14 @@
         super.onUpdate(context, appWidgetManager, appWidgetIds);
 
         if (DEBUG) Log.d(TAG, "onUpdate called");
+        boolean showSingleConversation = Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
+        if (showSingleConversation) {
+            PeopleSpaceUtils.updateSingleConversationWidgets(context, appWidgetIds,
+                    appWidgetManager, INotificationManager.Stub.asInterface(
+                            ServiceManager.getService(Context.NOTIFICATION_SERVICE)));
+            return;
+        }
         // Perform this loop procedure for each App Widget that belongs to this provider
         for (int appWidgetId : appWidgetIds) {
             RemoteViews views =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index 5afe526..3866382 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -143,8 +143,6 @@
     }
 
     public void showDeviceMonitoringDialog() {
-        mHost.collapsePanels();
-        // TODO: Delay dialog creation until after panels are collapsed.
         createDialog();
     }
 
@@ -291,6 +289,7 @@
         if (which == DialogInterface.BUTTON_NEGATIVE) {
             final Intent intent = new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS);
             mDialog.dismiss();
+            // This dismisses the shade on opening the activity
             mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
         }
     }
@@ -605,6 +604,7 @@
         public void onClick(View widget) {
             final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
             mDialog.dismiss();
+            // This dismisses the shade on opening the activity
             mActivityStarter.postStartActivityDismissingKeyguard(intent, 0);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 3765e5a..5259aa9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -117,6 +117,8 @@
     private boolean mPowerPluggedIn;
     private boolean mPowerPluggedInWired;
     private boolean mPowerCharged;
+    private boolean mBatteryOverheated;
+    private boolean mEnableBatteryDefender;
     private int mChargingSpeed;
     private int mChargingWattage;
     private int mBatteryLevel;
@@ -410,7 +412,7 @@
             } else if (!TextUtils.isEmpty(mAlignmentIndication)) {
                 mTextView.switchIndication(mAlignmentIndication);
                 mTextView.setTextColor(mContext.getColor(R.color.misalignment_text_color));
-            } else if (mPowerPluggedIn) {
+            } else if (mPowerPluggedIn || mEnableBatteryDefender) {
                 String indication = computePowerIndication();
                 if (animate) {
                     animateText(mTextView, indication);
@@ -430,7 +432,7 @@
         String trustManagedIndication = getTrustManagedIndication();
 
         String powerIndication = null;
-        if (mPowerPluggedIn) {
+        if (mPowerPluggedIn || mEnableBatteryDefender) {
             powerIndication = computePowerIndication();
         }
 
@@ -465,7 +467,7 @@
             mTextView.switchIndication(mAlignmentIndication);
             isError = true;
             hideIndication = !mBatteryPresent;
-        } else if (mPowerPluggedIn) {
+        } else if (mPowerPluggedIn || mEnableBatteryDefender) {
             if (DEBUG_CHARGING_SPEED) {
                 powerIndication += ",  " + (mChargingWattage / 1000) + " mW";
             }
@@ -545,8 +547,14 @@
             return mContext.getResources().getString(R.string.keyguard_charged);
         }
 
-        final boolean hasChargingTime = mChargingTimeRemaining > 0;
         int chargingId;
+        String percentage = NumberFormat.getPercentInstance().format(mBatteryLevel / 100f);
+        if (mBatteryOverheated) {
+            chargingId = R.string.keyguard_plugged_in_charging_limited;
+            return mContext.getResources().getString(chargingId, percentage);
+        }
+
+        final boolean hasChargingTime = mChargingTimeRemaining > 0;
         if (mPowerPluggedInWired) {
             switch (mChargingSpeed) {
                 case BatteryStatus.CHARGING_FAST:
@@ -571,8 +579,6 @@
                     : R.string.keyguard_plugged_in_wireless;
         }
 
-        String percentage = NumberFormat.getPercentInstance()
-                .format(mBatteryLevel / 100f);
         if (hasChargingTime) {
             String chargingTimeFormatted = Formatter.formatShortElapsedTimeRoundingUpToMinutes(
                     mContext, mChargingTimeRemaining);
@@ -692,6 +698,8 @@
             mChargingSpeed = status.getChargingSpeed(mContext);
             mBatteryLevel = status.level;
             mBatteryPresent = status.present;
+            mBatteryOverheated = status.isOverheated();
+            mEnableBatteryDefender = mBatteryOverheated && status.isPluggedIn();
             try {
                 mChargingTimeRemaining = mPowerPluggedIn
                         ? mBatteryInfo.computeChargeTimeRemaining() : -1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 3c48302..7eb921b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -335,7 +335,7 @@
         }
         NotificationEntry visibleEntry = getEntryManager().getActiveNotificationUnfiltered(key);
         return isLockscreenPublicMode(mCurrentUserId) && visibleEntry != null
-                && visibleEntry.getRanking().getVisibilityOverride() == VISIBILITY_SECRET;
+                && visibleEntry.getRanking().getLockscreenVisibilityOverride() == VISIBILITY_SECRET;
     }
 
     public boolean shouldShowOnKeyguard(NotificationEntry entry) {
@@ -513,7 +513,8 @@
         }
         NotificationEntry entry = getEntryManager().getActiveNotificationUnfiltered(key);
         return entry != null
-                && entry.getRanking().getVisibilityOverride() == Notification.VISIBILITY_PRIVATE;
+                && entry.getRanking().getLockscreenVisibilityOverride() 
+                == Notification.VISIBILITY_PRIVATE;
     }
 
     private void updateCurrentProfilesCache() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index b1c6f53..23d5369 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -120,7 +120,7 @@
                 // notifications to show in public mode
                 if (mLockscreenUserManager.isLockscreenPublicMode(currUserId)
                         || mLockscreenUserManager.isLockscreenPublicMode(notifUserId)) {
-                    if (entry.getRanking().getVisibilityOverride() == VISIBILITY_SECRET) {
+                    if (entry.getRanking().getLockscreenVisibilityOverride() == VISIBILITY_SECRET) {
                         return true;
                     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 37d5da2..7c5d4a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -20,6 +20,7 @@
 
 import android.app.Notification;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.util.ArraySet;
 import android.view.NotificationHeaderView;
 import android.view.NotificationTopLineView;
@@ -168,9 +169,11 @@
 
     public void applyConversationSkin() {
         if (mAppNameText != null) {
+            final ColorStateList colors = mAppNameText.getTextColors();
             mAppNameText.setTextAppearance(
                     com.android.internal.R.style
                             .TextAppearance_DeviceDefault_Notification_Conversation_AppName);
+            mAppNameText.setTextColor(colors);
             MarginLayoutParams layoutParams = (MarginLayoutParams) mAppNameText.getLayoutParams();
             layoutParams.setMarginStart(0);
         }
@@ -189,11 +192,13 @@
 
     public void clearConversationSkin() {
         if (mAppNameText != null) {
+            final ColorStateList colors = mAppNameText.getTextColors();
             final int textAppearance = Utils.getThemeAttr(
                     mAppNameText.getContext(),
                     com.android.internal.R.attr.notificationHeaderTextAppearance,
                     com.android.internal.R.style.TextAppearance_DeviceDefault_Notification_Info);
             mAppNameText.setTextAppearance(textAppearance);
+            mAppNameText.setTextColor(colors);
             MarginLayoutParams layoutParams = (MarginLayoutParams) mAppNameText.getLayoutParams();
             final int marginStart = mAppNameText.getResources().getDimensionPixelSize(
                     com.android.internal.R.dimen.notification_header_app_name_margin_start);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index ac3b6d2..885048d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -82,6 +82,9 @@
     private ExpandableNotificationRow mTrackedHeadsUpRow;
     private float mAppearFraction;
 
+    /** Tracks the state from AlertingNotificationManager#hasNotifications() */
+    private boolean mHasAlertEntries;
+
     public AmbientState(
             Context context,
             @NonNull SectionProvider sectionProvider) {
@@ -365,10 +368,21 @@
         mPanelTracking = panelTracking;
     }
 
+    public boolean hasPulsingNotifications() {
+        return mPulsing && mHasAlertEntries;
+    }
+
     public void setPulsing(boolean hasPulsing) {
         mPulsing = hasPulsing;
     }
 
+    /**
+     * @return if we're pulsing in general
+     */
+    public boolean isPulsing() {
+        return mPulsing;
+    }
+
     public boolean isPulsing(NotificationEntry entry) {
         return mPulsing && entry.isAlerting();
     }
@@ -527,4 +541,8 @@
     public float getAppearFraction() {
         return mAppearFraction;
     }
+
+    public void setHasAlertEntries(boolean hasAlertEntries) {
+        mHasAlertEntries = hasAlertEntries;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
index ba03a50..1131a65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
@@ -31,22 +31,175 @@
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 
 /**
- * Represents the priority of a notification section and tracks first and last visible children.
+ * Represents the bounds of a section of the notification shade and handles animation when the
+ * bounds change.
  */
 public class NotificationSection {
     private @PriorityBucket int mBucket;
+    private View mOwningView;
+    private Rect mBounds = new Rect();
+    private Rect mCurrentBounds = new Rect(-1, -1, -1, -1);
+    private Rect mStartAnimationRect = new Rect();
+    private Rect mEndAnimationRect = new Rect();
+    private ObjectAnimator mTopAnimator = null;
+    private ObjectAnimator mBottomAnimator = null;
     private ExpandableView mFirstVisibleChild;
     private ExpandableView mLastVisibleChild;
 
-    NotificationSection(@PriorityBucket int bucket) {
+    NotificationSection(View owningView, @PriorityBucket int bucket) {
+        mOwningView = owningView;
         mBucket = bucket;
     }
 
+    public void cancelAnimators() {
+        if (mBottomAnimator != null) {
+            mBottomAnimator.cancel();
+        }
+        if (mTopAnimator != null) {
+            mTopAnimator.cancel();
+        }
+    }
+
+    public Rect getCurrentBounds() {
+        return mCurrentBounds;
+    }
+
+    public Rect getBounds() {
+        return mBounds;
+    }
+
+    public boolean didBoundsChange() {
+        return !mCurrentBounds.equals(mBounds);
+    }
+
+    public boolean areBoundsAnimating() {
+        return mBottomAnimator != null || mTopAnimator != null;
+    }
+
     @PriorityBucket
     public int getBucket() {
         return mBucket;
     }
 
+    public void startBackgroundAnimation(boolean animateTop, boolean animateBottom) {
+        // Left and right bounds are always applied immediately.
+        mCurrentBounds.left = mBounds.left;
+        mCurrentBounds.right = mBounds.right;
+        startBottomAnimation(animateBottom);
+        startTopAnimation(animateTop);
+    }
+
+
+    @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER)
+    private void startTopAnimation(boolean animate) {
+        int previousEndValue = mEndAnimationRect.top;
+        int newEndValue = mBounds.top;
+        ObjectAnimator previousAnimator = mTopAnimator;
+        if (previousAnimator != null && previousEndValue == newEndValue) {
+            return;
+        }
+        if (!animate) {
+            // just a local update was performed
+            if (previousAnimator != null) {
+                // we need to increase all animation keyframes of the previous animator by the
+                // relative change to the end value
+                int previousStartValue = mStartAnimationRect.top;
+                PropertyValuesHolder[] values = previousAnimator.getValues();
+                values[0].setIntValues(previousStartValue, newEndValue);
+                mStartAnimationRect.top = previousStartValue;
+                mEndAnimationRect.top = newEndValue;
+                previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+                return;
+            } else {
+                // no new animation needed, let's just apply the value
+                setBackgroundTop(newEndValue);
+                return;
+            }
+        }
+        if (previousAnimator != null) {
+            previousAnimator.cancel();
+        }
+        ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundTop",
+                mCurrentBounds.top, newEndValue);
+        Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
+        animator.setInterpolator(interpolator);
+        animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+        // remove the tag when the animation is finished
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mStartAnimationRect.top = -1;
+                mEndAnimationRect.top = -1;
+                mTopAnimator = null;
+            }
+        });
+        animator.start();
+        mStartAnimationRect.top = mCurrentBounds.top;
+        mEndAnimationRect.top = newEndValue;
+        mTopAnimator = animator;
+    }
+
+    @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER)
+    private void startBottomAnimation(boolean animate) {
+        int previousStartValue = mStartAnimationRect.bottom;
+        int previousEndValue = mEndAnimationRect.bottom;
+        int newEndValue = mBounds.bottom;
+        ObjectAnimator previousAnimator = mBottomAnimator;
+        if (previousAnimator != null && previousEndValue == newEndValue) {
+            return;
+        }
+        if (!animate) {
+            // just a local update was performed
+            if (previousAnimator != null) {
+                // we need to increase all animation keyframes of the previous animator by the
+                // relative change to the end value
+                PropertyValuesHolder[] values = previousAnimator.getValues();
+                values[0].setIntValues(previousStartValue, newEndValue);
+                mStartAnimationRect.bottom = previousStartValue;
+                mEndAnimationRect.bottom = newEndValue;
+                previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+                return;
+            } else {
+                // no new animation needed, let's just apply the value
+                setBackgroundBottom(newEndValue);
+                return;
+            }
+        }
+        if (previousAnimator != null) {
+            previousAnimator.cancel();
+        }
+        ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundBottom",
+                mCurrentBounds.bottom, newEndValue);
+        Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
+        animator.setInterpolator(interpolator);
+        animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+        // remove the tag when the animation is finished
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mStartAnimationRect.bottom = -1;
+                mEndAnimationRect.bottom = -1;
+                mBottomAnimator = null;
+            }
+        });
+        animator.start();
+        mStartAnimationRect.bottom = mCurrentBounds.bottom;
+        mEndAnimationRect.bottom = newEndValue;
+        mBottomAnimator = animator;
+    }
+
+    @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW)
+    private void setBackgroundTop(int top) {
+        mCurrentBounds.top = top;
+        mOwningView.invalidate();
+    }
+
+    @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW)
+    private void setBackgroundBottom(int bottom) {
+        mCurrentBounds.bottom = bottom;
+        mOwningView.invalidate();
+    }
+
     public ExpandableView getFirstVisibleChild() {
         return mFirstVisibleChild;
     }
@@ -66,4 +219,93 @@
         mLastVisibleChild = child;
         return changed;
     }
+
+    public void resetCurrentBounds() {
+        mCurrentBounds.set(mBounds);
+    }
+
+    /**
+     * Returns true if {@code top} is equal to the top of this section (if not currently animating)
+     * or where the top of this section will be when animation completes.
+     */
+    public boolean isTargetTop(int top) {
+        return (mTopAnimator == null && mCurrentBounds.top == top)
+                || (mTopAnimator != null && mEndAnimationRect.top == top);
+    }
+
+    /**
+     * Returns true if {@code bottom} is equal to the bottom of this section (if not currently
+     * animating) or where the bottom of this section will be when animation completes.
+     */
+    public boolean isTargetBottom(int bottom) {
+        return (mBottomAnimator == null && mCurrentBounds.bottom == bottom)
+                || (mBottomAnimator != null && mEndAnimationRect.bottom == bottom);
+    }
+
+    /**
+     * Update the bounds of this section based on it's views
+     *
+     * @param minTopPosition the minimum position that the top needs to have
+     * @param minBottomPosition the minimum position that the bottom needs to have
+     * @return the position of the new bottom
+     */
+    public int updateBounds(int minTopPosition, int minBottomPosition,
+            boolean shiftBackgroundWithFirst) {
+        int top = minTopPosition;
+        int bottom = minTopPosition;
+        ExpandableView firstView = getFirstVisibleChild();
+        if (firstView != null) {
+            // Round Y up to avoid seeing the background during animation
+            int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView));
+            // TODO: look into the already animating part
+            int newTop;
+            if (isTargetTop(finalTranslationY)) {
+                // we're ending up at the same location as we are now, let's just skip the
+                // animation
+                newTop = finalTranslationY;
+            } else {
+                newTop = (int) Math.ceil(firstView.getTranslationY());
+            }
+            top = Math.max(newTop, top);
+            if (firstView.showingPulsing()) {
+                // If we're pulsing, the notification can actually go below!
+                bottom = Math.max(bottom, finalTranslationY
+                        + ExpandableViewState.getFinalActualHeight(firstView));
+                if (shiftBackgroundWithFirst) {
+                    mBounds.left += Math.max(firstView.getTranslation(), 0);
+                    mBounds.right += Math.min(firstView.getTranslation(), 0);
+                }
+            }
+        }
+        top = Math.max(minTopPosition, top);
+        ExpandableView lastView = getLastVisibleChild();
+        if (lastView != null) {
+            float finalTranslationY = ViewState.getFinalTranslationY(lastView);
+            int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
+            // Round Y down to avoid seeing the background during animation
+            int finalBottom = (int) Math.floor(
+                    finalTranslationY + finalHeight - lastView.getClipBottomAmount());
+            int newBottom;
+            if (isTargetBottom(finalBottom)) {
+                // we're ending up at the same location as we are now, lets just skip the animation
+                newBottom = finalBottom;
+            } else {
+                newBottom = (int) (lastView.getTranslationY() + lastView.getActualHeight()
+                        - lastView.getClipBottomAmount());
+                // The background can never be lower than the end of the last view
+                minBottomPosition = (int) Math.min(
+                        lastView.getTranslationY() + lastView.getActualHeight(),
+                        minBottomPosition);
+            }
+            bottom = Math.max(bottom, Math.max(newBottom, minBottomPosition));
+        }
+        bottom = Math.max(top, bottom);
+        mBounds.top = top;
+        mBounds.bottom = bottom;
+        return bottom;
+    }
+
+    public boolean needsBackground() {
+        return mFirstVisibleChild != null && mBucket != BUCKET_MEDIA_CONTROLS;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 36c5419..4f7e14b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -126,7 +126,7 @@
 
     fun createSectionsForBuckets(): Array<NotificationSection> =
             sectionsFeatureManager.getNotificationBuckets()
-                    .map { NotificationSection(it) }
+                    .map { NotificationSection(parent, it) }
                     .toTypedArray()
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 5cc17a0..4487142 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -38,9 +38,12 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.PointF;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -69,6 +72,7 @@
 import android.widget.ScrollView;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.ColorUtils;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.KeyguardSliceView;
@@ -153,6 +157,8 @@
     private ExpandHelper mExpandHelper;
     private NotificationSwipeHelper mSwipeHelper;
     private int mCurrentStackHeight = Integer.MAX_VALUE;
+    private final Paint mBackgroundPaint = new Paint();
+    private final boolean mShouldDrawNotificationBackground;
     private boolean mHighPriorityBeforeSpeedBump;
     private boolean mDismissRtl;
 
@@ -251,6 +257,7 @@
     protected FooterView mFooterView;
     protected EmptyShadeView mEmptyShadeView;
     private boolean mDismissAllInProgress;
+    private boolean mFadeNotificationsOnDismiss;
     private FooterDismissListener mFooterDismissListener;
     private boolean mFlingAfterUpEvent;
 
@@ -320,6 +327,10 @@
         }
     };
     private NotificationSection[] mSections;
+    private boolean mAnimateNextBackgroundTop;
+    private boolean mAnimateNextBackgroundBottom;
+    private boolean mAnimateNextSectionBoundsChange;
+    private int mBgColor;
     private float mDimAmount;
     private ValueAnimator mDimAnimator;
     private ArrayList<ExpandableView> mTmpSortedChildren = new ArrayList<>();
@@ -330,14 +341,25 @@
         }
     };
     private ValueAnimator.AnimatorUpdateListener mDimUpdateListener
-            = animation -> setDimAmount((Float) animation.getAnimatedValue());
+            = new ValueAnimator.AnimatorUpdateListener() {
+
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            setDimAmount((Float) animation.getAnimatedValue());
+        }
+    };
     protected ViewGroup mQsContainer;
     private boolean mContinuousShadowUpdate;
+    private boolean mContinuousBackgroundUpdate;
     private ViewTreeObserver.OnPreDrawListener mShadowUpdater
             = () -> {
                 updateViewShadows();
                 return true;
             };
+    private ViewTreeObserver.OnPreDrawListener mBackgroundUpdater = () -> {
+                updateBackground();
+                return true;
+            };
     private Comparator<ExpandableView> mViewPositionComparator = (view, otherView) -> {
         float endY = view.getTranslationY() + view.getActualHeight();
         float otherEndY = otherView.getTranslationY() + otherView.getActualHeight();
@@ -356,7 +378,7 @@
             if (mAmbientState.isHiddenAtAll()) {
                 float xProgress = mHideXInterpolator.getInterpolation(
                         (1 - mLinearHideAmount) * mBackgroundXFactor);
-                outline.setRoundRect(mOutlineAnimationRect,
+                outline.setRoundRect(mBackgroundAnimationRect,
                         MathUtils.lerp(mCornerRadius / 2.0f, mCornerRadius,
                                 xProgress));
                 outline.setAlpha(1.0f - mAmbientState.getHideAmount());
@@ -365,6 +387,7 @@
             }
         }
     };
+    private PorterDuffXfermode mSrcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
     private boolean mPulsing;
     private boolean mScrollable;
     private View mForcedScroll;
@@ -397,6 +420,7 @@
     private boolean mInHeadsUpPinnedMode;
     private boolean mHeadsUpAnimatingAway;
     private int mStatusBarState;
+    private int mCachedBackgroundColor;
     private boolean mHeadsUpGoingAwayAnimationsAllowed = true;
     private Runnable mReflingAndAnimateScroll = () -> {
         if (ANCHOR_SCROLLING) {
@@ -406,7 +430,7 @@
     };
     private int mCornerRadius;
     private int mSidePaddings;
-    private final Rect mOutlineAnimationRect = new Rect();
+    private final Rect mBackgroundAnimationRect = new Rect();
     private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
     private int mHeadsUpInset;
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
@@ -426,6 +450,7 @@
 
     private final NotificationSectionsManager mSectionsManager;
     private ForegroundServiceDungeonView mFgsSectionView;
+    private boolean mAnimateBottomOnLayout;
     private float mLastSentAppear;
     private float mLastSentExpandedHeight;
     private boolean mWillExpand;
@@ -436,6 +461,7 @@
 
     private boolean mKeyguardMediaControllorVisible;
     private NotificationEntry mTopHeadsUpEntry;
+    private long mNumHeadsUp;
     private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
 
     private final ExpandableView.OnHeightChangedListener mOnChildHeightChangedListener =
@@ -502,6 +528,7 @@
         mSections = mSectionsManager.createSectionsForBuckets();
 
         mAmbientState = new AmbientState(context, mSectionsManager);
+        mBgColor = Utils.getColorAttr(mContext, android.R.attr.colorBackground).getDefaultColor();
         int minHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
         int maxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
         mExpandHelper = new ExpandHelper(getContext(), mExpandHelperCallback,
@@ -510,9 +537,13 @@
         mExpandHelper.setScrollAdapter(mScrollAdapter);
 
         mStackScrollAlgorithm = createStackScrollAlgorithm(context);
+        mShouldDrawNotificationBackground =
+                res.getBoolean(R.bool.config_drawNotificationBackground);
         setOutlineProvider(mOutlineProvider);
 
-        setWillNotDraw(!DEBUG);
+        boolean willDraw = mShouldDrawNotificationBackground || DEBUG;
+        setWillNotDraw(!willDraw);
+        mBackgroundPaint.setAntiAlias(true);
         if (DEBUG) {
             mDebugPaint = new Paint();
             mDebugPaint.setColor(0xffff0000);
@@ -557,7 +588,7 @@
      * @return the height at which we will wake up when pulsing
      */
     public float getWakeUpHeight() {
-        ExpandableView firstChild = getFirstExpandableView();
+        ExpandableView firstChild = getFirstChildWithBackground();
         if (firstChild != null) {
             if (mKeyguardBypassEnabledProvider.getBypassEnabled()) {
                 return firstChild.getHeadsUpHeightWithoutHeader();
@@ -608,11 +639,22 @@
     }
 
     void updateBgColor() {
+        mBgColor = Utils.getColorAttr(mContext, android.R.attr.colorBackground).getDefaultColor();
+        updateBackgroundDimming();
         mShelf.onUiModeChanged();
     }
 
     @ShadeViewRefactor(RefactorComponent.DECORATOR)
     protected void onDraw(Canvas canvas) {
+        if (mShouldDrawNotificationBackground
+                && (mSections[0].getCurrentBounds().top
+                < mSections[mSections.length - 1].getCurrentBounds().bottom
+                || mAmbientState.isDozing())) {
+            drawBackground(canvas);
+        } else if (mInHeadsUpPinnedMode || mHeadsUpAnimatingAway) {
+            drawHeadsUpBackground(canvas);
+        }
+
         if (DEBUG) {
             int y = mTopPadding;
             canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
@@ -647,6 +689,160 @@
         }
     }
 
+    @ShadeViewRefactor(RefactorComponent.DECORATOR)
+    private void drawBackground(Canvas canvas) {
+        int lockScreenLeft = mSidePaddings;
+        int lockScreenRight = getWidth() - mSidePaddings;
+        int lockScreenTop = mSections[0].getCurrentBounds().top;
+        int lockScreenBottom = mSections[mSections.length - 1].getCurrentBounds().bottom;
+        int hiddenLeft = getWidth() / 2;
+        int hiddenTop = mTopPadding;
+
+        float yProgress = 1 - mInterpolatedHideAmount;
+        float xProgress = mHideXInterpolator.getInterpolation(
+                (1 - mLinearHideAmount) * mBackgroundXFactor);
+
+        int left = (int) MathUtils.lerp(hiddenLeft, lockScreenLeft, xProgress);
+        int right = (int) MathUtils.lerp(hiddenLeft, lockScreenRight, xProgress);
+        int top = (int) MathUtils.lerp(hiddenTop, lockScreenTop, yProgress);
+        int bottom = (int) MathUtils.lerp(hiddenTop, lockScreenBottom, yProgress);
+        mBackgroundAnimationRect.set(
+                left,
+                top,
+                right,
+                bottom);
+
+        int backgroundTopAnimationOffset = top - lockScreenTop;
+        // TODO(kprevas): this may not be necessary any more since we don't display the shelf in AOD
+        boolean anySectionHasVisibleChild = false;
+        for (NotificationSection section : mSections) {
+            if (section.needsBackground()) {
+                anySectionHasVisibleChild = true;
+                break;
+            }
+        }
+        boolean shouldDrawBackground;
+        if (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard()) {
+            shouldDrawBackground = isPulseExpanding();
+        } else {
+            shouldDrawBackground = !mAmbientState.isDozing() || anySectionHasVisibleChild;
+        }
+        if (shouldDrawBackground) {
+            drawBackgroundRects(canvas, left, right, top, backgroundTopAnimationOffset);
+        }
+
+        updateClipping();
+    }
+
+    /**
+     * Draws round rects for each background section.
+     *
+     * We want to draw a round rect for each background section as defined by {@link #mSections}.
+     * However, if two sections are directly adjacent with no gap between them (e.g. on the
+     * lockscreen where the shelf can appear directly below the high priority section, or while
+     * scrolling the shade so that the top of the shelf is right at the bottom of the high priority
+     * section), we don't want to round the adjacent corners.
+     *
+     * Since {@link Canvas} doesn't provide a way to draw a half-rounded rect, this means that we
+     * need to coalesce the backgrounds for adjacent sections and draw them as a single round rect.
+     * This method tracks the top of each rect we need to draw, then iterates through the visible
+     * sections.  If a section is not adjacent to the previous section, we draw the previous rect
+     * behind the sections we've accumulated up to that point, then start a new rect at the top of
+     * the current section.  When we're done iterating we will always have one rect left to draw.
+     */
+    private void drawBackgroundRects(Canvas canvas, int left, int right, int top,
+            int animationYOffset) {
+        int backgroundRectTop = top;
+        int lastSectionBottom =
+                mSections[0].getCurrentBounds().bottom + animationYOffset;
+        int currentLeft = left;
+        int currentRight = right;
+        boolean first = true;
+        for (NotificationSection section : mSections) {
+            if (!section.needsBackground()) {
+                continue;
+            }
+            int sectionTop = section.getCurrentBounds().top + animationYOffset;
+            int ownLeft = Math.min(Math.max(left, section.getCurrentBounds().left), right);
+            int ownRight = Math.max(Math.min(right, section.getCurrentBounds().right), ownLeft);
+            // If sections are directly adjacent to each other, we don't want to draw them
+            // as separate roundrects, as the rounded corners right next to each other look
+            // bad.
+            if (sectionTop - lastSectionBottom > DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX
+                    || ((currentLeft != ownLeft || currentRight != ownRight) && !first)) {
+                canvas.drawRoundRect(currentLeft,
+                        backgroundRectTop,
+                        currentRight,
+                        lastSectionBottom,
+                        mCornerRadius, mCornerRadius, mBackgroundPaint);
+                backgroundRectTop = sectionTop;
+            }
+            currentLeft = ownLeft;
+            currentRight = ownRight;
+            lastSectionBottom =
+                    section.getCurrentBounds().bottom + animationYOffset;
+            first = false;
+        }
+        canvas.drawRoundRect(currentLeft,
+                backgroundRectTop,
+                currentRight,
+                lastSectionBottom,
+                mCornerRadius, mCornerRadius, mBackgroundPaint);
+    }
+
+    private void drawHeadsUpBackground(Canvas canvas) {
+        int left = mSidePaddings;
+        int right = getWidth() - mSidePaddings;
+
+        float top = getHeight();
+        float bottom = 0;
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View child = getChildAt(i);
+            if (child.getVisibility() != View.GONE
+                    && child instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+                if ((row.isPinned() || row.isHeadsUpAnimatingAway()) && row.getTranslation() < 0
+                        && row.getProvider().shouldShowGutsOnSnapOpen()) {
+                    top = Math.min(top, row.getTranslationY());
+                    bottom = Math.max(bottom, row.getTranslationY() + row.getActualHeight());
+                }
+            }
+        }
+
+        if (top < bottom) {
+            canvas.drawRoundRect(
+                    left, top, right, bottom,
+                    mCornerRadius, mCornerRadius, mBackgroundPaint);
+        }
+    }
+
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    void updateBackgroundDimming() {
+        // No need to update the background color if it's not being drawn.
+        if (!mShouldDrawNotificationBackground) {
+            return;
+        }
+        final boolean newFlowHideShelf = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.SHOW_NEW_NOTIF_DISMISS, 1 /* on by default */) == 1;
+        if (newFlowHideShelf) {
+            mBackgroundPaint.setColor(Color.TRANSPARENT);
+            invalidate();
+            return;
+        }
+        // Interpolate between semi-transparent notification panel background color
+        // and white AOD separator.
+        float colorInterpolation = MathUtils.smoothStep(0.4f /* start */, 1f /* end */,
+                mLinearHideAmount);
+        int color = ColorUtils.blendARGB(mBgColor, Color.WHITE, colorInterpolation);
+
+        if (mCachedBackgroundColor != color) {
+            mCachedBackgroundColor = color;
+            mBackgroundPaint.setColor(color);
+            invalidate();
+        }
+    }
+
     private void reinitView() {
         initView(getContext(), mKeyguardBypassEnabledProvider, mSwipeHelper);
     }
@@ -781,7 +977,7 @@
         updateContentHeight();
         clampScrollPosition();
         requestChildrenUpdate();
-        updateFirstAndLastExpandableView();
+        updateFirstAndLastBackgroundViews();
         updateAlgorithmLayoutMinHeight();
         updateOwnTranslationZ();
     }
@@ -852,6 +1048,9 @@
     private void onPreDrawDuringAnimation() {
         mShelf.updateAppearance();
         updateClippingToTopRoundedCorner();
+        if (!mNeedsAnimation && !mChildrenUpdateRequested) {
+            updateBackground();
+        }
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -2168,6 +2367,131 @@
         }
     }
 
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    private void updateBackground() {
+        // No need to update the background color if it's not being drawn.
+        if (!mShouldDrawNotificationBackground) {
+            return;
+        }
+
+        updateBackgroundBounds();
+        if (didSectionBoundsChange()) {
+            boolean animate = mAnimateNextSectionBoundsChange || mAnimateNextBackgroundTop
+                    || mAnimateNextBackgroundBottom || areSectionBoundsAnimating();
+            if (!isExpanded()) {
+                abortBackgroundAnimators();
+                animate = false;
+            }
+            if (animate) {
+                startBackgroundAnimation();
+            } else {
+                for (NotificationSection section : mSections) {
+                    section.resetCurrentBounds();
+                }
+                invalidate();
+            }
+        } else {
+            abortBackgroundAnimators();
+        }
+        mAnimateNextBackgroundTop = false;
+        mAnimateNextBackgroundBottom = false;
+        mAnimateNextSectionBoundsChange = false;
+    }
+
+    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
+    private void abortBackgroundAnimators() {
+        for (NotificationSection section : mSections) {
+            section.cancelAnimators();
+        }
+    }
+
+    private boolean didSectionBoundsChange() {
+        for (NotificationSection section : mSections) {
+            if (section.didBoundsChange()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
+    private boolean areSectionBoundsAnimating() {
+        for (NotificationSection section : mSections) {
+            if (section.areBoundsAnimating()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
+    private void startBackgroundAnimation() {
+        // TODO(kprevas): do we still need separate fields for top/bottom?
+        // or can each section manage its own animation state?
+        NotificationSection firstVisibleSection = getFirstVisibleSection();
+        NotificationSection lastVisibleSection = getLastVisibleSection();
+        for (NotificationSection section : mSections) {
+            section.startBackgroundAnimation(
+                    section == firstVisibleSection
+                            ? mAnimateNextBackgroundTop
+                            : mAnimateNextSectionBoundsChange,
+                    section == lastVisibleSection
+                            ? mAnimateNextBackgroundBottom
+                            : mAnimateNextSectionBoundsChange);
+        }
+    }
+
+    /**
+     * Update the background bounds to the new desired bounds
+     */
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    private void updateBackgroundBounds() {
+        int left = mSidePaddings;
+        int right = getWidth() - mSidePaddings;
+        for (NotificationSection section : mSections) {
+            section.getBounds().left = left;
+            section.getBounds().right = right;
+        }
+
+        if (!mIsExpanded) {
+            for (NotificationSection section : mSections) {
+                section.getBounds().top = 0;
+                section.getBounds().bottom = 0;
+            }
+            return;
+        }
+        int minTopPosition;
+        NotificationSection lastSection = getLastVisibleSection();
+        boolean onKeyguard = mStatusBarState == StatusBarState.KEYGUARD;
+        if (!onKeyguard) {
+            minTopPosition = (int) (mTopPadding + mStackTranslation);
+        } else if (lastSection == null) {
+            minTopPosition = mTopPadding;
+        } else {
+            // The first sections could be empty while there could still be elements in later
+            // sections. The position of these first few sections is determined by the position of
+            // the first visible section.
+            NotificationSection firstVisibleSection = getFirstVisibleSection();
+            firstVisibleSection.updateBounds(0 /* minTopPosition*/, 0 /* minBottomPosition */,
+                    false /* shiftPulsingWithFirst */);
+            minTopPosition = firstVisibleSection.getBounds().top;
+        }
+        boolean shiftPulsingWithFirst = mNumHeadsUp <= 1
+                && (mAmbientState.isDozing()
+                        || (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard));
+        for (NotificationSection section : mSections) {
+            int minBottomPosition = minTopPosition;
+            if (section == lastSection) {
+                // We need to make sure the section goes all the way to the shelf
+                minBottomPosition = (int) (ViewState.getFinalTranslationY(mShelf)
+                        + mShelf.getIntrinsicHeight());
+            }
+            minTopPosition = section.updateBounds(minTopPosition, minBottomPosition,
+                    shiftPulsingWithFirst);
+            shiftPulsingWithFirst = false;
+        }
+    }
+
     private NotificationSection getFirstVisibleSection() {
         for (NotificationSection section : mSections) {
             if (section.getFirstVisibleChild() != null) {
@@ -2188,7 +2512,7 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
-    private ExpandableView getLastExpandableView() {
+    private ExpandableView getLastChildWithBackground() {
         int childCount = getChildCount();
         for (int i = childCount - 1; i >= 0; i--) {
             ExpandableView child = (ExpandableView) getChildAt(i);
@@ -2201,7 +2525,7 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
-    private ExpandableView getFirstExpandableView() {
+    private ExpandableView getFirstChildWithBackground() {
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             ExpandableView child = (ExpandableView) getChildAt(i);
@@ -2214,7 +2538,7 @@
     }
 
     //TODO: We shouldn't have to generate this list every time
-    private List<ExpandableView> getExpandableViewList() {
+    private List<ExpandableView> getChildrenWithBackground() {
         ArrayList<ExpandableView> children = new ArrayList<>();
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
@@ -2752,13 +3076,32 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
-    private void updateFirstAndLastExpandableView() {
-        ExpandableView lastChild = getLastExpandableView();
-        mSectionsManager.updateFirstAndLastViewsForAllSections(
-                mSections, getExpandableViewList());
+    private void updateFirstAndLastBackgroundViews() {
+        NotificationSection firstSection = getFirstVisibleSection();
+        NotificationSection lastSection = getLastVisibleSection();
+        ExpandableView previousFirstChild =
+                firstSection == null ? null : firstSection.getFirstVisibleChild();
+        ExpandableView previousLastChild =
+                lastSection == null ? null : lastSection.getLastVisibleChild();
+
+        ExpandableView firstChild = getFirstChildWithBackground();
+        ExpandableView lastChild = getLastChildWithBackground();
+        boolean sectionViewsChanged = mSectionsManager.updateFirstAndLastViewsForAllSections(
+                mSections, getChildrenWithBackground());
+
+        if (mAnimationsEnabled && mIsExpanded) {
+            mAnimateNextBackgroundTop = firstChild != previousFirstChild;
+            mAnimateNextBackgroundBottom = lastChild != previousLastChild || mAnimateBottomOnLayout;
+            mAnimateNextSectionBoundsChange = sectionViewsChanged;
+        } else {
+            mAnimateNextBackgroundTop = false;
+            mAnimateNextBackgroundBottom = false;
+            mAnimateNextSectionBoundsChange = false;
+        }
         mAmbientState.setLastVisibleBackgroundChild(lastChild);
         // TODO: Refactor SectionManager and put the RoundnessManager there.
         mController.getNoticationRoundessManager().updateRoundedChildren(mSections);
+        mAnimateBottomOnLayout = false;
         invalidate();
     }
 
@@ -2920,6 +3263,7 @@
             setAnimationRunning(true);
             mStateAnimator.startAnimationForEvents(mAnimationEvents, mGoToFullShadeDelay);
             mAnimationEvents.clear();
+            updateBackground();
             updateViewShadows();
             updateClippingToTopRoundedCorner();
         } else {
@@ -4004,6 +4348,7 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     private void setDimAmount(float dimAmount) {
         mDimAmount = dimAmount;
+        updateBackgroundDimming();
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4072,6 +4417,7 @@
         }
         runAnimationFinishedRunnables();
         setAnimationRunning(false);
+        updateBackground();
         updateViewShadows();
         updateClippingToTopRoundedCorner();
     }
@@ -4200,6 +4546,7 @@
             invalidateOutline();
         }
         updateAlgorithmHeightAndPadding();
+        updateBackgroundDimming();
         requestChildrenUpdate();
         updateOwnTranslationZ();
     }
@@ -5080,6 +5427,7 @@
      */
     public void setDozeAmount(float dozeAmount) {
         mAmbientState.setDozeAmount(dozeAmount);
+        updateContinuousBackgroundDrawing();
         requestChildrenUpdate();
     }
 
@@ -5117,6 +5465,7 @@
     }
 
     void setAnimateBottomOnLayout(boolean animateBottomOnLayout) {
+        mAnimateBottomOnLayout = animateBottomOnLayout;
     }
 
     public void setOnPulseHeightChangedListener(Runnable listener) {
@@ -5149,14 +5498,25 @@
 
     void onSwipeBegin() {
         requestDisallowInterceptTouchEvent(true);
+        updateFirstAndLastBackgroundViews();
         updateContinuousShadowDrawing();
+        updateContinuousBackgroundDrawing();
         requestChildrenUpdate();
     }
 
+    void onSwipeEnd() {
+        updateFirstAndLastBackgroundViews();
+    }
+
     void setTopHeadsUpEntry(NotificationEntry topEntry) {
         mTopHeadsUpEntry = topEntry;
     }
 
+    void setNumHeadsUp(long numHeadsUp) {
+        mNumHeadsUp = numHeadsUp;
+        mAmbientState.setHasAlertEntries(numHeadsUp > 0);
+    }
+
     public boolean getIsExpanded() {
         return mIsExpanded;
     }
@@ -5271,6 +5631,27 @@
         mSectionsManager.updateSectionBoundaries(reason);
     }
 
+    boolean isSilkDismissEnabled() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.SHOW_NEW_NOTIF_DISMISS, 1 /* enabled by default */) == 1;
+    }
+
+    void updateContinuousBackgroundDrawing() {
+        if (isSilkDismissEnabled()) {
+            return;
+        }
+        boolean continuousBackground = !mAmbientState.isFullyAwake()
+                && mSwipeHelper.isSwiping();
+        if (continuousBackground != mContinuousBackgroundUpdate) {
+            mContinuousBackgroundUpdate = continuousBackground;
+            if (continuousBackground) {
+                getViewTreeObserver().addOnPreDrawListener(mBackgroundUpdater);
+            } else {
+                getViewTreeObserver().removeOnPreDrawListener(mBackgroundUpdater);
+            }
+        }
+    }
+
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     void updateContinuousShadowDrawing() {
         boolean continuousShadowUpdate = mAnimationRunning
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 8a03309..c2d030b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -395,6 +395,7 @@
                     if (mView.getDismissAllInProgress()) {
                         return;
                     }
+                    mView.onSwipeEnd();
                     if (view instanceof ExpandableNotificationRow) {
                         ExpandableNotificationRow row = (ExpandableNotificationRow) view;
                         if (row.isHeadsUp()) {
@@ -454,6 +455,7 @@
 
                 @Override
                 public void onChildSnappedBack(View animView, float targetLeft) {
+                    mView.onSwipeEnd();
                     if (animView instanceof ExpandableNotificationRow) {
                         ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
                         if (row.isPinned() && !canChildBeDismissed(row)
@@ -517,7 +519,9 @@
 
                 @Override
                 public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
+                    long numEntries = mHeadsUpManager.getAllEntries().count();
                     NotificationEntry topEntry = mHeadsUpManager.getTopEntry();
+                    mView.setNumHeadsUp(numEntries);
                     mView.setTopHeadsUpEntry(topEntry);
                     mNotificationRoundnessManager.updateView(entry.getRow(), false /* animate */);
                 }
@@ -661,6 +665,8 @@
         mHeadsUpManager.setAnimationStateHandler(mView::setHeadsUpGoingAwayAnimationsAllowed);
         mDynamicPrivacyController.addListener(mDynamicPrivacyControllerListener);
 
+        mScrimController.setScrimBehindChangeRunnable(mView::updateBackgroundDimming);
+
         mLockscreenUserManager.addUserChangedListener(mLockscreenUserChangeListener);
 
         mFadeNotificationsOnDismiss =  // TODO: this should probably be injected directly
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 9854f54..4ca9c5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -289,6 +289,8 @@
                     SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN);
             mDismissCallbackRegistry.notifyDismissCancelled();
         }
+        mExpansion = EXPANSION_HIDDEN;
+        dispatchExpansionChanged();
         mIsScrimmed = false;
         mFalsingCollector.onBouncerHidden();
         mCallback.onBouncerVisiblityChanged(false /* shown */);
@@ -377,6 +379,7 @@
      */
     public void setExpansion(float fraction) {
         float oldExpansion = mExpansion;
+        boolean expansionChanged = mExpansion != fraction;
         mExpansion = fraction;
         if (mKeyguardViewController != null && !mIsAnimatingAway) {
             mKeyguardViewController.setExpansion(fraction);
@@ -394,6 +397,10 @@
                 mKeyguardViewController.onStartingToHide();
             }
         }
+
+        if (expansionChanged) {
+            dispatchExpansionChanged();
+        }
     }
 
     public boolean willDismissWithAction() {
@@ -518,6 +525,12 @@
         }
     }
 
+    private void dispatchExpansionChanged() {
+        for (BouncerExpansionCallback callback : mExpansionCallbacks) {
+            callback.onExpansionChanged(mExpansion);
+        }
+    }
+
     public void dump(PrintWriter pw) {
         pw.println("KeyguardBouncer");
         pw.println("  isShowing(): " + isShowing());
@@ -534,6 +547,12 @@
         void onStartingToHide();
         void onStartingToShow();
         void onFullyHidden();
+
+        /**
+         * From 0f {@link KeyguardBouncer#EXPANSION_VISIBLE} when fully visible
+         * to 1f {@link KeyguardBouncer#EXPANSION_HIDDEN} when fully hidden
+         */
+        default void onExpansionChanged(float bouncerHideAmount) {}
     }
 
     /** Create a {@link KeyguardBouncer} once a container and bouncer callback are available. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 1a2d1cf..b9e8d74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -116,6 +116,11 @@
      */
     private float mDarkAmount;
 
+    /**
+     * How visible the quick settings panel is.
+     */
+    private float mQsExpansion;
+
     private float mEmptyDragAmount;
 
     /**
@@ -159,7 +164,8 @@
     public void setup(int statusBarMinHeight, int maxShadeBottom, int notificationStackHeight,
             float panelExpansion, int parentHeight, int keyguardStatusHeight, int clockPreferredY,
             boolean hasCustomClock, boolean hasVisibleNotifs, float dark, float emptyDragAmount,
-            boolean bypassEnabled, int unlockedStackScrollerPadding, boolean udfpsEnrolled) {
+            boolean bypassEnabled, int unlockedStackScrollerPadding, boolean udfpsEnrolled,
+            float qsExpansion) {
         mMinTopMargin = statusBarMinHeight + (udfpsEnrolled ? mContainerTopPaddingWithoutLockIcon :
                 mContainerTopPaddingWithLockIcon);
         mMaxShadeBottom = maxShadeBottom;
@@ -174,6 +180,7 @@
         mEmptyDragAmount = emptyDragAmount;
         mBypassEnabled = bypassEnabled;
         mUnlockedStackScrollerPadding = unlockedStackScrollerPadding;
+        mQsExpansion = qsExpansion;
     }
 
     public void run(Result result) {
@@ -274,6 +281,7 @@
      */
     private float getClockAlpha(int y) {
         float alphaKeyguard = Math.max(0, y / Math.max(1f, getClockY(1f)));
+        alphaKeyguard *= (1f - mQsExpansion);
         alphaKeyguard = Interpolators.ACCELERATE.getInterpolation(alphaKeyguard);
         return MathUtils.lerp(alphaKeyguard, 1f, mDarkAmount);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
index 0e7e2fd..547a370 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
@@ -23,6 +23,7 @@
 import static com.android.systemui.statusbar.phone.LockIcon.STATE_LOCK_OPEN;
 import static com.android.systemui.statusbar.phone.LockIcon.STATE_SCANNING_FACE;
 
+import android.animation.ArgbEvaluator;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -38,6 +39,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -84,7 +86,7 @@
     private boolean mDocked;
     private boolean mWakeAndUnlockRunning;
     private boolean mShowingLaunchAffordance;
-    private boolean mBouncerShowing;
+    private float mBouncerHiddenAmount = KeyguardBouncer.EXPANSION_HIDDEN;
     private boolean mBouncerShowingScrimmed;
     private boolean mFingerprintUnlock;
     private int mStatusBarState = StatusBarState.SHADE;
@@ -104,6 +106,8 @@
 
             mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
             mConfigurationListener.onThemeChanged();
+
+            updateColor();
             update();
         }
 
@@ -348,7 +352,6 @@
      */
     public void attach(LockIcon lockIcon) {
         mLockIcon = lockIcon;
-        updateColor();
 
         mLockIcon.setOnClickListener(this::handleClick);
         mLockIcon.setOnLongClickListener(this::handleLongClick);
@@ -408,20 +411,44 @@
 
     /** Sets whether the bouncer is showing. */
     public void setBouncerShowingScrimmed(boolean showing, boolean scrimmed) {
-        mBouncerShowing = showing;
         mBouncerShowingScrimmed = scrimmed;
         update();
     }
 
+    /**
+     * Sets how hidden the bouncer is, where 0f is fully visible and 1f is fully hidden
+     * See {@link KeyguardBouncer#EXPANSION_VISIBLE} and {@link KeyguardBouncer#EXPANSION_HIDDEN}.
+     */
+    public void setBouncerHideAmount(float hideAmount) {
+        mBouncerHiddenAmount = hideAmount;
+        updateColor();
+    }
+
     private void updateColor() {
         if (mLockIcon == null) {
             return;
         }
 
-        TypedArray typedArray = mLockIcon.getContext().getTheme().obtainStyledAttributes(
-                null, new int[]{ android.R.attr.textColorPrimary }, 0, 0);
-        int iconColor = typedArray.getColor(0, Color.WHITE);
-        typedArray.recycle();
+        int iconColor = -1;
+        if (mBouncerHiddenAmount == KeyguardBouncer.EXPANSION_VISIBLE) {
+            TypedArray typedArray = mLockIcon.getContext().getTheme().obtainStyledAttributes(
+                    null, new int[]{ android.R.attr.textColorPrimary }, 0, 0);
+            iconColor = typedArray.getColor(0, Color.WHITE);
+            typedArray.recycle();
+        } else if (mBouncerHiddenAmount == KeyguardBouncer.EXPANSION_HIDDEN) {
+            iconColor = Utils.getColorAttrDefaultColor(
+                    mLockIcon.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
+        } else {
+            // bouncer is transitioning
+            TypedArray typedArray = mLockIcon.getContext().getTheme().obtainStyledAttributes(
+                    null, new int[]{ android.R.attr.textColorPrimary }, 0, 0);
+            int bouncerIconColor = typedArray.getColor(0, Color.WHITE);
+            typedArray.recycle();
+            int keyguardIconColor = Utils.getColorAttrDefaultColor(
+                    mLockIcon.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
+            iconColor = (int) new ArgbEvaluator().evaluate(
+                    mBouncerHiddenAmount, bouncerIconColor, keyguardIconColor);
+        }
         mLockIcon.updateColor(iconColor);
     }
 
@@ -520,10 +547,7 @@
             return changed;
         }
         boolean onAodOrDocked = mStatusBarStateController.isDozing() || mDocked;
-        boolean onKeyguardWithoutBouncer = mStatusBarState == StatusBarState.KEYGUARD
-                && !mBouncerShowing;
-        boolean invisible = onAodOrDocked || mWakeAndUnlockRunning || mShowingLaunchAffordance
-                || onKeyguardWithoutBouncer;
+        boolean invisible = onAodOrDocked || mWakeAndUnlockRunning || mShowingLaunchAffordance;
         boolean fingerprintOrBypass = mFingerprintUnlock
                 || mKeyguardBypassController.getBypassEnabled();
         if (fingerprintOrBypass && !mBouncerShowingScrimmed) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 84eacdc..01a7292 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -292,6 +292,7 @@
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
     private final QSDetailDisplayer mQSDetailDisplayer;
+    private final ScrimController mScrimController;
     // Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow card.
     // If there are exactly 1 + mMaxKeyguardNotifications, then still shows all notifications
     private final int mMaxKeyguardNotifications;
@@ -549,6 +550,7 @@
             NotificationIconAreaController notificationIconAreaController,
             AuthController authController,
             QSDetailDisplayer qsDetailDisplayer,
+            ScrimController scrimController,
             MediaDataManager mediaDataManager) {
         super(view, falsingManager, dozeLog, keyguardStateController,
                 (SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
@@ -579,6 +581,7 @@
         mPulseExpansionHandler = pulseExpansionHandler;
         mDozeParameters = dozeParameters;
         mBiometricUnlockController = biometricUnlockController;
+        mScrimController = scrimController;
         mMediaDataManager = mediaDataManager;
         pulseExpansionHandler.setPulseExpandAbortListener(() -> {
             if (mQs != null) {
@@ -909,7 +912,7 @@
                     clockPreferredY, hasCustomClock(),
                     hasVisibleNotifications, mInterpolatedDarkAmount, mEmptyDragAmount,
                     bypassEnabled, getUnlockedStackScrollerPadding(),
-                    mUpdateMonitor.isUdfpsEnrolled());
+                    mUpdateMonitor.isUdfpsEnrolled(), getQsExpansionFraction());
             mClockPositionAlgorithm.run(mClockPositionResult);
             mKeyguardStatusViewController.updatePosition(
                     mClockPositionResult.clockX, mClockPositionResult.clockY,
@@ -1756,6 +1759,7 @@
         updateHeaderKeyguardAlpha();
         if (mBarState == StatusBarState.SHADE_LOCKED || mBarState == KEYGUARD) {
             updateKeyguardBottomAreaAlpha();
+            positionClockAndNotifications();
             updateBigClockAlpha();
         }
 
@@ -1782,6 +1786,7 @@
         float qsExpansionFraction = getQsExpansionFraction();
         mQs.setQsExpansion(qsExpansionFraction, getHeaderTranslation());
         mMediaHierarchyManager.setQsExpansion(qsExpansionFraction);
+        mScrimController.setQsExpansion(qsExpansionFraction);
         mNotificationStackScrollLayoutController.setQsExpansionFraction(qsExpansionFraction);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 9e7efc1..f8e361f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -125,11 +125,6 @@
      */
     public static final float BUSY_SCRIM_ALPHA = 1f;
 
-    /**
-     * Same as above, but when blur is supported.
-     */
-    public static final float BLUR_SCRIM_ALPHA = 0.80f;
-
     static final int TAG_KEY_ANIM = R.id.scrim;
     private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
     private static final int TAG_END_ALPHA = R.id.scrim_alpha_end;
@@ -161,6 +156,7 @@
 
     // Assuming the shade is expanded during initialization
     private float mExpansionFraction = 1f;
+    private float mQsExpansion;
 
     private boolean mDarkenWhileDragging;
     private boolean mExpansionAffectsAlpha = true;
@@ -206,8 +202,7 @@
             BlurUtils blurUtils, ConfigurationController configurationController) {
 
         mScrimStateListener = lightBarController::setScrimState;
-        mDefaultScrimAlpha = blurUtils.supportsBlursOnWindows()
-                ? BLUR_SCRIM_ALPHA : BUSY_SCRIM_ALPHA;
+        mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
         mBlurUtils = blurUtils;
 
         mKeyguardStateController = keyguardStateController;
@@ -464,6 +459,31 @@
 
             boolean relevantState = (mState == ScrimState.UNLOCKED
                     || mState == ScrimState.KEYGUARD
+                    || mState == ScrimState.SHADE_LOCKED
+                    || mState == ScrimState.PULSING
+                    || mState == ScrimState.BUBBLE_EXPANDED);
+            if (!(relevantState && mExpansionAffectsAlpha)) {
+                return;
+            }
+            applyAndDispatchExpansion();
+        }
+    }
+
+    /**
+     * Current state of the QuickSettings expansion when pulling it from the top.
+     *
+     * @param fraction From 0 to 1 where 0 means collapsed and 1 expanded.
+     */
+    public void setQsExpansion(float fraction) {
+        if (isNaN(fraction)) {
+            return;
+        }
+        if (mQsExpansion != fraction) {
+            mQsExpansion = fraction;
+            Log.d(TAG, "set qs fraction");
+
+            boolean relevantState = (mState == ScrimState.SHADE_LOCKED
+                    || mState == ScrimState.KEYGUARD
                     || mState == ScrimState.PULSING
                     || mState == ScrimState.BUBBLE_EXPANDED);
             if (!(relevantState && mExpansionAffectsAlpha)) {
@@ -506,7 +526,8 @@
             behindFraction = (float) Math.pow(behindFraction, 0.8f);
             mBehindAlpha = behindFraction * mDefaultScrimAlpha;
             mInFrontAlpha = 0;
-        } else if (mState == ScrimState.KEYGUARD || mState == ScrimState.PULSING) {
+        } else if (mState == ScrimState.KEYGUARD || mState == ScrimState.SHADE_LOCKED
+                || mState == ScrimState.PULSING) {
             // Either darken of make the scrim transparent when you
             // pull down the shade
             float interpolatedFract = getInterpolatedFraction();
@@ -522,6 +543,11 @@
             }
             mBehindTint = ColorUtils.blendARGB(ScrimState.BOUNCER.getBehindTint(),
                     mState.getBehindTint(), interpolatedFract);
+            if (mQsExpansion > 0) {
+                mBehindAlpha = MathUtils.lerp(mBehindAlpha, mDefaultScrimAlpha, mQsExpansion);
+                mBehindTint = ColorUtils.blendARGB(mBehindTint,
+                        ScrimState.SHADE_LOCKED.getBehindTint(), mQsExpansion);
+            }
         }
         if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha)) {
             throw new IllegalStateException("Scrim opacity is NaN for state: " + mState
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index fc91c16..994da79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -112,6 +112,15 @@
         }
     },
 
+    SHADE_LOCKED {
+        @Override
+        public void prepare(ScrimState previousState) {
+            mBehindAlpha = mDefaultScrimAlpha;
+            mBubbleAlpha = 0f;
+            mFrontAlpha = 0f;
+        }
+    },
+
     /**
      * Changing screen brightness from quick settings.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 9e872ab..9ebde53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3794,6 +3794,14 @@
     }
 
     /**
+     * Sets how hidden the bouncer is, where 0f is fully visible and 1f is fully hidden
+     * See {@link KeyguardBouncer#EXPANSION_VISIBLE} and {@link KeyguardBouncer#EXPANSION_HIDDEN}.
+     */
+    public void setBouncerHideAmount(float hideAmount) {
+        mLockscreenLockIconController.setBouncerHideAmount(hideAmount);
+    }
+
+    /**
      * Collapses the notification shade if it is tracking or expanded.
      */
     public void collapseShade() {
@@ -4091,6 +4099,8 @@
             mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
         } else if (mBrightnessMirrorVisible) {
             mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
+        } else if (mState == StatusBarState.SHADE_LOCKED) {
+            mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
         } else if (mDozeServiceHost.isPulsing()) {
             mScrimController.transitionTo(ScrimState.PULSING,
                     mDozeScrimController.getScrimCallback());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index b912614..055b78a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -130,6 +130,11 @@
             updateStates();
             updateLockIcon();
         }
+
+        @Override
+        public void onExpansionChanged(float hideAmount) {
+            mStatusBar.setBouncerHideAmount(hideAmount);
+        }
     };
     private final DockManager.DockEventListener mDockEventListener =
             new DockManager.DockEventListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index acca953..6a0ebf7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -378,8 +378,8 @@
                 // We have to post the removal to the UI thread for synchronization.
                 mMainThreadHandler.post(() -> {
                     final Runnable removeNotification = () -> {
-                        mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK);
                         mClickNotifier.onNotificationClick(entry.getKey(), nv);
+                        mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK);
                     };
                     if (mPresenter.isCollapsing()) {
                         // To avoid lags we're only performing the remove
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index adbc85b..6c5251b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -18,7 +18,6 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.Notification;
@@ -42,6 +41,7 @@
 import android.text.TextWatcher;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Pair;
 import android.view.ContentInfo;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -74,8 +74,8 @@
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.LightBarController;
 
+import java.util.Collection;
 import java.util.HashMap;
-import java.util.Map;
 import java.util.function.Consumer;
 
 /**
@@ -315,8 +315,7 @@
         mRemoteInputs = remoteInputs;
         mRemoteInput = remoteInput;
         mEditText.setHint(mRemoteInput.getLabel());
-        mEditText.mSupportedMimeTypes = (remoteInput.getAllowedDataTypes() == null) ? null
-                : remoteInput.getAllowedDataTypes().toArray(new String[0]);
+        mEditText.setSupportedMimeTypes(remoteInput.getAllowedDataTypes());
 
         mEntry.editedSuggestionInfo = editedSuggestionInfo;
         if (editedSuggestionInfo != null) {
@@ -570,12 +569,13 @@
      */
     public static class RemoteEditText extends EditText {
 
+        private final OnReceiveContentListener mOnReceiveContentListener = this::onReceiveContent;
+
         private final Drawable mBackground;
         private RemoteInputView mRemoteInputView;
         boolean mShowImeOnInputConnection;
         private LightBarController mLightBarController;
         UserHandle mUser;
-        private String[] mSupportedMimeTypes;
 
         public RemoteEditText(Context context, AttributeSet attrs) {
             super(context, attrs);
@@ -583,39 +583,14 @@
             mLightBarController = Dependency.get(LightBarController.class);
         }
 
-        @Override
-        protected void onFinishInflate() {
-            super.onFinishInflate();
-            if (mSupportedMimeTypes != null && mSupportedMimeTypes.length > 0) {
-                setOnReceiveContentListener(mSupportedMimeTypes,
-                        new OnReceiveContentListener() {
-                            @Override
-                            @Nullable
-                            public ContentInfo onReceiveContent(@NonNull View view,
-                                    @NonNull ContentInfo payload) {
-                                Map<Boolean, ContentInfo> split = payload.partition(
-                                        item -> item.getUri() != null);
-                                ContentInfo uriItems = split.get(true);
-                                ContentInfo remainingItems = split.get(false);
-                                if (uriItems != null) {
-                                    ClipData clip = uriItems.getClip();
-                                    ClipDescription description = clip.getDescription();
-                                    if (clip.getItemCount() > 1
-                                            || description.getMimeTypeCount() < 1
-                                            || remainingItems != null) {
-                                        // TODO(b/172363500): Update to loop over all the items
-                                        return payload;
-                                    }
-                                    Uri contentUri = clip.getItemAt(0).getUri();
-                                    String mimeType = description.getMimeType(0);
-                                    Intent dataIntent = mRemoteInputView
-                                            .prepareRemoteInputFromData(mimeType, contentUri);
-                                    mRemoteInputView.sendRemoteInput(dataIntent);
-                                }
-                                return remainingItems;
-                            }
-                        });
+        void setSupportedMimeTypes(@Nullable Collection<String> mimeTypes) {
+            String[] types = null;
+            OnReceiveContentListener listener = null;
+            if (mimeTypes != null && !mimeTypes.isEmpty()) {
+                types = mimeTypes.toArray(new String[0]);
+                listener = mOnReceiveContentListener;
             }
+            setOnReceiveContentListener(types, listener);
         }
 
         private void defocusIfNeeded(boolean animate) {
@@ -759,5 +734,28 @@
                 setBackground(null);
             }
         }
+
+        private ContentInfo onReceiveContent(View view, ContentInfo payload) {
+            Pair<ContentInfo, ContentInfo> split =
+                    payload.partition(item -> item.getUri() != null);
+            ContentInfo uriItems = split.first;
+            ContentInfo remainingItems = split.second;
+            if (uriItems != null) {
+                ClipData clip = uriItems.getClip();
+                ClipDescription description = clip.getDescription();
+                if (clip.getItemCount() > 1
+                        || description.getMimeTypeCount() < 1
+                        || remainingItems != null) {
+                    // TODO(b/172363500): Update to loop over all the items
+                    return payload;
+                }
+                Uri contentUri = clip.getItemAt(0).getUri();
+                String mimeType = description.getMimeType(0);
+                Intent dataIntent =
+                        mRemoteInputView.prepareRemoteInputFromData(mimeType, contentUri);
+                mRemoteInputView.sendRemoteInput(dataIntent);
+            }
+            return remainingItems;
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
index 286b7c0..21d700e 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbConfirmActivity.java
@@ -35,6 +35,8 @@
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.TextView;
@@ -58,6 +60,9 @@
 
     @Override
     public void onCreate(Bundle icicle) {
+        getWindow().addSystemFlags(
+                WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+
         super.onCreate(icicle);
 
         Intent intent = getIntent();
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index be5ed0c..71a883d 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -16,14 +16,19 @@
 
 package com.android.systemui.wmshell;
 
+import static android.os.Process.THREAD_PRIORITY_DISPLAY;
+
+import android.animation.AnimationHandler;
 import android.app.IActivityManager;
 import android.content.Context;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.view.IWindowManager;
 import android.view.WindowManager;
 
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.dagger.WMSingleton;
@@ -36,7 +41,6 @@
 import com.android.wm.shell.apppairs.AppPairs;
 import com.android.wm.shell.bubbles.BubbleController;
 import com.android.wm.shell.bubbles.Bubbles;
-import com.android.wm.shell.common.AnimationThread;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
 import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -46,6 +50,9 @@
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.annotations.ChoreographerSfVsync;
+import com.android.wm.shell.common.annotations.ShellAnimationThread;
+import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
@@ -62,6 +69,7 @@
 import com.android.wm.shell.splitscreen.SplitScreen;
 
 import java.util.Optional;
+import java.util.concurrent.TimeUnit;
 
 import dagger.BindsOptionalOf;
 import dagger.Module;
@@ -74,6 +82,89 @@
 @Module
 public abstract class WMShellBaseModule {
 
+    private static final boolean ENABLE_SHELL_MAIN_THREAD = false;
+
+    //
+    // Shell Concurrency - Components used for managing threading in the Shell and SysUI
+    //
+
+    /**
+     * Provide a SysUI main-thread Executor.
+     */
+    @WMSingleton
+    @Provides
+    @Main
+    public static ShellExecutor provideSysUIMainExecutor(@Main Handler sysuiMainHandler) {
+        return new HandlerExecutor(sysuiMainHandler);
+    }
+
+    /**
+     * Shell main-thread Handler, don't use this unless really necessary (ie. need to dedupe
+     * multiple types of messages, etc.)
+     */
+    @WMSingleton
+    @Provides
+    @ShellMainThread
+    public static Handler provideShellMainHandler(@Main Handler sysuiMainHandler) {
+        if (ENABLE_SHELL_MAIN_THREAD) {
+             HandlerThread shellMainThread = new HandlerThread("wmshell.main");
+             shellMainThread.start();
+             return shellMainThread.getThreadHandler();
+        }
+        return sysuiMainHandler;
+    }
+
+    /**
+     * Provide a Shell main-thread Executor.
+     */
+    @WMSingleton
+    @Provides
+    @ShellMainThread
+    public static ShellExecutor provideShellMainExecutor(@ShellMainThread Handler shellMainHandler,
+            @Main ShellExecutor sysuiMainExecutor) {
+        if (ENABLE_SHELL_MAIN_THREAD) {
+            return new HandlerExecutor(shellMainHandler);
+        }
+        return sysuiMainExecutor;
+    }
+
+    /**
+     * Provide a Shell animation-thread Executor.
+     */
+    @WMSingleton
+    @Provides
+    @ShellAnimationThread
+    public static ShellExecutor provideShellAnimationExecutor() {
+         HandlerThread shellAnimationThread = new HandlerThread("wmshell.anim",
+                 THREAD_PRIORITY_DISPLAY);
+         shellAnimationThread.start();
+         return new HandlerExecutor(shellAnimationThread.getThreadHandler());
+    }
+
+    /**
+     * Provide a Shell animation-thread AnimationHandler.  The AnimationHandler can be set on
+     * {@link android.animation.ValueAnimator}s and will ensure that the animation will run on
+     * the Shell animation-thread.
+     */
+    @WMSingleton
+    @Provides
+    @ChoreographerSfVsync
+    public static AnimationHandler provideShellAnimationExecutorSfVsyncAnimationHandler(
+            @ShellAnimationThread ShellExecutor shellAnimationExecutor) {
+        try {
+            AnimationHandler handler = new AnimationHandler();
+            shellAnimationExecutor.executeBlocking(() -> {
+                // This is called on the animation thread since it calls
+                // Choreographer.getSfInstance() which returns a thread-local Choreographer instance
+                // that uses the SF vsync
+                handler.setProvider(new SfVsyncFrameCallbackProvider());
+            }, 1, TimeUnit.SECONDS);
+            return handler;
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Failed to initialize SfVsync animation handler in 1s", e);
+        }
+    }
+
     @WMSingleton
     @Provides
     static ShellInit provideShellInit(DisplayImeController displayImeController,
@@ -139,8 +230,9 @@
 
     @WMSingleton
     @Provides
-    static WindowManagerShellWrapper provideWindowManagerShellWrapper() {
-        return new WindowManagerShellWrapper();
+    static WindowManagerShellWrapper provideWindowManagerShellWrapper(
+            @ShellMainThread ShellExecutor shellMainExecutor) {
+        return new WindowManagerShellWrapper(shellMainExecutor);
     }
 
     @WMSingleton
@@ -187,9 +279,11 @@
     @WMSingleton
     @Provides
     static ShellTaskOrganizer provideShellTaskOrganizer(SyncTransactionQueue syncQueue,
-            ShellExecutor mainExecutor, TransactionPool transactionPool, Context context) {
-        return new ShellTaskOrganizer(syncQueue, transactionPool, mainExecutor,
-                AnimationThread.instance().getExecutor(), context);
+            @ShellMainThread ShellExecutor shellMainExecutor,
+            @ShellAnimationThread ShellExecutor shellAnimationExecutor,
+            TransactionPool transactionPool, Context context) {
+        return new ShellTaskOrganizer(syncQueue, transactionPool, shellMainExecutor,
+                shellAnimationExecutor, context);
     }
 
     @WMSingleton
@@ -230,12 +324,6 @@
 
     @WMSingleton
     @Provides
-    static ShellExecutor provideMainShellExecutor(@Main Handler handler) {
-        return new HandlerExecutor(handler);
-    }
-
-    @WMSingleton
-    @Provides
     static Optional<HideDisplayCutout> provideHideDisplayCutoutController(Context context,
             DisplayController displayController) {
         return Optional.ofNullable(HideDisplayCutoutController.create(context, displayController));
@@ -262,5 +350,4 @@
     static LetterboxConfigController provideLetterboxConfigController(Context context) {
         return new LetterboxConfigController(context);
     }
-
 }
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
index 5f48c42..281b1aa 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
@@ -34,6 +34,7 @@
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.pip.PipBoundsState;
@@ -95,11 +96,12 @@
             PipBoundsState pipBoundsState, PipMediaController pipMediaController,
             PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
             PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper,
-            TaskStackListenerImpl taskStackListener, ShellExecutor mainExecutor) {
+            TaskStackListenerImpl taskStackListener,
+            @ShellMainThread ShellExecutor shellMainExecutor) {
         return Optional.ofNullable(PipController.create(context, displayController,
                 pipAppOpsListener, pipBoundsAlgorithm, pipBoundsState, pipMediaController,
                 phonePipMenuController, pipTaskOrganizer, pipTouchHandler,
-                windowManagerShellWrapper, taskStackListener, mainExecutor));
+                windowManagerShellWrapper, taskStackListener, shellMainExecutor));
     }
 
     @WMSingleton
@@ -129,9 +131,11 @@
             PipBoundsState pipBoundsState,
             PipTaskOrganizer pipTaskOrganizer,
             FloatingContentCoordinator floatingContentCoordinator,
-            PipUiEventLogger pipUiEventLogger) {
+            PipUiEventLogger pipUiEventLogger,
+            @ShellMainThread ShellExecutor shellMainExecutor) {
         return new PipTouchHandler(context, menuPhoneController, pipBoundsAlgorithm,
-                pipBoundsState, pipTaskOrganizer, floatingContentCoordinator, pipUiEventLogger);
+                pipBoundsState, pipTaskOrganizer, floatingContentCoordinator, pipUiEventLogger,
+                shellMainExecutor);
     }
 
     @WMSingleton
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index 4559113..a2eaea1 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.ContentResolver;
 import android.content.res.Resources;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -72,6 +73,8 @@
     Resources mResources;
     @Mock
     NotificationIconAreaController mNotificationIconAreaController;
+    @Mock
+    ContentResolver mContentResolver;
 
     private KeyguardClockSwitchController mController;
 
@@ -90,7 +93,8 @@
                 mColorExtractor,
                 mClockManager,
                 mKeyguardSliceViewController,
-                mNotificationIconAreaController);
+                mNotificationIconAreaController,
+                mContentResolver);
 
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
         when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index a0ae35f..1115043 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -29,20 +29,23 @@
 import static com.android.systemui.accessibility.MagnificationModeSwitch.getIconResId;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
 
 import static org.hamcrest.CoreMatchers.hasItems;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
@@ -60,15 +63,18 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class MagnificationModeSwitchTest extends SysuiTestCase {
@@ -81,11 +87,10 @@
     private AccessibilityManager mAccessibilityManager;
     @Mock
     private WindowManager mWindowManager;
-    @Mock
     private ViewPropertyAnimator mViewPropertyAnimator;
     private MagnificationModeSwitch mMagnificationModeSwitch;
-    @Captor
-    private ArgumentCaptor<View.OnTouchListener> mTouchListenerCaptor;
+    private View.OnTouchListener mTouchListener;
+    private List<MotionEvent> mMotionEvents = new ArrayList<>();
 
     @Before
     public void setUp() throws Exception {
@@ -97,9 +102,23 @@
         mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
         mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager);
         mSpyImageView = Mockito.spy(new ImageView(mContext));
-        resetMockImageViewAndAnimator();
-
+        mViewPropertyAnimator = Mockito.spy(mSpyImageView.animate());
+        resetAndStubMockImageViewAndAnimator();
+        doAnswer((invocation) -> {
+            mTouchListener = invocation.getArgument(0);
+            return null;
+        }).when(mSpyImageView).setOnTouchListener(
+                any(View.OnTouchListener.class));
         mMagnificationModeSwitch = new MagnificationModeSwitch(mContext, mSpyImageView);
+        assertNotNull(mTouchListener);
+    }
+
+    @After
+    public void tearDown() {
+        for (MotionEvent event:mMotionEvents) {
+            event.recycle();
+        }
+        mMotionEvents.clear();
     }
 
     @Test
@@ -124,7 +143,7 @@
     }
 
     @Test
-    public void showMagnificationButton_a11yTimeout_autoFadeOut() {
+    public void showMagnificationButton_setA11yTimeout_postDelayedAnimationWithA11yTimeout() {
         final int a11yTimeout = 12345;
         when(mAccessibilityManager.getRecommendedTimeoutMillis(anyInt(), anyInt())).thenReturn(
                 a11yTimeout);
@@ -134,14 +153,21 @@
         verify(mAccessibilityManager).getRecommendedTimeoutMillis(
                 DEFAULT_FADE_OUT_ANIMATION_DELAY_MS, AccessibilityManager.FLAG_CONTENT_ICONS
                         | AccessibilityManager.FLAG_CONTENT_CONTROLS);
-        final ArgumentCaptor<Runnable> fadeOutCaptor = ArgumentCaptor.forClass(Runnable.class);
-        final ArgumentCaptor<Long> fadeOutDelay = ArgumentCaptor.forClass(Long.class);
-        verify(mSpyImageView).postOnAnimationDelayed(fadeOutCaptor.capture(),
-                fadeOutDelay.capture());
-        assertEquals(a11yTimeout, (long) fadeOutDelay.getValue());
+        verify(mSpyImageView).postOnAnimationDelayed(any(Runnable.class), eq((long) a11yTimeout));
+    }
+
+    @Test
+    public void showMagnificationButton_windowMode_verifyAnimationEndAction() {
+        // Execute the runnable immediately to run the animation.
+        doAnswer((invocation) -> {
+            final Runnable action = invocation.getArgument(0);
+            action.run();
+            return null;
+        }).when(mSpyImageView).postOnAnimationDelayed(any(Runnable.class), anyLong());
+
+        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
 
         // Verify the end action after fade-out.
-        fadeOutCaptor.getValue().run();
         final ArgumentCaptor<Runnable> endActionCaptor = ArgumentCaptor.forClass(Runnable.class);
         verify(mViewPropertyAnimator).withEndAction(endActionCaptor.capture());
 
@@ -154,7 +180,7 @@
     @Test
     public void onConfigurationChanged_buttonIsShowing_setImageResource() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-        resetMockImageViewAndAnimator();
+        resetAndStubMockImageViewAndAnimator();
 
         mMagnificationModeSwitch.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
 
@@ -165,42 +191,46 @@
     @Test
     public void performSingleTap_fullscreenMode_removeViewAndChangeSettingsValue() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-        resetMockImageViewAndAnimator();
+        resetAndStubMockImageViewAndAnimator();
 
         // Perform a single-tap
-        final View.OnTouchListener listener = mTouchListenerCaptor.getValue();
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, 0, ACTION_DOWN, 100, 100, 0));
+        final long downTime = SystemClock.uptimeMillis();
+        mTouchListener.onTouch(mSpyImageView,
+                obtainMotionEvent(downTime, 0, ACTION_DOWN, 100, 100));
+
         verify(mViewPropertyAnimator).cancel();
 
-        resetMockImageViewAndAnimator();
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, ViewConfiguration.getTapTimeout(), ACTION_UP, 100, 100, 0));
+        resetAndStubMockImageViewAndAnimator();
+        mTouchListener.onTouch(mSpyImageView,
+                obtainMotionEvent(downTime, downTime, ACTION_UP, 100, 100));
+
         verifyTapAction(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
     }
 
     @Test
-    public void showMagnificationButton_performDragging_updateViewLayout() {
+    public void performDragging_showMagnificationButton_updateViewLayout() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-        resetMockImageViewAndAnimator();
-
-        // Perform dragging
-        final View.OnTouchListener listener = mTouchListenerCaptor.getValue();
-        final int offset = ViewConfiguration.get(mContext).getScaledTouchSlop();
+        resetAndStubMockImageViewAndAnimator();
         final int previousMode = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0, UserHandle.USER_CURRENT);
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, 0, ACTION_DOWN, 100, 100, 0));
+
+        // Perform dragging
+        final int offset = ViewConfiguration.get(mContext).getScaledTouchSlop() + 10;
+        final long downTime = SystemClock.uptimeMillis();
+        mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
+                downTime, 0, ACTION_DOWN, 100, 100));
         verify(mViewPropertyAnimator).cancel();
 
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, ViewConfiguration.getTapTimeout(), ACTION_MOVE, 100 + offset, 100, 0));
+        mTouchListener.onTouch(mSpyImageView,
+                obtainMotionEvent(downTime, downTime, ACTION_MOVE, 100 + offset,
+                        100));
         verify(mWindowManager).updateViewLayout(eq(mSpyImageView),
                 any(WindowManager.LayoutParams.class));
 
-        resetMockImageViewAndAnimator();
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, ViewConfiguration.getTapTimeout() + 10, ACTION_UP, 100 + offset, 100, 0));
+        resetAndStubMockImageViewAndAnimator();
+        mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
+                downTime, downTime, ACTION_UP, 100 + offset, 100));
+
         assertModeUnchanged(previousMode);
         assertShowFadingAnimation(FADE_OUT_ALPHA);
     }
@@ -208,18 +238,17 @@
     @Test
     public void performSingleTapActionCanceled_showButtonAnimation() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-        resetMockImageViewAndAnimator();
-
-        // Perform single tap
-        final View.OnTouchListener listener = mTouchListenerCaptor.getValue();
+        resetAndStubMockImageViewAndAnimator();
         final int previousMode = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0);
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, 0, ACTION_DOWN, 100, 100, 0));
 
-        resetMockImageViewAndAnimator();
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, ViewConfiguration.getTapTimeout(), ACTION_CANCEL, 100, 100, 0));
+        final long downTime = SystemClock.uptimeMillis();
+        mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
+                downTime, downTime, ACTION_DOWN, 100, 100));
+        resetAndStubMockImageViewAndAnimator();
+        mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
+                downTime, downTime, ACTION_CANCEL, 100, 100));
+
         assertModeUnchanged(previousMode);
         assertShowFadingAnimation(FADE_OUT_ALPHA);
     }
@@ -227,21 +256,21 @@
     @Test
     public void performDraggingActionCanceled_showButtonAnimation() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
-        resetMockImageViewAndAnimator();
-
-        // Perform dragging
-        final View.OnTouchListener listener = mTouchListenerCaptor.getValue();
-        final int offset = ViewConfiguration.get(mContext).getScaledTouchSlop();
+        resetAndStubMockImageViewAndAnimator();
         final int previousMode = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0);
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, 0, ACTION_DOWN, 100, 100, 0));
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, ViewConfiguration.getTapTimeout(), ACTION_MOVE, 100 + offset, 100, 0));
 
-        resetMockImageViewAndAnimator();
-        listener.onTouch(mSpyImageView, MotionEvent.obtain(
-                0, ViewConfiguration.getTapTimeout(), ACTION_CANCEL, 100 + offset, 100, 0));
+        // Perform dragging
+        final long downTime = SystemClock.uptimeMillis();
+        final int offset = ViewConfiguration.get(mContext).getScaledTouchSlop() + 10;
+        mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
+                0, 0, ACTION_DOWN, 100, 100));
+        mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
+                downTime, downTime, ACTION_MOVE, 100 + offset, 100));
+        resetAndStubMockImageViewAndAnimator();
+        mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
+                downTime, downTime, ACTION_CANCEL, 100 + offset, 100));
+
         assertModeUnchanged(previousMode);
         assertShowFadingAnimation(FADE_OUT_ALPHA);
     }
@@ -266,7 +295,7 @@
     @Test
     public void performA11yActions_showWindowModeButton_verifyTapAction() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
-        resetMockImageViewAndAnimator();
+        resetAndStubMockImageViewAndAnimator();
 
         mSpyImageView.performAccessibilityAction(
                 ACTION_CLICK.getId(), null);
@@ -278,7 +307,7 @@
     public void showButton_showFadeOutAnimation_fadeOutAnimationCanceled() {
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
         assertShowFadingAnimation(FADE_OUT_ALPHA);
-        resetMockImageViewAndAnimator();
+        resetAndStubMockImageViewAndAnimator();
 
         mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
 
@@ -327,7 +356,7 @@
         } else { // Fade-out
             verify(mSpyImageView).postOnAnimationDelayed(runnableCaptor.capture(), anyLong());
         }
-        resetMockAnimator();
+        resetAndStubMockAnimator();
 
         runnableCaptor.getValue().run();
 
@@ -336,20 +365,15 @@
         verify(mViewPropertyAnimator).start();
     }
 
-    private void resetMockImageViewAndAnimator() {
+    private void resetAndStubMockImageViewAndAnimator() {
+        resetAndStubMockAnimator();
         Mockito.reset(mSpyImageView);
-        doAnswer(invocation -> null).when(mSpyImageView).setOnTouchListener(
-                mTouchListenerCaptor.capture());
-        resetMockAnimator();
+        doReturn(mViewPropertyAnimator).when(mSpyImageView).animate();
     }
 
-    private void resetMockAnimator() {
+    private void resetAndStubMockAnimator() {
         Mockito.reset(mViewPropertyAnimator);
-        when(mViewPropertyAnimator.setDuration(anyLong())).thenReturn(mViewPropertyAnimator);
-        when(mViewPropertyAnimator.alpha(anyFloat())).thenReturn(mViewPropertyAnimator);
-        when(mViewPropertyAnimator.withEndAction(any(Runnable.class))).thenReturn(
-                mViewPropertyAnimator);
-        when(mSpyImageView.animate()).thenReturn(mViewPropertyAnimator);
+        doNothing().when(mViewPropertyAnimator).start();
     }
 
     /**
@@ -366,4 +390,11 @@
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0, UserHandle.USER_CURRENT);
         assertEquals(expectedMode, actualMode);
     }
+
+    private MotionEvent obtainMotionEvent(long downTime, long eventTime, int action, float x,
+            float y) {
+        MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, x, y, 0);
+        mMotionEvents.add(event);
+        return event;
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index 477fe63..019424c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -29,12 +29,20 @@
 
 import static java.util.Objects.requireNonNull;
 
+import android.app.INotificationManager;
 import android.app.NotificationChannel;
-import android.content.Context;
+import android.appwidget.AppWidgetManager;
+import android.content.SharedPreferences;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.ShortcutInfo;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.notification.ConversationChannelWrapper;
 import android.testing.AndroidTestingRunner;
+import android.widget.RemoteViews;
 
+import androidx.preference.PreferenceManager;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.appwidget.IAppWidgetService;
@@ -54,6 +62,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
@@ -65,14 +76,23 @@
     private static final String TEST_CHANNEL_NAME = "channel_name";
     private static final String TEST_PARENT_CHANNEL_ID = "parent_channel_id";
     private static final String TEST_CONVERSATION_ID = "conversation_id";
+    private static final int WIDGET_ID_WITH_SHORTCUT = 1;
+    private static final int WIDGET_ID_WITHOUT_SHORTCUT = 2;
+    private static final String SHORTCUT_ID = "101";
 
     private PeopleSpaceWidgetManager mManager;
 
-    @Mock private NotificationListener mListenerService;
-    @Mock private IAppWidgetService mIAppWidgetService;
-    @Mock private Context mContext;
+    @Mock
+    private NotificationListener mListenerService;
+    @Mock
+    private IAppWidgetService mIAppWidgetService;
+    @Mock
+    private AppWidgetManager mAppWidgetManager;
+    @Mock
+    private INotificationManager mINotificationManager;
 
-    @Captor private ArgumentCaptor<NotificationHandler> mListenerCaptor;
+    @Captor
+    private ArgumentCaptor<NotificationHandler> mListenerCaptor;
 
     private final NoManSimulator mNoMan = new NoManSimulator();
     private final FakeSystemClock mClock = new FakeSystemClock();
@@ -80,18 +100,18 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-
         mManager =
                 new PeopleSpaceWidgetManager(mContext);
-        mManager.setAppWidgetManager(mIAppWidgetService);
+        mManager.setAppWidgetManager(mIAppWidgetService, mAppWidgetManager, mINotificationManager);
         mManager.attach(mListenerService);
 
         verify(mListenerService).addNotificationHandler(mListenerCaptor.capture());
         NotificationHandler serviceListener = requireNonNull(mListenerCaptor.getValue());
         mNoMan.addListener(serviceListener);
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 2);
     }
 
-
     @Test
     public void testDoNotNotifyAppWidgetIfNoWidgets() throws RemoteException {
         int[] widgetIdsArray = {};
@@ -105,7 +125,24 @@
 
         verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
         verify(mIAppWidgetService, never()).notifyAppWidgetViewDataChanged(any(), any(), anyInt());
+    }
 
+    @Test
+    public void testDoNotNotifySingleConversationAppWidgetIfNoWidgets() throws RemoteException {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
+        int[] widgetIdsArray = {};
+        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        NotifEvent notif1 = mNoMan.postNotif(
+                new NotificationEntryBuilder()
+                        .setId(0)
+                        .setPkg(TEST_PACKAGE_A));
+        mClock.advanceTime(MIN_LINGER_DURATION);
+
+        verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
+        verify(mAppWidgetManager, never()).updateAppWidget(anyInt(), any(RemoteViews.class));
+        verify(mIAppWidgetService, never()).notifyAppWidgetViewDataChanged(any(), any(), anyInt());
     }
 
     @Test
@@ -122,7 +159,66 @@
         verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
         verify(mIAppWidgetService, times(1))
                 .notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
+        verify(mIAppWidgetService, never()).updateAppWidgetIds(any(), any(),
+                any(RemoteViews.class));
+    }
 
+    @Test
+    public void testNotifySingleConversationAppWidgetOnceIfNotificationPosted()
+            throws RemoteException {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
+        when(mINotificationManager.getConversations(true)).thenReturn(
+                new ParceledListSlice(getConversationWithShortcutId()));
+        int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+        SharedPreferences.Editor editor = sp.edit();
+        editor.putString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), SHORTCUT_ID);
+        editor.commit();
+        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setPkg(TEST_PACKAGE_A)
+                .setId(1));
+
+        verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
+        verify(mIAppWidgetService, never())
+                .notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
+        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+                any(RemoteViews.class));
+        verify(mAppWidgetManager, never()).updateAppWidget(eq(WIDGET_ID_WITHOUT_SHORTCUT),
+                any(RemoteViews.class));
+    }
+
+    @Test
+    public void testNotifySingleConversationAppWidgetTwiceIfTwoNotificationsPosted()
+            throws RemoteException {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
+        when(mINotificationManager.getConversations(true)).thenReturn(
+                new ParceledListSlice(getConversationWithShortcutId()));
+        int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
+        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+        SharedPreferences.Editor editor = sp.edit();
+        editor.putString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), SHORTCUT_ID);
+        editor.commit();
+        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+        NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setPkg(TEST_PACKAGE_A)
+                .setId(1));
+        mClock.advanceTime(4);
+        NotifEvent notif2 = mNoMan.postNotif(new NotificationEntryBuilder()
+                .setPkg(TEST_PACKAGE_B)
+                .setId(2));
+
+        verify(mIAppWidgetService, times(2)).getAppWidgetIds(any());
+        verify(mIAppWidgetService, never())
+                .notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
+        verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+                any(RemoteViews.class));
+        verify(mAppWidgetManager, never()).updateAppWidget(eq(WIDGET_ID_WITHOUT_SHORTCUT),
+                any(RemoteViews.class));
     }
 
     @Test
@@ -141,6 +237,8 @@
         verify(mIAppWidgetService, times(2)).getAppWidgetIds(any());
         verify(mIAppWidgetService, times(2))
                 .notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
+        verify(mAppWidgetManager, never()).updateAppWidget(anyInt(),
+                any(RemoteViews.class));
     }
 
     @Test
@@ -157,6 +255,8 @@
         verify(mIAppWidgetService, times(2)).getAppWidgetIds(any());
         verify(mIAppWidgetService, times(2))
                 .notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
+        verify(mAppWidgetManager, never()).updateAppWidget(anyInt(),
+                any(RemoteViews.class));
     }
 
     @Test
@@ -173,7 +273,8 @@
 
         verify(mIAppWidgetService, never()).getAppWidgetIds(any());
         verify(mIAppWidgetService, never()).notifyAppWidgetViewDataChanged(any(), any(), anyInt());
-
+        verify(mAppWidgetManager, never()).updateAppWidget(anyInt(),
+                any(RemoteViews.class));
     }
 
     @Test
@@ -192,6 +293,17 @@
         verify(mIAppWidgetService, times(1)).getAppWidgetIds(any());
         verify(mIAppWidgetService, times(1))
                 .notifyAppWidgetViewDataChanged(any(), eq(widgetIdsArray), anyInt());
+        verify(mAppWidgetManager, never()).updateAppWidget(anyInt(),
+                any(RemoteViews.class));
+    }
 
+    /** Returns a list of a single conversation associated with {@code SHORTCUT_ID}. */
+    private List<ConversationChannelWrapper> getConversationWithShortcutId() {
+        List<ConversationChannelWrapper> convos = new ArrayList<>();
+        ConversationChannelWrapper convo1 = new ConversationChannelWrapper();
+        convo1.setShortcutInfo(new ShortcutInfo.Builder(mContext, SHORTCUT_ID).setLongLabel(
+                "name").build());
+        convos.add(convo1);
+        return convos;
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index f9b14ba..91144be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -82,6 +82,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.text.NumberFormat;
 import java.util.Collections;
 
 @SmallTest
@@ -546,4 +547,68 @@
                 pluggedIndication, powerIndication);
         assertThat(mTextView.getText()).isEqualTo(pluggedIndication);
     }
+
+    @Test
+    public void onRefreshBatteryInfo_chargingWithOverheat_presentChargingLimited() {
+        createController();
+        BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING,
+                80 /* level */, BatteryManager.BATTERY_PLUGGED_AC,
+                BatteryManager.BATTERY_HEALTH_OVERHEAT, 0 /* maxChargingWattage */,
+                true /* present */);
+
+        mController.getKeyguardCallback().onRefreshBatteryInfo(status);
+        mController.setVisible(true);
+
+        String percentage = NumberFormat.getPercentInstance().format(80 / 100f);
+        String pluggedIndication = mContext.getString(
+                R.string.keyguard_plugged_in_charging_limited, percentage);
+        assertThat(mTextView.getText()).isEqualTo(pluggedIndication);
+    }
+
+    @Test
+    public void onRefreshBatteryInfo_pluggedWithOverheat_presentChargingLimited() {
+        createController();
+        BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_DISCHARGING,
+                80 /* level */, BatteryManager.BATTERY_PLUGGED_AC,
+                BatteryManager.BATTERY_HEALTH_OVERHEAT, 0 /* maxChargingWattage */,
+                true /* present */);
+
+        mController.getKeyguardCallback().onRefreshBatteryInfo(status);
+        mController.setVisible(true);
+
+        String percentage = NumberFormat.getPercentInstance().format(80 / 100f);
+        String pluggedIndication = mContext.getString(
+                R.string.keyguard_plugged_in_charging_limited, percentage);
+        assertThat(mTextView.getText()).isEqualTo(pluggedIndication);
+    }
+
+    @Test
+    public void onRefreshBatteryInfo_fullChargedWithOverheat_presentCharged() {
+        createController();
+        BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING,
+                100 /* level */, BatteryManager.BATTERY_PLUGGED_AC,
+                BatteryManager.BATTERY_HEALTH_OVERHEAT, 0 /* maxChargingWattage */,
+                true /* present */);
+
+        mController.getKeyguardCallback().onRefreshBatteryInfo(status);
+        mController.setVisible(true);
+
+        String chargedIndication = mContext.getString(R.string.keyguard_charged);
+        assertThat(mTextView.getText()).isEqualTo(chargedIndication);
+    }
+
+    @Test
+    public void onRefreshBatteryInfo_dischargingWithOverheat_presentBatteryPercentage() {
+        createController();
+        BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_DISCHARGING,
+                90 /* level */, 0 /* plugged */, BatteryManager.BATTERY_HEALTH_OVERHEAT,
+                0 /* maxChargingWattage */, true /* present */);
+
+        mController.getKeyguardCallback().onRefreshBatteryInfo(status);
+        mController.setDozing(true);
+        mController.setVisible(true);
+
+        String percentage = NumberFormat.getPercentInstance().format(90 / 100f);
+        assertThat(mTextView.getText()).isEqualTo(percentage);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
index 3c9c9cc..353647b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
@@ -39,8 +39,11 @@
 
     @Test
     public void needReinflate_differentLength() {
+        // TODO(b/174258598) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         PendingIntent pendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+                PendingIntent.getActivity(mContext, 0, new Intent(),
+                        PendingIntent.FLAG_MUTABLE_UNAUDITED);
         Notification.Action action =
                 createActionBuilder("first", R.drawable.ic_corp_icon, pendingIntent).build();
         assertThat(NotificationUiAdjustment.needReinflate(
@@ -51,8 +54,11 @@
 
     @Test
     public void needReinflate_differentLabels() {
+        // TODO(b/174258598) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         PendingIntent pendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+                PendingIntent.getActivity(mContext, 0, new Intent(),
+                        PendingIntent.FLAG_MUTABLE_UNAUDITED);
         Notification.Action firstAction =
                 createActionBuilder("first", R.drawable.ic_corp_icon, pendingIntent).build();
         Notification.Action secondAction =
@@ -66,8 +72,11 @@
 
     @Test
     public void needReinflate_differentIcons() {
+        // TODO(b/174258598) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         PendingIntent pendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+                PendingIntent.getActivity(mContext, 0, new Intent(),
+                        PendingIntent.FLAG_MUTABLE_UNAUDITED);
         Notification.Action firstAction =
                 createActionBuilder("same", R.drawable.ic_corp_icon, pendingIntent).build();
         Notification.Action secondAction =
@@ -82,10 +91,14 @@
 
     @Test
     public void needReinflate_differentPendingIntent() {
+        // TODO(b/174258598) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         PendingIntent firstPendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(Intent.ACTION_VIEW), 0);
+                PendingIntent.getActivity(mContext, 0, new Intent(Intent.ACTION_VIEW),
+                        PendingIntent.FLAG_MUTABLE_UNAUDITED);
         PendingIntent secondPendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(Intent.ACTION_PROCESS_TEXT), 0);
+                PendingIntent.getActivity(mContext, 0, new Intent(Intent.ACTION_PROCESS_TEXT),
+                        PendingIntent.FLAG_MUTABLE_UNAUDITED);
         Notification.Action firstAction =
                 createActionBuilder("same", R.drawable.ic_corp_icon, firstPendingIntent)
                         .build();
@@ -101,8 +114,11 @@
 
     @Test
     public void needReinflate_differentChoices() {
+        // TODO(b/174258598) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         PendingIntent pendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+                PendingIntent.getActivity(mContext, 0, new Intent(),
+                        PendingIntent.FLAG_MUTABLE_UNAUDITED);
 
         RemoteInput firstRemoteInput =
                 createRemoteInput("same", "same", new CharSequence[] {"first"});
@@ -126,8 +142,11 @@
 
     @Test
     public void needReinflate_differentRemoteInputLabel() {
+        // TODO(b/174258598) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         PendingIntent pendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+                PendingIntent.getActivity(mContext, 0, new Intent(),
+                        PendingIntent.FLAG_MUTABLE_UNAUDITED);
 
         RemoteInput firstRemoteInput =
                 createRemoteInput("same", "first", new CharSequence[] {"same"});
@@ -151,8 +170,11 @@
 
     @Test
     public void needReinflate_negative() {
+        // TODO(b/174258598) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         PendingIntent pendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+                PendingIntent.getActivity(mContext, 0, new Intent(),
+                        PendingIntent.FLAG_MUTABLE_UNAUDITED);
         RemoteInput firstRemoteInput =
                 createRemoteInput("same", "same", new CharSequence[] {"same"});
         RemoteInput secondRemoteInput =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java
index 152c51e..ac699f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/RankingBuilder.java
@@ -65,7 +65,7 @@
         mKey = ranking.getKey();
         mRank = ranking.getRank();
         mMatchesInterruptionFilter = ranking.matchesInterruptionFilter();
-        mVisibilityOverride = ranking.getVisibilityOverride();
+        mVisibilityOverride = ranking.getLockscreenVisibilityOverride();
         mSuppressedVisualEffects = ranking.getSuppressedVisualEffects();
         mImportance = ranking.getImportance();
         mExplanation = ranking.getImportanceExplanation();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 0be9f7d..b0e17cd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -629,7 +629,10 @@
         return new Notification.Action.Builder(
                 Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
                 "action",
-                PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0)).build();
+                // TODO(b/174935104) Please replace FLAG_MUTABLE_UNAUDITED below
+                // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+                PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"),
+                    PendingIntent.FLAG_MUTABLE_UNAUDITED)).build();
     }
 
     private static class FakeNotificationLifetimeExtender implements NotificationLifetimeExtender {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index 1a022ec..01b3d8e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -233,7 +233,10 @@
         return new Notification.Action.Builder(
                 Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
                 title,
-                PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0))
+                // TODO(b/174965424) Please replace FLAG_MUTABLE_UNAUDITED below
+                // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+                PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"),
+                    PendingIntent.FLAG_MUTABLE_UNAUDITED))
                 .setContextual(true)
                 .build();
     }
@@ -242,7 +245,10 @@
         return new Notification.Action.Builder(
                 Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
                 title,
-                PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0)).build();
+                // TODO(b/174965424) Please replace FLAG_MUTABLE_UNAUDITED below
+                // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+                PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"),
+                    PendingIntent.FLAG_MUTABLE_UNAUDITED)).build();
     }
 
     private ArrayList<Notification.Action> createActions(String... titles) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index e254cd2..d606316 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -476,7 +476,10 @@
 
     private NotificationEntry createBubble() {
         Notification.BubbleMetadata data = new Notification.BubbleMetadata.Builder(
-                PendingIntent.getActivity(mContext, 0, new Intent(), 0),
+                // TODO(b/174970399) Please replace FLAG_MUTABLE_UNAUDITED below
+                // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+                PendingIntent.getActivity(mContext, 0, new Intent(),
+                    PendingIntent.FLAG_MUTABLE_UNAUDITED),
                         Icon.createWithResource(mContext.getResources(), R.drawable.android))
                 .build();
         Notification n = new Notification.Builder(getContext(), "a")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index f7dfe0b..1387a63 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -213,8 +213,11 @@
                 notification, UserHandle.CURRENT, null, 0);
         mEntry = new NotificationEntryBuilder().setSbn(mSbn).setShortcutInfo(mShortcutInfo).build();
 
+        // TODO(b/175005650) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0,
-                new Intent(mContext, BubblesTestActivity.class), 0);
+                new Intent(mContext, BubblesTestActivity.class),
+                PendingIntent.FLAG_MUTABLE_UNAUDITED);
         mBubbleSbn = new SbnBuilder(mSbn).setBubbleMetadata(
                 new Notification.BubbleMetadata.Builder(bubbleIntent,
                         Icon.createWithResource(mContext, R.drawable.android)).build())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 7470a13..43ba844 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -455,7 +455,10 @@
 
     private BubbleMetadata makeBubbleMetadata(PendingIntent deleteIntent) {
         Intent target = new Intent(mContext, BubblesTestActivity.class);
-        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, 0);
+        // TODO(b/175014468) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target,
+                PendingIntent.FLAG_MUTABLE_UNAUDITED);
 
         return new BubbleMetadata.Builder(bubbleIntent,
                         Icon.createWithResource(mContext, R.drawable.android))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index 83ef87a..c7c1823 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -19,7 +19,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
 
 import androidx.test.filters.SmallTest;
 
@@ -31,7 +30,6 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
 public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase {
 
     private static final int SCREEN_HEIGHT = 2000;
@@ -53,6 +51,7 @@
     private int mPreferredClockY;
     private boolean mHasCustomClock;
     private boolean mHasVisibleNotifs;
+    private float mQsExpansion;
 
     @Before
     public void setUp() {
@@ -355,6 +354,17 @@
     }
 
     @Test
+    public void clockHiddenWhenQsIsExpanded() {
+        // GIVEN on the lock screen with a custom clock and visible notifications
+        givenLockScreen();
+        mQsExpansion = 1;
+        // WHEN the clock position algorithm is run
+        positionClock();
+        // THEN the clock Y position is the middle of the screen (SCREEN_HEIGHT / 2).
+        assertThat(mClockPosition.clockAlpha).isEqualTo(TRANSPARENT);
+    }
+
+    @Test
     public void preferredCustomClockPositionWithVisibleNotificationsOnAod() {
         // GIVEN on the lock screen with a custom clock and visible notifications
         givenAOD();
@@ -384,7 +394,7 @@
         mClockPositionAlgorithm.setup(EMPTY_MARGIN, SCREEN_HEIGHT, mNotificationStackHeight,
                 mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight, mPreferredClockY,
                 mHasCustomClock, mHasVisibleNotifs, mDark, ZERO_DRAG, false /* bypassEnabled */,
-                0 /* unlockedStackScrollerPadding */, false /* udfpsEnrolled */);
+                0 /* unlockedStackScrollerPadding */, false /* udfpsEnrolled */, mQsExpansion);
         mClockPositionAlgorithm.run(mClockPosition);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index d4a94a1..d452861 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -199,6 +199,8 @@
     @Mock
     private AuthController mAuthController;
     @Mock
+    private ScrimController mScrimController;
+    @Mock
     private MediaDataManager mMediaDataManager;
 
     private NotificationPanelViewController mNotificationPanelViewController;
@@ -279,6 +281,7 @@
                 mNotificationAreaController,
                 mAuthController,
                 new QSDetailDisplayer(),
+                mScrimController,
                 mMediaDataManager);
         mNotificationPanelViewController.initDependencies(
                 mStatusBar,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index eaf31ed..342b2f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -249,6 +249,20 @@
     }
 
     @Test
+    public void transitionToShadeLocked() {
+        mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
+        finishAnimationsImmediately();
+
+        assertScrimAlpha(TRANSPARENT /* front */,
+                OPAQUE /* back */,
+                TRANSPARENT /* bubble */);
+
+        assertScrimTint(false /* front */,
+                false /* behind */,
+                false /* bubble */);
+    }
+
+    @Test
     public void transitionToOff() {
         mScrimController.transitionTo(ScrimState.OFF);
         finishAnimationsImmediately();
@@ -464,7 +478,7 @@
         // Front scrim should be transparent
         // Back scrim should be visible without tint
         assertScrimAlpha(TRANSPARENT /* front */,
-                SEMI_TRANSPARENT /* back */,
+                OPAQUE /* back */,
                 TRANSPARENT /* bubble */);
 
         assertScrimTint(false /* front */,
@@ -478,7 +492,7 @@
         finishAnimationsImmediately();
         // Front scrim should be transparent
         // Back scrim should be visible without tint
-        assertScrimAlpha(SEMI_TRANSPARENT /* front */,
+        assertScrimAlpha(OPAQUE /* front */,
                 TRANSPARENT /* back */,
                 TRANSPARENT /* bubble */);
         assertScrimTint(false /* front */,
@@ -519,11 +533,11 @@
         Assert.assertEquals(ScrimController.TRANSPARENT,
                 mScrimInFront.getViewAlpha(), 0.0f);
         // Back scrim should be visible
-        Assert.assertEquals(ScrimController.BLUR_SCRIM_ALPHA,
+        Assert.assertEquals(ScrimController.BUSY_SCRIM_ALPHA,
                 mScrimBehind.getViewAlpha(), 0.0f);
         // Bubble scrim should be visible
-        Assert.assertEquals(ScrimController.BLUR_SCRIM_ALPHA,
-                mScrimBehind.getViewAlpha(), 0.0f);
+        Assert.assertEquals(ScrimController.BUBBLE_SCRIM_ALPHA,
+                mScrimForBubble.getViewAlpha(), 0.0f);
     }
 
     @Test
@@ -564,6 +578,15 @@
     }
 
     @Test
+    public void qsExpansion() {
+        reset(mScrimBehind);
+        mScrimController.setQsExpansion(1f);
+        finishAnimationsImmediately();
+
+        assertScrimAlpha(TRANSPARENT, OPAQUE, TRANSPARENT);
+    }
+
+    @Test
     public void panelExpansionAffectsAlpha() {
         mScrimController.setPanelExpansion(0f);
         mScrimController.setPanelExpansion(0.5f);
@@ -888,7 +911,7 @@
         HashSet<ScrimState> regularStates = new HashSet<>(Arrays.asList(
                 ScrimState.UNINITIALIZED, ScrimState.KEYGUARD, ScrimState.BOUNCER,
                 ScrimState.BOUNCER_SCRIMMED, ScrimState.BRIGHTNESS_MIRROR, ScrimState.UNLOCKED,
-                ScrimState.BUBBLE_EXPANDED));
+                ScrimState.BUBBLE_EXPANDED, ScrimState.SHADE_LOCKED));
 
         for (ScrimState state : ScrimState.values()) {
             if (!lowPowerModeStates.contains(state) && !regularStates.contains(state)) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 1f31fcd..52b7b02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -81,7 +81,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.InOrder;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.stubbing.Answer;
 
@@ -261,11 +263,12 @@
 
         verify(mAssistManager).hideAssist();
 
-        verify(mClickNotifier).onNotificationClick(
+        InOrder orderVerifier = Mockito.inOrder(mClickNotifier, mOnUserInteractionCallback);
+        orderVerifier.verify(mClickNotifier).onNotificationClick(
                 eq(sbn.getKey()), any(NotificationVisibility.class));
-
         // Notification calls dismiss callback to remove notification due to FLAG_AUTO_CANCEL
-        verify(mOnUserInteractionCallback).onDismiss(mNotificationRow.getEntry(), REASON_CLICK);
+        orderVerifier.verify(mOnUserInteractionCallback).onDismiss(mNotificationRow.getEntry(),
+                REASON_CLICK);
     }
 
     @Test
diff --git a/packages/Tethering/OWNERS b/packages/Tethering/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/packages/Tethering/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/packages/VpnDialogs/OWNERS b/packages/VpnDialogs/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/packages/VpnDialogs/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/packages/WAPPushManager/OWNERS b/packages/WAPPushManager/OWNERS
new file mode 100644
index 0000000..640baf2
--- /dev/null
+++ b/packages/WAPPushManager/OWNERS
@@ -0,0 +1 @@
+include /telephony/OWNERS
diff --git a/packages/WallpaperBackup/OWNERS b/packages/WallpaperBackup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/packages/WallpaperBackup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/packages/WallpaperCropper/OWNERS b/packages/WallpaperCropper/OWNERS
new file mode 100644
index 0000000..8ff0f74
--- /dev/null
+++ b/packages/WallpaperCropper/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/wallpaper/OWNERS
diff --git a/packages/WindowManager/OWNERS b/packages/WindowManager/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/packages/WindowManager/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/packages/overlays/OWNERS b/packages/overlays/OWNERS
new file mode 100644
index 0000000..afb98d4
--- /dev/null
+++ b/packages/overlays/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/content/om/OWNERS
diff --git a/packages/services/PacProcessor/OWNERS b/packages/services/PacProcessor/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/packages/services/PacProcessor/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/packages/services/Proxy/OWNERS b/packages/services/Proxy/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/packages/services/Proxy/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/proto/src/OWNERS b/proto/src/OWNERS
new file mode 100644
index 0000000..e7ddf86
--- /dev/null
+++ b/proto/src/OWNERS
@@ -0,0 +1,2 @@
+per-file gnss.proto = file:/services/core/java/com/android/server/location/OWNERS
+per-file wifi.proto = file:/wifi/OWNERS
diff --git a/proto/src/metrics_constants/OWNERS b/proto/src/metrics_constants/OWNERS
index 7009282..ab4d808 100644
--- a/proto/src/metrics_constants/OWNERS
+++ b/proto/src/metrics_constants/OWNERS
@@ -1,4 +1,4 @@
-cwren@android.com
+cwren@google.com
 yanglu@google.com
 yaochen@google.com
 yro@google.com
diff --git a/samples/training/network-usage/OWNERS b/samples/training/network-usage/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/samples/training/network-usage/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/services/OWNERS b/services/OWNERS
new file mode 100644
index 0000000..88d0b61
--- /dev/null
+++ b/services/OWNERS
@@ -0,0 +1 @@
+per-file Android.bp = file:platform/build/soong:/OWNERS
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index d6d4e4f..8f093c7 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -1797,4 +1797,7 @@
     public void setTouchExplorationPassthroughRegion(int displayId, Region region) {
         mSystemSupport.setTouchExplorationPassthroughRegion(displayId, region);
     }
+
+    @Override
+    public void setFocusAppearance(int strokeWidth, int color) { }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index be2f8f1..c6919ad 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1968,6 +1968,7 @@
         // Update the capabilities before the mode.
         updateMagnificationCapabilitiesSettingsChangeLocked(userState);
         updateMagnificationModeChangeSettingsLocked(userState);
+        updateFocusAppearanceDataLocked(userState);
     }
 
     private void updateWindowsForAccessibilityCallbackLocked(AccessibilityUserState userState) {
@@ -3012,6 +3013,30 @@
         }
     }
 
+    /**
+     * Gets the stroke width of the focus rectangle.
+     * @return The stroke width.
+     */
+    public int getFocusStrokeWidth() {
+        synchronized (mLock) {
+            final AccessibilityUserState userState = getCurrentUserStateLocked();
+
+            return userState.getFocusStrokeWidthLocked();
+        }
+    }
+
+    /**
+     * Gets the color of the focus rectangle.
+     * @return The color.
+     */
+    public int getFocusColor() {
+        synchronized (mLock) {
+            final AccessibilityUserState userState = getCurrentUserStateLocked();
+
+            return userState.getFocusColorLocked();
+        }
+    }
+
     @Override
     public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
@@ -3623,4 +3648,18 @@
             }
         }
     }
+
+    private void updateFocusAppearanceDataLocked(AccessibilityUserState userState) {
+        if (userState.mUserId != mCurrentUserId) {
+            return;
+        }
+
+        mMainHandler.post(() -> {
+            broadcastToClients(userState, ignoreRemoteException(client -> {
+                client.mCallback.setFocusAppearance(userState.getFocusStrokeWidthLocked(),
+                        userState.getFocusColorLocked());
+            }));
+        });
+
+    }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index e48d11d..5d67992 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -120,6 +120,8 @@
         AccessibilityUserState userState = mUserStateWeakReference.get();
         if (userState == null) return;
         userState.removeServiceLocked(this);
+        userState.resetFocusAppearanceLocked();
+        mSystemSupport.onClientChangeLocked(false);
         mSystemSupport.getFullScreenMagnificationController().resetAllIfNeeded(mId);
         mActivityTaskManagerService.setAllowAppSwitches(mComponentName.flattenToString(), -1,
                 userState.mUserId);
@@ -144,6 +146,7 @@
                 } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
+                userState.resetFocusAppearanceLocked();
                 mSystemSupport.onClientChangeLocked(false);
             }
         }
@@ -310,6 +313,7 @@
             AccessibilityUserState userState = mUserStateWeakReference.get();
             if (userState != null) {
                 userState.serviceDisconnectedLocked(this);
+                userState.resetFocusAppearanceLocked();
             }
             resetLocked();
             mSystemSupport.getFullScreenMagnificationController().resetAllIfNeeded(mId);
@@ -391,4 +395,32 @@
             }
         }
     }
+
+    @Override
+    public void setFocusAppearance(int strokeWidth, int color) {
+        AccessibilityUserState userState = mUserStateWeakReference.get();
+        if (userState == null) {
+            return;
+        }
+
+        synchronized (mLock) {
+            if (!hasRightsToCurrentUserLocked()) {
+                return;
+            }
+
+            if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
+                return;
+            }
+
+            if (userState.getFocusStrokeWidthLocked() == strokeWidth
+                    && userState.getFocusColorLocked() == color) {
+                return;
+            }
+
+            // Sets the appearance data in the A11yUserState.
+            userState.setFocusAppearanceLocked(strokeWidth, color);
+            // Updates the appearance data in the A11yManager.
+            mSystemSupport.onClientChangeLocked(false);
+        }
+    }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index 240c7ff..90e2fdf 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -45,6 +45,7 @@
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.IAccessibilityManagerClient;
 
+import com.android.internal.R;
 import com.android.internal.accessibility.AccessibilityShortcutController;
 
 import java.io.FileDescriptor;
@@ -122,6 +123,15 @@
     // The magnification capabilities used to know magnification mode could be switched.
     private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
 
+    /** The stroke width of the focus rectangle in pixels */
+    private int mFocusStrokeWidth;
+    /** The color of the focus rectangle */
+    private int mFocusColor;
+    // The default value of the focus stroke width.
+    private final int mFocusStrokeWidthDefaultValue;
+    // The default value of the focus color.
+    private final int mFocusColorDefaultValue;
+
     private Context mContext;
 
     @SoftKeyboardShowMode
@@ -140,6 +150,12 @@
         mUserId = userId;
         mContext = context;
         mServiceInfoChangeListener = serviceInfoChangeListener;
+        mFocusStrokeWidthDefaultValue = mContext.getResources().getDimensionPixelSize(
+                R.dimen.accessibility_focus_highlight_stroke_width);
+        mFocusColorDefaultValue = mContext.getResources().getColor(
+                R.color.accessibility_focus_highlight_color);
+        mFocusStrokeWidth = mFocusStrokeWidthDefaultValue;
+        mFocusColor = mFocusColorDefaultValue;
     }
 
     boolean isHandlingAccessibilityEventsLocked() {
@@ -178,6 +194,7 @@
         mUserNonInteractiveUiTimeout = 0;
         mUserInteractiveUiTimeout = 0;
         mMagnificationMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+        resetFocusAppearanceLocked();
     }
 
     void addServiceLocked(AccessibilityServiceConnection serviceConnection) {
@@ -880,4 +897,40 @@
         }
         return false;
     }
+
+    /**
+     * Gets the stroke width of the focus rectangle.
+     * @return The stroke width.
+     */
+    public int getFocusStrokeWidthLocked() {
+        return mFocusStrokeWidth;
+    }
+
+    /**
+     * Gets the color of the focus rectangle.
+     * @return The color.
+     */
+    public int getFocusColorLocked() {
+        return mFocusColor;
+    }
+
+    /**
+     * Sets the stroke width and color of the focus rectangle.
+     *
+     * @param strokeWidth The strokeWidth of the focus rectangle.
+     * @param color The color of the focus rectangle.
+     */
+    public void setFocusAppearanceLocked(int strokeWidth, int color) {
+        mFocusStrokeWidth = strokeWidth;
+        mFocusColor = color;
+    }
+
+    /**
+     * Resets the stroke width and color of the focus rectangle to the default value.
+     *
+     */
+    public void resetFocusAppearanceLocked() {
+        mFocusStrokeWidth = mFocusStrokeWidthDefaultValue;
+        mFocusColor = mFocusColorDefaultValue;
+    }
 }
diff --git a/services/api/OWNERS b/services/api/OWNERS
new file mode 100644
index 0000000..a609390
--- /dev/null
+++ b/services/api/OWNERS
@@ -0,0 +1,4 @@
+per-file Android.bp = file:platform/build/soong:/OWNERS
+
+# API changes are managed via Prolog rules, not OWNERS
+*
diff --git a/services/appprediction/OWNERS b/services/appprediction/OWNERS
new file mode 100644
index 0000000..3a5d23d
--- /dev/null
+++ b/services/appprediction/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/appprediction/OWNERS
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index f1988e9..449063d 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -19,6 +19,7 @@
 import static android.content.Context.KEYGUARD_SERVICE;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import android.annotation.UserIdInt;
@@ -102,6 +103,7 @@
 import android.view.Display;
 import android.view.View;
 import android.widget.RemoteViews;
+
 import com.android.internal.R;
 import com.android.internal.app.SuspendedAppActivity;
 import com.android.internal.app.UnlaunchableAppActivity;
@@ -111,11 +113,14 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
-import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.widget.IRemoteViewsFactory;
 import com.android.server.LocalServices;
 import com.android.server.WidgetBackupProvider;
 import com.android.server.policy.IconUtilities;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -137,9 +142,6 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider,
         OnCrossProfileWidgetProvidersChangeListener {
@@ -2497,85 +2499,80 @@
         }
     }
 
-    private static void serializeProvider(XmlSerializer out, Provider p) throws IOException {
+    private static void serializeProvider(TypedXmlSerializer out, Provider p) throws IOException {
         out.startTag(null, "p");
         out.attribute(null, "pkg", p.info.provider.getPackageName());
         out.attribute(null, "cl", p.info.provider.getClassName());
-        out.attribute(null, "tag", Integer.toHexString(p.tag));
+        out.attributeIntHex(null, "tag", p.tag);
         if (!TextUtils.isEmpty(p.infoTag)) {
             out.attribute(null, "info_tag", p.infoTag);
         }
         out.endTag(null, "p");
     }
 
-    private static void serializeHost(XmlSerializer out, Host host) throws IOException {
+    private static void serializeHost(TypedXmlSerializer out, Host host) throws IOException {
         out.startTag(null, "h");
         out.attribute(null, "pkg", host.id.packageName);
-        out.attribute(null, "id", Integer.toHexString(host.id.hostId));
-        out.attribute(null, "tag", Integer.toHexString(host.tag));
+        out.attributeIntHex(null, "id", host.id.hostId);
+        out.attributeIntHex(null, "tag", host.tag);
         out.endTag(null, "h");
     }
 
-    private static void serializeAppWidget(XmlSerializer out, Widget widget,
+    private static void serializeAppWidget(TypedXmlSerializer out, Widget widget,
             boolean saveRestoreCompleted) throws IOException {
         out.startTag(null, "g");
-        out.attribute(null, "id", Integer.toHexString(widget.appWidgetId));
-        out.attribute(null, "rid", Integer.toHexString(widget.restoredId));
-        out.attribute(null, "h", Integer.toHexString(widget.host.tag));
+        out.attributeIntHex(null, "id", widget.appWidgetId);
+        out.attributeIntHex(null, "rid", widget.restoredId);
+        out.attributeIntHex(null, "h", widget.host.tag);
         if (widget.provider != null) {
-            out.attribute(null, "p", Integer.toHexString(widget.provider.tag));
+            out.attributeIntHex(null, "p", widget.provider.tag);
         }
         if (widget.options != null) {
             int minWidth = widget.options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
             int minHeight = widget.options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
             int maxWidth = widget.options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH);
             int maxHeight = widget.options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT);
-            out.attribute(null, "min_width", Integer.toHexString((minWidth > 0) ? minWidth : 0));
-            out.attribute(null, "min_height", Integer.toHexString((minHeight > 0) ? minHeight : 0));
-            out.attribute(null, "max_width", Integer.toHexString((maxWidth > 0) ? maxWidth : 0));
-            out.attribute(null, "max_height", Integer.toHexString((maxHeight > 0) ? maxHeight : 0));
-            out.attribute(null, "host_category", Integer.toHexString(widget.options.getInt(
-                    AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)));
+            out.attributeIntHex(null, "min_width", (minWidth > 0) ? minWidth : 0);
+            out.attributeIntHex(null, "min_height", (minHeight > 0) ? minHeight : 0);
+            out.attributeIntHex(null, "max_width", (maxWidth > 0) ? maxWidth : 0);
+            out.attributeIntHex(null, "max_height", (maxHeight > 0) ? maxHeight : 0);
+            out.attributeIntHex(null, "host_category", widget.options.getInt(
+                    AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY));
             if (saveRestoreCompleted) {
                 boolean restoreCompleted = widget.options.getBoolean(
                         AppWidgetManager.OPTION_APPWIDGET_RESTORE_COMPLETED);
-                out.attribute(null, "restore_completed", Boolean.toString(restoreCompleted));
+                out.attributeBoolean(null, "restore_completed", restoreCompleted);
             }
         }
         out.endTag(null, "g");
     }
 
-    private static Bundle parseWidgetIdOptions(XmlPullParser parser) {
+    private static Bundle parseWidgetIdOptions(TypedXmlPullParser parser) {
         Bundle options = new Bundle();
-        String restoreCompleted = parser.getAttributeValue(null, "restore_completed");
-        if (restoreCompleted != null) {
-            options.putBoolean(AppWidgetManager.OPTION_APPWIDGET_RESTORE_COMPLETED,
-                    Boolean.valueOf(restoreCompleted));
+        boolean restoreCompleted = parser.getAttributeBoolean(null, "restore_completed", false);
+        if (restoreCompleted) {
+            options.putBoolean(AppWidgetManager.OPTION_APPWIDGET_RESTORE_COMPLETED, true);
         }
-        String minWidthString = parser.getAttributeValue(null, "min_width");
-        if (minWidthString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH,
-                    Integer.parseInt(minWidthString, 16));
+        int minWidth = parser.getAttributeIntHex(null, "min_width", -1);
+        if (minWidth != -1) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minWidth);
         }
-        String minHeightString = parser.getAttributeValue(null, "min_height");
-        if (minHeightString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT,
-                    Integer.parseInt(minHeightString, 16));
+        int minHeight = parser.getAttributeIntHex(null, "min_height", -1);
+        if (minHeight != -1) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight);
         }
-        String maxWidthString = parser.getAttributeValue(null, "max_width");
-        if (maxWidthString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH,
-                    Integer.parseInt(maxWidthString, 16));
+        int maxWidth = parser.getAttributeIntHex(null, "max_width", -1);
+        if (maxWidth != -1) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxWidth);
         }
-        String maxHeightString = parser.getAttributeValue(null, "max_height");
-        if (maxHeightString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT,
-                    Integer.parseInt(maxHeightString, 16));
+        int maxHeight = parser.getAttributeIntHex(null, "max_height", -1);
+        if (maxHeight != -1) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight);
         }
-        String categoryString = parser.getAttributeValue(null, "host_category");
-        if (categoryString != null) {
-            options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
-                    Integer.parseInt(categoryString, 16));
+        int category = parser.getAttributeIntHex(null, "host_category",
+                AppWidgetProviderInfo.WIDGET_CATEGORY_UNKNOWN);
+        if (category != AppWidgetProviderInfo.WIDGET_CATEGORY_UNKNOWN) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, category);
         }
         return options;
     }
@@ -3080,7 +3077,7 @@
             TypedXmlSerializer out = Xml.resolveSerializer(stream);
             out.startDocument(null, true);
             out.startTag(null, "gs");
-            out.attribute(null, "version", String.valueOf(CURRENT_VERSION));
+            out.attributeInt(null, "version", CURRENT_VERSION);
 
             N = mProviders.size();
             for (int i = 0; i < N; i++) {
@@ -3149,12 +3146,7 @@
                 if (type == XmlPullParser.START_TAG) {
                     String tag = parser.getName();
                     if ("gs".equals(tag)) {
-                        String attributeValue = parser.getAttributeValue(null, "version");
-                        try {
-                            version = Integer.parseInt(attributeValue);
-                        } catch (NumberFormatException e) {
-                            version = 0;
-                        }
+                        version = parser.getAttributeInt(null, "version", 0);
                     } else if ("p".equals(tag)) {
                         legacyProviderIndex++;
                         // TODO: do we need to check that this package has the same signature
@@ -3193,9 +3185,8 @@
                             mProviders.add(provider);
                         }
 
-                        String tagAttribute = parser.getAttributeValue(null, "tag");
-                        final int providerTag = !TextUtils.isEmpty(tagAttribute)
-                                ? Integer.parseInt(tagAttribute, 16) : legacyProviderIndex;
+                        final int providerTag = parser.getAttributeIntHex(null, "tag",
+                                legacyProviderIndex);
                         provider.tag = providerTag;
 
                         provider.infoTag = parser.getAttributeValue(null, "info_tag");
@@ -3221,12 +3212,9 @@
                         if (!host.zombie || mSafeMode) {
                             // In safe mode, we don't discard the hosts we don't recognize
                             // so that they're not pruned from our list. Otherwise, we do.
-                            final int hostId = Integer.parseInt(parser.getAttributeValue(
-                                    null, "id"), 16);
-
-                            String tagAttribute = parser.getAttributeValue(null, "tag");
-                            final int hostTag = !TextUtils.isEmpty(tagAttribute)
-                                    ? Integer.parseInt(tagAttribute, 16) : legacyHostIndex;
+                            final int hostId = parser.getAttributeIntHex(null, "id");
+                            final int hostTag = parser.getAttributeIntHex(null, "tag",
+                                    legacyHostIndex);
 
                             host.tag = hostTag;
                             host.id = new HostId(uid, hostId, pkg);
@@ -3241,21 +3229,17 @@
                         }
                     } else if ("g".equals(tag)) {
                         Widget widget = new Widget();
-                        widget.appWidgetId = Integer.parseInt(parser.getAttributeValue(
-                                null, "id"), 16);
+                        widget.appWidgetId = parser.getAttributeIntHex(null, "id");
                         setMinAppWidgetIdLocked(userId, widget.appWidgetId + 1);
 
                         // restored ID is allowed to be absent
-                        String restoredIdString = parser.getAttributeValue(null, "rid");
-                        widget.restoredId = (restoredIdString == null) ? 0
-                                : Integer.parseInt(restoredIdString, 16);
+                        widget.restoredId = parser.getAttributeIntHex(null, "rid", 0);
                         widget.options = parseWidgetIdOptions(parser);
 
-                        final int hostTag = Integer.parseInt(parser.getAttributeValue(
-                                null, "h"), 16);
+                        final int hostTag = parser.getAttributeIntHex(null, "h");
                         String providerString = parser.getAttributeValue(null, "p");
-                        final int providerTag = (providerString != null) ? Integer.parseInt(
-                                parser.getAttributeValue(null, "p"), 16) : TAG_UNDEFINED;
+                        final int providerTag = (providerString != null)
+                                ? parser.getAttributeIntHex(null, "p") : TAG_UNDEFINED;
 
                         // We can match widgets with hosts and providers only after hosts
                         // and providers for all users have been loaded since the widget
@@ -4372,11 +4356,11 @@
                 }
 
                 try {
-                    XmlSerializer out = new FastXmlSerializer();
+                    TypedXmlSerializer out = Xml.newFastSerializer();
                     out.setOutput(stream, StandardCharsets.UTF_8.name());
                     out.startDocument(null, true);
                     out.startTag(null, "ws");      // widget state
-                    out.attribute(null, "version", String.valueOf(WIDGET_STATE_VERSION));
+                    out.attributeInt(null, "version", WIDGET_STATE_VERSION);
                     out.attribute(null, "pkg", backedupPackage);
 
                     // Remember all the providers that are currently hosted or published
@@ -4464,7 +4448,7 @@
                 // Hosts mentioned in the widget dataset by ordinal
                 ArrayList<Host> restoredHosts = new ArrayList<>();
 
-                XmlPullParser parser = Xml.newPullParser();
+                TypedXmlPullParser parser = Xml.newFastPullParser();
                 parser.setInput(stream, StandardCharsets.UTF_8.name());
 
                 synchronized (mLock) {
@@ -4474,11 +4458,9 @@
                         if (type == XmlPullParser.START_TAG) {
                             final String tag = parser.getName();
                             if ("ws".equals(tag)) {
-                                String version = parser.getAttributeValue(null, "version");
-
-                                final int versionNumber = Integer.parseInt(version);
+                                final int versionNumber = parser.getAttributeInt(null, "version");
                                 if (versionNumber > WIDGET_STATE_VERSION) {
-                                    Slog.w(TAG, "Unable to process state version " + version);
+                                    Slog.w(TAG, "Unable to process state version " + versionNumber);
                                     return;
                                 }
 
@@ -4520,8 +4502,7 @@
                                 String pkg = parser.getAttributeValue(null, "pkg");
 
                                 final int uid = getUidForPackage(pkg, userId);
-                                final int hostId = Integer.parseInt(
-                                        parser.getAttributeValue(null, "id"), 16);
+                                final int hostId = parser.getAttributeIntHex(null, "id");
 
                                 HostId id = new HostId(uid, hostId, pkg);
                                 Host h = lookupOrAddHostLocked(id);
@@ -4532,17 +4513,14 @@
                                             + "]: {" + h.id + "}");
                                 }
                             } else if ("g".equals(tag)) {
-                                int restoredId = Integer.parseInt(
-                                        parser.getAttributeValue(null, "id"), 16);
-                                int hostIndex = Integer.parseInt(
-                                        parser.getAttributeValue(null, "h"), 16);
+                                int restoredId = parser.getAttributeIntHex(null, "id");
+                                int hostIndex = parser.getAttributeIntHex(null, "h");
                                 Host host = restoredHosts.get(hostIndex);
                                 Provider p = null;
-                                String prov = parser.getAttributeValue(null, "p");
-                                if (prov != null) {
+                                int which = parser.getAttributeIntHex(null, "p", -1);
+                                if (which != -1) {
                                     // could have been null if the app had allocated an id
                                     // but not yet established a binding under that id
-                                    int which = Integer.parseInt(prov, 16);
                                     p = restoredProviders.get(which);
                                 }
 
diff --git a/services/art-profile b/services/art-profile
index 23a2e16..287e6094b 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -32073,6 +32073,32 @@
 PLcom/android/server/wm/AccessibilityController;->setMagnificationCallbacksLocked(ILcom/android/server/wm/WindowManagerInternal$MagnificationCallbacks;)Z
 PLcom/android/server/wm/AccessibilityController;->setMagnificationSpecLocked(ILandroid/view/MagnificationSpec;)V
 PLcom/android/server/wm/AccessibilityController;->setWindowsForAccessibilityCallbackLocked(ILcom/android/server/wm/WindowManagerInternal$WindowsForAccessibilityCallback;)Z
+HPLcom/android/server/wm/ActivityClientController;->activityDestroyed(Landroid/os/IBinder;)V
+HPLcom/android/server/wm/ActivityClientController;->activityIdle(Landroid/os/IBinder;Landroid/content/res/Configuration;Z)V
+HPLcom/android/server/wm/ActivityClientController;->activityPaused(Landroid/os/IBinder;)V
+PLcom/android/server/wm/ActivityClientController;->activityRelaunched(Landroid/os/IBinder;)V
+HPLcom/android/server/wm/ActivityClientController;->activityResumed(Landroid/os/IBinder;)V
+HPLcom/android/server/wm/ActivityClientController;->activityStopped(Landroid/os/IBinder;Landroid/os/Bundle;Landroid/os/PersistableBundle;Ljava/lang/CharSequence;)V
+HPLcom/android/server/wm/ActivityClientController;->activityTopResumedStateLost()V
+PLcom/android/server/wm/ActivityClientController;->ensureValidPictureInPictureActivityParamsLocked(Ljava/lang/String;Landroid/os/IBinder;Landroid/app/PictureInPictureParams;)Lcom/android/server/wm/ActivityRecord;
+PLcom/android/server/wm/ActivityClientController;->enterPictureInPictureMode(Landroid/os/IBinder;Landroid/app/PictureInPictureParams;)Z
+HPLcom/android/server/wm/ActivityClientController;->getActivityOptions(Landroid/os/IBinder;)Landroid/os/Bundle;
+PLcom/android/server/wm/ActivityClientController;->getCallingRecord(Landroid/os/IBinder;)Lcom/android/server/wm/ActivityRecord;
+PLcom/android/server/wm/ActivityClientController;->isTopOfTask(Landroid/os/IBinder;)Z
+PLcom/android/server/wm/ActivityClientController;->moveActivityTaskToBack(Landroid/os/IBinder;Z)Z
+PLcom/android/server/wm/ActivityClientController;->navigateUpTo(Landroid/os/IBinder;Landroid/content/Intent;ILandroid/content/Intent;)Z
+HPLcom/android/server/wm/ActivityClientController;->notifyActivityDrawn(Landroid/os/IBinder;)V
+HPLcom/android/server/wm/ActivityClientController;->onBackPressedOnTaskRoot(Landroid/os/IBinder;)V
+PLcom/android/server/wm/ActivityClientController;->overridePendingTransition(Landroid/os/IBinder;Ljava/lang/String;II)V
+PLcom/android/server/wm/ActivityClientController;->registerRemoteAnimations(Landroid/os/IBinder;Landroid/view/RemoteAnimationDefinition;)V
+PLcom/android/server/wm/ActivityClientController;->releaseActivityInstance(Landroid/os/IBinder;)Z
+PLcom/android/server/wm/ActivityClientController;->reportActivityFullyDrawn(Landroid/os/IBinder;Z)V
+HPLcom/android/server/wm/ActivityClientController;->reportSizeConfigurations(Landroid/os/IBinder;[I[I[I)V
+PLcom/android/server/wm/ActivityClientController;->setDisablePreviewScreenshots(Landroid/os/IBinder;Z)V
+PLcom/android/server/wm/ActivityClientController;->setShowWhenLocked(Landroid/os/IBinder;Z)V
+HPLcom/android/server/wm/ActivityClientController;->setTaskDescription(Landroid/os/IBinder;Landroid/app/ActivityManager$TaskDescription;)V
+PLcom/android/server/wm/ActivityClientController;->setTurnScreenOn(Landroid/os/IBinder;Z)V
+PLcom/android/server/wm/ActivityClientController;->unregisterRemoteAnimations(Landroid/os/IBinder;)V
 HSPLcom/android/server/wm/ActivityMetricsLogger$LaunchingState;-><init>()V
 HSPLcom/android/server/wm/ActivityMetricsLogger$LaunchingState;->access$000(Lcom/android/server/wm/ActivityMetricsLogger$LaunchingState;)J
 HSPLcom/android/server/wm/ActivityMetricsLogger$LaunchingState;->access$002(Lcom/android/server/wm/ActivityMetricsLogger$LaunchingState;J)J
@@ -32859,13 +32885,6 @@
 HSPLcom/android/server/wm/ActivityTaskManagerService;->access$602(Lcom/android/server/wm/ActivityTaskManagerService;Lcom/android/server/wm/BackgroundActivityStartCallback;)Lcom/android/server/wm/BackgroundActivityStartCallback;
 PLcom/android/server/wm/ActivityTaskManagerService;->access$802(Lcom/android/server/wm/ActivityTaskManagerService;Z)Z
 HSPLcom/android/server/wm/ActivityTaskManagerService;->access$900(Lcom/android/server/wm/ActivityTaskManagerService;)Z
-HPLcom/android/server/wm/ActivityTaskManagerService;->activityDestroyed(Landroid/os/IBinder;)V
-HPLcom/android/server/wm/ActivityTaskManagerService;->activityIdle(Landroid/os/IBinder;Landroid/content/res/Configuration;Z)V
-HPLcom/android/server/wm/ActivityTaskManagerService;->activityPaused(Landroid/os/IBinder;)V
-PLcom/android/server/wm/ActivityTaskManagerService;->activityRelaunched(Landroid/os/IBinder;)V
-HPLcom/android/server/wm/ActivityTaskManagerService;->activityResumed(Landroid/os/IBinder;)V
-HPLcom/android/server/wm/ActivityTaskManagerService;->activityStopped(Landroid/os/IBinder;Landroid/os/Bundle;Landroid/os/PersistableBundle;Ljava/lang/CharSequence;)V
-HPLcom/android/server/wm/ActivityTaskManagerService;->activityTopResumedStateLost()V
 HSPLcom/android/server/wm/ActivityTaskManagerService;->addWindowLayoutReasons(I)V
 HPLcom/android/server/wm/ActivityTaskManagerService;->applyUpdateLockStateLocked(Lcom/android/server/wm/ActivityRecord;)V
 HPLcom/android/server/wm/ActivityTaskManagerService;->applyUpdateVrModeLocked(Lcom/android/server/wm/ActivityRecord;)V
@@ -32898,8 +32917,6 @@
 HPLcom/android/server/wm/ActivityTaskManagerService;->enforceTaskPermission(Ljava/lang/String;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->enqueueAssistContext(ILandroid/content/Intent;Ljava/lang/String;Landroid/app/IAssistDataReceiver;Landroid/os/Bundle;Landroid/os/IBinder;ZZILandroid/os/Bundle;JI)Lcom/android/server/wm/ActivityTaskManagerService$PendingAssistExtras;
 HSPLcom/android/server/wm/ActivityTaskManagerService;->ensureConfigAndVisibilityAfterUpdate(Lcom/android/server/wm/ActivityRecord;I)Z
-PLcom/android/server/wm/ActivityTaskManagerService;->ensureValidPictureInPictureActivityParamsLocked(Ljava/lang/String;Landroid/os/IBinder;Landroid/app/PictureInPictureParams;)Lcom/android/server/wm/ActivityRecord;
-PLcom/android/server/wm/ActivityTaskManagerService;->enterPictureInPictureMode(Landroid/os/IBinder;Landroid/app/PictureInPictureParams;)Z
 PLcom/android/server/wm/ActivityTaskManagerService;->enterPictureInPictureMode(Lcom/android/server/wm/ActivityRecord;Landroid/app/PictureInPictureParams;)Z
 PLcom/android/server/wm/ActivityTaskManagerService;->expireStartAsCallerTokenMsg(Landroid/os/IBinder;)V
 HPLcom/android/server/wm/ActivityTaskManagerService;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
@@ -32909,7 +32926,6 @@
 PLcom/android/server/wm/ActivityTaskManagerService;->finishVoiceTask(Landroid/service/voice/IVoiceInteractionSession;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->forgetStartAsCallerTokenMsg(Landroid/os/IBinder;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->getActivityClassForToken(Landroid/os/IBinder;)Landroid/content/ComponentName;
-HPLcom/android/server/wm/ActivityTaskManagerService;->getActivityOptions(Landroid/os/IBinder;)Landroid/os/Bundle;
 HSPLcom/android/server/wm/ActivityTaskManagerService;->getActivityStartController()Lcom/android/server/wm/ActivityStartController;
 PLcom/android/server/wm/ActivityTaskManagerService;->getAllRootTaskInfosOnDisplay(I)Ljava/util/List;
 HSPLcom/android/server/wm/ActivityTaskManagerService;->getAppInfoForUser(Landroid/content/pm/ApplicationInfo;I)Landroid/content/pm/ApplicationInfo;
@@ -32919,7 +32935,6 @@
 HSPLcom/android/server/wm/ActivityTaskManagerService;->getBackgroundActivityStartCallback()Lcom/android/server/wm/BackgroundActivityStartCallback;
 PLcom/android/server/wm/ActivityTaskManagerService;->getCallingActivity(Landroid/os/IBinder;)Landroid/content/ComponentName;
 PLcom/android/server/wm/ActivityTaskManagerService;->getCallingPackage(Landroid/os/IBinder;)Ljava/lang/String;
-PLcom/android/server/wm/ActivityTaskManagerService;->getCallingRecordLocked(Landroid/os/IBinder;)Lcom/android/server/wm/ActivityRecord;
 PLcom/android/server/wm/ActivityTaskManagerService;->getConfiguration()Landroid/content/res/Configuration;
 PLcom/android/server/wm/ActivityTaskManagerService;->getCurrentUserId()I
 HPLcom/android/server/wm/ActivityTaskManagerService;->getDeviceConfigurationInfo()Landroid/content/pm/ConfigurationInfo;
@@ -32984,7 +32999,6 @@
 HPLcom/android/server/wm/ActivityTaskManagerService;->isSameApp(ILjava/lang/String;)Z
 HSPLcom/android/server/wm/ActivityTaskManagerService;->isSleepingLocked()Z
 HPLcom/android/server/wm/ActivityTaskManagerService;->isSleepingOrShuttingDownLocked()Z
-PLcom/android/server/wm/ActivityTaskManagerService;->isTopOfTask(Landroid/os/IBinder;)Z
 HPLcom/android/server/wm/ActivityTaskManagerService;->isUidForeground(I)Z
 HPLcom/android/server/wm/ActivityTaskManagerService;->keyguardGoingAway(I)V
 PLcom/android/server/wm/ActivityTaskManagerService;->lambda$4YLTqMi21jZ51BFcKX_h_gIoeGg(Lcom/android/server/wm/ActivityTaskManagerService;Ljava/util/Locale;)V
@@ -33000,33 +33014,22 @@
 PLcom/android/server/wm/ActivityTaskManagerService;->lambda$tPFRgtovnZu_2Zm4sCcLa9-oBto(Lcom/android/server/wm/ActivityTaskManagerService;Landroid/os/IBinder;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->lambda$uDPnzqVuuoVSFA7RJcXFWsrCwrY(Lcom/android/server/wm/ActivityTaskManagerService;ILandroid/content/res/Configuration;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->logAppTooSlow(Lcom/android/server/wm/WindowProcessController;JLjava/lang/String;)V
-PLcom/android/server/wm/ActivityTaskManagerService;->moveActivityTaskToBack(Landroid/os/IBinder;Z)Z
 PLcom/android/server/wm/ActivityTaskManagerService;->moveTaskToFrontLocked(Landroid/app/IApplicationThread;Ljava/lang/String;IILcom/android/server/wm/SafeActivityOptions;)V
-PLcom/android/server/wm/ActivityTaskManagerService;->navigateUpTo(Landroid/os/IBinder;Landroid/content/Intent;ILandroid/content/Intent;)Z
-HPLcom/android/server/wm/ActivityTaskManagerService;->notifyActivityDrawn(Landroid/os/IBinder;)V
-HSPLcom/android/server/wm/ActivityTaskManagerService;->notifyEnterAnimationComplete(Landroid/os/IBinder;)V
-PLcom/android/server/wm/ActivityTaskManagerService;->notifyLaunchTaskBehindComplete(Landroid/os/IBinder;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->notifyTaskPersisterLocked(Lcom/android/server/wm/Task;Z)V
 HSPLcom/android/server/wm/ActivityTaskManagerService;->onActivityManagerInternalAdded()V
-HPLcom/android/server/wm/ActivityTaskManagerService;->onBackPressedOnTaskRoot(Landroid/os/IBinder;)V
 HSPLcom/android/server/wm/ActivityTaskManagerService;->onInitPowerManagement()V
 HPLcom/android/server/wm/ActivityTaskManagerService;->onScreenAwakeChanged(Z)V
 HSPLcom/android/server/wm/ActivityTaskManagerService;->onStartActivitySetDidAppSwitch()V
 HSPLcom/android/server/wm/ActivityTaskManagerService;->onSystemReady()V
-PLcom/android/server/wm/ActivityTaskManagerService;->overridePendingTransition(Landroid/os/IBinder;Ljava/lang/String;II)V
 PLcom/android/server/wm/ActivityTaskManagerService;->pendingAssistExtrasTimedOut(Lcom/android/server/wm/ActivityTaskManagerService$PendingAssistExtras;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->postFinishBooting(ZZ)V
 PLcom/android/server/wm/ActivityTaskManagerService;->registerRemoteAnimationForNextActivityStart(Ljava/lang/String;Landroid/view/RemoteAnimationAdapter;)V
-PLcom/android/server/wm/ActivityTaskManagerService;->registerRemoteAnimations(Landroid/os/IBinder;Landroid/view/RemoteAnimationDefinition;)V
 HPLcom/android/server/wm/ActivityTaskManagerService;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->relaunchReasonToString(I)Ljava/lang/String;
-PLcom/android/server/wm/ActivityTaskManagerService;->releaseActivityInstance(Landroid/os/IBinder;)Z
 PLcom/android/server/wm/ActivityTaskManagerService;->releaseSomeActivities(Landroid/app/IApplicationThread;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->removeRootTasksInWindowingModes([I)V
 PLcom/android/server/wm/ActivityTaskManagerService;->removeTask(I)Z
-PLcom/android/server/wm/ActivityTaskManagerService;->reportActivityFullyDrawn(Landroid/os/IBinder;Z)V
 PLcom/android/server/wm/ActivityTaskManagerService;->reportAssistContextExtras(Landroid/os/IBinder;Landroid/os/Bundle;Landroid/app/assist/AssistStructure;Landroid/app/assist/AssistContent;Landroid/net/Uri;)V
-HPLcom/android/server/wm/ActivityTaskManagerService;->reportSizeConfigurations(Landroid/os/IBinder;[I[I[I)V
 PLcom/android/server/wm/ActivityTaskManagerService;->requestAssistContextExtras(ILandroid/app/IAssistDataReceiver;Landroid/os/Bundle;Landroid/os/IBinder;ZZ)Z
 PLcom/android/server/wm/ActivityTaskManagerService;->requestAutofillData(Landroid/app/IAssistDataReceiver;Landroid/os/Bundle;Landroid/os/IBinder;I)Z
 PLcom/android/server/wm/ActivityTaskManagerService;->requestStartActivityPermissionToken(Landroid/os/IBinder;)Landroid/os/IBinder;
@@ -33039,7 +33042,6 @@
 PLcom/android/server/wm/ActivityTaskManagerService;->setBooted(Z)V
 PLcom/android/server/wm/ActivityTaskManagerService;->setBooting(Z)V
 HSPLcom/android/server/wm/ActivityTaskManagerService;->setDeviceOwnerUid(I)V
-PLcom/android/server/wm/ActivityTaskManagerService;->setDisablePreviewScreenshots(Landroid/os/IBinder;Z)V
 PLcom/android/server/wm/ActivityTaskManagerService;->setFocusedTask(I)V
 PLcom/android/server/wm/ActivityTaskManagerService;->setImmersive(Landroid/os/IBinder;Z)V
 HPLcom/android/server/wm/ActivityTaskManagerService;->setLockScreenShown(ZZ)V
@@ -33047,10 +33049,7 @@
 HSPLcom/android/server/wm/ActivityTaskManagerService;->setRecentTasks(Lcom/android/server/wm/RecentTasks;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->setRequestedOrientation(Landroid/os/IBinder;I)V
 HPLcom/android/server/wm/ActivityTaskManagerService;->setResumedActivityUncheckLocked(Lcom/android/server/wm/ActivityRecord;Ljava/lang/String;)V
-PLcom/android/server/wm/ActivityTaskManagerService;->setShowWhenLocked(Landroid/os/IBinder;Z)V
 PLcom/android/server/wm/ActivityTaskManagerService;->setSplitScreenResizing(Z)V
-HPLcom/android/server/wm/ActivityTaskManagerService;->setTaskDescription(Landroid/os/IBinder;Landroid/app/ActivityManager$TaskDescription;)V
-PLcom/android/server/wm/ActivityTaskManagerService;->setTurnScreenOn(Landroid/os/IBinder;Z)V
 HSPLcom/android/server/wm/ActivityTaskManagerService;->setUsageStatsManager(Landroid/app/usage/UsageStatsManagerInternal;)V
 HSPLcom/android/server/wm/ActivityTaskManagerService;->setWindowManager(Lcom/android/server/wm/WindowManagerService;)V
 PLcom/android/server/wm/ActivityTaskManagerService;->shouldDisableNonVrUiLocked()Z
@@ -33070,7 +33069,6 @@
 PLcom/android/server/wm/ActivityTaskManagerService;->stopAppSwitches()V
 PLcom/android/server/wm/ActivityTaskManagerService;->stopLockTaskModeInternal(Landroid/os/IBinder;Z)V
 PLcom/android/server/wm/ActivityTaskManagerService;->stopSystemLockTaskMode()V
-PLcom/android/server/wm/ActivityTaskManagerService;->unregisterRemoteAnimations(Landroid/os/IBinder;)V
 HPLcom/android/server/wm/ActivityTaskManagerService;->unregisterTaskStackListener(Landroid/app/ITaskStackListener;)V
 HPLcom/android/server/wm/ActivityTaskManagerService;->updateActivityUsageStats(Lcom/android/server/wm/ActivityRecord;I)V
 HPLcom/android/server/wm/ActivityTaskManagerService;->updateBatteryStats(Lcom/android/server/wm/ActivityRecord;Z)V
diff --git a/services/autofill/OWNERS b/services/autofill/OWNERS
new file mode 100644
index 0000000..c52751d
--- /dev/null
+++ b/services/autofill/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/autofill/OWNERS
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 3212698..33d13de 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -1138,7 +1138,7 @@
         final int sessionCount = mSessions.size();
         for (int i = sessionCount - 1; i >= 0; i--) {
             final Session session = mSessions.valueAt(i);
-            if (session.isSavingLocked()) {
+            if (session.isSaveUiShowingLocked()) {
                 if (sDebug) Slog.d(TAG, "destroyFinishedSessionsLocked(): " + session.id);
                 session.forceRemoveFromServiceLocked();
             } else {
@@ -1660,7 +1660,7 @@
 
                     if (sessionToRemove != null && sessionsToRemove.valueAt(i)
                             == sessionToRemove.getActivityTokenLocked()) {
-                        if (sessionToRemove.isSavingLocked()) {
+                        if (sessionToRemove.isSaveUiShowingLocked()) {
                             if (sVerbose) {
                                 Slog.v(TAG, "Session " + sessionToRemove.id + " is saving");
                             }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index b48d71a..9d8901a 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -39,6 +39,7 @@
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
@@ -113,6 +114,8 @@
 import com.android.server.inputmethod.InputMethodManagerInternal;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -153,6 +156,33 @@
 
     private static AtomicInteger sIdCounter = new AtomicInteger(2);
 
+    @GuardedBy("mLock")
+    private @SessionState int mSessionState = STATE_UNKNOWN;
+
+    /** Session state uninitiated. */
+    public static final int STATE_UNKNOWN = 0;
+
+    /** Session is active for filling. */
+    public static final int STATE_ACTIVE = 1;
+
+    /** Session finished for filling, staying alive for saving. */
+    public static final int STATE_FINISHED = 2;
+
+    /** Session is destroyed and removed from the manager service. */
+    public static final int STATE_REMOVED = 3;
+
+    @IntDef(prefix = { "STATE_" }, value = {
+            STATE_UNKNOWN,
+            STATE_ACTIVE,
+            STATE_FINISHED,
+            STATE_REMOVED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface SessionState{}
+
+    @GuardedBy("mLock")
+    private final SessionFlags mSessionFlags;
+
     /**
      * ID of the session.
      *
@@ -236,10 +266,6 @@
     @GuardedBy("mLock")
     private boolean mDestroyed;
 
-    /** Whether the session is currently saving. */
-    @GuardedBy("mLock")
-    private boolean mIsSaving;
-
     /**
      * Helper used to handle state of Save UI when it must be hiding to show a custom description
      * link and later recovered.
@@ -270,9 +296,6 @@
     @GuardedBy("mLock")
     private final LocalLog mWtfHistory;
 
-    @GuardedBy("mLock")
-    private boolean mExpiredResponse;
-
     /**
      * Map of {@link MetricsEvent#AUTOFILL_REQUEST} metrics, keyed by fill request id.
      */
@@ -307,13 +330,6 @@
     @GuardedBy("mLock")
     private ArrayList<AutofillId> mAugmentedAutofillableIds;
 
-    /**
-     * When {@code true}, the session was created only to handle Augmented Autofill requests (i.e.,
-     * the session would not have existed otherwsie).
-     */
-    @GuardedBy("mLock")
-    private boolean mForAugmentedAutofillOnly;
-
     @Nullable
     private final AutofillInlineSessionController mInlineSessionController;
 
@@ -327,18 +343,18 @@
         // returns null, and augmented autofill is triggered,  and then the user switches the input
         // method. Tapping on the field again will not trigger a new augmented autofill request.
         // This may be fixed by adding more checks such as whether mCurrentViewId is null.
-        if (mExpiredResponse) {
+        if (mSessionFlags.mExpiredResponse) {
             return;
         }
         if (shouldResetSessionStateOnInputMethodSwitch()) {
             // Set the old response expired, so the next action (ACTION_VIEW_ENTERED) can trigger
             // a new fill request.
-            mExpiredResponse = true;
+            mSessionFlags.mExpiredResponse = true;
             // Clear the augmented autofillable ids so augmented autofill will trigger again.
             mAugmentedAutofillableIds = null;
             // In case the field is augmented autofill only, we clear the current view id, so that
             // we won't skip view entered due to same view entered, for the augmented autofill.
-            if (mForAugmentedAutofillOnly) {
+            if (mSessionFlags.mAugmentedAutofillOnly) {
                 mCurrentViewId = null;
             }
         }
@@ -356,7 +372,7 @@
             return false;
         }
 
-        if (isInlineSuggestionsEnabledByAutofillProviderLocked()) {
+        if (mSessionFlags.mInlineSupportedByService) {
             return true;
         }
 
@@ -370,6 +386,31 @@
     }
 
     /**
+     * Collection of flags/booleans that helps determine Session behaviors.
+     */
+    private final class SessionFlags {
+        /** Whether autofill is disabled by the service */
+        @GuardedBy("mLock")
+        private boolean mAutofillDisabled;
+
+        /** Whether the autofill service supports inline suggestions */
+        @GuardedBy("mLock")
+        private boolean mInlineSupportedByService;
+
+        /** True if session is for augmented only */
+        @GuardedBy("mLock")
+        private boolean mAugmentedAutofillOnly;
+
+        /** Whether the session is currently showing the SaveUi. */
+        @GuardedBy("mLock")
+        private boolean mShowingSaveUi;
+
+        /** Whether the current {@link FillResponse} is expired. */
+        @GuardedBy("mLock")
+        private boolean mExpiredResponse;
+    }
+
+    /**
      * TODO(b/151867668): improve how asynchronous data dependencies are handled, without using
      * CountDownLatch.
      */
@@ -423,7 +464,7 @@
         public void onHandleAssistData(Bundle resultData) throws RemoteException {
             if (mRemoteFillService == null) {
                 wtf(null, "onHandleAssistData() called without a remote service. "
-                        + "mForAugmentedAutofillOnly: %s", mForAugmentedAutofillOnly);
+                        + "mForAugmentedAutofillOnly: %s", mSessionFlags.mAugmentedAutofillOnly);
                 return;
             }
             // Keeps to prevent it is cleared on multiple threads.
@@ -685,7 +726,7 @@
     private void cancelCurrentRequestLocked() {
         if (mRemoteFillService == null) {
             wtf(null, "cancelCurrentRequestLocked() called without a remote service. "
-                    + "mForAugmentedAutofillOnly: %s", mForAugmentedAutofillOnly);
+                    + "mForAugmentedAutofillOnly: %s", mSessionFlags.mAugmentedAutofillOnly);
             return;
         }
         final int canceledRequest = mRemoteFillService.cancelCurrentRequest();
@@ -705,14 +746,6 @@
         }
     }
 
-    /**
-     * Returns whether inline suggestions are supported by Autofill provider (not augmented
-     * Autofill provider).
-     */
-    private boolean isInlineSuggestionsEnabledByAutofillProviderLocked() {
-        return mService.isInlineSuggestionsEnabledLocked();
-    }
-
     private boolean isViewFocusedLocked(int flags) {
         return (flags & FLAG_VIEW_NOT_FOCUSED) == 0;
     }
@@ -733,14 +766,15 @@
                     ViewState.STATE_INITIAL,
                     /* clearResponse= */ true);
         }
-        mExpiredResponse = false;
-        if (mForAugmentedAutofillOnly || mRemoteFillService == null) {
+        mSessionFlags.mExpiredResponse = false;
+        mSessionState = STATE_ACTIVE;
+        if (mSessionFlags.mAugmentedAutofillOnly || mRemoteFillService == null) {
             if (sVerbose) {
                 Slog.v(TAG, "requestNewFillResponse(): triggering augmented autofill instead "
-                        + "(mForAugmentedAutofillOnly=" + mForAugmentedAutofillOnly
+                        + "(mForAugmentedAutofillOnly=" + mSessionFlags.mAugmentedAutofillOnly
                         + ", flags=" + flags + ")");
             }
-            mForAugmentedAutofillOnly = true;
+            mSessionFlags.mAugmentedAutofillOnly = true;
             triggerAugmentedAutofillLocked(flags);
             return;
         }
@@ -779,7 +813,7 @@
         // is also not focused.
         final RemoteInlineSuggestionRenderService remoteRenderService =
                 mService.getRemoteInlineSuggestionRenderServiceLocked();
-        if (isInlineSuggestionsEnabledByAutofillProviderLocked()
+        if (mSessionFlags.mInlineSupportedByService
                 && remoteRenderService != null
                 && isViewFocusedLocked(flags)) {
             Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer =
@@ -849,8 +883,13 @@
         mWtfHistory = wtfHistory;
         mComponentName = componentName;
         mCompatMode = compatMode;
-        mForAugmentedAutofillOnly = forAugmentedAutofillOnly;
-        setClientLocked(client);
+        mSessionState = STATE_ACTIVE;
+        synchronized (mLock) {
+            mSessionFlags = new SessionFlags();
+            mSessionFlags.mAugmentedAutofillOnly = forAugmentedAutofillOnly;
+            mSessionFlags.mInlineSupportedByService = mService.isInlineSuggestionsEnabledLocked();
+            setClientLocked(client);
+        }
 
         mInlineSessionController = new AutofillInlineSessionController(inputMethodManagerInternal,
                 userId, componentName, handler, mLock,
@@ -906,9 +945,10 @@
         unlinkClientVultureLocked();
         mClient = IAutoFillManagerClient.Stub.asInterface(client);
         mClientVulture = () -> {
-            Slog.d(TAG, "handling death of " + mActivityToken + " when saving=" + mIsSaving);
             synchronized (mLock) {
-                if (mIsSaving) {
+                Slog.d(TAG, "handling death of " + mActivityToken + " when saving="
+                        + mSessionFlags.mShowingSaveUi);
+                if (mSessionFlags.mShowingSaveUi) {
                     mUi.hideFillUi(this);
                 } else {
                     mUi.destroyAll(mPendingSaveUi, this, false);
@@ -973,9 +1013,9 @@
 
         mService.setLastResponse(id, response);
 
-        int sessionFinishedState = 0;
         final long disableDuration = response.getDisableDuration();
-        if (disableDuration > 0) {
+        final boolean autofillDisabled = disableDuration > 0;
+        if (autofillDisabled) {
             final int flags = response.getFlags();
             final boolean disableActivityOnly =
                     (flags & FillResponse.FLAG_DISABLE_ACTIVITY_ONLY) != 0;
@@ -990,15 +1030,21 @@
                         id, mCompatMode);
             }
 
-            // Although "standard" autofill is disabled, it might still trigger augmented autofill
-            if (triggerAugmentedAutofillLocked(requestFlags) != null) {
-                mForAugmentedAutofillOnly = true;
-                if (sDebug) {
-                    Slog.d(TAG, "Service disabled autofill for " + mComponentName
-                            + ", but session is kept for augmented autofill only");
+            synchronized (mLock) {
+                mSessionFlags.mAutofillDisabled = true;
+
+                // Although "standard" autofill is disabled, it might still trigger augmented
+                // autofill
+                if (triggerAugmentedAutofillLocked(requestFlags) != null) {
+                    mSessionFlags.mAugmentedAutofillOnly = true;
+                    if (sDebug) {
+                        Slog.d(TAG, "Service disabled autofill for " + mComponentName
+                                + ", but session is kept for augmented autofill only");
+                    }
+                    return;
                 }
-                return;
             }
+
             if (sDebug) {
                 final StringBuilder message = new StringBuilder("Service disabled autofill for ")
                                 .append(mComponentName)
@@ -1007,14 +1053,15 @@
                 TimeUtils.formatDuration(disableDuration, message);
                 Slog.d(TAG, message.toString());
             }
-            sessionFinishedState = AutofillManager.STATE_DISABLED_BY_SERVICE;
         }
 
         if (((response.getDatasets() == null || response.getDatasets().isEmpty())
                         && response.getAuthentication() == null)
-                || disableDuration > 0) {
+                || autofillDisabled) {
             // Response is "empty" from an UI point of view, need to notify client.
-            notifyUnavailableToClient(sessionFinishedState, /* autofillableIds= */ null);
+            notifyUnavailableToClient(
+                    autofillDisabled ? AutofillManager.STATE_DISABLED_BY_SERVICE : 0,
+                    /* autofillableIds= */ null);
             synchronized (mLock) {
                 mInlineSessionController.setInlineFillUiLocked(
                         InlineFillUi.emptyUi(mCurrentViewId));
@@ -1094,7 +1141,7 @@
     public void onSaveRequestSuccess(@NonNull String servicePackageName,
             @Nullable IntentSender intentSender) {
         synchronized (mLock) {
-            mIsSaving = false;
+            mSessionFlags.mShowingSaveUi = false;
 
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#onSaveRequestSuccess() rejected - session: "
@@ -1120,7 +1167,7 @@
             @NonNull String servicePackageName) {
         boolean showMessage = !TextUtils.isEmpty(message);
         synchronized (mLock) {
-            mIsSaving = false;
+            mSessionFlags.mShowingSaveUi = false;
 
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#onSaveRequestFailure() rejected - session: "
@@ -1246,7 +1293,7 @@
     @Override
     public void cancelSave() {
         synchronized (mLock) {
-            mIsSaving = false;
+            mSessionFlags.mShowingSaveUi = false;
 
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#cancelSave() rejected - session: "
@@ -1424,7 +1471,7 @@
         }
 
         // The client becomes invisible for the authentication, the response is effective.
-        mExpiredResponse = false;
+        mSessionFlags.mExpiredResponse = false;
 
         final Parcelable result = data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT);
         final Bundle newClientState = data.getBundle(AutofillManager.EXTRA_CLIENT_STATE);
@@ -1996,6 +2043,7 @@
             return new SaveResult(/* logSaveShown= */ false, /* removeSession= */ false,
                     Event.NO_SAVE_REASON_NONE);
         }
+        mSessionState = STATE_FINISHED;
         final FillResponse response = getLastResponseLocked("showSaveLocked(%s)");
         final SaveInfo saveInfo = response == null ? null : response.getSaveInfo();
 
@@ -2267,7 +2315,7 @@
                         Slog.e(TAG, "Error notifying client to set save UI state to shown: " + e);
                     }
                 }
-                mIsSaving = true;
+                mSessionFlags.mShowingSaveUi = true;
                 return new SaveResult(/* logSaveShown= */ true, /* removeSession= */ false,
                         Event.NO_SAVE_REASON_NONE);
             }
@@ -2316,8 +2364,8 @@
      * Returns whether the session is currently showing the save UI
      */
     @GuardedBy("mLock")
-    boolean isSavingLocked() {
-        return mIsSaving;
+    boolean isSaveUiShowingLocked() {
+        return mSessionFlags.mShowingSaveUi;
     }
 
     /**
@@ -2435,7 +2483,7 @@
         }
         if (mRemoteFillService == null) {
             wtf(null, "callSaveLocked() called without a remote service. "
-                    + "mForAugmentedAutofillOnly: %s", mForAugmentedAutofillOnly);
+                    + "mForAugmentedAutofillOnly: %s", mSessionFlags.mAugmentedAutofillOnly);
             return;
         }
 
@@ -2540,7 +2588,7 @@
     private boolean requestNewFillResponseOnViewEnteredIfNecessaryLocked(@NonNull AutofillId id,
             @NonNull ViewState viewState, int flags) {
         if ((flags & FLAG_MANUAL_REQUEST) != 0) {
-            mForAugmentedAutofillOnly = false;
+            mSessionFlags.mAugmentedAutofillOnly = false;
             if (sDebug) Slog.d(TAG, "Re-starting session on view " + id + " and flags " + flags);
             requestNewFillResponseLocked(viewState, ViewState.STATE_RESTARTED_SESSION, flags);
             return true;
@@ -2578,7 +2626,7 @@
                     & ViewState.STATE_PENDING_CREATE_INLINE_REQUEST) == 0;
         }
 
-        if (mExpiredResponse) {
+        if (mSessionFlags.mExpiredResponse) {
             if (sDebug) {
                 Slog.d(TAG, "Starting a new partition because the response has expired.");
             }
@@ -2637,7 +2685,7 @@
             return;
         }
         if (action == ACTION_RESPONSE_EXPIRED) {
-            mExpiredResponse = true;
+            mSessionFlags.mExpiredResponse = true;
             if (sDebug) {
                 Slog.d(TAG, "Set the response has expired.");
             }
@@ -2652,7 +2700,8 @@
         ViewState viewState = mViewStates.get(id);
         if (sVerbose) {
             Slog.v(TAG, "updateLocked(" + this.id + "): mCurrentViewId=" + mCurrentViewId
-                    + ", mExpiredResponse=" + mExpiredResponse + ", viewState=" + viewState);
+                    + ", mExpiredResponse=" + mSessionFlags.mExpiredResponse
+                    + ", viewState=" + viewState);
         }
 
         if (viewState == null) {
@@ -2753,7 +2802,7 @@
                             if (sDebug) Slog.d(TAG, "skip augmented autofill for same view.");
                         }
                         return;
-                    } else if (mForAugmentedAutofillOnly && isSameViewEntered) {
+                    } else if (mSessionFlags.mAugmentedAutofillOnly && isSameViewEntered) {
                         // Regular autofill is disabled.
                         if (sDebug) Slog.d(TAG, "skip augmented autofill for same view.");
                         return;
@@ -3369,9 +3418,9 @@
         final RemoteInlineSuggestionRenderService remoteRenderService =
                 mService.getRemoteInlineSuggestionRenderServiceLocked();
         if (remoteRenderService != null
-                && (mForAugmentedAutofillOnly
-                || !isInlineSuggestionsEnabledByAutofillProviderLocked()
-                || mExpiredResponse)
+                && (mSessionFlags.mAugmentedAutofillOnly
+                || !mSessionFlags.mInlineSupportedByService
+                || mSessionFlags.mExpiredResponse)
                 && isViewFocusedLocked(flags)) {
             if (sDebug) Slog.d(TAG, "Create inline request for augmented autofill");
             remoteRenderService.getInlineSuggestionsRendererInfo(new RemoteCallback(
@@ -3694,7 +3743,8 @@
 
     @Override
     public String toString() {
-        return "Session: [id=" + id + ", component=" + mComponentName + "]";
+        return "Session: [id=" + id + ", component=" + mComponentName
+                + ", state=" + sessionStateAsString(mSessionState) + "]";
     }
 
     @GuardedBy("mLock")
@@ -3704,6 +3754,7 @@
         pw.print(prefix); pw.print("uid: "); pw.println(uid);
         pw.print(prefix); pw.print("taskId: "); pw.println(taskId);
         pw.print(prefix); pw.print("flags: "); pw.println(mFlags);
+        pw.print(prefix); pw.print("state: "); pw.println(sessionStateAsString(mSessionState));
         pw.print(prefix); pw.print("mComponentName: "); pw.println(mComponentName);
         pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
         pw.print(prefix); pw.print("mStartTime: "); pw.println(mStartTime);
@@ -3734,7 +3785,7 @@
         }
         pw.print(prefix); pw.print("mCurrentViewId: "); pw.println(mCurrentViewId);
         pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
-        pw.print(prefix); pw.print("mIsSaving: "); pw.println(mIsSaving);
+        pw.print(prefix); pw.print("mShowingSaveUi: "); pw.println(mSessionFlags.mShowingSaveUi);
         pw.print(prefix); pw.print("mPendingSaveUi: "); pw.println(mPendingSaveUi);
         final int numberViews = mViewStates.size();
         pw.print(prefix); pw.print("mViewStates size: "); pw.println(mViewStates.size());
@@ -3778,7 +3829,7 @@
         pw.print(prefix); pw.print("mSaveOnAllViewsInvisible: "); pw.println(
                 mSaveOnAllViewsInvisible);
         pw.print(prefix); pw.print("mSelectedDatasetIds: "); pw.println(mSelectedDatasetIds);
-        if (mForAugmentedAutofillOnly) {
+        if (mSessionFlags.mAugmentedAutofillOnly) {
             pw.print(prefix); pw.println("For Augmented Autofill Only");
         }
         if (mAugmentedAutofillDestroyer != null) {
@@ -3967,7 +4018,7 @@
             log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUMBER_AUGMENTED_REQUESTS,
                     totalAugmentedRequests);
         }
-        if (mForAugmentedAutofillOnly) {
+        if (mSessionFlags.mAugmentedAutofillOnly) {
             log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_AUGMENTED_ONLY, 1);
         }
         mMetricsLogger.write(log);
@@ -3988,9 +4039,9 @@
     void forceRemoveFromServiceIfForAugmentedOnlyLocked() {
         if (sVerbose) {
             Slog.v(TAG, "forceRemoveFromServiceIfForAugmentedOnlyLocked(" + this.id + "): "
-                    + mForAugmentedAutofillOnly);
+                    + mSessionFlags.mAugmentedAutofillOnly);
         }
-        if (!mForAugmentedAutofillOnly) return;
+        if (!mSessionFlags.mAugmentedAutofillOnly) return;
 
         forceRemoveFromServiceLocked();
     }
@@ -4052,6 +4103,7 @@
         if (remoteFillService != null) {
             remoteFillService.destroy();
         }
+        mSessionState = STATE_REMOVED;
     }
 
     void onPendingSaveUi(int operation, @NonNull IBinder token) {
@@ -4168,4 +4220,19 @@
                 return "UNKNOWN_" + action;
         }
     }
+
+    private static String sessionStateAsString(@SessionState int sessionState) {
+        switch (sessionState) {
+            case STATE_UNKNOWN:
+                return "STATE_UNKNOWN";
+            case STATE_ACTIVE:
+                return "STATE_ACTIVE";
+            case STATE_FINISHED:
+                return "STATE_FINISHED";
+            case STATE_REMOVED:
+                return "STATE_REMOVED";
+            default:
+                return "UNKNOWN_SESSION_STATE_" + sessionState;
+        }
+    }
 }
diff --git a/services/backup/Android.bp b/services/backup/Android.bp
index b5444f4..68376c5 100644
--- a/services/backup/Android.bp
+++ b/services/backup/Android.bp
@@ -10,5 +10,5 @@
     defaults: ["platform_service_defaults"],
     srcs: [":services.backup-sources"],
     libs: ["services.core"],
-    static_libs: ["backuplib"],
+    static_libs: ["backuplib", "app-compat-annotations"],
 }
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 2ff66b5..136cd22f 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -3030,9 +3030,11 @@
             }
             Slog.i(TAG, addUserIdToLogMessage(mUserId, "Beginning adb backup..."));
 
+            BackupEligibilityRules eligibilityRules = getEligibilityRulesForOperation(
+                    OperationType.ADB_BACKUP);
             AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs,
                     includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue,
-                    pkgList, mScheduledBackupEligibility);
+                    pkgList, eligibilityRules);
             final int token = generateRandomIntegerToken();
             synchronized (mAdbBackupRestoreConfirmations) {
                 mAdbBackupRestoreConfirmations.put(token, params);
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
index c94286f..e03150e 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -24,6 +24,7 @@
 import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_HEADER_MAGIC;
 import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_VERSION;
 
+import android.app.backup.BackupManager;
 import android.app.backup.IFullBackupRestoreObserver;
 import android.content.pm.PackageManagerInternal;
 import android.os.ParcelFileDescriptor;
@@ -104,11 +105,13 @@
                 return;
             }
 
+            BackupEligibilityRules eligibilityRules = new BackupEligibilityRules(
+                    mBackupManagerService.getPackageManager(),
+                    LocalServices.getService(PackageManagerInternal.class),
+                    mBackupManagerService.getUserId(), BackupManager.OperationType.ADB_BACKUP);
             FullRestoreEngine mEngine = new FullRestoreEngine(mBackupManagerService, null,
                     mObserver, null, null, true, 0 /*unused*/, true,
-                    BackupEligibilityRules.forBackup(mBackupManagerService.getPackageManager(),
-                                    LocalServices.getService(PackageManagerInternal.class),
-                                    mBackupManagerService.getUserId()));
+                    eligibilityRules);
             FullRestoreEngineThread mEngineThread = new FullRestoreEngineThread(mEngine,
                     tarInputStream);
             mEngineThread.run();
diff --git a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
index 73ba1f1..2078492 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
@@ -25,12 +25,16 @@
 import android.annotation.Nullable;
 import android.app.backup.BackupManager.OperationType;
 import android.app.backup.BackupTransport;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
+import android.app.compat.CompatChanges;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.Signature;
 import android.content.pm.SigningInfo;
+import android.os.Build;
 import android.os.UserHandle;
 import android.util.Slog;
 
@@ -41,6 +45,7 @@
 
 import com.google.android.collect.Sets;
 
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -57,6 +62,15 @@
     private final int mUserId;
     @OperationType  private final int mOperationType;
 
+    /**
+     * When  this change is enabled, {@code adb backup}  is automatically turned on for apps
+     * running as debuggable ({@code android:debuggable} set to {@code true}) and unavailable to
+     * any other apps.
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+    static final long RESTRICT_ADB_BACKUP = 171032338L;
+
     public static BackupEligibilityRules forBackup(PackageManager packageManager,
             PackageManagerInternal packageManagerInternal,
             int userId) {
@@ -134,12 +148,53 @@
     * @return boolean indicating whether backup is allowed.
     */
     public boolean isAppBackupAllowed(ApplicationInfo app) {
-        if (mOperationType == OperationType.MIGRATION && !UserHandle.isCore(app.uid)) {
-            // Backup / restore of all apps is force allowed during device-to-device migration.
-            return true;
-        }
+        boolean isSystemApp = UserHandle.isCore(app.uid);
+        boolean allowBackup = (app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0;
+        switch (mOperationType) {
+            case OperationType.MIGRATION:
+                // Backup / restore of all non-system apps is force allowed during
+                // device-to-device migration.
+                return !isSystemApp || allowBackup;
+            case OperationType.ADB_BACKUP:
+                String packageName = app.packageName;
+                if (packageName == null) {
+                    Slog.w(TAG, "Invalid ApplicationInfo object");
+                    return false;
+                }
 
-        return (app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0;
+                if (!CompatChanges.isChangeEnabled(RESTRICT_ADB_BACKUP, packageName,
+                        UserHandle.of(mUserId))) {
+                    return allowBackup;
+                }
+
+                if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
+                    // Always enable adb backup for SystemBackupAgent in "android" package (this is
+                    // done to avoid breaking existing integration tests and might change in the
+                    // future).
+                    return true;
+                }
+
+                boolean isPrivileged = (app.flags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
+                boolean isDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+                if (isSystemApp || isPrivileged) {
+                    try {
+                        return mPackageManager.getProperty(PackageManager.PROPERTY_ALLOW_ADB_BACKUP,
+                                packageName).getBoolean();
+                    } catch (PackageManager.NameNotFoundException e) {
+                        Slog.w(TAG, "Failed to read allowAdbBackup property for + "
+                                + packageName);
+                        return false;
+                    }
+                } else {
+                    // All other apps can use adb backup only when running in debuggable mode.
+                    return isDebuggable;
+                }
+            case OperationType.BACKUP:
+                return allowBackup;
+            default:
+                Slog.w(TAG, "Unknown operation type:" + mOperationType);
+                return false;
+        }
     }
 
     /**
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 5fedf9f..0a80b02 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -31,8 +31,12 @@
 import android.annotation.CheckResult;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
+import android.app.role.RoleManager;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
 import android.companion.Association;
 import android.companion.AssociationRequest;
 import android.companion.CompanionDeviceManager;
@@ -47,6 +51,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
 import android.net.NetworkPolicyManager;
 import android.os.Binder;
 import android.os.Environment;
@@ -62,6 +67,7 @@
 import android.os.ShellCallback;
 import android.os.ShellCommand;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.SettingsStringUtil.ComponentNameSet;
 import android.text.BidiFormatter;
@@ -70,6 +76,7 @@
 import android.util.ExceptionUtils;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.Xml;
 
 import com.android.internal.annotations.GuardedBy;
@@ -116,12 +123,16 @@
 //TODO on associate called again after configuration change -> replace old callback with new
 //TODO avoid leaking calling activity in IFindDeviceCallback (see PrintManager#print for example)
 /** @hide */
+@SuppressLint("LongLogTag")
 public class CompanionDeviceManagerService extends SystemService implements Binder.DeathRecipient {
 
     private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative(
             CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
             ".DeviceDiscoveryService");
 
+    // 10 min
+    public static final int DEVICE_DISCONNECT_PROFILE_REVOKE_DELAY_MS = 10 * 60 * 1000;
+
     private static final boolean DEBUG = false;
     private static final String LOG_TAG = "CompanionDeviceManagerService";
 
@@ -132,6 +143,8 @@
     private static final String XML_TAG_ASSOCIATION = "association";
     private static final String XML_ATTR_PACKAGE = "package";
     private static final String XML_ATTR_DEVICE = "device";
+    private static final String XML_ATTR_PROFILE = "profile";
+    private static final String XML_ATTR_PERSISTENT_PROFILE_GRANTS = "persistent_profile_grants";
     private static final String XML_FILE_NAME = "companion_device_manager_associations.xml";
 
     private final CompanionDeviceManagerImpl mImpl;
@@ -139,21 +152,29 @@
     private PowerWhitelistManager mPowerWhitelistManager;
     private PerUser<ServiceConnector<ICompanionDeviceDiscoveryService>> mServiceConnectors;
     private IAppOpsService mAppOpsManager;
+    private RoleManager mRoleManager;
+    private BluetoothAdapter mBluetoothAdapter;
 
     private IFindDeviceCallback mFindDeviceCallback;
     private AssociationRequest mRequest;
     private String mCallingPackage;
     private AndroidFuture<Association> mOngoingDeviceDiscovery;
 
+    private BluetoothDeviceConnectedListener mBluetoothDeviceConnectedListener =
+            new BluetoothDeviceConnectedListener();
+    private List<String> mCurrentlyConnectedDevices = new ArrayList<>();
+
     private final Object mLock = new Object();
 
+    /** userId -> [association] */
     @GuardedBy("mLock")
-    private @Nullable Set<Association> mCachedAssociations = null;
+    private @Nullable SparseArray<Set<Association>> mCachedAssociations = new SparseArray<>();
 
     public CompanionDeviceManagerService(Context context) {
         super(context);
         mImpl = new CompanionDeviceManagerImpl();
         mPowerWhitelistManager = context.getSystemService(PowerWhitelistManager.class);
+        mRoleManager = context.getSystemService(RoleManager.class);
         mAppOpsManager = IAppOpsService.Stub.asInterface(
                 ServiceManager.getService(Context.APP_OPS_SERVICE));
 
@@ -184,9 +205,9 @@
             @Override
             public void onPackageModified(String packageName) {
                 int userId = getChangingUserId();
-                if (!ArrayUtils.isEmpty(getAllAssociations(userId, packageName))) {
-                    updateSpecialAccessPermissionForAssociatedPackage(packageName, userId);
-                }
+                forEach(getAllAssociations(userId, packageName), association -> {
+                    updateSpecialAccessPermissionForAssociatedPackage(association);
+                });
             }
 
         }.register(getContext(), FgThread.get().getLooper(), UserHandle.ALL, true);
@@ -198,6 +219,18 @@
     }
 
     @Override
+    public void onBootPhase(int phase) {
+        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
+            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+            if (mBluetoothAdapter != null) {
+                mBluetoothAdapter.registerBluetoothConnectionCallback(
+                        getContext().getMainExecutor(),
+                        mBluetoothDeviceConnectedListener);
+            }
+        }
+    }
+
+    @Override
     public void onUserUnlocking(@NonNull TargetUser user) {
         int userHandle = user.getUserIdentifier();
         Set<Association> associations = getAllAssociations(userHandle);
@@ -495,12 +528,14 @@
 
             fout.append("Companion Device Associations:").append('\n');
             synchronized (mLock) {
-                forEach(mCachedAssociations, a -> {
-                    fout.append("  ")
-                            .append("u").append("" + a.getUserId()).append(": ")
-                            .append(a.getPackageName()).append(" - ")
-                            .append(a.getDeviceMacAddress()).append('\n');
-                });
+                for (UserInfo user : getAllUsers()) {
+                    forEach(mCachedAssociations.get(user.id), a -> {
+                        fout.append("  ")
+                                .append("u").append("" + a.getUserId()).append(": ")
+                                .append(a.getPackageName()).append(" - ")
+                                .append(a.getDeviceMacAddress()).append('\n');
+                    });
+                }
             }
         }
     }
@@ -513,32 +548,34 @@
         return Binder.getCallingUid() == Process.SYSTEM_UID;
     }
 
-    void addAssociation(int userId, String packageName, String deviceAddress) {
-        addAssociation(new Association(userId, deviceAddress, packageName));
-    }
-
     void addAssociation(Association association) {
-        updateSpecialAccessPermissionForAssociatedPackage(
-                association.getPackageName(), association.getUserId());
+        updateSpecialAccessPermissionForAssociatedPackage(association);
         recordAssociation(association);
     }
 
     void removeAssociation(int userId, String pkg, String deviceMacAddress) {
-        updateAssociations(associations -> CollectionUtils.remove(associations,
-                new Association(userId, deviceMacAddress, pkg)));
+        updateAssociations(associations -> CollectionUtils.filter(associations, association -> {
+            return association.getUserId() != userId
+                    || !Objects.equals(association.getDeviceMacAddress(), deviceMacAddress)
+                    || !Objects.equals(association.getPackageName(), pkg);
+        }));
     }
 
-    private void updateSpecialAccessPermissionForAssociatedPackage(String packageName, int userId) {
-        PackageInfo packageInfo = getPackageInfo(packageName, userId);
+    private void updateSpecialAccessPermissionForAssociatedPackage(Association association) {
+        PackageInfo packageInfo = getPackageInfo(
+                association.getPackageName(),
+                association.getUserId());
         if (packageInfo == null) {
             return;
         }
 
         Binder.withCleanCallingIdentity(obtainRunnable(CompanionDeviceManagerService::
-                updateSpecialAccessPermissionAsSystem, this, packageInfo).recycleOnUse());
+                updateSpecialAccessPermissionAsSystem, this, association, packageInfo)
+                .recycleOnUse());
     }
 
-    private void updateSpecialAccessPermissionAsSystem(PackageInfo packageInfo) {
+    private void updateSpecialAccessPermissionAsSystem(
+            Association association, PackageInfo packageInfo) {
         if (containsEither(packageInfo.requestedPermissions,
                 android.Manifest.permission.RUN_IN_BACKGROUND,
                 android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND)) {
@@ -602,10 +639,6 @@
         updateAssociations(associations -> CollectionUtils.add(associations, association));
     }
 
-    private void recordAssociation(String privilegedPackage, String deviceAddress) {
-        recordAssociation(new Association(getCallingUserId(), deviceAddress, privilegedPackage));
-    }
-
     private void updateAssociations(Function<Set<Association>, Set<Association>> update) {
         updateAssociations(update, getCallingUserId());
     }
@@ -625,7 +658,7 @@
             if (DEBUG) {
                 Slog.i(LOG_TAG, "Updating associations: " + old + "  -->  " + associations);
             }
-            mCachedAssociations = Collections.unmodifiableSet(associations);
+            mCachedAssociations.put(userId, Collections.unmodifiableSet(associations));
             BackgroundThread.getHandler().sendMessage(PooledLambda.obtainMessage(
                     CompanionDeviceManagerService::persistAssociations,
                     this, associations, userId));
@@ -651,10 +684,17 @@
                     xml.startTag(null, XML_TAG_ASSOCIATIONS);
 
                     forEach(associations, association -> {
-                        xml.startTag(null, XML_TAG_ASSOCIATION)
+                        XmlSerializer tag = xml.startTag(null, XML_TAG_ASSOCIATION)
                                 .attribute(null, XML_ATTR_PACKAGE, association.getPackageName())
-                                .attribute(null, XML_ATTR_DEVICE, association.getDeviceMacAddress())
-                                .endTag(null, XML_TAG_ASSOCIATION);
+                                .attribute(null, XML_ATTR_DEVICE,
+                                        association.getDeviceMacAddress());
+                        if (association.getDeviceProfile() != null) {
+                            tag.attribute(null, XML_ATTR_PROFILE, association.getDeviceProfile());
+                            tag.attribute(null, XML_ATTR_PERSISTENT_PROFILE_GRANTS,
+                                    Boolean.toString(
+                                            association.isKeepProfilePrivilegesWhenDeviceAway()));
+                        }
+                        tag.endTag(null, XML_TAG_ASSOCIATION);
                     });
 
                     xml.endTag(null, XML_TAG_ASSOCIATIONS);
@@ -678,17 +718,21 @@
     @Nullable
     private Set<Association> getAllAssociations(int userId) {
         synchronized (mLock) {
-            if (mCachedAssociations == null) {
-                mCachedAssociations = Collections.unmodifiableSet(
-                        emptyIfNull(readAllAssociations(userId)));
+            if (mCachedAssociations.get(userId) == null) {
+                mCachedAssociations.put(userId, Collections.unmodifiableSet(
+                        emptyIfNull(readAllAssociations(userId))));
                 if (DEBUG) {
                     Slog.i(LOG_TAG, "Read associations from disk: " + mCachedAssociations);
                 }
             }
-            return mCachedAssociations;
+            return mCachedAssociations.get(userId);
         }
     }
 
+    private List<UserInfo> getAllUsers() {
+        return getContext().getSystemService(UserManager.class).getUsers();
+    }
+
     @Nullable
     private Set<Association> getAllAssociations(int userId, @Nullable String packageFilter) {
         return CollectionUtils.filter(
@@ -714,10 +758,15 @@
                     final String appPackage = parser.getAttributeValue(null, XML_ATTR_PACKAGE);
                     final String deviceAddress = parser.getAttributeValue(null, XML_ATTR_DEVICE);
 
+                    final String profile = parser.getAttributeValue(null, XML_ATTR_PROFILE);
+                    final boolean persistentGrants = Boolean.valueOf(
+                            parser.getAttributeValue(null, XML_ATTR_PERSISTENT_PROFILE_GRANTS));
+
                     if (appPackage == null || deviceAddress == null) continue;
 
                     result = ArrayUtils.add(result,
-                            new Association(userId, deviceAddress, appPackage));
+                            new Association(userId, deviceAddress, appPackage,
+                                    profile, persistentGrants));
                 }
                 return result;
             } catch (XmlPullParserException | IOException e) {
@@ -727,6 +776,77 @@
         }
     }
 
+    void onDeviceConnected(String address) {
+        mCurrentlyConnectedDevices.add(address);
+
+        Handler.getMain().removeCallbacksAndMessages(getDisconnectJobHandlerId(address));
+
+        for (UserInfo user : getAllUsers()) {
+            for (Association association : getAllAssociations(user.id)) {
+                if (Objects.equals(address, association.getDeviceMacAddress())) {
+                    if (association.getDeviceProfile() != null) {
+                        Log.i(LOG_TAG, "Granting role " + association.getDeviceProfile()
+                                + " to " + association.getPackageName()
+                                + " due to device connected: " + address);
+                        mRoleManager.addRoleHolderAsUser(
+                                association.getDeviceProfile(),
+                                association.getPackageName(),
+                                RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP,
+                                UserHandle.of(association.getUserId()),
+                                getContext().getMainExecutor(),
+                                success -> {
+                                    if (!success) {
+                                        Log.e(LOG_TAG, "Failed to grant device profile role "
+                                                + association.getDeviceProfile()
+                                                + " to " + association.getPackageName()
+                                                + " for user " + association.getUserId());
+                                    }
+                                });
+                    }
+                }
+            }
+        }
+    }
+
+    void onDeviceDisconnected(String address) {
+        mCurrentlyConnectedDevices.remove(address);
+
+        Handler.getMain().postDelayed(() -> {
+            if (!mCurrentlyConnectedDevices.contains(address)) {
+                for (UserInfo user : getAllUsers()) {
+                    for (Association association : getAllAssociations(user.id)) {
+                        if (association.getDeviceProfile() != null
+                                && Objects.equals(address, association.getDeviceMacAddress())
+                                && !association.isKeepProfilePrivilegesWhenDeviceAway()) {
+                            Log.i(LOG_TAG, "Revoking role " + association.getDeviceProfile()
+                                    + " to " + association.getPackageName()
+                                    + " due to device disconnected: " + address);
+                            mRoleManager.removeRoleHolderAsUser(
+                                    association.getDeviceProfile(),
+                                    association.getPackageName(),
+                                    RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP,
+                                    UserHandle.of(association.getUserId()),
+                                    getContext().getMainExecutor(),
+                                    success -> {
+                                        if (!success) {
+                                            Log.e(LOG_TAG, "Failed to revoke device profile role "
+                                                    + association.getDeviceProfile()
+                                                    + " to " + association.getPackageName()
+                                                    + " for user " + association.getUserId());
+                                        }
+                                    });
+                        }
+                    }
+                }
+            }
+        }, getDisconnectJobHandlerId(address), DEVICE_DISCONNECT_PROFILE_REVOKE_DELAY_MS);
+    }
+
+    @NonNull
+    private String getDisconnectJobHandlerId(String address) {
+        return "CDM_onDisconnected_" + address;
+    }
+
     private class ShellCmd extends ShellCommand {
         public static final String USAGE = "help\n"
                 + "list USER_ID\n"
@@ -749,13 +869,22 @@
                 } break;
 
                 case "associate": {
-                    addAssociation(getNextArgInt(), getNextArgRequired(), getNextArgRequired());
+                    addAssociation(new Association(getNextArgInt(), getNextArgRequired(),
+                            getNextArgRequired(), null, false));
                 } break;
 
                 case "disassociate": {
                     removeAssociation(getNextArgInt(), getNextArgRequired(), getNextArgRequired());
                 } break;
 
+                case "simulate_connect": {
+                    onDeviceConnected(getNextArgRequired());
+                } break;
+
+                case "simulate_disconnect": {
+                    onDeviceDisconnected(getNextArgRequired());
+                } break;
+
                 default: return handleDefaultCommands(cmd);
             }
             return 0;
@@ -771,4 +900,17 @@
         }
     }
 
+
+    private class BluetoothDeviceConnectedListener
+            extends BluetoothAdapter.BluetoothConnectionCallback {
+        @Override
+        public void onDeviceConnected(BluetoothDevice device) {
+            CompanionDeviceManagerService.this.onDeviceConnected(device.getAddress());
+        }
+
+        @Override
+        public void onDeviceDisconnected(BluetoothDevice device) {
+            CompanionDeviceManagerService.this.onDeviceDisconnected(device.getAddress());
+        }
+    }
 }
diff --git a/services/contentcapture/OWNERS b/services/contentcapture/OWNERS
new file mode 100644
index 0000000..a28e00a
--- /dev/null
+++ b/services/contentcapture/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/contentcapture/OWNERS
diff --git a/services/contentsuggestions/OWNERS b/services/contentsuggestions/OWNERS
new file mode 100644
index 0000000..449db3a
--- /dev/null
+++ b/services/contentsuggestions/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/contentsuggestions/OWNERS
diff --git a/services/core/OWNERS b/services/core/OWNERS
new file mode 100644
index 0000000..88d0b61
--- /dev/null
+++ b/services/core/OWNERS
@@ -0,0 +1 @@
+per-file Android.bp = file:platform/build/soong:/OWNERS
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 6989e32..53bfcec 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -949,9 +949,6 @@
     /** Returns whether or not permissions need to be upgraded for the given user */
     public abstract boolean isPermissionUpgradeNeeded(@UserIdInt int userId);
 
-    /** Sets the enforcement of reading external storage */
-    public abstract void setReadExternalStorageEnforced(boolean enforced);
-
     /**
      * Allows the integrity component to respond to the
      * {@link Intent#ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION package verification
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index f0677a2..0d0f0dd 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -169,7 +169,6 @@
 import android.util.LocalLog;
 import android.util.Log;
 import android.util.Pair;
-import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.Xml;
@@ -1973,7 +1972,7 @@
     private void registerNetdEventCallback() {
         final IIpConnectivityMetrics ipConnectivityMetrics = mDeps.getIpConnectivityMetrics();
         if (ipConnectivityMetrics == null) {
-            Slog.wtf(TAG, "Missing IIpConnectivityMetrics");
+            Log.wtf(TAG, "Missing IIpConnectivityMetrics");
             return;
         }
 
@@ -2439,7 +2438,7 @@
             if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu);
             mNetd.interfaceSetMtu(iface, mtu);
         } catch (RemoteException | ServiceSpecificException e) {
-            Slog.e(TAG, "exception in interfaceSetMtu()" + e);
+            loge("exception in interfaceSetMtu()" + e);
         }
     }
 
@@ -2461,7 +2460,7 @@
         if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return;
 
         try {
-            if (VDBG || DDBG) Slog.d(TAG, "Setting tx/rx TCP buffers to " + tcpBufferSizes);
+            if (VDBG || DDBG) log("Setting tx/rx TCP buffers to " + tcpBufferSizes);
 
             String rmemValues = String.join(" ", values[0], values[1], values[2]);
             String wmemValues = String.join(" ", values[3], values[4], values[5]);
@@ -2762,7 +2761,7 @@
                 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
                     NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj;
                     if (networkCapabilities.hasConnectivityManagedCapability()) {
-                        Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
+                        Log.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
                     }
                     if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
                         // Make sure the original object is not mutated. NetworkAgent normally
@@ -3067,7 +3066,7 @@
             // Legacy version of notifyNetworkTestedWithExtras.
             // Would only be called if the system has a NetworkStack module older than the
             // framework, which does not happen in practice.
-            Slog.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken");
+            Log.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken");
         }
 
         @Override
@@ -3544,7 +3543,7 @@
                 numRequests = nai.numForegroundNetworkRequests();
                 break;
             default:
-                Slog.wtf(TAG, "Invalid reason. Cannot happen.");
+                Log.wtf(TAG, "Invalid reason. Cannot happen.");
                 return true;
         }
 
@@ -3706,7 +3705,7 @@
         synchronized (mUidToNetworkRequestCount) {
             final int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
             if (requests < 1) {
-                Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " + nri.mUid);
+                Log.wtf(TAG, "BUG: too small request count " + requests + " for UID " + nri.mUid);
             } else if (requests == 1) {
                 mUidToNetworkRequestCount.removeAt(mUidToNetworkRequestCount.indexOfKey(nri.mUid));
             } else {
@@ -3751,7 +3750,7 @@
         }
 
         if (!nai.networkAgentConfig.explicitlySelected) {
-            Slog.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
+            Log.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
         }
 
         if (accept != nai.networkAgentConfig.acceptUnvalidated) {
@@ -4021,7 +4020,7 @@
                 highPriority = nai.networkAgentConfig.explicitlySelected;
                 break;
             default:
-                Slog.wtf(TAG, "Unknown notification type " + type);
+                Log.wtf(TAG, "Unknown notification type " + type);
                 return;
         }
 
@@ -4343,7 +4342,7 @@
         synchronized (this) {
             if (!mNetTransitionWakeLock.isHeld()) {
                 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event));
-                Slog.w(TAG, "expected Net Transition WakeLock to be held");
+                Log.w(TAG, "expected Net Transition WakeLock to be held");
                 return;
             }
             mNetTransitionWakeLock.release();
@@ -4515,7 +4514,7 @@
 
         @Override
         public void onChange(boolean selfChange) {
-            Slog.wtf(TAG, "Should never be reached.");
+            Log.wtf(TAG, "Should never be reached.");
         }
 
         @Override
@@ -4530,15 +4529,19 @@
     }
 
     private static void log(String s) {
-        Slog.d(TAG, s);
+        Log.d(TAG, s);
+    }
+
+    private static void logw(String s) {
+        Log.w(TAG, s);
     }
 
     private static void loge(String s) {
-        Slog.e(TAG, s);
+        Log.e(TAG, s);
     }
 
     private static void loge(String s, Throwable t) {
-        Slog.e(TAG, s, t);
+        Log.e(TAG, s, t);
     }
 
     /**
@@ -4825,7 +4828,7 @@
     @Override
     public boolean updateLockdownVpn() {
         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            Slog.w(TAG, "Lockdown VPN only available to AID_SYSTEM");
+            logw("Lockdown VPN only available to AID_SYSTEM");
             return false;
         }
 
@@ -4835,21 +4838,21 @@
             if (mLockdownEnabled) {
                 byte[] profileTag = mKeyStore.get(Credentials.LOCKDOWN_VPN);
                 if (profileTag == null) {
-                    Slog.e(TAG, "Lockdown VPN configured but cannot be read from keystore");
+                    loge("Lockdown VPN configured but cannot be read from keystore");
                     return false;
                 }
                 String profileName = new String(profileTag);
                 final VpnProfile profile = VpnProfile.decode(
                         profileName, mKeyStore.get(Credentials.VPN + profileName));
                 if (profile == null) {
-                    Slog.e(TAG, "Lockdown VPN configured invalid profile " + profileName);
+                    loge("Lockdown VPN configured invalid profile " + profileName);
                     setLockdownTracker(null);
                     return true;
                 }
                 int user = UserHandle.getUserId(Binder.getCallingUid());
                 Vpn vpn = mVpns.get(user);
                 if (vpn == null) {
-                    Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown");
+                    logw("VPN for user " + user + " not ready yet. Skipping lockdown");
                     return false;
                 }
                 setLockdownTracker(new LockdownVpnTracker(mContext, this, mHandler, vpn, profile));
@@ -4909,7 +4912,7 @@
             if (vpn == null) {
                 // Shouldn't happen as all code paths that point here should have checked the Vpn
                 // exists already.
-                Slog.wtf(TAG, "User " + userId + " has no Vpn configuration");
+                Log.wtf(TAG, "User " + userId + " has no Vpn configuration");
                 return false;
             }
 
@@ -4925,7 +4928,7 @@
         synchronized (mVpns) {
             Vpn vpn = mVpns.get(userId);
             if (vpn == null) {
-                Slog.w(TAG, "User " + userId + " has no Vpn configuration");
+                logw("User " + userId + " has no Vpn configuration");
                 return false;
             }
             return vpn.isAlwaysOnPackageSupported(packageName, mKeyStore);
@@ -4946,7 +4949,7 @@
 
             Vpn vpn = mVpns.get(userId);
             if (vpn == null) {
-                Slog.w(TAG, "User " + userId + " has no Vpn configuration");
+                logw("User " + userId + " has no Vpn configuration");
                 return false;
             }
             if (!vpn.setAlwaysOnPackage(packageName, lockdown, lockdownWhitelist, mKeyStore)) {
@@ -4968,7 +4971,7 @@
         synchronized (mVpns) {
             Vpn vpn = mVpns.get(userId);
             if (vpn == null) {
-                Slog.w(TAG, "User " + userId + " has no Vpn configuration");
+                logw("User " + userId + " has no Vpn configuration");
                 return null;
             }
             return vpn.getAlwaysOnPackage();
@@ -4983,7 +4986,7 @@
         synchronized (mVpns) {
             Vpn vpn = mVpns.get(userId);
             if (vpn == null) {
-                Slog.w(TAG, "User " + userId + " has no Vpn configuration");
+                logw("User " + userId + " has no Vpn configuration");
                 return false;
             }
             return vpn.getLockdown();
@@ -4998,7 +5001,7 @@
         synchronized (mVpns) {
             Vpn vpn = mVpns.get(userId);
             if (vpn == null) {
-                Slog.w(TAG, "User " + userId + " has no Vpn configuration");
+                logw("User " + userId + " has no Vpn configuration");
                 return null;
             }
             return vpn.getLockdownAllowlist();
@@ -5183,7 +5186,7 @@
 
     private void onPackageReplaced(String packageName, int uid) {
         if (TextUtils.isEmpty(packageName) || uid < 0) {
-            Slog.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid);
+            Log.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid);
             return;
         }
         final int userId = UserHandle.getUserId(uid);
@@ -5194,7 +5197,7 @@
             }
             // Legacy always-on VPN won't be affected since the package name is not set.
             if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName)) {
-                Slog.d(TAG, "Restarting always-on VPN package " + packageName + " for user "
+                log("Restarting always-on VPN package " + packageName + " for user "
                         + userId);
                 vpn.startAlwaysOnVpn(mKeyStore);
             }
@@ -5203,7 +5206,7 @@
 
     private void onPackageRemoved(String packageName, int uid, boolean isReplacing) {
         if (TextUtils.isEmpty(packageName) || uid < 0) {
-            Slog.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid);
+            Log.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid);
             return;
         }
 
@@ -5215,7 +5218,7 @@
             }
             // Legacy always-on VPN won't be affected since the package name is not set.
             if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName) && !isReplacing) {
-                Slog.d(TAG, "Removing always-on VPN package " + packageName + " for user "
+                log("Removing always-on VPN package " + packageName + " for user "
                         + userId);
                 vpn.setAlwaysOnPackage(null, false, null, mKeyStore);
             }
@@ -5831,7 +5834,7 @@
             // Avoid creating duplicates. even if an app makes a direct AIDL call.
             // This will never happen if an app calls ConnectivityManager#registerNetworkProvider,
             // as that will throw if a duplicate provider is registered.
-            Slog.e(TAG, "Attempt to register existing NetworkProviderInfo "
+            loge("Attempt to register existing NetworkProviderInfo "
                     + mNetworkProviderInfos.get(npi.messenger).name);
             return;
         }
@@ -6049,6 +6052,7 @@
      * Stores into |nai| any data coming from the agent that might also be written to the network's
      * LinkProperties by ConnectivityService itself. This ensures that the data provided by the
      * agent is not lost when updateLinkProperties is called.
+     * This method should never alter the agent's LinkProperties, only store data in |nai|.
      */
     private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
         lp.ensureDirectlyConnectedRoutes();
@@ -6350,6 +6354,7 @@
      * Stores into |nai| any data coming from the agent that might also be written to the network's
      * NetworkCapabilities by ConnectivityService itself. This ensures that the data provided by the
      * agent is not lost when updateCapabilities is called.
+     * This method should never alter the agent's NetworkCapabilities, only store data in |nai|.
      */
     private void processCapabilitiesFromAgent(NetworkAgentInfo nai, NetworkCapabilities nc) {
         nai.declaredMetered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED);
@@ -6441,7 +6446,7 @@
             // stop being matched by the updated agent.
             String diff = nai.networkCapabilities.describeImmutableDifferences(nc);
             if (!TextUtils.isEmpty(diff)) {
-                Slog.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
+                Log.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
             }
         }
 
@@ -7001,7 +7006,7 @@
             }
             newSatisfier.unlingerRequest(nri.request);
             if (!newSatisfier.addRequest(nri.request)) {
-                Slog.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has "
+                Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has "
                         + nri.request);
             }
         } else {
@@ -7349,7 +7354,7 @@
             networkAgent.everConnected = true;
 
             if (networkAgent.linkProperties == null) {
-                Slog.wtf(TAG, networkAgent.toShortString() + " connected with null LinkProperties");
+                Log.wtf(TAG, networkAgent.toShortString() + " connected with null LinkProperties");
             }
 
             // NetworkCapabilities need to be set before sending the private DNS config to
@@ -8197,8 +8202,10 @@
 
         final NetworkRequestInfo nri = cbInfo.mRequestInfo;
 
-        if (uid != nri.mUid) {
-            if (VDBG) loge("Different uid than registrant attempting to unregister cb");
+        // Caller's UID must either be the registrants (if they are unregistering) or the System's
+        // (if the Binder died)
+        if (uid != nri.mUid && uid != Process.SYSTEM_UID) {
+            if (DBG) loge("Uid(" + uid + ") not registrant's (" + nri.mUid + ") or System's");
             return;
         }
 
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index 793e342..e248b21 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -25,7 +25,6 @@
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.Slog;
 import android.view.WindowManager;
 
@@ -59,6 +58,7 @@
                 .getString(com.android.internal.R.string.config_factoryResetPackage);
         if (Intent.ACTION_FACTORY_RESET.equals(intent.getAction())
                 && !TextUtils.isEmpty(factoryResetPackage)) {
+            Slog.i(TAG, "Re-directing intent to " + factoryResetPackage);
             intent.setPackage(factoryResetPackage).setComponent(null);
             context.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
             return;
@@ -77,9 +77,12 @@
             @Override
             public void run() {
                 try {
+                    Slog.i(TAG, "Calling RecoverySystem.rebootWipeUserData(context, "
+                            + "shutdown=" + shutdown + ", reason=" + reason
+                            + ", forceWipe=" + forceWipe + ", wipeEsims=" + mWipeEsims + ")");
                     RecoverySystem
                             .rebootWipeUserData(context, shutdown, reason, forceWipe, mWipeEsims);
-                    Log.wtf(TAG, "Still running after master clear?!");
+                    Slog.wtf(TAG, "Still running after master clear?!");
                 } catch (IOException e) {
                     Slog.e(TAG, "Can't perform master clear/factory reset", e);
                 } catch (SecurityException e) {
@@ -90,8 +93,10 @@
 
         if (mWipeExternalStorage) {
             // thr will be started at the end of this task.
+            Slog.i(TAG, "Wiping external storage on async task");
             new WipeDataTask(context, thr).execute();
         } else {
+            Slog.i(TAG, "NOT wiping external storage; starting thread " + thr.getName());
             thr.start();
         }
     }
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 1c99465..821a967 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -24,12 +24,14 @@
 import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
 import static android.net.INetd.FIREWALL_CHAIN_NONE;
 import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
+import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED;
 import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
 import static android.net.INetd.FIREWALL_DENYLIST;
 import static android.net.INetd.FIREWALL_RULE_ALLOW;
 import static android.net.INetd.FIREWALL_RULE_DENY;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
 import static android.net.NetworkStats.SET_DEFAULT;
@@ -88,7 +90,6 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FrameworkStatsLog;
@@ -122,7 +123,7 @@
      * Helper class that encapsulates NetworkManagementService dependencies and makes them
      * easier to mock in unit tests.
      */
-    static class SystemServices {
+    static class Dependencies {
         public IBinder getService(String name) {
             return ServiceManager.getService(name);
         }
@@ -132,6 +133,10 @@
         public INetd getNetd() {
             return NetdService.get();
         }
+
+        public int getCallingUid() {
+            return Binder.getCallingUid();
+        }
     }
 
     private static final String TAG = "NetworkManagement";
@@ -157,7 +162,7 @@
 
     private final Handler mDaemonHandler;
 
-    private final SystemServices mServices;
+    private final Dependencies mDeps;
 
     private INetd mNetdService;
 
@@ -215,6 +220,11 @@
      */
     @GuardedBy("mRulesLock")
     private SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
+    /**
+     * Contains the per-UID firewall rules that are used when Restricted Networking Mode is enabled.
+     */
+    @GuardedBy("mRulesLock")
+    private SparseIntArray mUidFirewallRestrictedRules = new SparseIntArray();
     /** Set of states for the child firewall chains. True if the chain is active. */
     @GuardedBy("mRulesLock")
     final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
@@ -254,33 +264,32 @@
      * @param context  Binder context for this service
      */
     private NetworkManagementService(
-            Context context, SystemServices services) {
+            Context context, Dependencies deps) {
         mContext = context;
-        mServices = services;
+        mDeps = deps;
 
         mDaemonHandler = new Handler(FgThread.get().getLooper());
 
         mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener();
 
-        mServices.registerLocalService(new LocalService());
+        mDeps.registerLocalService(new LocalService());
 
         synchronized (mTetheringStatsProviders) {
             mTetheringStatsProviders.put(new NetdTetheringStatsProvider(), "netd");
         }
     }
 
-    @VisibleForTesting
-    NetworkManagementService() {
+    private NetworkManagementService() {
         mContext = null;
         mDaemonHandler = null;
-        mServices = null;
+        mDeps = null;
         mNetdUnsolicitedEventListener = null;
     }
 
-    static NetworkManagementService create(Context context, SystemServices services)
+    static NetworkManagementService create(Context context, Dependencies deps)
             throws InterruptedException {
         final NetworkManagementService service =
-                new NetworkManagementService(context, services);
+                new NetworkManagementService(context, deps);
         if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
         if (DBG) Slog.d(TAG, "Connecting native netd service");
         service.connectNativeNetdService();
@@ -289,7 +298,7 @@
     }
 
     public static NetworkManagementService create(Context context) throws InterruptedException {
-        return create(context, new SystemServices());
+        return create(context, new Dependencies());
     }
 
     public void systemReady() {
@@ -310,7 +319,7 @@
                 return mBatteryStats;
             }
             mBatteryStats =
-                    IBatteryStats.Stub.asInterface(mServices.getService(BatteryStats.SERVICE_NAME));
+                    IBatteryStats.Stub.asInterface(mDeps.getService(BatteryStats.SERVICE_NAME));
             return mBatteryStats;
         }
     }
@@ -511,7 +520,7 @@
     }
 
     private void connectNativeNetdService() {
-        mNetdService = mServices.getNetd();
+        mNetdService = mDeps.getNetd();
         try {
             mNetdService.registerUnsolicitedEventListener(mNetdUnsolicitedEventListener);
             if (DBG) Slog.d(TAG, "Register unsolicited event listener");
@@ -602,9 +611,15 @@
             syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, "standby ");
             syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable ");
             syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave ");
+            syncFirewallChainLocked(FIREWALL_CHAIN_RESTRICTED, "restricted ");
 
-            final int[] chains =
-                    {FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE};
+            final int[] chains = {
+                    FIREWALL_CHAIN_STANDBY,
+                    FIREWALL_CHAIN_DOZABLE,
+                    FIREWALL_CHAIN_POWERSAVE,
+                    FIREWALL_CHAIN_RESTRICTED
+            };
+
             for (int chain : chains) {
                 if (getFirewallChainState(chain)) {
                     setFirewallChainEnabled(chain, true);
@@ -1437,7 +1452,7 @@
 
     @Override
     public void setUidCleartextNetworkPolicy(int uid, int policy) {
-        if (Binder.getCallingUid() != uid) {
+        if (mDeps.getCallingUid() != uid) {
             NetworkStack.checkNetworkStackPermission(mContext);
         }
 
@@ -1695,6 +1710,8 @@
                 return FIREWALL_CHAIN_NAME_DOZABLE;
             case FIREWALL_CHAIN_POWERSAVE:
                 return FIREWALL_CHAIN_NAME_POWERSAVE;
+            case FIREWALL_CHAIN_RESTRICTED:
+                return FIREWALL_CHAIN_NAME_RESTRICTED;
             default:
                 throw new IllegalArgumentException("Bad child chain: " + chain);
         }
@@ -1708,6 +1725,8 @@
                 return FIREWALL_ALLOWLIST;
             case FIREWALL_CHAIN_POWERSAVE:
                 return FIREWALL_ALLOWLIST;
+            case FIREWALL_CHAIN_RESTRICTED:
+                return FIREWALL_ALLOWLIST;
             default:
                 return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST;
         }
@@ -1752,6 +1771,9 @@
                     case FIREWALL_CHAIN_POWERSAVE:
                         mNetdService.firewallReplaceUidChain("fw_powersave", true, uids);
                         break;
+                    case FIREWALL_CHAIN_RESTRICTED:
+                        mNetdService.firewallReplaceUidChain("fw_restricted", true, uids);
+                        break;
                     case FIREWALL_CHAIN_NONE:
                     default:
                         Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain);
@@ -1836,6 +1858,8 @@
                 return mUidFirewallDozableRules;
             case FIREWALL_CHAIN_POWERSAVE:
                 return mUidFirewallPowerSaveRules;
+            case FIREWALL_CHAIN_RESTRICTED:
+                return mUidFirewallRestrictedRules;
             case FIREWALL_CHAIN_NONE:
                 return mUidFirewallRules;
             default:
@@ -1851,8 +1875,8 @@
         return rule;
     }
 
-    private static void enforceSystemUid() {
-        final int uid = Binder.getCallingUid();
+    private void enforceSystemUid() {
+        final int uid = mDeps.getCallingUid();
         if (uid != Process.SYSTEM_UID) {
             throw new SecurityException("Only available to AID_SYSTEM");
         }
@@ -1910,17 +1934,22 @@
         synchronized (mRulesLock) {
             dumpUidFirewallRule(pw, "", mUidFirewallRules);
 
-            pw.print("UID firewall standby chain enabled: "); pw.println(
-                    getFirewallChainState(FIREWALL_CHAIN_STANDBY));
+            pw.print("UID firewall standby chain enabled: ");
+            pw.println(getFirewallChainState(FIREWALL_CHAIN_STANDBY));
             dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules);
 
-            pw.print("UID firewall dozable chain enabled: "); pw.println(
-                    getFirewallChainState(FIREWALL_CHAIN_DOZABLE));
+            pw.print("UID firewall dozable chain enabled: ");
+            pw.println(getFirewallChainState(FIREWALL_CHAIN_DOZABLE));
             dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules);
 
-            pw.println("UID firewall powersave chain enabled: " +
-                    getFirewallChainState(FIREWALL_CHAIN_POWERSAVE));
+            pw.print("UID firewall powersave chain enabled: ");
+            pw.println(getFirewallChainState(FIREWALL_CHAIN_POWERSAVE));
             dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_POWERSAVE, mUidFirewallPowerSaveRules);
+
+            pw.print("UID firewall restricted mode chain enabled: ");
+            pw.println(getFirewallChainState(FIREWALL_CHAIN_RESTRICTED));
+            dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_RESTRICTED,
+                    mUidFirewallRestrictedRules);
         }
 
         synchronized (mIdleTimerLock) {
@@ -2071,6 +2100,11 @@
                 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
                 return true;
             }
+            if (getFirewallChainState(FIREWALL_CHAIN_RESTRICTED)
+                    && mUidFirewallRestrictedRules.get(uid) != FIREWALL_RULE_ALLOW) {
+                if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of restricted mode");
+                return true;
+            }
             if (mUidRejectOnMetered.get(uid)) {
                 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
                         + " in the background");
@@ -2096,60 +2130,10 @@
         }
     }
 
-    @VisibleForTesting
-    class LocalService extends NetworkManagementInternal {
+    private class LocalService extends NetworkManagementInternal {
         @Override
         public boolean isNetworkRestrictedForUid(int uid) {
             return isNetworkRestrictedInternal(uid);
         }
     }
-
-    @VisibleForTesting
-    Injector getInjector() {
-        return new Injector();
-    }
-
-    @VisibleForTesting
-    class Injector {
-        void setDataSaverMode(boolean dataSaverMode) {
-            mDataSaverMode = dataSaverMode;
-        }
-
-        void setFirewallChainState(int chain, boolean state) {
-            NetworkManagementService.this.setFirewallChainState(chain, state);
-        }
-
-        void setFirewallRule(int chain, int uid, int rule) {
-            synchronized (mRulesLock) {
-                getUidFirewallRulesLR(chain).put(uid, rule);
-            }
-        }
-
-        void setUidOnMeteredNetworkList(boolean denylist, int uid, boolean enable) {
-            synchronized (mRulesLock) {
-                if (denylist) {
-                    mUidRejectOnMetered.put(uid, enable);
-                } else {
-                    mUidAllowOnMetered.put(uid, enable);
-                }
-            }
-        }
-
-        void reset() {
-            synchronized (mRulesLock) {
-                setDataSaverMode(false);
-                final int[] chains = {
-                        FIREWALL_CHAIN_DOZABLE,
-                        FIREWALL_CHAIN_STANDBY,
-                        FIREWALL_CHAIN_POWERSAVE
-                };
-                for (int chain : chains) {
-                    setFirewallChainState(chain, false);
-                    getUidFirewallRulesLR(chain).clear();
-                }
-                mUidAllowOnMetered.clear();
-                mUidRejectOnMetered.clear();
-            }
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 3443918..fc3a7c8 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -59,7 +59,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.util.DumpUtils;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.permission.LegacyPermissionManagerInternal;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -290,7 +290,7 @@
                     String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
                             Global.USE_OPEN_WIFI_PACKAGE);
                     if (!TextUtils.isEmpty(useOpenWifiPackage)) {
-                        LocalServices.getService(PermissionManagerServiceInternal.class)
+                        LocalServices.getService(LegacyPermissionManagerInternal.class)
                                 .grantDefaultPermissionsToDefaultUseOpenWifiApp(useOpenWifiPackage,
                                         userId);
                     }
@@ -302,7 +302,7 @@
                 false /*notifyForDescendants*/,
                 mUseOpenWifiPackageObserver);
         // Set a callback for the package manager to query the use open wifi app.
-        LocalServices.getService(PermissionManagerServiceInternal.class)
+        LocalServices.getService(LegacyPermissionManagerInternal.class)
                 .setUseOpenWifiAppPackagesProvider((userId) -> {
                     String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
                             Global.USE_OPEN_WIFI_PACKAGE);
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 8706cdf..48cbd54 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -9,3 +9,19 @@
 
 # Userspace reboot
 per-file UserspaceRebootLogger.java = ioffe@google.com, tomcherry@google.com
+
+per-file *Alarm* = file:/apex/jobscheduler/OWNERS
+per-file *AppOps* = file:/core/java/android/permission/OWNERS
+per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS
+per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS
+per-file *Location* = file:/services/core/java/com/android/server/location/OWNERS
+per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
+per-file *Storage* = file:/core/java/android/os/storage/OWNERS
+per-file *TimeUpdate* = file:/core/java/android/app/timezone/OWNERS
+per-file ConnectivityService.java = file:/services/core/java/com/android/server/net/OWNERS
+per-file IpSecService.java = file:/services/core/java/com/android/server/net/OWNERS
+per-file MmsServiceBroker.java = file:/telephony/OWNERS
+per-file NetIdManager.java = file:/services/core/java/com/android/server/net/OWNERS
+per-file PackageWatchdog.java = file:/services/core/java/com/android/server/rollback/OWNERS
+per-file TelephonyRegistry.java = file:/telephony/OWNERS
+per-file UiModeManagerService.java = file:/packages/SystemUI/OWNERS
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 9bf63cb..99a1d86 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -52,9 +52,7 @@
 
 import libcore.io.IoUtils;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -149,6 +147,7 @@
     private static final String ATTR_DURATION = "duration";
     private static final String ATTR_EXPLICIT_HEALTH_CHECK_DURATION = "health-check-duration";
     private static final String ATTR_PASSED_HEALTH_CHECK = "passed-health-check";
+    private static final String ATTR_MITIGATION_CALLS = "mitigation-calls";
 
     @GuardedBy("PackageWatchdog.class")
     private static PackageWatchdog sPackageWatchdog;
@@ -779,7 +778,6 @@
 
     @GuardedBy("mLock")
     private Set<String> getPackagesPendingHealthChecksLocked() {
-        Slog.d(TAG, "Getting all observed packages pending health checks");
         Set<String> packages = new ArraySet<>();
         Iterator<ObserverInternal> oit = mAllObservers.values().iterator();
         while (oit.hasNext()) {
@@ -828,7 +826,6 @@
             Slog.i(TAG, "Cancelling state sync, nothing to sync");
             mUptimeAtLastStateSync = 0;
         } else {
-            Slog.i(TAG, "Scheduling next state sync in " + durationMs + "ms");
             mUptimeAtLastStateSync = mSystemClock.uptimeMillis();
             mShortTaskHandler.postDelayed(mSyncStateWithScheduledReason, durationMs);
         }
@@ -869,7 +866,6 @@
             return;
         }
 
-        Slog.i(TAG, "Removing " + elapsedMs + "ms from all packages on all observers");
         Iterator<ObserverInternal> it = mAllObservers.values().iterator();
         while (it.hasNext()) {
             ObserverInternal observer = it.next();
@@ -1067,6 +1063,33 @@
         }
     }
 
+    /** Convert a {@code LongArrayQueue} to a String of comma-separated values. */
+    public static String longArrayQueueToString(LongArrayQueue queue) {
+        if (queue.size() > 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(queue.get(0));
+            for (int i = 1; i < queue.size(); i++) {
+                sb.append(",");
+                sb.append(queue.get(i));
+            }
+            return sb.toString();
+        }
+        return "";
+    }
+
+    /** Parse a comma-separated String of longs into a LongArrayQueue. */
+    public static LongArrayQueue parseLongArrayQueue(String commaSeparatedValues) {
+        LongArrayQueue result = new LongArrayQueue();
+        if (!TextUtils.isEmpty(commaSeparatedValues)) {
+            String[] values = commaSeparatedValues.split(",");
+            for (String value : values) {
+                result.addLast(Long.parseLong(value));
+            }
+        }
+        return result;
+    }
+
+
     /** Dump status of every observer in mAllObservers. */
     public void dump(IndentingPrintWriter pw) {
         pw.println("Package Watchdog status");
@@ -1240,16 +1263,7 @@
                 while (XmlUtils.nextElementWithin(parser, innerDepth)) {
                     if (TAG_PACKAGE.equals(parser.getName())) {
                         try {
-                            String packageName = parser.getAttributeValue(
-                                    null, ATTR_NAME);
-                            long duration = parser.getAttributeLong(
-                                    null, ATTR_DURATION);
-                            long healthCheckDuration = parser.getAttributeLong(
-                                    null, ATTR_EXPLICIT_HEALTH_CHECK_DURATION);
-                            boolean hasPassedHealthCheck = parser.getAttributeBoolean(
-                                    null, ATTR_PASSED_HEALTH_CHECK, false);
-                            MonitoredPackage pkg = watchdog.newMonitoredPackage(packageName,
-                                    duration, healthCheckDuration, hasPassedHealthCheck);
+                            MonitoredPackage pkg = watchdog.parseMonitoredPackage(parser);
                             if (pkg != null) {
                                 packages.add(pkg);
                             }
@@ -1305,16 +1319,31 @@
 
     MonitoredPackage newMonitoredPackage(
             String name, long durationMs, boolean hasPassedHealthCheck) {
-        return newMonitoredPackage(name, durationMs, Long.MAX_VALUE, hasPassedHealthCheck);
+        return newMonitoredPackage(name, durationMs, Long.MAX_VALUE, hasPassedHealthCheck,
+                new LongArrayQueue());
     }
 
     MonitoredPackage newMonitoredPackage(String name, long durationMs, long healthCheckDurationMs,
-            boolean hasPassedHealthCheck) {
+            boolean hasPassedHealthCheck, LongArrayQueue mitigationCalls) {
         VersionedPackage pkg = getVersionedPackage(name);
         if (pkg == null) {
             return null;
         }
-        return new MonitoredPackage(pkg, durationMs, healthCheckDurationMs, hasPassedHealthCheck);
+        return new MonitoredPackage(pkg, durationMs, healthCheckDurationMs,
+                hasPassedHealthCheck, mitigationCalls);
+    }
+
+    MonitoredPackage parseMonitoredPackage(TypedXmlPullParser parser)
+            throws XmlPullParserException {
+        String packageName = parser.getAttributeValue(null, ATTR_NAME);
+        long duration = parser.getAttributeLong(null, ATTR_DURATION);
+        long healthCheckDuration = parser.getAttributeLong(null,
+                        ATTR_EXPLICIT_HEALTH_CHECK_DURATION);
+        boolean hasPassedHealthCheck = parser.getAttributeBoolean(null, ATTR_PASSED_HEALTH_CHECK);
+        LongArrayQueue mitigationCalls = parseLongArrayQueue(
+                parser.getAttributeValue(null, ATTR_MITIGATION_CALLS));
+        return newMonitoredPackage(packageName,
+                duration, healthCheckDuration, hasPassedHealthCheck, mitigationCalls);
     }
 
     /**
@@ -1332,7 +1361,7 @@
         // Times when an observer was called to mitigate this package's failure. Sorted in
         // ascending order.
         @GuardedBy("mLock")
-        private final LongArrayQueue mMitigationCalls = new LongArrayQueue();
+        private final LongArrayQueue mMitigationCalls;
         // One of STATE_[ACTIVE|INACTIVE|PASSED|FAILED]. Updated on construction and after
         // methods that could change the health check state: handleElapsedTimeLocked and
         // tryPassHealthCheckLocked
@@ -1353,12 +1382,14 @@
         @GuardedBy("mLock")
         private long mHealthCheckDurationMs = Long.MAX_VALUE;
 
-        private MonitoredPackage(VersionedPackage pkg, long durationMs,
-                long healthCheckDurationMs, boolean hasPassedHealthCheck) {
+        MonitoredPackage(VersionedPackage pkg, long durationMs,
+                long healthCheckDurationMs, boolean hasPassedHealthCheck,
+                LongArrayQueue mitigationCalls) {
             mPackage = pkg;
             mDurationMs = durationMs;
             mHealthCheckDurationMs = healthCheckDurationMs;
             mHasPassedHealthCheck = hasPassedHealthCheck;
+            mMitigationCalls = mitigationCalls;
             updateHealthCheckStateLocked();
         }
 
@@ -1370,6 +1401,8 @@
             out.attributeLong(null, ATTR_DURATION, mDurationMs);
             out.attributeLong(null, ATTR_EXPLICIT_HEALTH_CHECK_DURATION, mHealthCheckDurationMs);
             out.attributeBoolean(null, ATTR_PASSED_HEALTH_CHECK, mHasPassedHealthCheck);
+            LongArrayQueue normalizedCalls = normalizeMitigationCalls();
+            out.attribute(null, ATTR_MITIGATION_CALLS, longArrayQueueToString(normalizedCalls));
             out.endTag(null, TAG_PACKAGE);
         }
 
@@ -1423,6 +1456,23 @@
         }
 
         /**
+         * Before writing to disk, make the mitigation call timestamps relative to the current
+         * system uptime. This is because they need to be relative to the uptime which will reset
+         * at the next boot.
+         *
+         * @return a LongArrayQueue of the mitigation calls relative to the current system uptime.
+         */
+        @GuardedBy("mLock")
+        public LongArrayQueue normalizeMitigationCalls() {
+            LongArrayQueue normalized = new LongArrayQueue();
+            final long now = mSystemClock.uptimeMillis();
+            for (int i = 0; i < mMitigationCalls.size(); i++) {
+                normalized.addLast(mMitigationCalls.get(i) - now);
+            }
+            return normalized;
+        }
+
+        /**
          * Sets the initial health check duration.
          *
          * @return the new health check state
@@ -1582,6 +1632,16 @@
         private long toPositive(long value) {
             return value > 0 ? value : Long.MAX_VALUE;
         }
+
+        /** Compares the equality of this object with another {@link MonitoredPackage}. */
+        @VisibleForTesting
+        boolean isEqualTo(MonitoredPackage pkg) {
+            return (getName().equals(pkg.getName()))
+                    && mDurationMs == pkg.mDurationMs
+                    && mHasPassedHealthCheck == pkg.mHasPassedHealthCheck
+                    && mHealthCheckDurationMs == pkg.mHealthCheckDurationMs
+                    && (mMitigationCalls.toString()).equals(pkg.mMitigationCalls.toString());
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java
index d30e9fb..51e2b12 100644
--- a/services/core/java/com/android/server/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/SensorPrivacyService.java
@@ -158,7 +158,7 @@
                 XmlUtils.beginDocument(parser, XML_TAG_SENSOR_PRIVACY);
                 parser.next();
                 String tagName = parser.getName();
-                enabled = Boolean.valueOf(parser.getAttributeValue(null, XML_ATTRIBUTE_ENABLED));
+                enabled = parser.getAttributeBoolean(null, XML_ATTRIBUTE_ENABLED, false);
             } catch (IOException | XmlPullParserException e) {
                 Log.e(TAG, "Caught an exception reading the state from storage: ", e);
                 // Delete the file to prevent the same error on subsequent calls and assume sensor
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index eb55512..52eb77d 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -80,6 +80,7 @@
 import android.telephony.ims.ImsReasonInfo;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.LocalLog;
 import android.util.Pair;
 
@@ -101,10 +102,13 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Since phone process can be restarted, this class provides a centralized place
@@ -144,14 +148,14 @@
         int callerUid;
         int callerPid;
 
-        long events;
+        Set<Integer> eventList;
 
         int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
         int phoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
 
-        boolean matchPhoneStateListenerEvent(long events) {
-            return (callback != null) && ((events & this.events) != 0);
+        boolean matchPhoneStateListenerEvent(int event) {
+            return (callback != null) && (this.eventList.contains(event));
         }
 
         boolean matchOnSubscriptionsChangedListener() {
@@ -179,7 +183,7 @@
                     + onSubscriptionsChangedListenerCallback
                     + " onOpportunisticSubscriptionsChangedListenererCallback="
                     + onOpportunisticSubscriptionsChangedListenerCallback + " subId=" + subId
-                    + " phoneId=" + phoneId + " events=" + Long.toHexString(events) + "}";
+                    + " phoneId=" + phoneId + " events=" + eventList + "}";
         }
     }
 
@@ -310,6 +314,10 @@
 
     private List<PhysicalChannelConfig> mPhysicalChannelConfigs;
 
+    private boolean mIsDataEnabled = false;
+
+    private int mDataEnabledReason;
+
     /**
      * Per-phone map of precise data connection state. The key of the map is the pair of transport
      * type and APN setting. This is the cache to prevent redundant callbacks to the listeners.
@@ -319,40 +327,62 @@
     private List<Map<Pair<Integer, ApnSetting>, PreciseDataConnectionState>>
             mPreciseDataConnectionStates;
 
-    // Starting in Q, almost all cellular location requires FINE location enforcement.
-    // Prior to Q, cellular was available with COARSE location enforcement. Bits in this
-    // list will be checked for COARSE on apps targeting P or earlier and FINE on Q or later.
-    static final long ENFORCE_LOCATION_PERMISSION_MASK =
-            PhoneStateListener.LISTEN_CELL_LOCATION
-                    | PhoneStateListener.LISTEN_CELL_INFO
-                    | PhoneStateListener.LISTEN_REGISTRATION_FAILURE
-                    | PhoneStateListener.LISTEN_BARRING_INFO;
+    private static final Set<Integer> REQUIRE_PRECISE_PHONE_STATE_PERMISSION;
+    static {
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION = new HashSet<Integer>();
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
+                PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
+                PhoneStateListener.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
+                PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
+                PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
+                PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
+                PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
+                PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
+        REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
+                PhoneStateListener.EVENT_DATA_ENABLED_CHANGED);
+    }
 
-    static final long ENFORCE_PHONE_STATE_PERMISSION_MASK =
-            PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
-                    | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
-                    | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST
-                    | PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED;
+    private boolean isLocationPermissionRequired(Set<Integer> events) {
+        return events.contains(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)
+                || events.contains(PhoneStateListener.EVENT_CELL_INFO_CHANGED)
+                || events.contains(PhoneStateListener.EVENT_REGISTRATION_FAILURE)
+                || events.contains(PhoneStateListener.EVENT_BARRING_INFO_CHANGED);
+    }
 
-    static final long ENFORCE_PRECISE_PHONE_STATE_PERMISSION_MASK =
-            PhoneStateListener.LISTEN_PRECISE_CALL_STATE
-                    | PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE
-                    | PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES
-                    | PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED
-                    | PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES
-                    | PhoneStateListener.LISTEN_REGISTRATION_FAILURE
-                    | PhoneStateListener.LISTEN_BARRING_INFO
-                    | PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION;
+    private boolean isPhoneStatePermissionRequired(Set<Integer> events) {
+        return events.contains(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
+                || events.contains(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
+                || events.contains(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)
+                || events.contains(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
+    }
 
-    static final long READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK =
-            PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL
-                    | PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS;
+    private boolean isPrecisePhoneStatePermissionRequired(Set<Integer> events) {
+        for (Integer requireEvent : REQUIRE_PRECISE_PHONE_STATE_PERMISSION) {
+            if (events.contains(requireEvent)) {
+                return true;
+            }
+        }
+        return false;
+    }
 
-    static final long READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK =
-            PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT
-                    | PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED
-                    | PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED
-                    | PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE;
+    private boolean isActiveEmergencySessionPermissionRequired(Set<Integer> events) {
+        return events.contains(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL)
+                || events.contains(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS);
+    }
+
+    private boolean isPrivilegedPhoneStatePermissionRequired(Set<Integer> events) {
+        return events.contains(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED)
+                || events.contains(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
+                || events.contains(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED);
+    }
 
     private static final int MSG_USER_SWITCHED = 1;
     private static final int MSG_UPDATE_DEFAULT_SUB = 2;
@@ -670,7 +700,7 @@
             r.callingFeatureId = callingFeatureId;
             r.callerUid = Binder.getCallingUid();
             r.callerPid = Binder.getCallingPid();
-            r.events = 0;
+            r.eventList = new ArraySet<>();
             if (DBG) {
                 log("listen oscl:  Register r=" + r);
             }
@@ -724,7 +754,7 @@
             r.callingFeatureId = callingFeatureId;
             r.callerUid = Binder.getCallingUid();
             r.callerPid = Binder.getCallingPid();
-            r.events = 0;
+            r.eventList = new ArraySet<>();
             if (DBG) {
                 log("listen ooscl:  Register r=" + r);
             }
@@ -797,331 +827,337 @@
         }
     }
 
-    @Deprecated
     @Override
-    public void listen(String callingPackage, IPhoneStateListener callback, int events,
-            boolean notifyNow) {
-        listenWithFeature(callingPackage, null, callback, events, notifyNow);
-    }
-
-    @Override
-    public void listenWithFeature(String callingPackage, String callingFeatureId,
-            IPhoneStateListener callback, long events, boolean notifyNow) {
-        listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, callingPackage,
-                callingFeatureId, callback, events, notifyNow);
-    }
-
-    @Override
-    public void listenForSubscriber(int subId, String callingPackage, String callingFeatureId,
-            IPhoneStateListener callback, long events, boolean notifyNow) {
-        listen(callingPackage, callingFeatureId, callback, events, notifyNow, subId);
+    public void listenWithEventList(int subId, String callingPackage, String callingFeatureId,
+            IPhoneStateListener callback, int[] events, boolean notifyNow) {
+        Set<Integer> eventList = Arrays.stream(events).boxed().collect(Collectors.toSet());
+        listen(callingPackage, callingFeatureId, callback, eventList, notifyNow, subId);
     }
 
     private void listen(String callingPackage, @Nullable String callingFeatureId,
-            IPhoneStateListener callback, long events, boolean notifyNow, int subId) {
+            IPhoneStateListener callback, Set<Integer> events, boolean notifyNow, int subId) {
         int callerUserId = UserHandle.getCallingUserId();
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         String str = "listen: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
-                + " events=0x" + Long.toHexString(events) + " notifyNow=" + notifyNow + " subId="
-                + subId + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId;
+                + " events=" + events + " notifyNow=" + notifyNow
+                + " subId=" + subId + " myUserId=" + UserHandle.myUserId()
+                + " callerUserId=" + callerUserId;
         mListenLog.log(str);
         if (VDBG) {
             log(str);
         }
 
-        if (events != PhoneStateListener.LISTEN_NONE) {
-            // Checks permission and throws SecurityException for disallowed operations. For pre-M
-            // apps whose runtime permission has been revoked, we return immediately to skip sending
-            // events to the app without crashing it.
-            if (!checkListenerPermission(events, subId, callingPackage, callingFeatureId,
-                    "listen")) {
+        if (events.isEmpty()) {
+            if (DBG) {
+                log("listen: Unregister");
+            }
+            events.clear();
+            remove(callback.asBinder());
+            return;
+        }
+
+        // Checks permission and throws SecurityException for disallowed operations. For pre-M
+        // apps whose runtime permission has been revoked, we return immediately to skip sending
+        // events to the app without crashing it.
+        if (!checkListenerPermission(events, subId, callingPackage, callingFeatureId,
+                "listen")) {
+            return;
+        }
+
+        int phoneId = getPhoneIdFromSubId(subId);
+        synchronized (mRecords) {
+            // register
+            IBinder b = callback.asBinder();
+            boolean doesLimitApply =
+                    Binder.getCallingUid() != Process.SYSTEM_UID
+                            && Binder.getCallingUid() != Process.PHONE_UID
+                            && Binder.getCallingUid() != Process.myUid();
+            Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply);
+
+            if (r == null) {
                 return;
             }
 
-            int phoneId = getPhoneIdFromSubId(subId);
-            synchronized (mRecords) {
-                // register
-                IBinder b = callback.asBinder();
-                boolean doesLimitApply =
-                        Binder.getCallingUid() != Process.SYSTEM_UID
-                        && Binder.getCallingUid() != Process.PHONE_UID
-                        && Binder.getCallingUid() != Process.myUid();
-                Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply);
-
-                if (r == null) {
-                    return;
+            r.context = mContext;
+            r.callback = callback;
+            r.callingPackage = callingPackage;
+            r.callingFeatureId = callingFeatureId;
+            r.callerUid = Binder.getCallingUid();
+            r.callerPid = Binder.getCallingPid();
+            // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
+            // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
+            if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+                r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+            } else {//APP specify subID
+                r.subId = subId;
+            }
+            r.phoneId = phoneId;
+            r.eventList = events;
+            if (DBG) {
+                log("listen:  Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId);
+            }
+            if (notifyNow && validatePhoneId(phoneId)) {
+                if (events.contains(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED)) {
+                    try {
+                        if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]);
+                        ServiceState rawSs = new ServiceState(mServiceState[phoneId]);
+                        if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                            r.callback.onServiceStateChanged(rawSs);
+                        } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) {
+                            r.callback.onServiceStateChanged(
+                                    rawSs.createLocationInfoSanitizedCopy(false));
+                        } else {
+                            r.callback.onServiceStateChanged(
+                                    rawSs.createLocationInfoSanitizedCopy(true));
+                        }
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
+                    }
                 }
-
-                r.context = mContext;
-                r.callback = callback;
-                r.callingPackage = callingPackage;
-                r.callingFeatureId = callingFeatureId;
-                r.callerUid = Binder.getCallingUid();
-                r.callerPid = Binder.getCallingPid();
-                // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
-                // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
-                if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-                    r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
-                 } else {//APP specify subID
-                    r.subId = subId;
+                if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED)) {
+                    try {
+                        if (mSignalStrength[phoneId] != null) {
+                            int gsmSignalStrength = mSignalStrength[phoneId]
+                                    .getGsmSignalStrength();
+                            r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
+                                    : gsmSignalStrength));
+                        }
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
+                    }
                 }
-                r.phoneId = phoneId;
-                r.events = events;
-                if (DBG) {
-                    log("listen:  Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId);
+                if (events.contains(
+                        PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) {
+                    try {
+                        r.callback.onMessageWaitingIndicatorChanged(
+                                mMessageWaiting[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
+                    }
                 }
-                if (notifyNow && validatePhoneId(phoneId)) {
-                    if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
-                        try {
-                            if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]);
-                            ServiceState rawSs = new ServiceState(mServiceState[phoneId]);
-                            if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
-                                r.callback.onServiceStateChanged(rawSs);
-                            } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) {
-                                r.callback.onServiceStateChanged(
-                                        rawSs.createLocationInfoSanitizedCopy(false));
-                            } else {
-                                r.callback.onServiceStateChanged(
-                                        rawSs.createLocationInfoSanitizedCopy(true));
-                            }
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                if (events.contains(
+                        PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) {
+                    try {
+                        r.callback.onCallForwardingIndicatorChanged(
+                                mCallForwarding[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
-                        try {
-                            if (mSignalStrength[phoneId] != null) {
-                                int gsmSignalStrength = mSignalStrength[phoneId]
-                                        .getGsmSignalStrength();
-                                r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
-                                        : gsmSignalStrength));
-                            }
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
+                }
+                if (validateEventAndUserLocked(
+                        r, PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)) {
+                    try {
+                        if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]);
+                        if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                                && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                            // null will be translated to empty CellLocation object in client.
+                            r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
                         }
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
-                        try {
-                            r.callback.onMessageWaitingIndicatorChanged(
-                                    mMessageWaiting[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_CALL_STATE_CHANGED)) {
+                    try {
+                        r.callback.onCallStateChanged(mCallState[phoneId],
+                                getCallIncomingNumber(r, phoneId));
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
-                        try {
-                            r.callback.onCallForwardingIndicatorChanged(
-                                    mCallForwarding[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
-                    }
-                    if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
-                        try {
-                            if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]);
-                            if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
-                                    && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
-                                // null will be translated to empty CellLocation object in client.
-                                r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
-                            }
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
-                    }
-                    if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
-                        try {
-                            r.callback.onCallStateChanged(mCallState[phoneId],
-                                     getCallIncomingNumber(r, phoneId));
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
-                    }
-                    if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
-                        try {
-                            r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
+                }
+                if (events.contains(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
+                    try {
+                        r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
                                 mDataConnectionNetworkType[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
-                        try {
-                            r.callback.onDataActivity(mDataActivity[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED)) {
+                    try {
+                        r.callback.onDataActivity(mDataActivity[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
-                        try {
-                            if (mSignalStrength[phoneId] != null) {
-                                r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
-                            }
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
+                }
+                if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED)) {
+                    try {
+                        if (mSignalStrength[phoneId] != null) {
+                            r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
                         }
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
-                            != 0) {
-                        updateReportSignalStrengthDecision(r.subId);
-                        try {
-                            if (mSignalStrength[phoneId] != null) {
-                                r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
-                            }
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
+                }
+                if (events.contains(
+                        PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
+                    updateReportSignalStrengthDecision(r.subId);
+                    try {
+                        if (mSignalStrength[phoneId] != null) {
+                            r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
                         }
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
-                        try {
-                            if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
-                                    + mCellInfo.get(phoneId));
-                            if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
-                                    && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
-                                r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
-                            }
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
+                }
+                if (validateEventAndUserLocked(
+                        r, PhoneStateListener.EVENT_CELL_INFO_CHANGED)) {
+                    try {
+                        if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
+                                + mCellInfo.get(phoneId));
+                        if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                                && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
+                            r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
                         }
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
-                        try {
-                            r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED)) {
+                    try {
+                        r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
-                        try {
-                            r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId],
-                                    mCallPreciseDisconnectCause[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)) {
+                    try {
+                        r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId],
+                                mCallPreciseDisconnectCause[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) {
-                        try {
-                            r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId));
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)) {
+                    try {
+                        r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId));
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
-                        try {
-                            for (PreciseDataConnectionState pdcs
-                                    : mPreciseDataConnectionStates.get(phoneId).values()) {
-                                r.callback.onPreciseDataConnectionStateChanged(pdcs);
-                            }
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
+                }
+                if (events.contains(
+                        PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)) {
+                    try {
+                        for (PreciseDataConnectionState pdcs
+                                : mPreciseDataConnectionStates.get(phoneId).values()) {
+                            r.callback.onPreciseDataConnectionStateChanged(pdcs);
                         }
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) {
-                        try {
-                            r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED)) {
+                    try {
+                        r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) !=0) {
-                        try {
-                            r.callback.onVoiceActivationStateChanged(
-                                    mVoiceActivationState[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED)) {
+                    try {
+                        r.callback.onVoiceActivationStateChanged(
+                                mVoiceActivationState[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) !=0) {
-                        try {
-                            r.callback.onDataActivationStateChanged(mDataActivationState[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED)) {
+                    try {
+                        r.callback.onDataActivationStateChanged(mDataActivationState[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) {
-                        try {
-                            r.callback.onUserMobileDataStateChanged(mUserMobileDataState[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) {
+                    try {
+                        r.callback.onUserMobileDataStateChanged(mUserMobileDataState[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) {
-                        try {
-                            if (mTelephonyDisplayInfos[phoneId] != null) {
-                                r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[phoneId]);
-                            }
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
+                }
+                if (events.contains(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED)) {
+                    try {
+                        if (mTelephonyDisplayInfos[phoneId] != null) {
+                            r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[phoneId]);
                         }
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) != 0) {
-                        try {
-                            r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)) {
+                    try {
+                        r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) {
-                        try {
-                            r.callback.onPhoneCapabilityChanged(mPhoneCapability);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED)) {
+                    try {
+                        r.callback.onPhoneCapabilityChanged(mPhoneCapability);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener
-                            .LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) {
-                        try {
-                            r.callback.onActiveDataSubIdChanged(mActiveDataSubId);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(
+                        PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) {
+                    try {
+                        r.callback.onActiveDataSubIdChanged(mActiveDataSubId);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) {
-                        try {
-                            r.callback.onRadioPowerStateChanged(mRadioPowerState);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED)) {
+                    try {
+                        r.callback.onRadioPowerStateChanged(mRadioPowerState);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) {
-                        try {
-                            r.callback.onSrvccStateChanged(mSrvccState[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED)) {
+                    try {
+                        r.callback.onSrvccStateChanged(mSrvccState[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) != 0) {
-                        try {
-                            r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED)) {
+                    try {
+                        r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_BARRING_INFO) != 0) {
-                        BarringInfo barringInfo = mBarringInfo.get(phoneId);
-                        BarringInfo biNoLocation = barringInfo != null
-                                ? barringInfo.createLocationInfoSanitizedCopy() : null;
-                        if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
-                        try {
-                            r.callback.onBarringInfoChanged(
-                                    checkFineLocationAccess(r, Build.VERSION_CODES.BASE)
-                                            ? barringInfo : biNoLocation);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(PhoneStateListener.EVENT_BARRING_INFO_CHANGED)) {
+                    BarringInfo barringInfo = mBarringInfo.get(phoneId);
+                    BarringInfo biNoLocation = barringInfo != null
+                            ? barringInfo.createLocationInfoSanitizedCopy() : null;
+                    if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
+                    try {
+                        r.callback.onBarringInfoChanged(
+                                checkFineLocationAccess(r, Build.VERSION_CODES.BASE)
+                                        ? barringInfo : biNoLocation);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
-                    if ((events & PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION) != 0) {
-                        try {
-                            r.callback.onPhysicalChannelConfigurationChanged(
-                                    mPhysicalChannelConfigs);
-                        } catch (RemoteException ex) {
-                            remove(r.binder);
-                        }
+                }
+                if (events.contains(
+                        PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)) {
+                    try {
+                        r.callback.onPhysicalChannelConfigChanged(
+                                mPhysicalChannelConfigs);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
+                    }
+                }
+                if (events.contains(
+                        PhoneStateListener.EVENT_DATA_ENABLED_CHANGED)) {
+                    try {
+                        r.callback.onDataEnabledChanged(mIsDataEnabled, mDataEnabledReason);
+                    } catch (RemoteException ex) {
+                        remove(r.binder);
                     }
                 }
             }
-        } else {
-            if(DBG) log("listen: Unregister");
-            remove(callback.asBinder());
         }
     }
 
@@ -1133,7 +1169,7 @@
                 // If any of the system clients wants to always listen to signal strength,
                 // we need to set it on.
                 if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)) {
+                        PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
                     telephonyManager.createForSubscriptionId(subscriptionId)
                             .setAlwaysReportSignalStrength(true);
                     return;
@@ -1234,7 +1270,7 @@
                     // strength is removed from registry records, we need to check if
                     // the signal strength decision needs to update on its slot.
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)) {
+                            PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
                         updateReportSignalStrengthDecision(r.subId);
                     }
                     return;
@@ -1254,8 +1290,8 @@
 
         synchronized (mRecords) {
             for (Record r : mRecords) {
-                if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
-                        (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
+                if (r.matchPhoneStateListenerEvent(PhoneStateListener.EVENT_CALL_STATE_CHANGED)
+                        && (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
                     try {
                         // Ensure the listener has read call log permission; if they do not return
                         // an empty phone number.
@@ -1289,9 +1325,9 @@
                 mCallState[phoneId] = state;
                 mCallIncomingNumber[phoneId] = incomingNumber;
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
-                            (r.subId == subId) &&
-                            (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
+                    if (r.matchPhoneStateListenerEvent(PhoneStateListener.EVENT_CALL_STATE_CHANGED)
+                            && (r.subId == subId)
+                            && (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
                         try {
                             String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId);
                             r.callback.onCallStateChanged(state, incomingNumberOrEmpty);
@@ -1331,8 +1367,9 @@
                         log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId
                                 + " phoneId=" + phoneId + " state=" + state);
                     }
-                    if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                    if (r.matchPhoneStateListenerEvent(
+                            PhoneStateListener.EVENT_SERVICE_STATE_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
 
                         try {
                             ServiceState stateToSend;
@@ -1393,7 +1430,7 @@
                     try {
                         if ((activationType == SIM_ACTIVATION_TYPE_VOICE)
                                 && r.matchPhoneStateListenerEvent(
-                                        PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE)
+                                        PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
                                 && idMatch(r.subId, subId, phoneId)) {
                             if (DBG) {
                                 log("notifyVoiceActivationStateForPhoneId: callback.onVASC r=" + r
@@ -1404,7 +1441,7 @@
                         }
                         if ((activationType == SIM_ACTIVATION_TYPE_DATA)
                                 && r.matchPhoneStateListenerEvent(
-                                        PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE)
+                                        PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED)
                                 && idMatch(r.subId, subId, phoneId)) {
                             if (DBG) {
                                 log("notifyDataActivationStateForPhoneId: callback.onDASC r=" + r
@@ -1443,9 +1480,11 @@
                         log("notifySignalStrengthForPhoneId: r=" + r + " subId=" + subId
                                 + " phoneId=" + phoneId + " ss=" + signalStrength);
                     }
-                    if ((r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)
+                    if ((r.matchPhoneStateListenerEvent(
+                            PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED)
                             || r.matchPhoneStateListenerEvent(
-                                    PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH))
+                                    PhoneStateListener.
+                                            EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED))
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG) {
@@ -1458,8 +1497,9 @@
                             mRemoveList.add(r.binder);
                         }
                     }
-                    if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                    if (r.matchPhoneStateListenerEvent(
+                            PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             int gsmSignalStrength = signalStrength.getGsmSignalStrength();
                             int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
@@ -1505,8 +1545,8 @@
                 }
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                            PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onCarrierNetworkChange(active);
                         } catch (RemoteException ex) {
@@ -1536,9 +1576,10 @@
             if (validatePhoneId(phoneId)) {
                 mCellInfo.set(phoneId, cellInfo);
                 for (Record r : mRecords) {
-                    if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) &&
-                            idMatch(r.subId, subId, phoneId) &&
-                            (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                    if (validateEventAndUserLocked(
+                            r, PhoneStateListener.EVENT_CELL_INFO_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)
+                            && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
                                     && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
                         try {
                             if (DBG_LOC) {
@@ -1570,8 +1611,8 @@
                 mMessageWaiting[phoneId] = mwi;
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                            PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onMessageWaitingIndicatorChanged(mwi);
                         } catch (RemoteException ex) {
@@ -1597,8 +1638,8 @@
                 mUserMobileDataState[phoneId] = state;
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                            PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onUserMobileDataStateChanged(state);
                         } catch (RemoteException ex) {
@@ -1636,7 +1677,7 @@
                 mTelephonyDisplayInfos[phoneId] = telephonyDisplayInfo;
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
+                            PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED)
                             && idMatchWithoutDefaultPhoneCheck(r.subId, subId)) {
                         try {
                             r.callback.onDisplayInfoChanged(telephonyDisplayInfo);
@@ -1668,8 +1709,8 @@
                 mCallForwarding[phoneId] = cfi;
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                            PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onCallForwardingIndicatorChanged(cfi);
                         } catch (RemoteException ex) {
@@ -1696,8 +1737,9 @@
                 mDataActivity[phoneId] = state;
                 for (Record r : mRecords) {
                     // Notify by correct subId.
-                    if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                    if (r.matchPhoneStateListenerEvent(
+                            PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onDataActivity(state);
                         } catch (RemoteException ex) {
@@ -1744,7 +1786,7 @@
                     mLocalLog.log(str);
                     for (Record r : mRecords) {
                         if (r.matchPhoneStateListenerEvent(
-                                PhoneStateListener.LISTEN_DATA_CONNECTION_STATE)
+                                PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED)
                                 && idMatch(r.subId, subId, phoneId)) {
                             try {
                                 if (DBG) {
@@ -1769,7 +1811,7 @@
                 if (!Objects.equals(oldState, preciseState)) {
                     for (Record r : mRecords) {
                         if (r.matchPhoneStateListenerEvent(
-                                PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
+                                PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)
                                 && idMatch(r.subId, subId, phoneId)) {
                             try {
                                 r.callback.onPreciseDataConnectionStateChanged(preciseState);
@@ -1814,9 +1856,10 @@
             if (validatePhoneId(phoneId) && !Objects.equals(cellIdentity, mCellIdentity[phoneId])) {
                 mCellIdentity[phoneId] = cellIdentity;
                 for (Record r : mRecords) {
-                    if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) &&
-                            idMatch(r.subId, subId, phoneId) &&
-                            (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
+                    if (validateEventAndUserLocked(
+                            r, PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)
+                            && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
                                     && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
                         try {
                             if (DBG_LOC) {
@@ -1867,7 +1910,8 @@
                 }
 
                 for (Record r : mRecords) {
-                    if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)
+                    if (r.matchPhoneStateListenerEvent(
+                            PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]);
@@ -1876,7 +1920,7 @@
                         }
                     }
                     if (notifyCallAttributes && r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED)
+                            PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
@@ -1925,7 +1969,7 @@
                 mImsReasonInfo.set(phoneId, imsReasonInfo);
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES)
+                            PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
@@ -1957,8 +2001,8 @@
                 mSrvccState[phoneId] = state;
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                            PhoneStateListener.EVENT_SRVCC_STATE_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
                                 log("notifySrvccStateChanged: mSrvccState=" + state + " r=" + r);
@@ -1986,7 +2030,7 @@
                         log("notifyOemHookRawEventForSubscriber:  r=" + r + " subId=" + subId);
                     }
                     if ((r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT))
+                            PhoneStateListener.EVENT_OEM_HOOK_RAW))
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onOemHookRawEvent(rawData);
@@ -2014,7 +2058,7 @@
 
             for (Record r : mRecords) {
                 if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE)) {
+                        PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED)) {
                     try {
                         r.callback.onPhoneCapabilityChanged(capability);
                     } catch (RemoteException ex) {
@@ -2039,7 +2083,7 @@
         synchronized (mRecords) {
             for (Record r : mRecords) {
                 if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)) {
+                        PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) {
                     try {
                         r.callback.onActiveDataSubIdChanged(activeDataSubId);
                     } catch (RemoteException ex) {
@@ -2066,7 +2110,7 @@
 
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED)
+                            PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onRadioPowerStateChanged(state);
@@ -2095,7 +2139,7 @@
 
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST)
+                            PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
@@ -2127,7 +2171,7 @@
             for (Record r : mRecords) {
                 // Send to all listeners regardless of subscription
                 if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL)) {
+                        PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL)) {
                     try {
                         r.callback.onOutgoingEmergencyCall(emergencyNumber, subId);
                     } catch (RemoteException ex) {
@@ -2151,7 +2195,7 @@
                 for (Record r : mRecords) {
                     // Send to all listeners regardless of subscription
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS)) {
+                            PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS)) {
                         try {
                             r.callback.onOutgoingEmergencySms(emergencyNumber, subId);
                         } catch (RemoteException ex) {
@@ -2181,7 +2225,7 @@
 
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED)
+                            PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
@@ -2212,7 +2256,7 @@
             if (validatePhoneId(phoneId)) {
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_REGISTRATION_FAILURE)
+                            PhoneStateListener.EVENT_REGISTRATION_FAILURE)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             r.callback.onRegistrationFailed(
@@ -2255,7 +2299,7 @@
                 if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_BARRING_INFO)
+                            PhoneStateListener.EVENT_BARRING_INFO_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
@@ -2282,14 +2326,14 @@
      * @param subId the subId
      * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
      */
-    public void notifyPhysicalChannelConfigurationForSubscriber(
+    public void notifyPhysicalChannelConfigForSubscriber(
             int subId, List<PhysicalChannelConfig> configs) {
-        if (!checkNotifyPermission("notifyPhysicalChannelConfiguration()")) {
+        if (!checkNotifyPermission("notifyPhysicalChannelConfig()")) {
             return;
         }
 
         if (VDBG) {
-            log("notifyPhysicalChannelConfiguration: subId=" + subId + " configs=" + configs);
+            log("notifyPhysicalChannelConfig: subId=" + subId + " configs=" + configs);
         }
 
         synchronized (mRecords) {
@@ -2298,15 +2342,15 @@
                 mPhysicalChannelConfigs.set(phoneId, configs.get(phoneId));
                 for (Record r : mRecords) {
                     if (r.matchPhoneStateListenerEvent(
-                            PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION)
+                            PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)
                             && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
-                                log("notifyPhysicalChannelConfiguration: "
+                                log("notifyPhysicalChannelConfig: "
                                         + "mPhysicalChannelConfigs="
                                         + configs + " r=" + r);
                             }
-                            r.callback.onPhysicalChannelConfigurationChanged(configs);
+                            r.callback.onPhysicalChannelConfigChanged(configs);
                         } catch (RemoteException ex) {
                             mRemoveList.add(r.binder);
                         }
@@ -2616,18 +2660,18 @@
                 == PackageManager.PERMISSION_GRANTED;
     }
 
-    private boolean checkListenerPermission(long events, int subId, String callingPackage,
-            @Nullable String callingFeatureId, String message) {
+    private boolean checkListenerPermission(Set<Integer> events, int subId, String callingPackage,
+                                            @Nullable String callingFeatureId, String message) {
         LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder =
                 new LocationAccessPolicy.LocationPermissionQuery.Builder()
-                .setCallingPackage(callingPackage)
-                .setMethod(message + " events: " + events)
-                .setCallingPid(Binder.getCallingPid())
-                .setCallingUid(Binder.getCallingUid());
+                        .setCallingPackage(callingPackage)
+                        .setMethod(message + " events: " + events)
+                        .setCallingPid(Binder.getCallingPid())
+                        .setCallingUid(Binder.getCallingUid());
 
         boolean shouldCheckLocationPermissions = false;
 
-        if ((events & ENFORCE_LOCATION_PERMISSION_MASK) != 0) {
+        if (isLocationPermissionRequired(events)) {
             // Everything that requires fine location started in Q. So far...
             locationQueryBuilder.setMinSdkVersionForFine(Build.VERSION_CODES.Q);
             // If we're enforcing fine starting in Q, we also want to enforce coarse even for
@@ -2652,14 +2696,14 @@
             }
         }
 
-        if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
+        if (isPhoneStatePermissionRequired(events)) {
             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                     mContext, subId, callingPackage, callingFeatureId, message)) {
                 isPermissionCheckSuccessful = false;
             }
         }
 
-        if ((events & ENFORCE_PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {
+        if (isPrecisePhoneStatePermissionRequired(events)) {
             // check if calling app has either permission READ_PRECISE_PHONE_STATE
             // or with carrier privileges
             try {
@@ -2670,21 +2714,20 @@
             }
         }
 
-        if ((events & READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK) != 0) {
+        if (isActiveEmergencySessionPermissionRequired(events)) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
         }
 
-        if ((events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) {
+        if ((events.contains(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED))) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH, null);
         }
 
-        if ((events & READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK) != 0) {
+        if (isPrivilegedPhoneStatePermissionRequired(events)) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
         }
-
         return isPermissionCheckSuccessful;
     }
 
@@ -2692,25 +2735,25 @@
         int size = mRemoveList.size();
         if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size);
         if (size > 0) {
-            for (IBinder b: mRemoveList) {
+            for (IBinder b : mRemoveList) {
                 remove(b);
             }
             mRemoveList.clear();
         }
     }
 
-    private boolean validateEventsAndUserLocked(Record r, int events) {
+    private boolean validateEventAndUserLocked(Record r, int event) {
         int foregroundUser;
         final long callingIdentity = Binder.clearCallingIdentity();
         boolean valid = false;
         try {
             foregroundUser = ActivityManager.getCurrentUser();
             valid = UserHandle.getUserId(r.callerUid) == foregroundUser
-                    && r.matchPhoneStateListenerEvent(events);
+                    && r.matchPhoneStateListenerEvent(event);
             if (DBG | DBG_LOC) {
-                log("validateEventsAndUserLocked: valid=" + valid
+                log("validateEventAndUserLocked: valid=" + valid
                         + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
-                        + " r.events=" + r.events + " events=" + events);
+                        + " r.eventList=" + r.eventList + " event=" + event);
             }
         } finally {
             Binder.restoreCallingIdentity(callingIdentity);
@@ -2822,9 +2865,14 @@
     }
 
     private void checkPossibleMissNotify(Record r, int phoneId) {
-        long events = r.events;
+        Set<Integer> events = r.eventList;
 
-        if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
+        if (events == null || events.isEmpty()) {
+            log("checkPossibleMissNotify: events = null.");
+            return;
+        }
+
+        if ((events.contains(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED))) {
             try {
                 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" +
                         mServiceState[phoneId]);
@@ -2843,8 +2891,9 @@
             }
         }
 
-        if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0
-                || (events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) {
+        if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED)
+                || events.contains(
+                PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
             try {
                 if (mSignalStrength[phoneId] != null) {
                     SignalStrength signalStrength = mSignalStrength[phoneId];
@@ -2859,7 +2908,7 @@
             }
         }
 
-        if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
+        if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED)) {
             try {
                 if (mSignalStrength[phoneId] != null) {
                     int gsmSignalStrength = mSignalStrength[phoneId]
@@ -2876,7 +2925,7 @@
             }
         }
 
-        if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
+        if (validateEventAndUserLocked(r, PhoneStateListener.EVENT_CELL_INFO_CHANGED)) {
             try {
                 if (DBG_LOC) {
                     log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = "
@@ -2891,7 +2940,7 @@
             }
         }
 
-        if ((events & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) {
+        if (events.contains(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) {
             try {
                 if (VDBG) {
                     log("checkPossibleMissNotify: onUserMobileDataStateChanged phoneId="
@@ -2903,7 +2952,7 @@
             }
         }
 
-        if ((events & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) {
+        if (events.contains(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED)) {
             try {
                 if (VDBG) {
                     log("checkPossibleMissNotify: onDisplayInfoChanged phoneId="
@@ -2917,7 +2966,7 @@
             }
         }
 
-        if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
+        if (events.contains(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) {
             try {
                 if (VDBG) {
                     log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId="
@@ -2930,7 +2979,7 @@
             }
         }
 
-        if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
+        if (events.contains(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) {
             try {
                 if (VDBG) {
                     log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId="
@@ -2943,7 +2992,7 @@
             }
         }
 
-        if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
+        if (validateEventAndUserLocked(r, PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)) {
             try {
                 if (DBG_LOC) {
                     log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = "
@@ -2959,7 +3008,7 @@
             }
         }
 
-        if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
+        if (events.contains(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
             try {
                 if (DBG) {
                     log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState"
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index f49f1b1..7f638b9 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -1737,9 +1737,12 @@
                                 context.getString(R.string.car_mode_disable_notification_title))
                         .setContentText(
                                 context.getString(R.string.car_mode_disable_notification_message))
+
                         .setContentIntent(
+                                // TODO(b/173744200) Please replace FLAG_MUTABLE_UNAUDITED below
+                                // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
                                 PendingIntent.getActivityAsUser(context, 0,
-                                        carModeOffIntent, 0,
+                                        carModeOffIntent, PendingIntent.FLAG_MUTABLE_UNAUDITED,
                                         null, UserHandle.CURRENT));
                 mNotificationManager.notifyAsUser(null,
                         SystemMessage.NOTE_CAR_MODE_DISABLE, n.build(), UserHandle.ALL);
diff --git a/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java b/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java
index b9453db..725bccf 100644
--- a/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java
+++ b/services/core/java/com/android/server/accounts/AccountAuthenticatorCache.java
@@ -27,10 +27,10 @@
 import android.content.res.TypedArray;
 import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 
@@ -83,13 +83,13 @@
 
     private static class MySerializer implements XmlSerializerAndParser<AuthenticatorDescription> {
         @Override
-        public void writeAsXml(AuthenticatorDescription item, XmlSerializer out)
+        public void writeAsXml(AuthenticatorDescription item, TypedXmlSerializer out)
                 throws IOException {
             out.attribute(null, "type", item.type);
         }
 
         @Override
-        public AuthenticatorDescription createFromXml(XmlPullParser parser)
+        public AuthenticatorDescription createFromXml(TypedXmlPullParser parser)
                 throws IOException, XmlPullParserException {
             return AuthenticatorDescription.newKey(parser.getAttributeValue(null, "type"));
         }
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index d99b195..1f35b88 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -71,7 +71,6 @@
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.util.dump.DualDumpOutputStream;
@@ -79,7 +78,6 @@
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -89,7 +87,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
 import java.security.SecureRandom;
 import java.util.AbstractMap;
@@ -1757,21 +1754,21 @@
             dump.write("user_keys", AdbDebuggingManagerProto.USER_KEYS,
                     FileUtils.readTextFile(new File("/data/misc/adb/adb_keys"), 0, null));
         } catch (IOException e) {
-            Slog.e(TAG, "Cannot read user keys", e);
+            Slog.i(TAG, "Cannot read user keys", e);
         }
 
         try {
             dump.write("system_keys", AdbDebuggingManagerProto.SYSTEM_KEYS,
                     FileUtils.readTextFile(new File("/adb_keys"), 0, null));
         } catch (IOException e) {
-            Slog.e(TAG, "Cannot read system keys", e);
+            Slog.i(TAG, "Cannot read system keys", e);
         }
 
         try {
             dump.write("keystore", AdbDebuggingManagerProto.KEYSTORE,
                     FileUtils.readTextFile(getAdbTempKeysFile(), 0, null));
         } catch (IOException e) {
-            Slog.e(TAG, "Cannot read keystore: ", e);
+            Slog.i(TAG, "Cannot read keystore: ", e);
         }
 
         dump.end(token);
@@ -1966,9 +1963,9 @@
                     String key = parser.getAttributeValue(null, XML_ATTRIBUTE_KEY);
                     long connectionTime;
                     try {
-                        connectionTime = Long.valueOf(
-                                parser.getAttributeValue(null, XML_ATTRIBUTE_LAST_CONNECTION));
-                    } catch (NumberFormatException e) {
+                        connectionTime = parser.getAttributeLong(null,
+                                XML_ATTRIBUTE_LAST_CONNECTION);
+                    } catch (XmlPullParserException e) {
                         Slog.e(TAG,
                                 "Caught a NumberFormatException parsing the last connection time: "
                                         + e);
@@ -2020,9 +2017,9 @@
                     String key = parser.getAttributeValue(null, XML_ATTRIBUTE_KEY);
                     long connectionTime;
                     try {
-                        connectionTime = Long.valueOf(
-                                parser.getAttributeValue(null, XML_ATTRIBUTE_LAST_CONNECTION));
-                    } catch (NumberFormatException e) {
+                        connectionTime = parser.getAttributeLong(null,
+                                XML_ATTRIBUTE_LAST_CONNECTION);
+                    } catch (XmlPullParserException e) {
                         Slog.e(TAG,
                                 "Caught a NumberFormatException parsing the last connection time: "
                                         + e);
@@ -2150,8 +2147,8 @@
                 for (Map.Entry<String, Long> keyEntry : mKeyMap.entrySet()) {
                     serializer.startTag(null, XML_TAG_ADB_KEY);
                     serializer.attribute(null, XML_ATTRIBUTE_KEY, keyEntry.getKey());
-                    serializer.attribute(null, XML_ATTRIBUTE_LAST_CONNECTION,
-                            String.valueOf(keyEntry.getValue()));
+                    serializer.attributeLong(null, XML_ATTRIBUTE_LAST_CONNECTION,
+                            keyEntry.getValue());
                     serializer.endTag(null, XML_TAG_ADB_KEY);
                 }
                 for (String bssid : mTrustedNetworks) {
diff --git a/services/core/java/com/android/server/adb/OWNERS b/services/core/java/com/android/server/adb/OWNERS
new file mode 100644
index 0000000..b97f795
--- /dev/null
+++ b/services/core/java/com/android/server/adb/OWNERS
@@ -0,0 +1 @@
+include platform/packages/modules/adb:/OWNERS
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index c7e3b23..dffe0ba 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -50,6 +50,7 @@
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.ApplicationExitInfo;
+import android.app.BroadcastOptions;
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
 import android.app.Notification;
@@ -3201,7 +3202,8 @@
                         + " for fg-service launch");
             }
             mAm.tempWhitelistUidLocked(r.appInfo.uid,
-                    SERVICE_START_FOREGROUND_TIMEOUT, "fg-service-launch");
+                    SERVICE_START_FOREGROUND_TIMEOUT, "fg-service-launch",
+                    BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED);
         }
 
         if (!mPendingServices.contains(r)) {
@@ -5284,8 +5286,9 @@
 
         if (ret == FGS_FEATURE_DENIED) {
             if (mAm.mConstants.mFlagFgsStartTempAllowListEnabled
-                    && mAm.isOnDeviceIdleWhitelistLocked(r.appInfo.uid, false)) {
-                // uid is on DeviceIdleController's allowlist.
+                    && mAm.isWhitelistedForFgsStartLocked(r.appInfo.uid)) {
+                // uid is on DeviceIdleController's user/system allowlist
+                // or AMS's FgsStartTempAllowList.
                 ret = FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST;
             }
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index da6e7ff..0f9e9ee 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -139,6 +139,7 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.Activity;
+import android.app.ActivityClient;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManagerInternal;
@@ -264,7 +265,6 @@
 import android.os.WorkSource;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
-import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.server.ServerProtoEnums;
@@ -288,7 +288,6 @@
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 import android.util.proto.ProtoUtils;
-import android.view.Display;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -326,7 +325,6 @@
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.HeptFunction;
 import com.android.internal.util.function.QuadFunction;
-import com.android.internal.util.function.TriFunction;
 import com.android.server.AlarmManagerInternal;
 import com.android.server.AttributeCache;
 import com.android.server.DeviceIdleInternal;
@@ -394,7 +392,6 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Executor;
-import java.util.function.BiFunction;
 
 public class ActivityManagerService extends IActivityManager.Stub
         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
@@ -1097,6 +1094,11 @@
     final PendingTempWhitelists mPendingTempWhitelist = new PendingTempWhitelists(this);
 
     /**
+     * The temp-allowlist that is allowed to start FGS from background.
+     */
+    final FgsStartTempAllowList mFgsStartTempAllowList = new FgsStartTempAllowList();
+
+    /**
      * Information about and control over application operations
      */
     final AppOpsService mAppOpsService;
@@ -2859,12 +2861,13 @@
     @Override
     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
             int finishTask) {
-        return mActivityTaskManager.finishActivity(token, resultCode, resultData, finishTask);
+        return ActivityClient.getInstance().finishActivity(token, resultCode, resultData,
+                finishTask);
     }
 
     @Override
     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
-        mActivityTaskManager.setRequestedOrientation(token, requestedOrientation);
+        ActivityClient.getInstance().setRequestedOrientation(token, requestedOrientation);
     }
 
     @Override
@@ -5512,6 +5515,12 @@
                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
     }
 
+    boolean isWhitelistedForFgsStartLocked(int uid) {
+        final int appId = UserHandle.getAppId(uid);
+        return Arrays.binarySearch(mDeviceIdleExceptIdleWhitelist, appId) >= 0
+                || mFgsStartTempAllowList.isAllowed(uid);
+    }
+
     /**
      * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
      * the whitelist
@@ -5711,7 +5720,7 @@
      */
     @Override
     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
-        return mActivityTaskManager.moveActivityTaskToBack(token, nonRoot);
+        return ActivityClient.getInstance().moveActivityTaskToBack(token, nonRoot);
     }
 
     @Override
@@ -5746,7 +5755,7 @@
 
     @Override
     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
-        return mActivityTaskManager.getTaskForActivity(token, onlyRoot);
+        return ActivityClient.getInstance().getTaskForActivity(token, onlyRoot);
     }
 
     @Override
@@ -6719,7 +6728,7 @@
 
     @Override
     public boolean isTopOfTask(IBinder token) {
-        return mActivityTaskManager.isTopOfTask(token);
+        return ActivityClient.getInstance().isTopOfTask(token);
     }
 
     @Override
@@ -14485,7 +14494,7 @@
                 mAppOpsService.setMode(AppOpsManager.OP_NO_ISOLATED_STORAGE, app.uid,
                         app.info.packageName, AppOpsManager.MODE_ERRORED);
                 mAppOpsService.setAppOpsServiceDelegate(null);
-                getPermissionManagerInternalLocked().setCheckPermissionDelegate(null);
+                getPermissionManagerInternalLocked().stopShellPermissionIdentityDelegation();
                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
                         instr.mUiAutomationConnection).sendToTarget();
             }
@@ -15326,17 +15335,22 @@
             }
         }
 
-        tempWhitelistUidLocked(targetUid, duration, tag);
+        tempWhitelistUidLocked(targetUid, duration, tag,
+                BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED);
     }
 
     /**
      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
      */
     @GuardedBy("this")
-    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
+    void tempWhitelistUidLocked(int targetUid, long duration, String tag, int type) {
         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
         setUidTempWhitelistStateLocked(targetUid, true);
         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
+
+        if (type == BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
+            mFgsStartTempAllowList.add(targetUid, duration);
+        }
     }
 
     void pushTempWhitelist() {
@@ -16305,14 +16319,9 @@
 
         @Override
         public ActivityPresentationInfo getActivityPresentationInfo(IBinder token) {
-            int displayId = Display.INVALID_DISPLAY;
-            try {
-                displayId = mActivityTaskManager.getDisplayId(token);
-            } catch (RemoteException e) {
-            }
-
-            return new ActivityPresentationInfo(mActivityTaskManager.getTaskForActivity(token,
-                    /*onlyRoot=*/ false), displayId,
+            final ActivityClient ac = ActivityClient.getInstance();
+            return new ActivityPresentationInfo(ac.getTaskForActivity(token,
+                    /*onlyRoot=*/ false), ac.getDisplayId(token),
                     mActivityTaskManager.getActivityClassForToken(token));
         }
 
@@ -17205,12 +17214,6 @@
 
         // We allow delegation only to one instrumentation started from the shell
         synchronized (ActivityManagerService.this) {
-            // If there is a delegate it should be the same instance for app ops and permissions.
-            if (mAppOpsService.getAppOpsServiceDelegate()
-                    != getPermissionManagerInternalLocked().getCheckPermissionDelegate()) {
-                throw new IllegalStateException("Bad shell delegate state");
-            }
-
             // If the delegate is already set up for the target UID, nothing to do.
             if (mAppOpsService.getAppOpsServiceDelegate() != null) {
                 if (!(mAppOpsService.getAppOpsServiceDelegate() instanceof ShellDelegate)) {
@@ -17239,10 +17242,14 @@
                 }
 
                 // Hook them up...
-                final ShellDelegate shellDelegate = new ShellDelegate(
-                        instr.mTargetInfo.packageName, delegateUid, permissions);
+                final ShellDelegate shellDelegate = new ShellDelegate(delegateUid,
+                        permissions);
                 mAppOpsService.setAppOpsServiceDelegate(shellDelegate);
-                getPermissionManagerInternalLocked().setCheckPermissionDelegate(shellDelegate);
+                final String packageName = instr.mTargetInfo.packageName;
+                final List<String> permissionNames = permissions != null ?
+                        Arrays.asList(permissions) : null;
+                getPermissionManagerInternalLocked().startShellPermissionIdentityDelegation(
+                        delegateUid, packageName, permissionNames);
                 return;
             }
         }
@@ -17256,17 +17263,15 @@
         }
         synchronized (ActivityManagerService.this) {
             mAppOpsService.setAppOpsServiceDelegate(null);
-            getPermissionManagerInternalLocked().setCheckPermissionDelegate(null);
+            getPermissionManagerInternalLocked().stopShellPermissionIdentityDelegation();
         }
     }
 
-    private class ShellDelegate implements CheckOpsDelegate, CheckPermissionDelegate {
-        private final String mTargetPackageName;
+    private class ShellDelegate implements CheckOpsDelegate {
         private final int mTargetUid;
         private @Nullable String[] mPermissions;
 
-        ShellDelegate(String targetPackageName, int targetUid, @Nullable String[] permissions) {
-            mTargetPackageName = targetPackageName;
+        ShellDelegate(int targetUid, @Nullable String[] permissions) {
             mTargetUid = targetUid;
             mPermissions = permissions;
         }
@@ -17284,10 +17289,11 @@
         public int checkOperation(int code, int uid, String packageName, boolean raw,
                 QuadFunction<Integer, Integer, String, Boolean, Integer> superImpl) {
             if (uid == mTargetUid && isTargetOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
+                        Process.SHELL_UID);
                 final long identity = Binder.clearCallingIdentity();
                 try {
-                    return superImpl.apply(code, Process.SHELL_UID,
-                            "com.android.shell", raw);
+                    return superImpl.apply(code, shellUid, "com.android.shell", raw);
                 } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
@@ -17299,10 +17305,11 @@
         public int checkAudioOperation(int code, int usage, int uid, String packageName,
                 QuadFunction<Integer, Integer, Integer, String, Integer> superImpl) {
             if (uid == mTargetUid && isTargetOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
+                        Process.SHELL_UID);
                 final long identity = Binder.clearCallingIdentity();
                 try {
-                    return superImpl.apply(code, usage, Process.SHELL_UID,
-                            "com.android.shell");
+                    return superImpl.apply(code, usage, shellUid, "com.android.shell");
                 } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
@@ -17317,9 +17324,11 @@
                 @NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
                         Integer> superImpl) {
             if (uid == mTargetUid && isTargetOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
+                        Process.SHELL_UID);
                 final long identity = Binder.clearCallingIdentity();
                 try {
-                    return superImpl.apply(code, Process.SHELL_UID, "com.android.shell", featureId,
+                    return superImpl.apply(code, shellUid, "com.android.shell", featureId,
                             shouldCollectAsyncNotedOp, message, shouldCollectMessage);
                 } finally {
                     Binder.restoreCallingIdentity(identity);
@@ -17329,34 +17338,6 @@
                     message, shouldCollectMessage);
         }
 
-        @Override
-        public int checkPermission(String permName, String pkgName, int userId,
-                TriFunction<String, String, Integer, Integer> superImpl) {
-            if (mTargetPackageName.equals(pkgName) && isTargetPermission(permName)) {
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply(permName, "com.android.shell", userId);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(permName, pkgName, userId);
-        }
-
-        @Override
-        public int checkUidPermission(String permName, int uid,
-                BiFunction<String, Integer, Integer> superImpl) {
-            if (uid == mTargetUid  && isTargetPermission(permName)) {
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply(permName, Process.SHELL_UID);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(permName, uid);
-        }
-
         private boolean isTargetOp(int code) {
             // null permissions means all ops are targeted
             if (mPermissions == null) {
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index fdc0f59..ca20224 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -353,7 +353,7 @@
                 mUidsToRemove.clear();
                 mCurrentFuture = null;
                 mUseLatestStates = true;
-                if ((updateFlags & UPDATE_ALL) != 0) {
+                if (updateFlags == UPDATE_ALL) {
                     cancelSyncDueToBatteryLevelChangeLocked();
                 }
                 if ((updateFlags & UPDATE_CPU) != 0) {
@@ -533,7 +533,7 @@
                 mStats.updateCpuTimeLocked(onBattery, onBatteryScreenOff);
             }
 
-            if ((updateFlags & UPDATE_ALL) != 0) {
+            if (updateFlags == UPDATE_ALL) {
                 mStats.updateKernelWakelocksLocked(elapsedRealtimeUs);
                 mStats.updateKernelMemoryBandwidthLocked(elapsedRealtimeUs);
             }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 46e16bc..3b6f0ac 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -25,6 +25,7 @@
 import android.hardware.power.stats.EnergyConsumerResult;
 import android.os.BatteryStats;
 import android.os.BatteryStatsInternal;
+import android.os.BatteryUsageStats;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -57,6 +58,7 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.BatteryUsageStatsProvider;
 import com.android.internal.os.BinderCallsStats;
 import com.android.internal.os.PowerProfile;
 import com.android.internal.os.RailStats;
@@ -105,6 +107,7 @@
     private final BatteryStatsImpl.UserInfoProvider mUserManagerUserInfoProvider;
     private final Context mContext;
     private final BatteryExternalStatsWorker mWorker;
+    private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;
 
     private native void getLowPowerStats(RpmStats rpmStats);
     private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
@@ -258,6 +261,7 @@
         mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_radioScanningTimeout) * 1000L);
         mStats.setPowerProfileLocked(new PowerProfile(context));
+        mBatteryUsageStatsProvider = new BatteryUsageStatsProvider(context, mStats);
     }
 
     public void publish() {
@@ -550,6 +554,16 @@
 
     // Public interface...
 
+    /**
+     * Returns BatteryUsageStats, which contains power attribution data on a per-subsystem
+     * and per-UID basis.
+     */
+    public BatteryUsageStats getBatteryUsageStats() {
+        mContext.enforceCallingPermission(
+                android.Manifest.permission.BATTERY_STATS, null);
+        return mBatteryUsageStatsProvider.getBatteryUsageStats();
+    }
+
     public byte[] getStatistics() {
         mContext.enforceCallingPermission(
                 android.Manifest.permission.BATTERY_STATS, null);
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 0877dd9..d2ee69e 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -896,7 +896,8 @@
         return false;
     }
 
-    final void scheduleTempWhitelistLocked(int uid, long duration, BroadcastRecord r) {
+    final void scheduleTempWhitelistLocked(int uid, long duration, BroadcastRecord r,
+            @BroadcastOptions.TempAllowListType int type) {
         if (duration > Integer.MAX_VALUE) {
             duration = Integer.MAX_VALUE;
         }
@@ -919,9 +920,9 @@
         }
         if (DEBUG_BROADCAST) {
             Slog.v(TAG, "Broadcast temp whitelist uid=" + uid + " duration=" + duration
-                    + " : " + b.toString());
+                    + " type=" + type + " : " + b.toString());
         }
-        mService.tempWhitelistUidLocked(uid, duration, b.toString());
+        mService.tempWhitelistUidLocked(uid, duration, b.toString(), type);
     }
 
     /**
@@ -1318,7 +1319,8 @@
                 }
                 if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
                     scheduleTempWhitelistLocked(filter.owningUid,
-                            brOptions.getTemporaryAppWhitelistDuration(), r);
+                            brOptions.getTemporaryAppWhitelistDuration(), r,
+                            brOptions.getTemporaryAppWhitelistType());
                 }
             }
             return;
@@ -1610,7 +1612,8 @@
                 (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0);
         if (isActivityCapable) {
             scheduleTempWhitelistLocked(receiverUid,
-                    brOptions.getTemporaryAppWhitelistDuration(), r);
+                    brOptions.getTemporaryAppWhitelistDuration(), r,
+                    brOptions.getTemporaryAppWhitelistType());
         }
 
         // Broadcast is being executed, its package can't be stopped.
diff --git a/services/core/java/com/android/server/am/FgsStartTempAllowList.java b/services/core/java/com/android/server/am/FgsStartTempAllowList.java
new file mode 100644
index 0000000..1f90393
--- /dev/null
+++ b/services/core/java/com/android/server/am/FgsStartTempAllowList.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.am;
+
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+
+import android.os.SystemClock;
+import android.util.Slog;
+import android.util.SparseLongArray;
+
+/**
+ * List of uids that are temporarily allowed to start FGS from background.
+ */
+final class FgsStartTempAllowList {
+    private static final int MAX_SIZE = 100;
+    /**
+     * The key is the UID, the value is expiration elapse time in ms of this temp-allowed UID.
+     */
+    private final SparseLongArray mTempAllowListFgs = new SparseLongArray();
+
+    FgsStartTempAllowList() {
+    }
+
+    void add(int uid, long duration) {
+        if (duration <= 0) {
+            Slog.e(TAG_AM, "FgsStartTempAllowList bad duration:" + duration + " uid: " + uid);
+            return;
+        }
+        // The temp allowlist should be a short list with only a few entries in it.
+        final int size = mTempAllowListFgs.size();
+        if (size > MAX_SIZE) {
+            Slog.w(TAG_AM, "FgsStartTempAllowList length:" + size + " exceeds " + MAX_SIZE);
+        }
+        final long now = SystemClock.elapsedRealtime();
+        for (int index = mTempAllowListFgs.size() - 1; index >= 0; index--) {
+            if (mTempAllowListFgs.valueAt(index) < now) {
+                mTempAllowListFgs.removeAt(index);
+            }
+        }
+        final long existingExpirationTime = mTempAllowListFgs.get(uid, -1);
+        final long expirationTime = now + duration;
+        if (existingExpirationTime == -1 || existingExpirationTime < expirationTime) {
+            mTempAllowListFgs.put(uid, expirationTime);
+        }
+    }
+
+    boolean isAllowed(int uid) {
+        final int index = mTempAllowListFgs.indexOfKey(uid);
+        if (index < 0) {
+            return false;
+        } else if (mTempAllowListFgs.valueAt(index) < SystemClock.elapsedRealtime()) {
+            mTempAllowListFgs.removeAt(index);
+            return false;
+        } else {
+            return true;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/appop/OWNERS b/services/core/java/com/android/server/appop/OWNERS
new file mode 100644
index 0000000..999ea0e
--- /dev/null
+++ b/services/core/java/com/android/server/appop/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/permission/OWNERS
diff --git a/services/core/java/com/android/server/attention/OWNERS b/services/core/java/com/android/server/attention/OWNERS
new file mode 100644
index 0000000..51fc9bd
--- /dev/null
+++ b/services/core/java/com/android/server/attention/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/attention/OWNERS
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 89150ae..af00731 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -545,7 +545,6 @@
             AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
             AudioSystem.DEVICE_OUT_HDMI_ARC,
-            AudioSystem.DEVICE_OUT_SPDIF,
             AudioSystem.DEVICE_OUT_AUX_LINE));
     // Devices for which the volume is always max, no volume panel
     Set<Integer> mFullVolumeDevices = new HashSet<>();
@@ -7445,8 +7444,8 @@
     private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours
     private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000;  // 1 minute polling interval
     private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;  // 30s after boot completed
-    // check playback or record activity every 3 seconds for UIDs owning mode IN_COMMUNICATION
-    private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 3000;
+    // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION
+    private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000;
 
     private int safeMediaVolumeIndex(int device) {
         if (!mSafeMediaVolumeDevices.contains(device)) {
diff --git a/services/core/java/com/android/server/backup/OWNERS b/services/core/java/com/android/server/backup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/services/core/java/com/android/server/backup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 0194259..75e1938 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -30,6 +30,7 @@
 import android.app.trust.ITrustManager;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
@@ -809,12 +810,13 @@
 
         public List<FingerprintSensorPropertiesInternal> getFingerprintSensorProperties(
                 Context context) {
-            final FingerprintManager fpm = context.getSystemService(FingerprintManager.class);
-            if (fpm != null) {
-                return fpm.getSensorPropertiesInternal();
-            } else {
-                return new ArrayList<>();
+            if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+                final FingerprintManager fpm = context.getSystemService(FingerprintManager.class);
+                if (fpm != null) {
+                    return fpm.getSensorPropertiesInternal();
+                }
             }
+            return new ArrayList<>();
         }
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
index 62c9295..f07bf1e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
@@ -53,7 +53,7 @@
 
     @Override
     public byte[] dumpSensorServiceStateProto() throws RemoteException {
-        return mFaceService.dumpSensorServiceStateProto();
+        return mFaceService.dumpSensorServiceStateProto(mSensorId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 47897a1..cb56e8c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -127,17 +127,6 @@
         return properties;
     }
 
-    @NonNull
-    private List<Face> getEnrolledFaces(int userId, String opPackageName) {
-        final Pair<Integer, ServiceProvider> provider = getSingleProvider();
-        if (provider == null) {
-            Slog.w(TAG, "Null provider for getEnrolledFaces, caller: " + opPackageName);
-            return Collections.emptyList();
-        }
-
-        return provider.second.getEnrolledFaces(provider.first, userId);
-    }
-
     /**
      * Receives the incoming binder calls from FaceManager.
      */
@@ -157,14 +146,13 @@
         }
 
         @Override
-        public byte[] dumpSensorServiceStateProto() {
+        public byte[] dumpSensorServiceStateProto(int sensorId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ProtoOutputStream proto = new ProtoOutputStream();
-            for (ServiceProvider provider : mServiceProviders) {
-                for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
-                    provider.dumpProtoState(props.sensorId, proto);
-                }
+            final ServiceProvider provider = getProviderForSensor(sensorId);
+            if (provider != null) {
+                provider.dumpProtoState(sensorId, proto);
             }
             proto.flush();
             return proto.getBytes();
@@ -439,6 +427,7 @@
                             pw.println("Dumping for sensorId: " + props.sensorId
                                     + ", provider: " + provider.getClass().getSimpleName());
                             provider.dumpInternal(props.sensorId, pw);
+                            pw.println();
                         }
                     }
                 }
@@ -472,7 +461,13 @@
                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
             }
 
-            return FaceService.this.getEnrolledFaces(userId, opPackageName);
+            final ServiceProvider provider = getProviderForSensor(sensorId);
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for getEnrolledFaces, caller: " + opPackageName);
+                return Collections.emptyList();
+            }
+
+            return provider.getEnrolledFaces(sensorId, userId);
         }
 
         @Override // Binder call
@@ -483,7 +478,16 @@
                 Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
             }
 
-            return !FaceService.this.getEnrolledFaces(userId, opPackageName).isEmpty();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for hasEnrolledFaces, caller: " + opPackageName);
+                return false;
+            }
+
+            final boolean enrolled = provider.getEnrolledFaces(sensorId, userId).size() > 0;
+            Slog.d(TAG, "hasEnrolledFaces, sensor: " + sensorId + ", enrolled: " + enrolled);
+
+            return provider.getEnrolledFaces(sensorId, userId).size() > 0;
         }
 
         @Override // Binder call
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceUtils.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceUtils.java
index a0ffe58..a0cd4a5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceUtils.java
@@ -72,13 +72,13 @@
     }
 
     /**
-     * Legacy getter for {@link android.hardware.biometrics.face.V1_0} and its extended subclasses,
-     * which do not support a well defined sensorId from the HAL.
+     * Legacy getter for {@link android.hardware.biometrics.face.V1_0} and its extended subclasses.
+     * Framework-side cache is always stored in the same file, regardless of sensorId.
      */
-    public static FaceUtils getInstance() {
+    public static FaceUtils getLegacyInstance(int sensorId) {
         // Note that sensorId for legacy services can be hard-coded to 0 since it's only used
         // to index into the sensor states map.
-        return getInstance(0 /* sensorId */, LEGACY_FACE_FILE);
+        return getInstance(sensorId, LEGACY_FACE_FILE);
     }
 
     private FaceUtils(String fileName) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
index 4c983fb..9ed8f78 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java
@@ -153,7 +153,8 @@
         Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         // Fake authentication with any of the existing fingers
-        List<Face> faces = FaceUtils.getInstance().getBiometricsForUser(mContext, userId);
+        List<Face> faces = FaceUtils.getLegacyInstance(mSensorId)
+                .getBiometricsForUser(mContext, userId);
         if (faces.isEmpty()) {
             Slog.w(TAG, "No faces, returning");
             return;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index d384bc6..c4e4d1f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -166,7 +166,7 @@
         @Override
         public void onEnrollResult(long deviceId, int faceId, int userId, int remaining) {
             mHandler.post(() -> {
-                final CharSequence name = FaceUtils.getInstance()
+                final CharSequence name = FaceUtils.getLegacyInstance(mSensorId)
                         .getUniqueName(mContext, userId);
                 final Face face = new Face(name, faceId, deviceId);
 
@@ -471,7 +471,7 @@
     @Override
     @NonNull
     public List<Face> getEnrolledFaces(int sensorId, int userId) {
-        return FaceUtils.getInstance().getBiometricsForUser(mContext, userId);
+        return FaceUtils.getLegacyInstance(mSensorId).getBiometricsForUser(mContext, userId);
     }
 
     @Override
@@ -610,8 +610,8 @@
 
             final FaceEnrollClient client = new FaceEnrollClient(mContext, mLazyDaemon, token,
                     new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
-                    opPackageName, FaceUtils.getInstance(), disabledFeatures, ENROLL_TIMEOUT_SEC,
-                    surfaceHandle, mSensorId);
+                    opPackageName, FaceUtils.getLegacyInstance(mSensorId), disabledFeatures,
+                    ENROLL_TIMEOUT_SEC, surfaceHandle, mSensorId);
 
             mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
                 @Override
@@ -665,7 +665,7 @@
 
             final FaceRemovalClient client = new FaceRemovalClient(mContext, mLazyDaemon, token,
                     new ClientMonitorCallbackConverter(receiver), faceId, userId, opPackageName,
-                    FaceUtils.getInstance(), mSensorId, mAuthenticatorIds);
+                    FaceUtils.getLegacyInstance(mSensorId), mSensorId, mAuthenticatorIds);
             mScheduler.scheduleClientMonitor(client);
         });
     }
@@ -748,7 +748,7 @@
             final List<Face> enrolledList = getEnrolledFaces(mSensorId, userId);
             final FaceInternalCleanupClient client = new FaceInternalCleanupClient(mContext,
                     mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId, enrolledList,
-                    FaceUtils.getInstance(), mAuthenticatorIds);
+                    FaceUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
             mScheduler.scheduleClientMonitor(client);
         });
     }
@@ -777,7 +777,7 @@
 
             final long userToken = proto.start(SensorStateProto.USER_STATES);
             proto.write(UserStateProto.USER_ID, userId);
-            proto.write(UserStateProto.NUM_ENROLLED, FaceUtils.getInstance()
+            proto.write(UserStateProto.NUM_ENROLLED, FaceUtils.getLegacyInstance(mSensorId)
                     .getBiometricsForUser(mContext, userId).size());
             proto.end(userToken);
         }
@@ -801,7 +801,8 @@
             JSONArray sets = new JSONArray();
             for (UserInfo user : UserManager.get(mContext).getUsers()) {
                 final int userId = user.getUserHandle().getIdentifier();
-                final int c = FaceUtils.getInstance().getBiometricsForUser(mContext, userId).size();
+                final int c = FaceUtils.getLegacyInstance(mSensorId)
+                        .getBiometricsForUser(mContext, userId).size();
                 JSONObject set = new JSONObject();
                 set.put("id", userId);
                 set.put("count", c);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
index ce880aa..cbffdd3 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
@@ -198,9 +198,11 @@
             final Intent intent = new Intent("android.settings.FACE_SETTINGS");
             intent.setPackage("com.android.settings");
 
+            // TODO(b/174187097) Please replace FLAG_MUTABLE_UNAUDITED below
+            // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
             final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(getContext(),
-                    0 /* requestCode */, intent, 0 /* flags */, null /* options */,
-                    UserHandle.CURRENT);
+                    0 /* requestCode */, intent, PendingIntent.FLAG_MUTABLE_UNAUDITED /* flags */,
+                    null /* options */, UserHandle.CURRENT);
 
             final String channelName = "FaceEnrollNotificationChannel";
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
index 1616457..d4cdc8b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
@@ -54,7 +54,7 @@
 
     @Override
     public byte[] dumpSensorServiceStateProto() throws RemoteException {
-        return mFingerprintService.dumpSensorServiceStateProto();
+        return mFingerprintService.dumpSensorServiceStateProto(mSensorId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 6e91c9a..61f9cc4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -115,15 +115,13 @@
         }
 
         @Override
-        public byte[] dumpSensorServiceStateProto() {
+        public byte[] dumpSensorServiceStateProto(int sensorId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final ProtoOutputStream proto = new ProtoOutputStream();
-            for (ServiceProvider provider : mServiceProviders) {
-                for (FingerprintSensorPropertiesInternal props
-                        : provider.getSensorProperties()) {
-                    provider.dumpProtoState(props.sensorId, proto);
-                }
+            final ServiceProvider provider = getProviderForSensor(sensorId);
+            if (provider != null) {
+                provider.dumpProtoState(sensorId, proto);
             }
             proto.flush();
             return proto.getBytes();
@@ -437,6 +435,7 @@
                             pw.println("Dumping for sensorId: " + props.sensorId
                                     + ", provider: " + provider.getClass().getSimpleName());
                             provider.dumpInternal(props.sensorId, pw);
+                            pw.println();
                         }
                     }
                 }
@@ -588,13 +587,13 @@
                 @Nullable byte [] hardwareAuthToken, String opPackageName) {
             Utils.checkPermission(getContext(), RESET_FINGERPRINT_LOCKOUT);
 
-            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            final ServiceProvider provider = getProviderForSensor(sensorId);
             if (provider == null) {
                 Slog.w(TAG, "Null provider for resetLockout, caller: " + opPackageName);
                 return;
             }
 
-            provider.second.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
+            provider.scheduleResetLockout(sensorId, userId, hardwareAuthToken);
         }
 
         @Override
@@ -747,14 +746,14 @@
     }
 
     /**
-     * For devices with only a single provider, returns that provider. If no providers, or multiple
-     * providers exist, returns null.
+     * For devices with only a single provider, returns that provider. If multiple providers,
+     * returns the first one. If no providers, returns null.
      */
     @Nullable
     private Pair<Integer, ServiceProvider> getSingleProvider() {
         final List<FingerprintSensorPropertiesInternal> properties = getSensorProperties();
-        if (properties.size() != 1) {
-            Slog.e(TAG, "Multiple sensors found: " + properties.size());
+        if (properties.isEmpty()) {
+            Slog.e(TAG, "No providers found");
             return null;
         }
 
@@ -767,7 +766,7 @@
             }
         }
 
-        Slog.e(TAG, "Single sensor, but provider not found");
+        Slog.e(TAG, "Provider not found");
         return null;
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
index 6da8650..b3d2419 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java
@@ -75,12 +75,12 @@
 
     /**
      * Legacy getter for {@link android.hardware.biometrics.fingerprint.V2_1} ands its extended
-     * subclasses, which do not support a well defined sensorId from the HAL.
+     * subclasses. Framework-side cache is always stored in the same file, regardless of sensorId.
      */
-    public static FingerprintUtils getInstance() {
+    public static FingerprintUtils getLegacyInstance(int sensorId) {
         // Note that sensorId for legacy services can be hard-coded to 0 since it's only used
         // to index into the sensor states map.
-        return getInstance(0 /* sensorId */, LEGACY_FINGERPRINT_FILE);
+        return getInstance(sensorId, LEGACY_FINGERPRINT_FILE);
     }
 
     private FingerprintUtils(String fileName) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index fd1181b..3e13c45 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.common.ICancellationSignal;
@@ -59,6 +60,15 @@
     }
 
     @Override
+    public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) {
+        super.onEnrollResult(identifier, remaining);
+
+        if (remaining == 0) {
+            UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
+        }
+    }
+
+    @Override
     protected boolean hasReachedEnrollmentLimit() {
         return FingerprintUtils.getInstance(getSensorId())
                 .getBiometricsForUser(getContext(), getTargetUserId()).size()
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
index 65ce34d..74549b9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java
@@ -144,7 +144,7 @@
         Utils.checkPermission(mContext, TEST_BIOMETRIC);
 
         // Fake authentication with any of the existing fingers
-        List<Fingerprint> fingerprints = FingerprintUtils.getInstance()
+        List<Fingerprint> fingerprints = FingerprintUtils.getLegacyInstance(mSensorId)
                 .getBiometricsForUser(mContext, userId);
         if (fingerprints.isEmpty()) {
             Slog.w(TAG, "No fingerprints, returning");
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 7c5b7c9..b8d27aa 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -111,6 +111,7 @@
     @NonNull private final HalResultController mHalResultController;
     @Nullable private IUdfpsOverlayController mUdfpsOverlayController;
     private int mCurrentUserId = UserHandle.USER_NULL;
+    private final int mSensorId;
 
     private final class BiometricTaskStackListener extends TaskStackListener {
         @Override
@@ -167,13 +168,15 @@
             void onHardwareUnavailable();
         }
 
+        private final int mSensorId;
         @NonNull private final Context mContext;
         @NonNull final Handler mHandler;
         @NonNull final BiometricScheduler mScheduler;
         @Nullable private Callback mCallback;
 
-        HalResultController(@NonNull Context context, @NonNull Handler handler,
+        HalResultController(int sensorId, @NonNull Context context, @NonNull Handler handler,
                 @NonNull BiometricScheduler scheduler) {
+            mSensorId = sensorId;
             mContext = context;
             mHandler = handler;
             mScheduler = scheduler;
@@ -194,7 +197,7 @@
                 }
 
                 final int currentUserId = client.getTargetUserId();
-                final CharSequence name = FingerprintUtils.getInstance()
+                final CharSequence name = FingerprintUtils.getLegacyInstance(mSensorId)
                         .getUniqueName(mContext, currentUserId);
                 final Fingerprint fingerprint = new Fingerprint(name, groupId, fingerId, deviceId);
 
@@ -307,6 +310,7 @@
             @NonNull LockoutResetDispatcher lockoutResetDispatcher,
             @NonNull HalResultController controller) {
         mContext = context;
+        mSensorId = sensorId;
         mScheduler = scheduler;
         mHandler = handler;
         mActivityTaskManager = ActivityTaskManager.getInstance();
@@ -361,7 +365,8 @@
         final Handler handler = new Handler(Looper.getMainLooper());
         final BiometricScheduler scheduler =
                 new BiometricScheduler(TAG, gestureAvailabilityDispatcher);
-        final HalResultController controller = new HalResultController(context, handler, scheduler);
+        final HalResultController controller = new HalResultController(sensorId, context, handler,
+                scheduler);
         return new Fingerprint21(context, scheduler, handler, sensorId, strength,
                 lockoutResetDispatcher, controller);
     }
@@ -549,7 +554,7 @@
 
             final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext,
                     mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
-                    hardwareAuthToken, opPackageName, FingerprintUtils.getInstance(),
+                    hardwareAuthToken, opPackageName, FingerprintUtils.getLegacyInstance(mSensorId),
                     ENROLL_TIMEOUT_SEC, mSensorProperties.sensorId, mUdfpsOverlayController);
             mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
                 @Override
@@ -624,7 +629,7 @@
 
            final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext,
                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), fingerId,
-                   userId, opPackageName, FingerprintUtils.getInstance(),
+                   userId, opPackageName, FingerprintUtils.getLegacyInstance(mSensorId),
                    mSensorProperties.sensorId, mAuthenticatorIds);
            mScheduler.scheduleClientMonitor(client);
         });
@@ -638,8 +643,8 @@
                     mSensorProperties.sensorId, userId);
             final FingerprintInternalCleanupClient client = new FingerprintInternalCleanupClient(
                     mContext, mLazyDaemon, userId, mContext.getOpPackageName(),
-                    mSensorProperties.sensorId, enrolledList, FingerprintUtils.getInstance(),
-                    mAuthenticatorIds);
+                    mSensorProperties.sensorId, enrolledList,
+                    FingerprintUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
             mScheduler.scheduleClientMonitor(client);
         });
     }
@@ -657,14 +662,15 @@
     @Override
     public void rename(int sensorId, int fingerId, int userId, @NonNull String name) {
         mHandler.post(() -> {
-            FingerprintUtils.getInstance().renameBiometricForUser(mContext, userId, fingerId, name);
+            FingerprintUtils.getLegacyInstance(mSensorId)
+                    .renameBiometricForUser(mContext, userId, fingerId, name);
         });
     }
 
     @Override
     @NonNull
     public List<Fingerprint> getEnrolledFingerprints(int sensorId, int userId) {
-        return FingerprintUtils.getInstance().getBiometricsForUser(mContext, userId);
+        return FingerprintUtils.getLegacyInstance(mSensorId).getBiometricsForUser(mContext, userId);
     }
 
     @Override
@@ -716,7 +722,7 @@
 
             final long userToken = proto.start(SensorStateProto.USER_STATES);
             proto.write(UserStateProto.USER_ID, userId);
-            proto.write(UserStateProto.NUM_ENROLLED, FingerprintUtils.getInstance()
+            proto.write(UserStateProto.NUM_ENROLLED, FingerprintUtils.getLegacyInstance(mSensorId)
                     .getBiometricsForUser(mContext, userId).size());
             proto.end(userToken);
         }
@@ -737,7 +743,8 @@
 
             proto.write(FingerprintUserStatsProto.USER_ID, userId);
             proto.write(FingerprintUserStatsProto.NUM_FINGERPRINTS,
-                    FingerprintUtils.getInstance().getBiometricsForUser(mContext, userId).size());
+                    FingerprintUtils.getLegacyInstance(mSensorId)
+                            .getBiometricsForUser(mContext, userId).size());
 
             // Normal fingerprint authentications (e.g. lockscreen)
             long countsToken = proto.start(FingerprintUserStatsProto.NORMAL);
@@ -777,7 +784,7 @@
             JSONArray sets = new JSONArray();
             for (UserInfo user : UserManager.get(mContext).getUsers()) {
                 final int userId = user.getUserHandle().getIdentifier();
-                final int N = FingerprintUtils.getInstance()
+                final int N = FingerprintUtils.getLegacyInstance(mSensorId)
                         .getBiometricsForUser(mContext, userId).size();
                 JSONObject set = new JSONObject();
                 set.put("id", userId);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
index e4933e4..791d224 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
@@ -210,9 +210,9 @@
         @NonNull private Fingerprint21UdfpsMock mFingerprint21;
         @Nullable private LastAuthArgs mLastAuthArgs;
 
-        MockHalResultController(@NonNull Context context, @NonNull Handler handler,
+        MockHalResultController(int sensorId, @NonNull Context context, @NonNull Handler handler,
                 @NonNull BiometricScheduler scheduler) {
-            super(context, handler, scheduler);
+            super(sensorId, context, handler, scheduler);
         }
 
         void init(@NonNull RestartAuthRunnable restartAuthRunnable,
@@ -280,7 +280,7 @@
         final TestableBiometricScheduler scheduler =
                 new TestableBiometricScheduler(TAG, gestureAvailabilityDispatcher);
         final MockHalResultController controller =
-                new MockHalResultController(context, handler, scheduler);
+                new MockHalResultController(sensorId, context, handler, scheduler);
         return new Fingerprint21UdfpsMock(context, scheduler, handler, sensorId, strength,
                 lockoutResetDispatcher, controller);
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
index 2a89a88..af61a8b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
@@ -100,6 +101,15 @@
     }
 
     @Override
+    public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) {
+        super.onEnrollResult(identifier, remaining);
+
+        if (remaining == 0) {
+            UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
+        }
+    }
+
+    @Override
     public void onPointerDown(int x, int y, float minor, float major) {
         UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
     }
diff --git a/services/core/java/com/android/server/camera/OWNERS b/services/core/java/com/android/server/camera/OWNERS
new file mode 100644
index 0000000..f48a95c
--- /dev/null
+++ b/services/core/java/com/android/server/camera/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/av:/camera/OWNERS
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index c789186..1f0fb5e 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -45,8 +45,8 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.Log;
 import android.util.Pair;
-import android.util.Slog;
 
 import java.net.InetAddress;
 import java.util.Arrays;
@@ -279,7 +279,7 @@
     }
 
     public PrivateDnsConfig updatePrivateDns(Network network, PrivateDnsConfig cfg) {
-        Slog.w(TAG, "updatePrivateDns(" + network + ", " + cfg + ")");
+        Log.w(TAG, "updatePrivateDns(" + network + ", " + cfg + ")");
         return (cfg != null)
                 ? mPrivateDnsMap.put(network.netId, cfg)
                 : mPrivateDnsMap.remove(network.netId);
@@ -389,7 +389,7 @@
             mPrivateDnsValidationMap.remove(netId);
         }
 
-        Slog.d(TAG, String.format("sendDnsConfigurationForNetwork(%d, %s, %s, %d, %d, %d, %d, "
+        Log.d(TAG, String.format("sendDnsConfigurationForNetwork(%d, %s, %s, %d, %d, %d, %d, "
                 + "%d, %d, %s, %s)", paramsParcel.netId, Arrays.toString(paramsParcel.servers),
                 Arrays.toString(paramsParcel.domains), paramsParcel.sampleValiditySeconds,
                 paramsParcel.successThreshold, paramsParcel.minSamples,
@@ -400,7 +400,7 @@
         try {
             mDnsResolver.setResolverConfiguration(paramsParcel);
         } catch (RemoteException | ServiceSpecificException e) {
-            Slog.e(TAG, "Error setting DNS configuration: " + e);
+            Log.e(TAG, "Error setting DNS configuration: " + e);
             return;
         }
     }
@@ -431,8 +431,8 @@
                 DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS,
                 DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS);
         if (mSampleValidity < 0 || mSampleValidity > 65535) {
-            Slog.w(TAG, "Invalid sampleValidity=" + mSampleValidity + ", using default=" +
-                    DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS);
+            Log.w(TAG, "Invalid sampleValidity=" + mSampleValidity + ", using default="
+                    + DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS);
             mSampleValidity = DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS;
         }
 
@@ -440,17 +440,17 @@
                 DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT,
                 DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT);
         if (mSuccessThreshold < 0 || mSuccessThreshold > 100) {
-            Slog.w(TAG, "Invalid successThreshold=" + mSuccessThreshold + ", using default=" +
-                    DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT);
+            Log.w(TAG, "Invalid successThreshold=" + mSuccessThreshold + ", using default="
+                    + DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT);
             mSuccessThreshold = DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT;
         }
 
         mMinSamples = getIntSetting(DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_DEFAULT_MIN_SAMPLES);
         mMaxSamples = getIntSetting(DNS_RESOLVER_MAX_SAMPLES, DNS_RESOLVER_DEFAULT_MAX_SAMPLES);
         if (mMinSamples < 0 || mMinSamples > mMaxSamples || mMaxSamples > 64) {
-            Slog.w(TAG, "Invalid sample count (min, max)=(" + mMinSamples + ", " + mMaxSamples +
-                    "), using default=(" + DNS_RESOLVER_DEFAULT_MIN_SAMPLES + ", " +
-                    DNS_RESOLVER_DEFAULT_MAX_SAMPLES + ")");
+            Log.w(TAG, "Invalid sample count (min, max)=(" + mMinSamples + ", " + mMaxSamples
+                    + "), using default=(" + DNS_RESOLVER_DEFAULT_MIN_SAMPLES + ", "
+                    + DNS_RESOLVER_DEFAULT_MAX_SAMPLES + ")");
             mMinSamples = DNS_RESOLVER_DEFAULT_MIN_SAMPLES;
             mMaxSamples = DNS_RESOLVER_DEFAULT_MAX_SAMPLES;
         }
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 17828a0..21ef356 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -60,8 +60,8 @@
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.util.DebugUtils;
+import android.util.Log;
 import android.util.Range;
-import android.util.Slog;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -230,7 +230,7 @@
             mUsageCallback = new UsageCallback() {
                 @Override
                 public void onThresholdReached(int networkType, String subscriberId) {
-                    if (DBG) Slog.d(TAG, "onThresholdReached for network " + network);
+                    if (DBG) Log.d(TAG, "onThresholdReached for network " + network);
                     mMultipathBudget = 0;
                     updateMultipathBudget();
                 }
@@ -252,7 +252,7 @@
             final long bytes = getNetworkTotalBytes(
                     start.toInstant().toEpochMilli(),
                     end.toInstant().toEpochMilli());
-            if (DBG) Slog.d(TAG, "Non-default data usage: " + bytes);
+            if (DBG) Log.d(TAG, "Non-default data usage: " + bytes);
             return bytes;
         }
 
@@ -261,7 +261,7 @@
                 return LocalServices.getService(NetworkStatsManagerInternal.class)
                         .getNetworkTotalBytes(mNetworkTemplate, start, end);
             } catch (RuntimeException e) {
-                Slog.w(TAG, "Failed to get data usage: " + e);
+                Log.w(TAG, "Failed to get data usage: " + e);
                 return -1;
             }
         }
@@ -326,17 +326,17 @@
         void updateMultipathBudget() {
             long quota = LocalServices.getService(NetworkPolicyManagerInternal.class)
                     .getSubscriptionOpportunisticQuota(this.network, QUOTA_TYPE_MULTIPATH);
-            if (DBG) Slog.d(TAG, "Opportunistic quota from data plan: " + quota + " bytes");
+            if (DBG) Log.d(TAG, "Opportunistic quota from data plan: " + quota + " bytes");
 
             // Fallback to user settings-based quota if not available from phone plan
             if (quota == OPPORTUNISTIC_QUOTA_UNKNOWN) {
                 quota = getUserPolicyOpportunisticQuotaBytes();
-                if (DBG) Slog.d(TAG, "Opportunistic quota from user policy: " + quota + " bytes");
+                if (DBG) Log.d(TAG, "Opportunistic quota from user policy: " + quota + " bytes");
             }
 
             if (quota == OPPORTUNISTIC_QUOTA_UNKNOWN) {
                 quota = getDefaultDailyMultipathQuotaBytes();
-                if (DBG) Slog.d(TAG, "Setting quota: " + quota + " bytes");
+                if (DBG) Log.d(TAG, "Setting quota: " + quota + " bytes");
             }
 
             // TODO: re-register if day changed: budget may have run out but should be refreshed.
@@ -344,7 +344,7 @@
                 // If there is already a usage callback pending , there's no need to re-register it
                 // if the quota hasn't changed. The callback will simply fire as expected when the
                 // budget is spent.
-                if (DBG) Slog.d(TAG, "Quota still " + quota + ", not updating.");
+                if (DBG) Log.d(TAG, "Quota still " + quota + ", not updating.");
                 return;
             }
             mQuota = quota;
@@ -364,8 +364,9 @@
             // since last time, so even if this is called very often the budget will not snap to 0
             // as soon as there are less than 2MB left for today.
             if (budget > NetworkStatsManager.MIN_THRESHOLD_BYTES) {
-                if (DBG) Slog.d(TAG, "Setting callback for " + budget +
-                        " bytes on network " + network);
+                if (DBG) {
+                    Log.d(TAG, "Setting callback for " + budget + " bytes on network " + network);
+                }
                 registerUsageCallback(budget);
             } else {
                 maybeUnregisterUsageCallback();
@@ -402,7 +403,7 @@
 
         private void maybeUnregisterUsageCallback() {
             if (haveMultipathBudget()) {
-                if (DBG) Slog.d(TAG, "Unregistering callback, budget was " + mMultipathBudget);
+                if (DBG) Log.d(TAG, "Unregistering callback, budget was " + mMultipathBudget);
                 mStatsManager.unregisterUsageCallback(mUsageCallback);
                 mMultipathBudget = 0;
             }
@@ -467,9 +468,9 @@
                 try {
                     mMultipathTrackers.put(network, new MultipathTracker(network, nc));
                 } catch (IllegalStateException e) {
-                    Slog.e(TAG, "Can't track mobile network " + network + ": " + e.getMessage());
+                    Log.e(TAG, "Can't track mobile network " + network + ": " + e.getMessage());
                 }
-                if (DBG) Slog.d(TAG, "Tracking mobile network " + network);
+                if (DBG) Log.d(TAG, "Tracking mobile network " + network);
             }
 
             @Override
@@ -479,7 +480,7 @@
                     existing.shutdown();
                     mMultipathTrackers.remove(network);
                 }
-                if (DBG) Slog.d(TAG, "No longer tracking mobile network " + network);
+                if (DBG) Log.d(TAG, "No longer tracking mobile network " + network);
             }
         };
 
@@ -524,16 +525,16 @@
 
         @Override
         public void onChange(boolean selfChange) {
-            Slog.wtf(TAG, "Should never be reached.");
+            Log.wtf(TAG, "Should never be reached.");
         }
 
         @Override
         public void onChange(boolean selfChange, Uri uri) {
             if (!Settings.Global.getUriFor(NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES)
                     .equals(uri)) {
-                Slog.wtf(TAG, "Unexpected settings observation: " + uri);
+                Log.wtf(TAG, "Unexpected settings observation: " + uri);
             }
-            if (DBG) Slog.d(TAG, "Settings change: updating budgets.");
+            if (DBG) Log.d(TAG, "Settings change: updating budgets.");
             updateAllMultipathBudgets();
         }
     }
@@ -541,7 +542,7 @@
     private final class ConfigChangeReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (DBG) Slog.d(TAG, "Configuration change: updating budgets.");
+            if (DBG) Log.d(TAG, "Configuration change: updating budgets.");
             updateAllMultipathBudgets();
         }
     }
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 163788f..d9c2e80 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -30,7 +30,7 @@
 import android.os.INetworkManagementService;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
-import android.util.Slog;
+import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
@@ -176,7 +176,7 @@
         try {
             mNMService.registerObserver(this);
         } catch (RemoteException e) {
-            Slog.e(TAG, "Can't register iface observer for clat on " + mNetwork.toShortString());
+            Log.e(TAG, "Can't register iface observer for clat on " + mNetwork.toShortString());
             return;
         }
 
@@ -185,7 +185,7 @@
         try {
             addrStr = mNetd.clatdStart(baseIface, mNat64PrefixInUse.toString());
         } catch (RemoteException | ServiceSpecificException e) {
-            Slog.e(TAG, "Error starting clatd on " + baseIface + ": " + e);
+            Log.e(TAG, "Error starting clatd on " + baseIface + ": " + e);
         }
         mIface = CLAT_PREFIX + baseIface;
         mBaseIface = baseIface;
@@ -193,7 +193,7 @@
         try {
             mIPv6Address = (Inet6Address) InetAddresses.parseNumericAddress(addrStr);
         } catch (ClassCastException | IllegalArgumentException | NullPointerException e) {
-            Slog.e(TAG, "Invalid IPv6 address " + addrStr);
+            Log.e(TAG, "Invalid IPv6 address " + addrStr);
         }
         if (mPrefixDiscoveryRunning && !isPrefixDiscoveryNeeded()) {
             stopPrefixDiscovery();
@@ -218,7 +218,7 @@
         try {
             mNMService.unregisterObserver(this);
         } catch (RemoteException | IllegalStateException e) {
-            Slog.e(TAG, "Error unregistering clatd observer on " + mBaseIface + ": " + e);
+            Log.e(TAG, "Error unregistering clatd observer on " + mBaseIface + ": " + e);
         }
         mNat64PrefixInUse = null;
         mIface = null;
@@ -242,37 +242,37 @@
     @VisibleForTesting
     protected void start() {
         if (isStarted()) {
-            Slog.e(TAG, "startClat: already started");
+            Log.e(TAG, "startClat: already started");
             return;
         }
 
         if (mNetwork.linkProperties == null) {
-            Slog.e(TAG, "startClat: Can't start clat with null LinkProperties");
+            Log.e(TAG, "startClat: Can't start clat with null LinkProperties");
             return;
         }
 
         String baseIface = mNetwork.linkProperties.getInterfaceName();
         if (baseIface == null) {
-            Slog.e(TAG, "startClat: Can't start clat on null interface");
+            Log.e(TAG, "startClat: Can't start clat on null interface");
             return;
         }
         // TODO: should we only do this if mNetd.clatdStart() succeeds?
-        Slog.i(TAG, "Starting clatd on " + baseIface);
+        Log.i(TAG, "Starting clatd on " + baseIface);
         enterStartingState(baseIface);
     }
 
     @VisibleForTesting
     protected void stop() {
         if (!isStarted()) {
-            Slog.e(TAG, "stopClat: already stopped");
+            Log.e(TAG, "stopClat: already stopped");
             return;
         }
 
-        Slog.i(TAG, "Stopping clatd on " + mBaseIface);
+        Log.i(TAG, "Stopping clatd on " + mBaseIface);
         try {
             mNetd.clatdStop(mBaseIface);
         } catch (RemoteException | ServiceSpecificException e) {
-            Slog.e(TAG, "Error stopping clatd on " + mBaseIface + ": " + e);
+            Log.e(TAG, "Error stopping clatd on " + mBaseIface + ": " + e);
         }
 
         String iface = mIface;
@@ -294,7 +294,7 @@
         try {
             mDnsResolver.startPrefix64Discovery(getNetId());
         } catch (RemoteException | ServiceSpecificException e) {
-            Slog.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e);
+            Log.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e);
         }
         mPrefixDiscoveryRunning = true;
     }
@@ -303,7 +303,7 @@
         try {
             mDnsResolver.stopPrefix64Discovery(getNetId());
         } catch (RemoteException | ServiceSpecificException e) {
-            Slog.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e);
+            Log.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e);
         }
         mPrefixDiscoveryRunning = false;
     }
@@ -320,7 +320,7 @@
         try {
             mDnsResolver.setPrefix64(getNetId(), prefixString);
         } catch (RemoteException | ServiceSpecificException e) {
-            Slog.e(TAG, "Error setting NAT64 prefix on netId " + getNetId() + " to "
+            Log.e(TAG, "Error setting NAT64 prefix on netId " + getNetId() + " to "
                     + prefix + ": " + e);
         }
     }
@@ -328,7 +328,7 @@
     private void maybeHandleNat64PrefixChange() {
         final IpPrefix newPrefix = selectNat64Prefix();
         if (!Objects.equals(mNat64PrefixInUse, newPrefix)) {
-            Slog.d(TAG, "NAT64 prefix changed from " + mNat64PrefixInUse + " to "
+            Log.d(TAG, "NAT64 prefix changed from " + mNat64PrefixInUse + " to "
                     + newPrefix);
             stop();
             // It's safe to call update here, even though this method is called from update, because
@@ -418,7 +418,7 @@
             return;
         }
 
-        Slog.d(TAG, "clatd running, updating NAI for " + mIface);
+        Log.d(TAG, "clatd running, updating NAI for " + mIface);
         for (LinkProperties stacked: oldLp.getStackedLinks()) {
             if (Objects.equals(mIface, stacked.getInterfaceName())) {
                 lp.addStackedLink(stacked);
@@ -451,7 +451,7 @@
             return new LinkAddress(
                     InetAddresses.parseNumericAddress(config.ipv4Addr), config.prefixLength);
         } catch (IllegalArgumentException | RemoteException | ServiceSpecificException e) {
-            Slog.e(TAG, "Error getting link properties: " + e);
+            Log.e(TAG, "Error getting link properties: " + e);
             return null;
         }
     }
@@ -480,11 +480,11 @@
 
         LinkAddress clatAddress = getLinkAddress(iface);
         if (clatAddress == null) {
-            Slog.e(TAG, "clatAddress was null for stacked iface " + iface);
+            Log.e(TAG, "clatAddress was null for stacked iface " + iface);
             return;
         }
 
-        Slog.i(TAG, String.format("interface %s is up, adding stacked link %s on top of %s",
+        Log.i(TAG, String.format("interface %s is up, adding stacked link %s on top of %s",
                 mIface, mIface, mBaseIface));
         enterRunningState();
         LinkProperties lp = new LinkProperties(mNetwork.linkProperties);
@@ -503,7 +503,7 @@
             return;
         }
 
-        Slog.i(TAG, "interface " + iface + " removed");
+        Log.i(TAG, "interface " + iface + " removed");
         // If we're running, and the interface was removed, then we didn't call stop(), and it's
         // likely that clatd crashed. Ensure we call stop() so we can start clatd again. Calling
         // stop() will also update LinkProperties, and if clatd crashed, the LinkProperties update
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 7f4fb40..7795ed3 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -35,7 +35,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.Slog;
+import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.widget.Toast;
@@ -175,7 +175,7 @@
         final int previousEventId = mNotificationTypeMap.get(id);
         final NotificationType previousNotifyType = NotificationType.getFromId(previousEventId);
         if (priority(previousNotifyType) > priority(notifyType)) {
-            Slog.d(TAG, String.format(
+            Log.d(TAG, String.format(
                     "ignoring notification %s for network %s with existing notification %s",
                     notifyType, id, previousNotifyType));
             return;
@@ -183,7 +183,7 @@
         clearNotification(id);
 
         if (DBG) {
-            Slog.d(TAG, String.format(
+            Log.d(TAG, String.format(
                     "showNotification tag=%s event=%s transport=%s name=%s highPriority=%s",
                     tag, nameOf(eventId), getTransportName(transportType), name, highPriority));
         }
@@ -253,7 +253,7 @@
             // are sent, but they are not implemented yet.
             return;
         } else {
-            Slog.wtf(TAG, "Unknown notification type " + notifyType + " on network transport "
+            Log.wtf(TAG, "Unknown notification type " + notifyType + " on network transport "
                     + getTransportName(transportType));
             return;
         }
@@ -294,7 +294,7 @@
         try {
             mNotificationManager.notify(tag, eventId, notification);
         } catch (NullPointerException npe) {
-            Slog.d(TAG, "setNotificationVisible: visible notificationManager error", npe);
+            Log.d(TAG, "setNotificationVisible: visible notificationManager error", npe);
         }
     }
 
@@ -317,13 +317,13 @@
         final String tag = tagFor(id);
         final int eventId = mNotificationTypeMap.get(id);
         if (DBG) {
-            Slog.d(TAG, String.format("clearing notification tag=%s event=%s", tag,
+            Log.d(TAG, String.format("clearing notification tag=%s event=%s", tag,
                    nameOf(eventId)));
         }
         try {
             mNotificationManager.cancel(tag, eventId);
         } catch (NullPointerException npe) {
-            Slog.d(TAG, String.format(
+            Log.d(TAG, String.format(
                     "failed to clear notification tag=%s event=%s", tag, nameOf(eventId)), npe);
         }
         mNotificationTypeMap.delete(id);
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index 26cc3ee..5cb3d94 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -35,7 +35,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
-import android.util.Slog;
+import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -168,7 +168,7 @@
                 proxyProperties = new ProxyInfo(host, port, exclList);
             }
             if (!proxyProperties.isValid()) {
-                if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
+                if (DBG) Log.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
                 return;
             }
 
@@ -223,7 +223,7 @@
         if (mPacManager.setCurrentProxyScriptUrl(proxyInfo) == PacManager.DONT_SEND_BROADCAST) {
             return;
         }
-        if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
+        if (DBG) Log.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
                 Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -255,7 +255,7 @@
             if (proxyInfo != null && (!TextUtils.isEmpty(proxyInfo.getHost()) ||
                     !Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))) {
                 if (!proxyInfo.isValid()) {
-                    if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
+                    if (DBG) Log.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
                     return;
                 }
                 mGlobalProxy = new ProxyInfo(proxyInfo);
@@ -296,7 +296,7 @@
         synchronized (mProxyLock) {
             if (Objects.equals(mDefaultProxy, proxyInfo)) return;
             if (proxyInfo != null &&  !proxyInfo.isValid()) {
-                if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
+                if (DBG) Log.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
                 return;
             }
 
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index a2c427b8..027b9af 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -76,8 +76,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
-import com.android.server.SystemService.TargetUser;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.permission.LegacyPermissionManagerInternal;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -296,8 +295,8 @@
 
         // Let the package manager query for the sync adapters for a given authority
         // as we grant default permissions to sync adapters for specific authorities.
-        final PermissionManagerServiceInternal permissionManagerInternal =
-                LocalServices.getService(PermissionManagerServiceInternal.class);
+        final LegacyPermissionManagerInternal permissionManagerInternal =
+                LocalServices.getService(LegacyPermissionManagerInternal.class);
         permissionManagerInternal.setSyncAdapterPackagesProvider((authority, userId) -> {
             return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
         });
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 0b2d4d7..6ae410a 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -3838,9 +3838,12 @@
             }
 
             UserHandle user = new UserHandle(userId);
+            // TODO(b/174186839) Please replace FLAG_MUTABLE_UNAUDITED below
+            // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
             final PendingIntent pendingIntent = PendingIntent
                     .getActivityAsUser(mContext, 0, clickIntent,
-                            PendingIntent.FLAG_CANCEL_CURRENT, null, user);
+                            PendingIntent.FLAG_CANCEL_CURRENT
+                            | PendingIntent.FLAG_MUTABLE_UNAUDITED, null, user);
 
             CharSequence tooManyDeletesDescFormat = mContext.getResources().getText(
                     R.string.contentServiceTooManyDeletesNotificationDesc);
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index d27cb16..668142b 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -1804,10 +1804,8 @@
         int id = -1;
         try {
             id = parser.getAttributeInt(null, "id");
-        } catch (NumberFormatException e) {
+        } catch (XmlPullParserException e) {
             Slog.e(TAG, "error parsing the id of the authority", e);
-        } catch (NullPointerException e) {
-            Slog.e(TAG, "the id of the authority is null", e);
         }
         if (id >= 0) {
             String authorityName = parser.getAttributeValue(null, "authority");
@@ -1920,28 +1918,26 @@
     private void parseExtra(TypedXmlPullParser parser, Bundle extras) {
         String name = parser.getAttributeValue(null, "name");
         String type = parser.getAttributeValue(null, "type");
-        String value1 = parser.getAttributeValue(null, "value1");
-        String value2 = parser.getAttributeValue(null, "value2");
 
         try {
             if ("long".equals(type)) {
-                extras.putLong(name, Long.parseLong(value1));
+                extras.putLong(name, parser.getAttributeLong(null, "value1"));
             } else if ("integer".equals(type)) {
-                extras.putInt(name, Integer.parseInt(value1));
+                extras.putInt(name, parser.getAttributeInt(null, "value1"));
             } else if ("double".equals(type)) {
-                extras.putDouble(name, Double.parseDouble(value1));
+                extras.putDouble(name, parser.getAttributeDouble(null, "value1"));
             } else if ("float".equals(type)) {
-                extras.putFloat(name, Float.parseFloat(value1));
+                extras.putFloat(name, parser.getAttributeFloat(null, "value1"));
             } else if ("boolean".equals(type)) {
-                extras.putBoolean(name, Boolean.parseBoolean(value1));
+                extras.putBoolean(name, parser.getAttributeBoolean(null, "value1"));
             } else if ("string".equals(type)) {
-                extras.putString(name, value1);
+                extras.putString(name, parser.getAttributeValue(null, "value1"));
             } else if ("account".equals(type)) {
+                final String value1 = parser.getAttributeValue(null, "value1");
+                final String value2 = parser.getAttributeValue(null, "value2");
                 extras.putParcelable(name, new Account(value1, value2));
             }
-        } catch (NumberFormatException e) {
-            Slog.e(TAG, "error parsing bundle value", e);
-        } catch (NullPointerException e) {
+        } catch (XmlPullParserException e) {
             Slog.e(TAG, "error parsing bundle value", e);
         }
     }
diff --git a/services/core/java/com/android/server/contentcapture/OWNERS b/services/core/java/com/android/server/contentcapture/OWNERS
new file mode 100644
index 0000000..a28e00a
--- /dev/null
+++ b/services/core/java/com/android/server/contentcapture/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/contentcapture/OWNERS
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 2a0e219..7a8ba9f 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -668,12 +668,11 @@
                     builder.setUserBrightnessPoint(
                             parser.getAttributeBoolean(null, ATTR_USER_POINT, false));
 
-                    String colorSampleDurationString =
-                            parser.getAttributeValue(null, ATTR_COLOR_SAMPLE_DURATION);
+                    long colorSampleDuration =
+                            parser.getAttributeLong(null, ATTR_COLOR_SAMPLE_DURATION, -1);
                     String colorValueBucketsString =
                             parser.getAttributeValue(null, ATTR_COLOR_VALUE_BUCKETS);
-                    if (colorSampleDurationString != null && colorValueBucketsString != null) {
-                        long colorSampleDuration = Long.parseLong(colorSampleDurationString);
+                    if (colorSampleDuration != -1 && colorValueBucketsString != null) {
                         String[] buckets = colorValueBucketsString.split(",");
                         long[] bucketValues = new long[buckets.length];
                         for (int i = 0; i < bucketValues.length; ++i) {
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 23e5a43..a8e56a1 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -73,15 +73,31 @@
     public static DisplayDeviceConfig create(long physicalDisplayId) {
         DisplayDeviceConfig config;
 
+        config = loadConfigFromDirectory(Environment.getProductDirectory(), physicalDisplayId);
+        if (config != null) {
+            return config;
+        }
+
+        config = loadConfigFromDirectory(Environment.getVendorDirectory(), physicalDisplayId);
+        if (config != null) {
+            return config;
+        }
+
+        return null;
+    }
+
+    private static DisplayDeviceConfig loadConfigFromDirectory(
+            File baseDirectory, long physicalDisplayId) {
+        DisplayDeviceConfig config;
         // Create config using filename from physical ID (including "stable" bit).
-        config = getConfigFromSuffix(STABLE_ID_SUFFIX_FORMAT, physicalDisplayId);
+        config = getConfigFromSuffix(baseDirectory, STABLE_ID_SUFFIX_FORMAT, physicalDisplayId);
         if (config != null) {
             return config;
         }
 
         // Create config using filename from physical ID (excluding "stable" bit).
         final long withoutStableFlag = physicalDisplayId & ~STABLE_FLAG;
-        config = getConfigFromSuffix(NO_SUFFIX_FORMAT, withoutStableFlag);
+        config = getConfigFromSuffix(baseDirectory, NO_SUFFIX_FORMAT, withoutStableFlag);
         if (config != null) {
             return config;
         }
@@ -90,7 +106,7 @@
         final DisplayAddress.Physical physicalAddress =
                 DisplayAddress.fromPhysicalDisplayId(physicalDisplayId);
         int port = physicalAddress.getPort();
-        config = getConfigFromSuffix(PORT_SUFFIX_FORMAT, port);
+        config = getConfigFromSuffix(baseDirectory, PORT_SUFFIX_FORMAT, port);
         if (config != null) {
             return config;
         }
@@ -127,12 +143,13 @@
         return str;
     }
 
-    private static DisplayDeviceConfig getConfigFromSuffix(String suffixFormat, long idNumber) {
+    private static DisplayDeviceConfig getConfigFromSuffix(File baseDirectory,
+            String suffixFormat, long idNumber) {
 
         final String suffix = String.format(suffixFormat, idNumber);
         final String filename = String.format(CONFIG_FILE_FORMAT, suffix);
         final File filePath = Environment.buildPath(
-                Environment.getProductDirectory(), ETC_DIR, DISPLAY_CONFIG_DIR, filename);
+                baseDirectory, ETC_DIR, DISPLAY_CONFIG_DIR, filename);
 
         if (filePath.exists()) {
             final DisplayDeviceConfig config = new DisplayDeviceConfig();
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index b0820e8..a62642b 100644
--- a/services/core/java/com/android/server/display/PersistentDataStore.java
+++ b/services/core/java/com/android/server/display/PersistentDataStore.java
@@ -31,17 +31,12 @@
 import android.view.Display;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 
 import libcore.io.IoUtils;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -49,7 +44,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
@@ -628,15 +622,7 @@
                     }
 
                     String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
-                    String timeStampString = parser.getAttributeValue(null, ATTR_TIME_STAMP);
-                    long timeStamp = -1;
-                    if (timeStampString != null) {
-                        try {
-                            timeStamp = Long.parseLong(timeStampString);
-                        } catch (NumberFormatException nfe) {
-                            // Ignore we will just not restore the timestamp.
-                        }
-                    }
+                    long timeStamp = parser.getAttributeLong(null, ATTR_TIME_STAMP, -1);
 
                     try {
                         BrightnessConfiguration config =
diff --git a/services/core/java/com/android/server/dreams/OWNERS b/services/core/java/com/android/server/dreams/OWNERS
index 426f002..3c9bbf8 100644
--- a/services/core/java/com/android/server/dreams/OWNERS
+++ b/services/core/java/com/android/server/dreams/OWNERS
@@ -1,3 +1,3 @@
-dsandler@android.com
+dsandler@google.com
 michaelwr@google.com
 roosa@google.com
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java b/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java
index 2878a94..a9eb75d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java
@@ -18,9 +18,14 @@
 
 import android.stats.hdmi.HdmiStatsEnums;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FrameworkStatsLog;
 
-class HdmiCecAtomWriter {
+/**
+ * Provides methods for writing HDMI-CEC statsd atoms.
+ */
+@VisibleForTesting
+public class HdmiCecAtomWriter {
 
     private static final int FEATURE_ABORT_OPCODE_UNKNOWN = 0x100;
     private static final int ERROR_CODE_UNKNOWN = -1;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
index a261fa1..98d130f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
@@ -253,7 +253,7 @@
                 return STORAGE_GLOBAL_SETTINGS;
             case HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION:
                 return STORAGE_GLOBAL_SETTINGS;
-            case HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP:
+            case HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE:
                 return STORAGE_GLOBAL_SETTINGS;
             case HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST:
                 return STORAGE_SHARED_PREFS;
@@ -271,7 +271,7 @@
                 return Global.HDMI_CONTROL_ENABLED;
             case HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION:
                 return Global.HDMI_CEC_VERSION;
-            case HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP:
+            case HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE:
                 return Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP;
             case HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST:
                 return setting.getName();
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 19dc017..bbd5ac3 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -635,7 +635,7 @@
      */
     private int incomingMessageDirection(int srcAddress, int dstAddress) {
         boolean sourceIsLocal = false;
-        boolean destinationIsLocal = false;
+        boolean destinationIsLocal = dstAddress == Constants.ADDR_BROADCAST;
         for (HdmiCecLocalDevice localDevice : mService.getHdmiCecNetwork().getLocalDeviceList()) {
             int logicalAddress = localDevice.getDeviceInfo().getLogicalAddress();
             if (logicalAddress == srcAddress) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 9ca1f91..e6cf18b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -160,20 +160,20 @@
         switch (standbyAction) {
             case HdmiControlService.STANDBY_SCREEN_OFF:
                 // Get latest setting value
-                @HdmiControlManager.StandbyBehavior
+                @HdmiControlManager.PowerControlMode
                 String sendStandbyOnSleep = mService.getHdmiCecConfig().getStringValue(
-                        HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
+                        HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE);
                 switch (sendStandbyOnSleep) {
-                    case HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV:
+                    case HdmiControlManager.POWER_CONTROL_MODE_TV:
                         mService.sendCecCommand(
                                 HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_TV));
                         break;
-                    case HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST:
+                    case HdmiControlManager.POWER_CONTROL_MODE_BROADCAST:
                         mService.sendCecCommand(
                                 HdmiCecMessageBuilder.buildStandby(mAddress,
                                         Constants.ADDR_BROADCAST));
                         break;
-                    case HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE:
+                    case HdmiControlManager.POWER_CONTROL_MODE_NONE:
                         break;
                 }
                 break;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
index 59ebdd5..8a1a728 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
@@ -107,8 +107,8 @@
     protected void sendStandby(int deviceId) {
         assertRunOnServiceThread();
         String sendStandbyOnSleep = mService.getHdmiCecConfig().getStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
-        if (sendStandbyOnSleep.equals(HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST)) {
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE);
+        if (sendStandbyOnSleep.equals(HdmiControlManager.POWER_CONTROL_MODE_BROADCAST)) {
             mService.sendCecCommand(
                     HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_BROADCAST));
             return;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
index 5d75a63..fc21724 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java
@@ -59,7 +59,8 @@
  * Note that the information cached in this class is not guaranteed to be up-to-date, especially OSD
  * names, power states can be outdated.
  */
-class HdmiCecNetwork {
+@VisibleForTesting
+public class HdmiCecNetwork {
     private static final String TAG = "HdmiCecNetwork";
 
     protected final Object mLock;
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 56b73ba..a1d13e9 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -564,7 +564,8 @@
         mTvInputManager.unregisterCallback(callback);
     }
 
-    PowerManager getPowerManager() {
+    @VisibleForTesting
+    protected PowerManager getPowerManager() {
         return mPowerManager;
     }
 
@@ -729,7 +730,8 @@
         Global.putInt(cr, key, toInt(value));
     }
 
-    void writeStringSystemProperty(String key, String value) {
+    @VisibleForTesting
+    protected void writeStringSystemProperty(String key, String value) {
         SystemProperties.set(key, value);
     }
 
@@ -3366,7 +3368,7 @@
     }
 
     @VisibleForTesting
-    HdmiCecAtomWriter getAtomWriter() {
+    protected HdmiCecAtomWriter getAtomWriter() {
         return mAtomWriter;
     }
 
@@ -3395,7 +3397,8 @@
                 HdmiControlService.PERMISSION);
     }
 
-    HdmiCecConfig getHdmiCecConfig() {
+    @VisibleForTesting
+    protected HdmiCecConfig getHdmiCecConfig() {
         return mHdmiCecConfig;
     }
 }
diff --git a/services/core/java/com/android/server/hdmi/OWNERS b/services/core/java/com/android/server/hdmi/OWNERS
new file mode 100644
index 0000000..c3c47ed
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/hardware/hdmi/OWNERS
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index f9f97fe..ea6e615 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -165,9 +165,9 @@
         if (service.isAudioSystemDevice()) {
             return false;
         }
-        @HdmiControlManager.StandbyBehavior String sendStandbyOnSleep =
+        @HdmiControlManager.PowerControlMode String sendStandbyOnSleep =
                 service.getHdmiCecConfig().getStringValue(
-                        HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
-        return sendStandbyOnSleep.equals(HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+                        HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE);
+        return sendStandbyOnSleep.equals(HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
     }
 }
diff --git a/services/core/java/com/android/server/incident/OWNERS b/services/core/java/com/android/server/incident/OWNERS
new file mode 100644
index 0000000..f766115
--- /dev/null
+++ b/services/core/java/com/android/server/incident/OWNERS
@@ -0,0 +1 @@
+include /cmds/incidentd/OWNERS
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 42aad7d..a0121bb 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -51,6 +51,7 @@
 import android.media.AudioManager;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.CombinedVibrationEffect;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
@@ -264,7 +265,11 @@
     private static native void nativeReloadCalibration(long ptr);
     private static native void nativeVibrate(long ptr, int deviceId, long[] pattern,
             int[] amplitudes, int repeat, int token);
+    private static native void nativeVibrateCombined(long ptr, int deviceId, long[] pattern,
+            SparseArray<int[]> amplitudes, int repeat, int token);
     private static native void nativeCancelVibrate(long ptr, int deviceId, int token);
+    private static native boolean nativeIsVibrating(long ptr, int deviceId);
+    private static native int[] nativeGetVibratorIds(long ptr, int deviceId);
     private static native void nativeReloadKeyboardLayouts(long ptr);
     private static native void nativeReloadDeviceAliases(long ptr);
     private static native String nativeDump(long ptr);
@@ -1801,43 +1806,57 @@
         return result;
     }
 
-    // Binder call
-    @Override
-    public void vibrate(int deviceId, VibrationEffect effect, IBinder token) {
-        long[] pattern;
-        int[] amplitudes;
-        int repeat;
-        if (effect instanceof VibrationEffect.OneShot) {
-            VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect;
-            pattern = new long[] { 0, oneShot.getDuration() };
-            int amplitude = oneShot.getAmplitude();
-            // android framework uses DEFAULT_AMPLITUDE to signal that the vibration
-            // should use some built-in default value, denoted here as DEFAULT_VIBRATION_MAGNITUDE
-            if (amplitude == VibrationEffect.DEFAULT_AMPLITUDE) {
-                amplitude = DEFAULT_VIBRATION_MAGNITUDE;
-            }
-            amplitudes = new int[] { 0, amplitude };
-            repeat = -1;
-        } else if (effect instanceof VibrationEffect.Waveform) {
-            VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect;
-            pattern = waveform.getTimings();
-            amplitudes = waveform.getAmplitudes();
-            for (int i = 0; i < amplitudes.length; i++) {
-                if (amplitudes[i] == VibrationEffect.DEFAULT_AMPLITUDE) {
-                    amplitudes[i] = DEFAULT_VIBRATION_MAGNITUDE;
+    private static class VibrationInfo {
+        private long[] mPattern = new long[0];
+        private int[] mAmplitudes = new int[0];
+        private int mRepeat = -1;
+
+        public long[] getPattern() {
+            return mPattern;
+        }
+
+        public int[] getAmplitudes() {
+            return mAmplitudes;
+        }
+
+        public int getRepeatIndex() {
+            return mRepeat;
+        }
+
+        VibrationInfo(VibrationEffect effect) {
+            if (effect instanceof VibrationEffect.OneShot) {
+                VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect;
+                mPattern = new long[] { 0, oneShot.getDuration() };
+                int amplitude = oneShot.getAmplitude();
+                // android framework uses DEFAULT_AMPLITUDE to signal that the vibration
+                // should use some built-in default value, denoted here as
+                // DEFAULT_VIBRATION_MAGNITUDE
+                if (amplitude == VibrationEffect.DEFAULT_AMPLITUDE) {
+                    amplitude = DEFAULT_VIBRATION_MAGNITUDE;
                 }
+                mAmplitudes = new int[] { 0, amplitude };
+                mRepeat = -1;
+            } else if (effect instanceof VibrationEffect.Waveform) {
+                VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect;
+                mPattern = waveform.getTimings();
+                mAmplitudes = waveform.getAmplitudes();
+                for (int i = 0; i < mAmplitudes.length; i++) {
+                    if (mAmplitudes[i] == VibrationEffect.DEFAULT_AMPLITUDE) {
+                        mAmplitudes[i] = DEFAULT_VIBRATION_MAGNITUDE;
+                    }
+                }
+                mRepeat = waveform.getRepeatIndex();
+                if (mRepeat >= mPattern.length) {
+                    throw new ArrayIndexOutOfBoundsException();
+                }
+            } else {
+                // TODO: Add support for prebaked effects
+                Slog.w(TAG, "Pre-baked effects aren't supported on input devices");
             }
-            repeat = waveform.getRepeatIndex();
-        } else {
-            // TODO: Add support for prebaked effects
-            Log.w(TAG, "Pre-baked effects aren't supported on input devices");
-            return;
         }
+    }
 
-        if (repeat >= pattern.length) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-
+    private VibratorToken getVibratorToken(int deviceId, IBinder token) {
         VibratorToken v;
         synchronized (mVibratorLock) {
             v = mVibratorTokens.get(token);
@@ -1852,9 +1871,70 @@
                 mVibratorTokens.put(token, v);
             }
         }
+        return v;
+    }
+
+    // Binder call
+    @Override
+    public void vibrate(int deviceId, VibrationEffect effect, IBinder token) {
+        VibrationInfo info = new VibrationInfo(effect);
+        VibratorToken v = getVibratorToken(deviceId, token);
         synchronized (v) {
             v.mVibrating = true;
-            nativeVibrate(mPtr, deviceId, pattern, amplitudes, repeat, v.mTokenValue);
+            nativeVibrate(mPtr, deviceId, info.getPattern(), info.getAmplitudes(),
+                    info.getRepeatIndex(), v.mTokenValue);
+        }
+    }
+
+    // Binder call
+    @Override
+    public int[] getVibratorIds(int deviceId) {
+        return nativeGetVibratorIds(mPtr, deviceId);
+    }
+
+    // Binder call
+    @Override
+    public boolean isVibrating(int deviceId) {
+        return nativeIsVibrating(mPtr, deviceId);
+    }
+
+    // Binder call
+    @Override
+    public void vibrateCombined(int deviceId, CombinedVibrationEffect effect, IBinder token) {
+        VibratorToken v = getVibratorToken(deviceId, token);
+        synchronized (v) {
+            if (!(effect instanceof CombinedVibrationEffect.Mono)
+                    && !(effect instanceof CombinedVibrationEffect.Stereo)) {
+                Slog.e(TAG, "Only Mono and Stereo effects are supported");
+                return;
+            }
+
+            v.mVibrating = true;
+            if (effect instanceof CombinedVibrationEffect.Mono) {
+                CombinedVibrationEffect.Mono mono = (CombinedVibrationEffect.Mono) effect;
+                VibrationInfo info = new VibrationInfo(mono.getEffect());
+                nativeVibrate(mPtr, deviceId, info.getPattern(), info.getAmplitudes(),
+                        info.getRepeatIndex(), v.mTokenValue);
+            } else if (effect instanceof CombinedVibrationEffect.Stereo) {
+                CombinedVibrationEffect.Stereo stereo = (CombinedVibrationEffect.Stereo) effect;
+                SparseArray<VibrationEffect> effects = stereo.getEffects();
+                long[] pattern = new long[0];
+                int repeat = Integer.MIN_VALUE;
+                SparseArray<int[]> amplitudes = new SparseArray<int[]>(effects.size());
+                for (int i = 0; i < effects.size(); i++) {
+                    VibrationInfo info = new VibrationInfo(effects.valueAt(i));
+                    // Pattern of all effects should be same
+                    if (pattern.length == 0) {
+                        pattern = info.getPattern();
+                    }
+                    if (repeat == Integer.MIN_VALUE) {
+                        repeat = info.getRepeatIndex();
+                    }
+                    amplitudes.put(effects.keyAt(i), info.getAmplitudes());
+                }
+                nativeVibrateCombined(mPtr, deviceId, pattern, amplitudes, repeat,
+                        v.mTokenValue);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java
index a735a8f..6cec272 100644
--- a/services/core/java/com/android/server/input/PersistentDataStore.java
+++ b/services/core/java/com/android/server/input/PersistentDataStore.java
@@ -510,7 +510,7 @@
                 serializer.startTag(null, "keyboard-layout");
                 serializer.attribute(null, "descriptor", layout);
                 if (layout.equals(mCurrentKeyboardLayout)) {
-                    serializer.attribute(null, "current", "true");
+                    serializer.attributeBoolean(null, "current", true);
                 }
                 serializer.endTag(null, "keyboard-layout");
             }
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index e5c1986..3854f8c 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -57,6 +57,7 @@
 import android.location.ILocationCallback;
 import android.location.ILocationListener;
 import android.location.ILocationManager;
+import android.location.LastLocationRequest;
 import android.location.Location;
 import android.location.LocationManager;
 import android.location.LocationManagerInternal;
@@ -113,7 +114,7 @@
 import com.android.server.location.provider.PassiveLocationProvider;
 import com.android.server.location.provider.PassiveLocationProviderManager;
 import com.android.server.location.provider.proxy.ProxyLocationProvider;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.permission.LegacyPermissionManagerInternal;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -261,8 +262,8 @@
 
         // Let the package manager query which are the default location
         // providers as they get certain permissions granted by default.
-        PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
-                PermissionManagerServiceInternal.class);
+        LegacyPermissionManagerInternal permissionManagerInternal = LocalServices.getService(
+                LegacyPermissionManagerInternal.class);
         permissionManagerInternal.setLocationPackagesProvider(
                 userId -> mContext.getResources().getStringArray(
                         com.android.internal.R.array.config_locationProviderPackageNames));
@@ -588,6 +589,30 @@
                 new String[0]);
     }
 
+    @Nullable
+    @Override
+    public ICancellationSignal getCurrentLocation(String provider, LocationRequest request,
+            ILocationCallback consumer, String packageName, String attributionTag,
+            String listenerId) {
+        CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag,
+                listenerId);
+        int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(),
+                identity.getPid());
+        LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel,
+                PERMISSION_COARSE);
+
+        // clients in the system process must have an attribution tag set
+        Preconditions.checkState(identity.getPid() != Process.myPid() || attributionTag != null);
+
+        request = validateLocationRequest(request, identity);
+
+        LocationProviderManager manager = getLocationProviderManager(provider);
+        Preconditions.checkArgument(manager != null,
+                "provider \"" + provider + "\" does not exist");
+
+        return manager.getCurrentLocation(request, identity, permissionLevel, consumer);
+    }
+
     @Override
     public void registerLocationListener(String provider, LocationRequest request,
             ILocationListener listener, String packageName, @Nullable String attributionTag,
@@ -741,7 +766,8 @@
     }
 
     @Override
-    public Location getLastLocation(String provider, String packageName, String attributionTag) {
+    public Location getLastLocation(String provider, LastLocationRequest request,
+            String packageName, String attributionTag) {
         CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag);
         int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(),
                 identity.getPid());
@@ -751,36 +777,29 @@
         // clients in the system process must have an attribution tag set
         Preconditions.checkArgument(identity.getPid() != Process.myPid() || attributionTag != null);
 
+        request = validateLastLocationRequest(request);
+
         LocationProviderManager manager = getLocationProviderManager(provider);
         if (manager == null) {
             return null;
         }
 
-        return manager.getLastLocation(identity, permissionLevel, false);
+        return manager.getLastLocation(request, identity, permissionLevel);
     }
 
-    @Nullable
-    @Override
-    public ICancellationSignal getCurrentLocation(String provider, LocationRequest request,
-            ILocationCallback consumer, String packageName, String attributionTag,
-            String listenerId) {
-        CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag,
-                listenerId);
-        int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(),
-                identity.getPid());
-        LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel,
-                PERMISSION_COARSE);
+    private LastLocationRequest validateLastLocationRequest(LastLocationRequest request) {
+        if (request.isHiddenFromAppOps()) {
+            mContext.enforceCallingOrSelfPermission(
+                    permission.UPDATE_APP_OPS_STATS,
+                    "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS);
+        }
+        if (request.isLocationSettingsIgnored()) {
+            mContext.enforceCallingOrSelfPermission(
+                    permission.WRITE_SECURE_SETTINGS,
+                    "ignoring location settings requires " + permission.WRITE_SECURE_SETTINGS);
+        }
 
-        // clients in the system process must have an attribution tag set
-        Preconditions.checkState(identity.getPid() != Process.myPid() || attributionTag != null);
-
-        request = validateLocationRequest(request, identity);
-
-        LocationProviderManager manager = getLocationProviderManager(provider);
-        Preconditions.checkArgument(manager != null,
-                "provider \"" + provider + "\" does not exist");
-
-        return manager.getCurrentLocation(request, identity, permissionLevel, consumer);
+        return request;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index c5d7f2c..2fe8bcc 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -49,6 +49,7 @@
 import android.location.Criteria;
 import android.location.ILocationCallback;
 import android.location.ILocationListener;
+import android.location.LastLocationRequest;
 import android.location.Location;
 import android.location.LocationManager;
 import android.location.LocationManagerInternal;
@@ -1467,9 +1468,9 @@
         }
     }
 
-    public @Nullable Location getLastLocation(CallerIdentity identity,
-            @PermissionLevel int permissionLevel, boolean ignoreLocationSettings) {
-        if (!isActive(ignoreLocationSettings, identity)) {
+    public @Nullable Location getLastLocation(LastLocationRequest request,
+            CallerIdentity identity, @PermissionLevel int permissionLevel) {
+        if (!isActive(request.isLocationSettingsIgnored(), identity)) {
             return null;
         }
 
@@ -1483,7 +1484,7 @@
                 getLastLocationUnsafe(
                         identity.getUserId(),
                         permissionLevel,
-                        ignoreLocationSettings,
+                        request.isLocationSettingsIgnored(),
                         Long.MAX_VALUE),
                 permissionLevel);
 
diff --git a/services/core/java/com/android/server/location/timezone/BinderLocationTimeZoneProvider.java b/services/core/java/com/android/server/location/timezone/BinderLocationTimeZoneProvider.java
index b4bcd7b..fd8cf70 100644
--- a/services/core/java/com/android/server/location/timezone/BinderLocationTimeZoneProvider.java
+++ b/services/core/java/com/android/server/location/timezone/BinderLocationTimeZoneProvider.java
@@ -55,7 +55,7 @@
 
     @Override
     void onInitialize() {
-        mProxy.setListener(new LocationTimeZoneProviderProxy.Listener() {
+        mProxy.initialize(new LocationTimeZoneProviderProxy.Listener() {
             @Override
             public void onReportLocationTimeZoneEvent(
                     @NonNull LocationTimeZoneEvent locationTimeZoneEvent) {
diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
index b7c7476..c8a1db6 100644
--- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
+++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneManagerService.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.Resources;
 import android.os.Binder;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
@@ -27,6 +28,7 @@
 import android.util.Log;
 import android.util.Slog;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.DumpUtils;
 import com.android.server.FgThread;
@@ -179,36 +181,45 @@
     }
 
     private LocationTimeZoneProvider createPrimaryProvider() {
+        Resources resources = mContext.getResources();
+        if (!resources.getBoolean(R.bool.config_enablePrimaryLocationTimeZoneProvider)) {
+            return new NullLocationTimeZoneProvider(mThreadingDomain, PRIMARY_PROVIDER_NAME);
+        }
+
         LocationTimeZoneProviderProxy proxy;
         if (isInSimulationMode(PRIMARY_PROVIDER_NAME)) {
             proxy = new SimulatedLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
         } else {
-            proxy = RealLocationTimeZoneProviderProxy.createAndRegister(
+            proxy = new RealLocationTimeZoneProviderProxy(
                     mContext,
                     mThreadingDomain,
                     PRIMARY_LOCATION_TIME_ZONE_SERVICE_ACTION,
-                    com.android.internal.R.bool.config_enablePrimaryLocationTimeZoneOverlay,
-                    com.android.internal.R.string.config_primaryLocationTimeZoneProviderPackageName
+                    R.bool.config_enablePrimaryLocationTimeZoneOverlay,
+                    R.string.config_primaryLocationTimeZoneProviderPackageName
             );
         }
-        return createLocationTimeZoneProvider(PRIMARY_PROVIDER_NAME, proxy);
+        return new BinderLocationTimeZoneProvider(mThreadingDomain, PRIMARY_PROVIDER_NAME, proxy);
     }
 
     private LocationTimeZoneProvider createSecondaryProvider() {
+        Resources resources = mContext.getResources();
+        if (!resources.getBoolean(R.bool.config_enableSecondaryLocationTimeZoneProvider)) {
+            return new NullLocationTimeZoneProvider(mThreadingDomain, SECONDARY_PROVIDER_NAME);
+        }
+
         LocationTimeZoneProviderProxy proxy;
         if (isInSimulationMode(SECONDARY_PROVIDER_NAME)) {
             proxy = new SimulatedLocationTimeZoneProviderProxy(mContext, mThreadingDomain);
         } else {
-            proxy = RealLocationTimeZoneProviderProxy.createAndRegister(
+            proxy = new RealLocationTimeZoneProviderProxy(
                     mContext,
                     mThreadingDomain,
                     SECONDARY_LOCATION_TIME_ZONE_SERVICE_ACTION,
-                    com.android.internal.R.bool.config_enableSecondaryLocationTimeZoneOverlay,
-                    com.android.internal.R.string
-                            .config_secondaryLocationTimeZoneProviderPackageName
+                    R.bool.config_enableSecondaryLocationTimeZoneOverlay,
+                    R.string.config_secondaryLocationTimeZoneProviderPackageName
             );
         }
-        return createLocationTimeZoneProvider(SECONDARY_PROVIDER_NAME, proxy);
+        return new BinderLocationTimeZoneProvider(mThreadingDomain, SECONDARY_PROVIDER_NAME, proxy);
     }
 
     private boolean isInSimulationMode(String providerName) {
@@ -216,21 +227,6 @@
                 SIMULATION_MODE_SYSTEM_PROPERTY_PREFIX + providerName, false);
     }
 
-    private LocationTimeZoneProvider createLocationTimeZoneProvider(
-            @NonNull String providerName, @NonNull LocationTimeZoneProviderProxy proxy) {
-        LocationTimeZoneProvider provider;
-        if (proxy != null) {
-            debugLog("LocationTimeZoneProvider found for providerName=" + providerName);
-            provider = new BinderLocationTimeZoneProvider(mThreadingDomain,
-                    providerName, proxy);
-        } else {
-            debugLog("No LocationTimeZoneProvider found for providerName=" + providerName
-                    + ": stubbing");
-            provider = new NullLocationTimeZoneProvider(mThreadingDomain, providerName);
-        }
-        return provider;
-    }
-
     @Override
     public void onShellCommand(FileDescriptor in, FileDescriptor out,
             FileDescriptor err, String[] args, ShellCallback callback,
diff --git a/services/core/java/com/android/server/location/timezone/LocationTimeZoneProviderProxy.java b/services/core/java/com/android/server/location/timezone/LocationTimeZoneProviderProxy.java
index 1b4706f..8a0259d 100644
--- a/services/core/java/com/android/server/location/timezone/LocationTimeZoneProviderProxy.java
+++ b/services/core/java/com/android/server/location/timezone/LocationTimeZoneProviderProxy.java
@@ -70,9 +70,11 @@
     }
 
     /**
-     * Sets the listener. The listener can expect to receive all events after this point.
+     * Initializes the proxy. The supplied listener can expect to receive all events after this
+     * point. This method also calls {@link #onInitialize()} for subclasses to handle their own
+     * initialization.
      */
-    void setListener(@NonNull Listener listener) {
+    void initialize(@NonNull Listener listener) {
         Objects.requireNonNull(listener);
         synchronized (mSharedLock) {
             if (mListener != null) {
@@ -80,9 +82,15 @@
             }
             this.mListener = listener;
         }
+        onInitialize();
     }
 
     /**
+     * Initializes the proxy. This is called after {@link #mListener} is set.
+     */
+    abstract void onInitialize();
+
+    /**
      * Sets a new request for the provider.
      */
     abstract void setRequest(@NonNull LocationTimeZoneProviderRequest request);
diff --git a/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java b/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java
index cd6d359..1a01288 100644
--- a/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java
+++ b/services/core/java/com/android/server/location/timezone/RealLocationTimeZoneProviderProxy.java
@@ -41,23 +41,6 @@
  */
 class RealLocationTimeZoneProviderProxy extends LocationTimeZoneProviderProxy {
 
-    /**
-     * Creates and registers this proxy. If no suitable service is available for the proxy, returns
-     * null.
-     */
-    @Nullable
-    static LocationTimeZoneProviderProxy createAndRegister(
-            @NonNull Context context, @NonNull ThreadingDomain threadingDomain,
-            @NonNull String action, int enableOverlayResId, int nonOverlayPackageResId) {
-        RealLocationTimeZoneProviderProxy proxy = new RealLocationTimeZoneProviderProxy(
-                context, threadingDomain, action, enableOverlayResId, nonOverlayPackageResId);
-        if (proxy.register()) {
-            return proxy;
-        } else {
-            return null;
-        }
-    }
-
     @NonNull private final ServiceWatcher mServiceWatcher;
 
     @GuardedBy("mProxyLock")
@@ -66,7 +49,7 @@
     @GuardedBy("mProxyLock")
     @NonNull private LocationTimeZoneProviderRequest mRequest;
 
-    private RealLocationTimeZoneProviderProxy(
+    RealLocationTimeZoneProviderProxy(
             @NonNull Context context, @NonNull ThreadingDomain threadingDomain,
             @NonNull String action, int enableOverlayResId,
             int nonOverlayPackageResId) {
@@ -77,6 +60,13 @@
                 enableOverlayResId, nonOverlayPackageResId);
     }
 
+    @Override
+    void onInitialize() {
+        if (!register()) {
+            throw new IllegalStateException("Unable to register binder proxy");
+        }
+    }
+
     private boolean register() {
         boolean resolves = mServiceWatcher.checkServiceResolves();
         if (resolves) {
diff --git a/services/core/java/com/android/server/location/timezone/SimulatedLocationTimeZoneProviderProxy.java b/services/core/java/com/android/server/location/timezone/SimulatedLocationTimeZoneProviderProxy.java
index 604ff74..5e66a99 100644
--- a/services/core/java/com/android/server/location/timezone/SimulatedLocationTimeZoneProviderProxy.java
+++ b/services/core/java/com/android/server/location/timezone/SimulatedLocationTimeZoneProviderProxy.java
@@ -49,6 +49,11 @@
         mRequest = LocationTimeZoneProviderRequest.EMPTY_REQUEST;
     }
 
+    @Override
+    void onInitialize() {
+        // No-op - nothing to do for the simulated provider.
+    }
+
     void simulate(@NonNull SimulatedBinderProviderEvent event) {
         mThreadingDomain.assertCurrentThread();
 
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index c4581c8..834cf05 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -16,8 +16,6 @@
 
 package com.android.server.locksettings;
 
-import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
-
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
 
@@ -271,15 +269,17 @@
     private boolean isNewCredentialSufficient(LockscreenCredential credential) {
         final PasswordMetrics requiredMetrics =
                 mLockPatternUtils.getRequestedPasswordMetrics(mCurrentUserId);
+        final int requiredComplexity =
+                mLockPatternUtils.getRequestedPasswordComplexity(mCurrentUserId);
         final List<PasswordValidationError> errors;
         if (credential.isPassword() || credential.isPin()) {
-            errors = PasswordMetrics.validatePassword(requiredMetrics, PASSWORD_COMPLEXITY_NONE,
+            errors = PasswordMetrics.validatePassword(requiredMetrics, requiredComplexity,
                     credential.isPin(), credential.getCredential());
         } else {
             PasswordMetrics metrics = new PasswordMetrics(
                     credential.isPattern() ? CREDENTIAL_TYPE_PATTERN : CREDENTIAL_TYPE_NONE);
             errors = PasswordMetrics.validatePasswordMetrics(
-                    requiredMetrics, PASSWORD_COMPLEXITY_NONE, false /* isPin */, metrics);
+                    requiredMetrics, requiredComplexity, false /* isPin */, metrics);
         }
         if (!errors.isEmpty()) {
             getOutPrintWriter().println(
diff --git a/services/core/java/com/android/server/locksettings/OWNERS b/services/core/java/com/android/server/locksettings/OWNERS
new file mode 100644
index 0000000..dad6e39
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/OWNERS
@@ -0,0 +1,2 @@
+jaggies@google.com
+kchyn@google.com
diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java
index 64c3c28..ea1d8da 100644
--- a/services/core/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java
@@ -37,7 +37,7 @@
 import android.security.Credentials;
 import android.security.KeyStore;
 import android.text.TextUtils;
-import android.util.Slog;
+import android.util.Log;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -128,7 +128,7 @@
         final int egressType = (egressInfo == null) ? TYPE_NONE : egressInfo.getType();
         final String egressIface = (egressProp == null) ?
                 null : egressProp.getInterfaceName();
-        Slog.d(TAG, "handleStateChanged: egress=" + egressType
+        Log.d(TAG, "handleStateChanged: egress=" + egressType
                 + " " + mAcceptedEgressIface + "->" + egressIface);
 
         if (egressDisconnected || egressChanged) {
@@ -149,7 +149,7 @@
 
         } else if (egressInfo.isConnected() && !vpnInfo.isConnectedOrConnecting()) {
             if (mProfile.isValidLockdownProfile()) {
-                Slog.d(TAG, "Active network connected; starting VPN");
+                Log.d(TAG, "Active network connected; starting VPN");
                 EventLogTags.writeLockdownVpnConnecting(egressType);
                 showNotification(R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected);
 
@@ -160,11 +160,11 @@
                     mVpn.startLegacyVpnPrivileged(mProfile, KeyStore.getInstance(), egressProp);
                 } catch (IllegalStateException e) {
                     mAcceptedEgressIface = null;
-                    Slog.e(TAG, "Failed to start VPN", e);
+                    Log.e(TAG, "Failed to start VPN", e);
                     showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
                 }
             } else {
-                Slog.e(TAG, "Invalid VPN profile; requires IP-based server and DNS");
+                Log.e(TAG, "Invalid VPN profile; requires IP-based server and DNS");
                 showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
             }
 
@@ -172,8 +172,8 @@
             final String iface = vpnConfig.interfaze;
             final List<LinkAddress> sourceAddrs = vpnConfig.addresses;
 
-            Slog.d(TAG, "VPN connected using iface=" + iface +
-                    ", sourceAddr=" + sourceAddrs.toString());
+            Log.d(TAG, "VPN connected using iface=" + iface
+                    + ", sourceAddr=" + sourceAddrs.toString());
             EventLogTags.writeLockdownVpnConnected(egressType);
             showNotification(R.string.vpn_lockdown_connected, R.drawable.vpn_connected);
 
@@ -190,7 +190,7 @@
     }
 
     private void initLocked() {
-        Slog.d(TAG, "initLocked()");
+        Log.d(TAG, "initLocked()");
 
         mVpn.setEnableTeardown(false);
         mVpn.setLockdown(true);
@@ -204,7 +204,7 @@
     }
 
     private void shutdownLocked() {
-        Slog.d(TAG, "shutdownLocked()");
+        Log.d(TAG, "shutdownLocked()");
 
         mAcceptedEgressIface = null;
         mErrorCount = 0;
@@ -222,7 +222,7 @@
      */
     @GuardedBy("mConnService.mVpns")
     public void reset() {
-        Slog.d(TAG, "reset()");
+        Log.d(TAG, "reset()");
         synchronized (mStateLock) {
             // cycle tracker, reset error count, and trigger retry
             shutdownLocked();
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index 006d78e..5bd352c 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -17,11 +17,13 @@
 
 import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
 import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
+import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED;
 import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
 import static android.net.INetd.FIREWALL_RULE_ALLOW;
 import static android.net.INetd.FIREWALL_RULE_DENY;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
 import static android.os.Process.INVALID_UID;
@@ -339,6 +341,8 @@
                 return FIREWALL_CHAIN_NAME_STANDBY;
             case FIREWALL_CHAIN_POWERSAVE:
                 return FIREWALL_CHAIN_NAME_POWERSAVE;
+            case FIREWALL_CHAIN_RESTRICTED:
+                return FIREWALL_CHAIN_NAME_RESTRICTED;
             default:
                 return String.valueOf(chain);
         }
diff --git a/services/core/java/com/android/server/net/OWNERS b/services/core/java/com/android/server/net/OWNERS
index 28ae6a4..d5c7618 100644
--- a/services/core/java/com/android/server/net/OWNERS
+++ b/services/core/java/com/android/server/net/OWNERS
@@ -2,7 +2,7 @@
 
 codewiz@google.com
 jchalard@google.com
-jsharkey@android.com
+jsharkey@google.com
 junyulai@google.com
 lorenzo@google.com
 reminv@google.com
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 8200ca0..769b781 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -123,7 +123,7 @@
         final Config c = new Config();
         c.caption = "condition provider";
         c.serviceInterface = ConditionProviderService.SERVICE_INTERFACE;
-        c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES;
+        c.secureSettingName = null;
         c.xmlTag = TAG_ENABLED_DND_APPS;
         c.secondarySettingName = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS;
         c.bindPermission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index a7ee272..54e9b37 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -437,9 +437,15 @@
                         }
                     }
                 }
-                Settings.Secure.putStringForUser(
-                        mContext.getContentResolver(), element, value, userId);
-                loadAllowedComponentsFromSettings();
+                if (shouldReflectToSettings()) {
+                    Settings.Secure.putStringForUser(
+                            mContext.getContentResolver(), element, value, userId);
+                }
+
+                for (UserInfo user : mUm.getUsers()) {
+                    addApprovedList(value, user.id, mConfig.secureSettingName.equals(element));
+                }
+                Slog.d(TAG, "Done loading approved values from settings");
                 rebindServices(false, userId);
             }
         }
@@ -498,10 +504,13 @@
                             out.endTag(null, TAG_MANAGED_SERVICES);
 
                             if (!forBackup && isPrimary) {
-                                // Also write values to settings, for observers who haven't migrated yet
-                                Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                                        getConfig().secureSettingName, allowedItems,
-                                        approvedUserId);
+                                if (shouldReflectToSettings()) {
+                                    // Also write values to settings, for observers who haven't
+                                    // migrated yet
+                                    Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                                            getConfig().secureSettingName, allowedItems,
+                                            approvedUserId);
+                                }
                             }
 
                         }
@@ -516,6 +525,13 @@
     }
 
     /**
+     * Returns whether the approved list of services should also be written to the Settings db
+     */
+    protected boolean shouldReflectToSettings() {
+        return false;
+    }
+
+    /**
      * Writes extra xml attributes to {@link #TAG_MANAGED_SERVICES} tag.
      */
     protected void writeExtraAttributes(TypedXmlSerializer out, int userId) throws IOException {}
@@ -530,8 +546,20 @@
      */
     protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException {}
 
-    protected void migrateToXml() {
-        loadAllowedComponentsFromSettings();
+    protected final void migrateToXml() {
+        for (UserInfo user : mUm.getUsers()) {
+            final ContentResolver cr = mContext.getContentResolver();
+            addApprovedList(Settings.Secure.getStringForUser(
+                    cr,
+                    getConfig().secureSettingName,
+                    user.id), user.id, true);
+            if (!TextUtils.isEmpty(getConfig().secondarySettingName)) {
+                addApprovedList(Settings.Secure.getStringForUser(
+                        cr,
+                        getConfig().secondarySettingName,
+                        user.id), user.id, false);
+            }
+        }
     }
 
     void readDefaults(TypedXmlPullParser parser) {
@@ -638,23 +666,6 @@
 
     protected abstract String getRequiredPermission();
 
-    private void loadAllowedComponentsFromSettings() {
-        for (UserInfo user : mUm.getUsers()) {
-            final ContentResolver cr = mContext.getContentResolver();
-            addApprovedList(Settings.Secure.getStringForUser(
-                    cr,
-                    getConfig().secureSettingName,
-                    user.id), user.id, true);
-            if (!TextUtils.isEmpty(getConfig().secondarySettingName)) {
-                addApprovedList(Settings.Secure.getStringForUser(
-                        cr,
-                        getConfig().secondarySettingName,
-                        user.id), user.id, false);
-            }
-        }
-        Slog.d(TAG, "Done loading approved values from settings");
-    }
-
     protected void addApprovedList(String approved, int userId, boolean isPrimary) {
         addApprovedList(approved, userId, isPrimary, approved);
     }
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index 7257f52..c1deb96 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -293,7 +293,9 @@
                                 .appendPath(file.getAbsolutePath()).build())
                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
                         .putExtra(EXTRA_KEY, file.getAbsolutePath()),
-                PendingIntent.FLAG_UPDATE_CURRENT);
+                // TODO(b/174161800) Please replace FLAG_MUTABLE_UNAUDITED below
+                // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
         mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, deletionTime, pi);
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ee860e3..692e97a 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -277,6 +277,7 @@
 import com.android.server.policy.PhoneWindowManager;
 import com.android.server.statusbar.StatusBarManagerInternal;
 import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.utils.quota.MultiRateLimiter;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.BackgroundActivityStartCallback;
 import com.android.server.wm.WindowManagerInternal;
@@ -298,6 +299,7 @@
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -371,6 +373,20 @@
             RoleManager.ROLE_EMERGENCY
     };
 
+    // Used for rate limiting toasts by package.
+    static final String TOAST_QUOTA_TAG = "toast_quota_tag";
+
+    // This constant defines rate limits applied to showing toasts. The numbers are set in a way
+    // such that an aggressive toast showing strategy would result in a roughly 1.5x longer wait
+    // time (before the package is allowed to show toasts again) each time the toast rate limit is
+    // reached. It's meant to protect the user against apps spamming them with toasts (either
+    // accidentally or on purpose).
+    private static final MultiRateLimiter.RateLimit[] TOAST_RATE_LIMITS = {
+            MultiRateLimiter.RateLimit.create(3, Duration.ofSeconds(20)),
+            MultiRateLimiter.RateLimit.create(5, Duration.ofSeconds(42)),
+            MultiRateLimiter.RateLimit.create(6, Duration.ofSeconds(68)),
+    };
+
     // When #matchesCallFilter is called from the ringer, wait at most
     // 3s to resolve the contacts. This timeout is required since
     // ContactsProvider might take a long time to start up.
@@ -422,6 +438,16 @@
     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
     private static final long NOTIFICATION_TRAMPOLINE_BLOCK = 167676448L;
 
+    /**
+     * Rate limit showing toasts, on a per package basis.
+     *
+     * It limits the effects of {@link android.widget.Toast#show()} calls to prevent overburdening
+     * the user with too many toasts in a limited time. Any attempt to show more toasts than allowed
+     * in a certain time frame will result in the toast being discarded.
+     */
+    @ChangeId
+    private static final long RATE_LIMIT_TOASTS = 154198299L;
+
     private IActivityManager mAm;
     private ActivityTaskManagerInternal mAtm;
     private ActivityManager mActivityManager;
@@ -500,6 +526,9 @@
     @GuardedBy("mToastQueue")
     private boolean mIsCurrentToastShown = false;
 
+    // Used for rate limiting toasts by package.
+    private MultiRateLimiter mToastRateLimiter;
+
     // The last key in this list owns the hardware.
     ArrayList<String> mLights = new ArrayList<>();
 
@@ -1662,6 +1691,11 @@
                 = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_HISTORY_ENABLED);
         private final Uri NOTIFICATION_SHOW_MEDIA_ON_QUICK_SETTINGS_URI
                 = Settings.Global.getUriFor(Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS);
+        private final Uri LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
+                = Settings.Secure.getUriFor(
+                        Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
+        private final Uri LOCK_SCREEN_SHOW_NOTIFICATIONS
+                = Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
 
         SettingsObserver(Handler handler) {
             super(handler);
@@ -1681,6 +1715,11 @@
                     false, this, UserHandle.USER_ALL);
             resolver.registerContentObserver(NOTIFICATION_SHOW_MEDIA_ON_QUICK_SETTINGS_URI,
                     false, this, UserHandle.USER_ALL);
+
+            resolver.registerContentObserver(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                    false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    false, this, UserHandle.USER_ALL);
             update(null);
         }
 
@@ -1722,6 +1761,12 @@
             if (uri == null || NOTIFICATION_SHOW_MEDIA_ON_QUICK_SETTINGS_URI.equals(uri)) {
                 mPreferencesHelper.updateMediaNotificationFilteringEnabled();
             }
+            if (uri == null || LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS.equals(uri)) {
+                mPreferencesHelper.updateLockScreenPrivateNotifications();
+            }
+            if (uri == null || LOCK_SCREEN_SHOW_NOTIFICATIONS.equals(uri)) {
+                mPreferencesHelper.updateLockScreenShowNotifications();
+            }
         }
     }
 
@@ -1915,7 +1960,8 @@
             DevicePolicyManagerInternal dpm, IUriGrantsManager ugm,
             UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, UserManager userManager,
             NotificationHistoryManager historyManager, StatsManager statsManager,
-            TelephonyManager telephonyManager, ActivityManagerInternal ami) {
+            TelephonyManager telephonyManager, ActivityManagerInternal ami,
+            MultiRateLimiter toastRateLimiter) {
         mHandler = handler;
         Resources resources = getContext().getResources();
         mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
@@ -2107,6 +2153,8 @@
                 com.android.internal.R.array.config_notificationMsgPkgsAllowedAsConvos));
         mStatsManager = statsManager;
 
+        mToastRateLimiter = toastRateLimiter;
+
         // register for various Intents.
         // If this is called within a test, make sure to unregister the intent receivers by
         // calling onDestroy()
@@ -2217,7 +2265,8 @@
                 mStatsManager = (StatsManager) getContext().getSystemService(
                         Context.STATS_MANAGER),
                 getContext().getSystemService(TelephonyManager.class),
-                LocalServices.getService(ActivityManagerInternal.class));
+                LocalServices.getService(ActivityManagerInternal.class),
+                createToastRateLimiter());
 
         publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
                 DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL);
@@ -2855,6 +2904,10 @@
         return mInternalService;
     }
 
+    private MultiRateLimiter createToastRateLimiter() {
+        return new MultiRateLimiter.Builder(getContext()).addRateLimits(TOAST_RATE_LIMITS).build();
+    }
+
     @VisibleForTesting
     final IBinder mService = new INotificationManager.Stub() {
         // Toasts
@@ -3591,8 +3644,9 @@
         public ParceledListSlice<ConversationChannelWrapper> getConversations(
                 boolean onlyImportant) {
             enforceSystemOrSystemUI("getConversations");
+            IntArray userIds = mUserProfiles.getCurrentProfileIds();
             ArrayList<ConversationChannelWrapper> conversations =
-                    mPreferencesHelper.getConversations(onlyImportant);
+                    mPreferencesHelper.getConversations(userIds, onlyImportant);
             for (ConversationChannelWrapper conversation : conversations) {
                 if (mShortcutHelper == null) {
                     conversation.setShortcutInfo(null);
@@ -7115,15 +7169,15 @@
         if (record.getSbn().isGroup() && record.getNotification().suppressAlertingDueToGrouping()) {
             return false;
         }
-        // not if in call or the screen's on
-        if (isInCall() || mScreenOn) {
+        // not if in call
+        if (isInCall()) {
             return false;
         }
         // check current user
         if (!isNotificationForCurrentUser(record)) {
             return false;
         }
-
+        // Light, but only when the screen is off
         return true;
     }
 
@@ -7329,10 +7383,21 @@
 
         ToastRecord record = mToastQueue.get(0);
         while (record != null) {
-            if (record.show()) {
+            int userId = UserHandle.getUserId(record.uid);
+            boolean rateLimitingEnabled =
+                    CompatChanges.isChangeEnabled(RATE_LIMIT_TOASTS, record.uid);
+            boolean isWithinQuota =
+                    mToastRateLimiter.isWithinQuota(userId, record.pkg, TOAST_QUOTA_TAG);
+            if ((!rateLimitingEnabled || isWithinQuota) && record.show()) {
                 scheduleDurationReachedLocked(record);
                 mIsCurrentToastShown = true;
+                if (rateLimitingEnabled) {
+                    mToastRateLimiter.noteEvent(userId, record.pkg, TOAST_QUOTA_TAG);
+                }
                 return;
+            } else if (rateLimitingEnabled && !isWithinQuota) {
+                Slog.w(TAG, "Package " + record.pkg + " is above allowed toast quota, the "
+                        + "following toast was blocked and discarded: " + record);
             }
             int index = mToastQueue.indexOf(record);
             if (index >= 0) {
@@ -9462,6 +9527,13 @@
             return null;
         }
 
+        @Override
+        protected boolean shouldReflectToSettings() {
+            // androidx has a public method that reads the approved set of listeners from
+            // Settings so we have to continue writing this list for this type of service
+            return true;
+        }
+
         @GuardedBy("mNotificationLock")
         public void setOnNotificationPostedTrimLocked(ManagedServiceInfo info, int trim) {
             if (trim == TRIM_LIGHT) {
diff --git a/services/core/java/com/android/server/notification/OWNERS b/services/core/java/com/android/server/notification/OWNERS
index 5a19656..4dcb799 100644
--- a/services/core/java/com/android/server/notification/OWNERS
+++ b/services/core/java/com/android/server/notification/OWNERS
@@ -1,4 +1,4 @@
-dsandler@android.com
+dsandler@google.com
 juliacr@google.com
 beverlyt@google.com
 pixel@google.com
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 1c0349d..cbd973a 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -52,6 +52,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.IntArray;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
@@ -170,6 +171,8 @@
     private final AppOpsManager mAppOps;
 
     private SparseBooleanArray mBadgingEnabled;
+    private SparseBooleanArray mLockScreenShowNotifications;
+    private SparseBooleanArray mLockScreenPrivateNotifications;
     private boolean mBubblesEnabledGlobally = DEFAULT_GLOBAL_ALLOW_BUBBLE;
     private boolean mIsMediaNotificationFilteringEnabled = DEFAULT_MEDIA_NOTIFICATION_FILTERING;
     private boolean mAreChannelsBypassingDnd;
@@ -1379,36 +1382,39 @@
         return null;
     }
 
-    public ArrayList<ConversationChannelWrapper> getConversations(boolean onlyImportant) {
+    public ArrayList<ConversationChannelWrapper> getConversations(IntArray userIds,
+            boolean onlyImportant) {
         synchronized (mPackagePreferences) {
             ArrayList<ConversationChannelWrapper> conversations = new ArrayList<>();
-
             for (PackagePreferences p : mPackagePreferences.values()) {
-                int N = p.channels.size();
-                for (int i = 0; i < N; i++) {
-                    final NotificationChannel nc = p.channels.valueAt(i);
-                    if (!TextUtils.isEmpty(nc.getConversationId()) && !nc.isDeleted()
-                            && !nc.isDemoted()
-                            && (nc.isImportantConversation() || !onlyImportant)) {
-                        ConversationChannelWrapper conversation = new ConversationChannelWrapper();
-                        conversation.setPkg(p.pkg);
-                        conversation.setUid(p.uid);
-                        conversation.setNotificationChannel(nc);
-                        conversation.setParentChannelLabel(
-                                p.channels.get(nc.getParentChannelId()).getName());
-                        boolean blockedByGroup = false;
-                        if (nc.getGroup() != null) {
-                            NotificationChannelGroup group = p.groups.get(nc.getGroup());
-                            if (group != null) {
-                                if (group.isBlocked()) {
-                                    blockedByGroup = true;
-                                } else {
-                                    conversation.setGroupLabel(group.getName());
+                if (userIds.binarySearch(UserHandle.getUserId(p.uid)) >= 0) {
+                    int N = p.channels.size();
+                    for (int i = 0; i < N; i++) {
+                        final NotificationChannel nc = p.channels.valueAt(i);
+                        if (!TextUtils.isEmpty(nc.getConversationId()) && !nc.isDeleted()
+                                && !nc.isDemoted()
+                                && (nc.isImportantConversation() || !onlyImportant)) {
+                            ConversationChannelWrapper conversation =
+                                    new ConversationChannelWrapper();
+                            conversation.setPkg(p.pkg);
+                            conversation.setUid(p.uid);
+                            conversation.setNotificationChannel(nc);
+                            conversation.setParentChannelLabel(
+                                    p.channels.get(nc.getParentChannelId()).getName());
+                            boolean blockedByGroup = false;
+                            if (nc.getGroup() != null) {
+                                NotificationChannelGroup group = p.groups.get(nc.getGroup());
+                                if (group != null) {
+                                    if (group.isBlocked()) {
+                                        blockedByGroup = true;
+                                    } else {
+                                        conversation.setGroupLabel(group.getName());
+                                    }
                                 }
                             }
-                        }
-                        if (!blockedByGroup) {
-                            conversations.add(conversation);
+                            if (!blockedByGroup) {
+                                conversations.add(conversation);
+                            }
                         }
                     }
                 }
@@ -2401,6 +2407,60 @@
         return mBadgingEnabled.get(userId, DEFAULT_SHOW_BADGE);
     }
 
+    public void updateLockScreenPrivateNotifications() {
+        if (mLockScreenPrivateNotifications == null) {
+            mLockScreenPrivateNotifications = new SparseBooleanArray();
+        }
+        boolean changed = false;
+        // update the cached values
+        for (int index = 0; index < mLockScreenPrivateNotifications.size(); index++) {
+            int userId = mLockScreenPrivateNotifications.keyAt(index);
+            final boolean oldValue = mLockScreenPrivateNotifications.get(userId);
+            final boolean newValue = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, userId) != 0;
+            mLockScreenPrivateNotifications.put(userId, newValue);
+            changed |= oldValue != newValue;
+        }
+        if (changed) {
+            updateConfig();
+        }
+    }
+
+    public void updateLockScreenShowNotifications() {
+        if (mLockScreenShowNotifications == null) {
+            mLockScreenShowNotifications = new SparseBooleanArray();
+        }
+        boolean changed = false;
+        // update the cached values
+        for (int index = 0; index < mLockScreenShowNotifications.size(); index++) {
+            int userId = mLockScreenShowNotifications.keyAt(index);
+            final boolean oldValue = mLockScreenShowNotifications.get(userId);
+            final boolean newValue = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1, userId) != 0;
+            mLockScreenShowNotifications.put(userId, newValue);
+            changed |= oldValue != newValue;
+        }
+        if (changed) {
+            updateConfig();
+        }
+    }
+
+    @Override
+    public boolean canShowNotificationsOnLockscreen(int userId) {
+        if (mLockScreenShowNotifications == null) {
+            mLockScreenShowNotifications = new SparseBooleanArray();
+        }
+        return mLockScreenShowNotifications.get(userId, true);
+    }
+
+    @Override
+    public boolean canShowPrivateNotificationsOnLockScreen(int userId) {
+        if (mLockScreenPrivateNotifications == null) {
+            mLockScreenPrivateNotifications = new SparseBooleanArray();
+        }
+        return mLockScreenPrivateNotifications.get(userId, true);
+    }
+
     public void unlockAllNotificationChannels() {
         synchronized (mPackagePreferences) {
             final int numPackagePreferences = mPackagePreferences.size();
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index b2827ba..8991ced 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -34,6 +34,8 @@
     /** Returns true when feature is enabled that shows media notifications in quick settings. */
     boolean isMediaNotificationFilteringEnabled();
     boolean isGroupBlocked(String packageName, int uid, String groupId);
+    boolean canShowNotificationsOnLockscreen(int userId);
+    boolean canShowPrivateNotificationsOnLockScreen(int userId);
 
     Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
             int uid);
diff --git a/services/core/java/com/android/server/notification/ShortcutHelper.java b/services/core/java/com/android/server/notification/ShortcutHelper.java
index 9c3d6d3..b0be206 100644
--- a/services/core/java/com/android/server/notification/ShortcutHelper.java
+++ b/services/core/java/com/android/server/notification/ShortcutHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.server.notification;
 
+import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_GET_PERSONS_DATA;
 import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED;
 import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC;
 import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER;
@@ -192,8 +193,8 @@
             LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery();
             query.setPackage(packageName);
             query.setShortcutIds(Arrays.asList(shortcutId));
-            query.setQueryFlags(
-                    FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED_BY_ANY_LAUNCHER | FLAG_MATCH_CACHED);
+            query.setQueryFlags(FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED_BY_ANY_LAUNCHER
+                    | FLAG_MATCH_CACHED | FLAG_GET_PERSONS_DATA);
             List<ShortcutInfo> shortcuts = mLauncherAppsService.getShortcuts(query, user);
             ShortcutInfo info = shortcuts != null && shortcuts.size() > 0
                     ? shortcuts.get(0)
diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java
index b5ca2ab..3e197fb 100644
--- a/services/core/java/com/android/server/notification/SnoozeHelper.java
+++ b/services/core/java/com/android/server/notification/SnoozeHelper.java
@@ -462,6 +462,8 @@
     }
 
     private PendingIntent createPendingIntent(String pkg, String key, int userId) {
+        // TODO(b/174969959) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         return PendingIntent.getBroadcast(mContext,
                 REQUEST_CODE_REPOST,
                 new Intent(REPOST_ACTION)
@@ -469,7 +471,7 @@
                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
                         .putExtra(EXTRA_KEY, key)
                         .putExtra(EXTRA_USER_ID, userId),
-                PendingIntent.FLAG_UPDATE_CURRENT);
+                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
     }
 
     public void scheduleRepostsForPersistedNotifications(long currentTime) {
@@ -558,8 +560,8 @@
                         if (value < currentTime) {
                             return;
                         }
-                        out.attribute(null, XML_SNOOZED_NOTIFICATION_TIME,
-                                value.toString());
+                        out.attributeLong(null, XML_SNOOZED_NOTIFICATION_TIME,
+                                value);
                     });
             writeXml(out, mPersistedSnoozedNotificationsWithContext,
                     XML_SNOOZED_NOTIFICATION_CONTEXT,
diff --git a/services/core/java/com/android/server/notification/VisibilityExtractor.java b/services/core/java/com/android/server/notification/VisibilityExtractor.java
index db54846..a363601 100644
--- a/services/core/java/com/android/server/notification/VisibilityExtractor.java
+++ b/services/core/java/com/android/server/notification/VisibilityExtractor.java
@@ -15,8 +15,11 @@
 */
 package com.android.server.notification;
 
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
 import android.content.Context;
-import android.service.notification.NotificationListenerService;
+import android.os.UserHandle;
 import android.util.Slog;
 
 /**
@@ -27,9 +30,11 @@
     private static final boolean DBG = false;
 
     private RankingConfig mConfig;
+    private DevicePolicyManager mDpm;
 
     public void initialize(Context ctx, NotificationUsageStats usageStats) {
         if (DBG) Slog.d(TAG, "Initializing  " + getClass().getSimpleName() + ".");
+        mDpm = ctx.getSystemService(DevicePolicyManager.class);
     }
 
     public RankingReconsideration process(NotificationRecord record) {
@@ -43,7 +48,38 @@
             return null;
         }
 
-        record.setPackageVisibilityOverride(record.getChannel().getLockscreenVisibility());
+        int userId = record.getUserId();
+
+        if (userId == UserHandle.USER_ALL) {
+            record.setPackageVisibilityOverride(record.getChannel().getLockscreenVisibility());
+        } else {
+            boolean userCanShowNotifications =
+                    mConfig.canShowNotificationsOnLockscreen(userId);
+            boolean dpmCanShowNotifications = adminAllowsKeyguardFeature(userId,
+                    DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+            boolean channelCanShowNotifications = record.getChannel().getLockscreenVisibility()
+                    != Notification.VISIBILITY_SECRET;
+
+            if (!userCanShowNotifications || !dpmCanShowNotifications
+                    || !channelCanShowNotifications) {
+                record.setPackageVisibilityOverride(Notification.VISIBILITY_SECRET);
+            } else {
+                // notifications are allowed but should they be redacted?
+
+                boolean userCanShowContents =
+                        mConfig.canShowPrivateNotificationsOnLockScreen(userId);
+                boolean dpmCanShowContents = adminAllowsKeyguardFeature(userId,
+                        DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+                boolean channelCanShowContents = record.getChannel().getLockscreenVisibility()
+                        != Notification.VISIBILITY_PRIVATE;
+
+                if (!userCanShowContents || !dpmCanShowContents || !channelCanShowContents) {
+                    record.setPackageVisibilityOverride(Notification.VISIBILITY_PRIVATE);
+                } else {
+                    record.setPackageVisibilityOverride(NotificationManager.VISIBILITY_NO_OVERRIDE);
+                }
+            }
+        }
 
         return null;
     }
@@ -57,4 +93,13 @@
     public void setZenHelper(ZenModeHelper helper) {
 
     }
+
+    private boolean adminAllowsKeyguardFeature(int userHandle, int feature) {
+        if (userHandle == UserHandle.USER_ALL) {
+            return true;
+        }
+        final int dpmFlags = mDpm.getKeyguardDisabledFeatures(null /* admin */, userHandle);
+        return (dpmFlags & feature) == 0;
+    }
+
 }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 94f46ba..5cd22e0 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -81,6 +81,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.XmlUtils;
 import com.android.server.LocalServices;
 
 import libcore.io.IoUtils;
@@ -1165,7 +1166,7 @@
         try {
             parser = resources.getXml(R.xml.default_zen_mode_config);
             while (parser.next() != XmlPullParser.END_DOCUMENT) {
-                final ZenModeConfig config = ZenModeConfig.readXml(parser);
+                final ZenModeConfig config = ZenModeConfig.readXml(XmlUtils.makeTyped(parser));
                 if (config != null) return config;
             }
         } catch (Exception e) {
diff --git a/services/core/java/com/android/server/om/OWNERS b/services/core/java/com/android/server/om/OWNERS
new file mode 100644
index 0000000..afb98d4
--- /dev/null
+++ b/services/core/java/com/android/server/om/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/content/om/OWNERS
diff --git a/services/core/java/com/android/server/om/TEST_MAPPING b/services/core/java/com/android/server/om/TEST_MAPPING
index 6edd76f..e8a2a02 100644
--- a/services/core/java/com/android/server/om/TEST_MAPPING
+++ b/services/core/java/com/android/server/om/TEST_MAPPING
@@ -15,9 +15,6 @@
       "name": "OverlayHostTests"
     },
     {
-      "name": "OverlayRemountedTest"
-    },
-    {
       "name": "CtsAppSecurityHostTestCases",
       "options": [
         {
@@ -25,5 +22,10 @@
         }
       ]
     }
+  ],
+  "presubmit-large": [
+    {
+      "name": "OverlayRemountedTest"
+    }
   ]
 }
diff --git a/services/core/java/com/android/server/people/OWNERS b/services/core/java/com/android/server/people/OWNERS
new file mode 100644
index 0000000..3198a5e
--- /dev/null
+++ b/services/core/java/com/android/server/people/OWNERS
@@ -0,0 +1 @@
+include /services/people/OWNERS
diff --git a/services/core/java/com/android/server/pm/DefaultAppProvider.java b/services/core/java/com/android/server/pm/DefaultAppProvider.java
new file mode 100644
index 0000000..a17967f
--- /dev/null
+++ b/services/core/java/com/android/server/pm/DefaultAppProvider.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.pm;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.role.RoleManager;
+import android.os.Binder;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.infra.AndroidFuture;
+import com.android.internal.util.CollectionUtils;
+import com.android.server.FgThread;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * Interacts with {@link RoleManager} to provide and manage default apps.
+ */
+public class DefaultAppProvider {
+    @NonNull
+    private final Supplier<RoleManager> mRoleManagerSupplier;
+
+    /**
+     * Create a new instance of this class
+     *
+     * @param roleManagerSupplier the supplier for {@link RoleManager}
+     */
+    public DefaultAppProvider(@NonNull Supplier<RoleManager> roleManagerSupplier) {
+        mRoleManagerSupplier = roleManagerSupplier;
+    }
+
+    /**
+     * Get the package name of the default browser.
+     *
+     * @param userId the user ID
+     * @return the package name of the default browser, or {@code null} if none
+     */
+    @Nullable
+    public String getDefaultBrowser(@UserIdInt int userId) {
+        return getRoleHolder(RoleManager.ROLE_BROWSER, userId);
+    }
+
+    /**
+     * Set the package name of the default browser.
+     *
+     * @param packageName package name of the default browser, or {@code null} to unset
+     * @param async whether the operation should be asynchronous
+     * @param userId the user ID
+     * @return whether the default browser was successfully set.
+     */
+    public boolean setDefaultBrowser(@Nullable String packageName, boolean async,
+            @UserIdInt int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            return false;
+        }
+        final RoleManager roleManager = mRoleManagerSupplier.get();
+        if (roleManager == null) {
+            return false;
+        }
+        final UserHandle user = UserHandle.of(userId);
+        final Executor executor = FgThread.getExecutor();
+        final AndroidFuture<Void> future = new AndroidFuture<>();
+        final Consumer<Boolean> callback = successful -> {
+            if (successful) {
+                future.complete(null);
+            } else {
+                future.completeExceptionally(new RuntimeException());
+            }
+        };
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            if (packageName != null) {
+                roleManager.addRoleHolderAsUser(RoleManager.ROLE_BROWSER, packageName, 0, user,
+                        executor, callback);
+            } else {
+                roleManager.clearRoleHoldersAsUser(RoleManager.ROLE_BROWSER, 0, user, executor,
+                        callback);
+            }
+            if (!async) {
+                try {
+                    future.get(5, TimeUnit.SECONDS);
+                } catch (InterruptedException | ExecutionException | TimeoutException e) {
+                    Slog.e(PackageManagerService.TAG, "Exception while setting default browser: "
+                            + packageName, e);
+                    return false;
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        return true;
+    }
+
+    /**
+     * Get the package name of the default dialer.
+     *
+     * @param userId the user ID
+     * @return the package name of the default dialer, or {@code null} if none
+     */
+    @Nullable
+    public String getDefaultDialer(@NonNull int userId) {
+        return getRoleHolder(RoleManager.ROLE_DIALER, userId);
+    }
+
+    /**
+     * Get the package name of the default home.
+     *
+     * @param userId the user ID
+     * @return the package name of the default home, or {@code null} if none
+     */
+    @Nullable
+    public String getDefaultHome(@NonNull int userId) {
+        return getRoleHolder(RoleManager.ROLE_HOME, userId);
+    }
+
+    /**
+     * Set the package name of the default home.
+     *
+     * @param packageName package name of the default home
+     * @param userId the user ID
+     * @param executor the {@link Executor} to execute callback on
+     * @param callback the callback made after the default home as been updated
+     * @return whether the default home was set
+     */
+    public boolean setDefaultHome(@NonNull String packageName, @UserIdInt int userId,
+            @NonNull Executor executor, @NonNull Consumer<Boolean> callback) {
+        final RoleManager roleManager = mRoleManagerSupplier.get();
+        if (roleManager == null) {
+            return false;
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, packageName, 0,
+                    UserHandle.of(userId), executor, callback);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        return true;
+    }
+
+    @Nullable
+    private String getRoleHolder(@NonNull String roleName, @NonNull int userId) {
+        final RoleManager roleManager = mRoleManagerSupplier.get();
+        if (roleManager == null) {
+            return null;
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return CollectionUtils.firstOrNull(roleManager.getRoleHoldersAsUser(roleName,
+                    UserHandle.of(userId)));
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index cca2b83..7a2b7a6 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -1,12 +1,12 @@
-hackbod@android.com
 hackbod@google.com
-jsharkey@android.com
+hackbod@google.com
+jsharkey@google.com
 jsharkey@google.com
 narayan@google.com
 patb@google.com
-svetoslavganov@android.com
 svetoslavganov@google.com
-toddke@android.com
+svetoslavganov@google.com
+toddke@google.com
 toddke@google.com
 
 # apex support
@@ -30,9 +30,10 @@
 per-file CrossProfileAppsService.java = omakoto@google.com, yamasani@google.com
 per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com
 per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com
+per-file RestrictionsSet.java = bookatz@google.com, omakoto@google.com, yamasani@google.com, rubinxu@google.com, sandness@google.com
+per-file UserManagerInternal.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
 per-file UserManagerService.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
 per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com
-per-file RestrictionsSet.java = bookatz@google.com, omakoto@google.com, yamasani@google.com, rubinxu@google.com, sandness@google.com
 per-file UserSystemPackageInstaller.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
 per-file UserTypeDetails.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
 per-file UserTypeFactory.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelper.java b/services/core/java/com/android/server/pm/PackageAbiHelper.java
index 30b1c2c..24a3e52 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelper.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelper.java
@@ -55,7 +55,7 @@
      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
      */
     Pair<Abis, NativeLibraryPaths> derivePackageAbi(AndroidPackage pkg, boolean isUpdatedSystemApp,
-            String cpuAbiOverride) throws PackageManagerException;
+            String cpuAbiOverride, File appLib32InstallDir) throws PackageManagerException;
 
     /**
      * Calculates adjusted ABIs for a set of packages belonging to a shared user so that they all
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
index da4ea16..71b99bd 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -296,7 +296,7 @@
 
     @Override
     public Pair<Abis, NativeLibraryPaths> derivePackageAbi(AndroidPackage pkg,
-            boolean isUpdatedSystemApp, String cpuAbiOverride)
+            boolean isUpdatedSystemApp, String cpuAbiOverride, File appLib32InstallDir)
             throws PackageManagerException {
         // Give ourselves some initial paths; we'll come back for another
         // pass once we've determined ABI below.
@@ -304,7 +304,7 @@
         String pkgRawSecondaryCpuAbi = AndroidPackageUtils.getRawSecondaryCpuAbi(pkg);
         final NativeLibraryPaths initialLibraryPaths = deriveNativeLibraryPaths(
                 new Abis(pkgRawPrimaryCpuAbi, pkgRawSecondaryCpuAbi),
-                PackageManagerService.sAppLib32InstallDir, pkg.getPath(),
+                appLib32InstallDir, pkg.getPath(),
                 pkg.getBaseApkPath(), pkg.isSystem(),
                 isUpdatedSystemApp);
 
@@ -452,7 +452,7 @@
 
         final Abis abis = new Abis(primaryCpuAbi, secondaryCpuAbi);
         return new Pair<>(abis,
-                deriveNativeLibraryPaths(abis, PackageManagerService.sAppLib32InstallDir,
+                deriveNativeLibraryPaths(abis, appLib32InstallDir,
                         pkg.getPath(), pkg.getBaseApkPath(), pkg.isSystem(),
                         isUpdatedSystemApp));
     }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 4cee2e5..34bee95 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -686,11 +686,6 @@
             }
         }
 
-        if (params.whitelistedRestrictedPermissions != null) {
-            mPermissionManager.retainHardAndSoftRestrictedPermissions(
-                    params.whitelistedRestrictedPermissions);
-        }
-
         final int sessionId;
         final PackageInstallerSession session;
         synchronized (mSessions) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index c10d394..4ab1282 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -31,22 +31,16 @@
 import static android.content.pm.PackageManager.INSTALL_STAGED;
 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
 import static android.content.pm.PackageParser.APEX_FILE_EXTENSION;
-import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
 import static android.system.OsConstants.O_CREAT;
 import static android.system.OsConstants.O_RDONLY;
 import static android.system.OsConstants.O_WRONLY;
 
 import static com.android.internal.util.XmlUtils.readBitmapAttribute;
-import static com.android.internal.util.XmlUtils.readBooleanAttribute;
 import static com.android.internal.util.XmlUtils.readByteArrayAttribute;
-import static com.android.internal.util.XmlUtils.readIntAttribute;
-import static com.android.internal.util.XmlUtils.readLongAttribute;
 import static com.android.internal.util.XmlUtils.readStringAttribute;
 import static com.android.internal.util.XmlUtils.readUriAttribute;
 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
 import static com.android.internal.util.XmlUtils.writeByteArrayAttribute;
-import static com.android.internal.util.XmlUtils.writeIntAttribute;
-import static com.android.internal.util.XmlUtils.writeLongAttribute;
 import static com.android.internal.util.XmlUtils.writeStringAttribute;
 import static com.android.internal.util.XmlUtils.writeUriAttribute;
 import static com.android.server.pm.PackageInstallerService.prepareStageDir;
@@ -110,6 +104,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.RevocableFileDescriptor;
+import android.os.SELinux;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.incremental.IStorageHealthListener;
@@ -156,7 +151,6 @@
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -483,6 +477,9 @@
     @GuardedBy("mLock")
     private IncrementalFileStorages mIncrementalFileStorages;
 
+    @GuardedBy("mLock")
+    private PackageLite mPackageLite;
+
     private static final FileFilter sAddedApkFilter = new FileFilter() {
         @Override
         public boolean accept(File file) {
@@ -759,6 +756,7 @@
 
             info.mode = params.mode;
             info.installReason = params.installReason;
+            info.installScenario = params.installScenario;
             info.sizeBytes = params.sizeBytes;
             info.appPackageName = mPackageName != null ? mPackageName : params.appPackageName;
             if (includeIcon) {
@@ -1092,6 +1090,31 @@
         }
     }
 
+    @Override
+    public void stageViaHardLink(String path) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException("link() can only be run by the system");
+        }
+
+        try {
+            final File target = new File(path);
+            final File source = new File(stageDir, target.getName());
+            try {
+                Os.link(path, source.getAbsolutePath());
+                // Grant READ access for APK to be read successfully
+                Os.chmod(source.getAbsolutePath(), 0644);
+            } catch (ErrnoException e) {
+                e.rethrowAsIOException();
+            }
+            if (!SELinux.restorecon(source)) {
+                throw new IOException("Can't relabel file: " + source);
+            }
+        } catch (IOException e) {
+            throw ExceptionUtils.wrap(e);
+        }
+    }
+
     private ParcelFileDescriptor openTargetInternal(String path, int flags, int mode)
             throws IOException, ErrnoException {
         // TODO: this should delegate to DCS so the system process avoids
@@ -2040,7 +2063,7 @@
 
         // TODO(b/136257624): Some logic in this if block probably belongs in
         //  makeInstallParams().
-        if (!params.isMultiPackage && !isApexSession()) {
+        if (!isMultiPackage() && !isApexSession()) {
             Objects.requireNonNull(mPackageName);
             Objects.requireNonNull(mSigningDetails);
             Objects.requireNonNull(mResolvedBaseFile);
@@ -2094,12 +2117,18 @@
                             "Failed to inherit existing install", e);
                 }
             }
+            // For mode inherit existing, it would link/copy existing files to stage dir in the
+            // above block. Therefore, we need to parse the complete package in stage dir here.
+            // Besides, PackageLite may be null for staged sessions that don't complete pre-reboot
+            // verification.
+            mPackageLite = getOrParsePackageLiteLocked(stageDir, /* flags */ 0);
 
             // TODO: surface more granular state from dexopt
             mInternalProgress = 0.5f;
             computeProgressLocked(true);
 
-            extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
+            extractNativeLibraries(mPackageLite, stageDir, params.abiOverride,
+                    mayInheritNativeLibs());
         }
 
         final IPackageInstallObserver2 localObserver;
@@ -2142,7 +2171,7 @@
             copiedParams.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
         }
         return mPm.new VerificationParams(user, stageDir, localObserver, copiedParams,
-                mInstallSource, mInstallerUid, mSigningDetails, sessionId);
+                mInstallSource, mInstallerUid, mSigningDetails, sessionId, mPackageLite);
     }
 
     private void onVerificationComplete() {
@@ -2215,12 +2244,39 @@
             params.installFlags |= INSTALL_STAGED;
         }
 
+        if (!isMultiPackage() && !isApexSession()) {
+            synchronized (mLock) {
+                // This shouldn't be null, but have this code path just in case.
+                if (mPackageLite == null) {
+                    Slog.wtf(TAG, "Session: " + sessionId + ". Don't have a valid PackageLite.");
+                }
+                mPackageLite = getOrParsePackageLiteLocked(stageDir, /* flags */ 0);
+            }
+        }
+
         synchronized (mLock) {
             return mPm.new InstallParams(stageDir, localObserver, params, mInstallSource, user,
-                    mSigningDetails, mInstallerUid);
+                    mSigningDetails, mInstallerUid, mPackageLite);
         }
     }
 
+    @GuardedBy("mLock")
+    private PackageLite getOrParsePackageLiteLocked(File packageFile, int flags)
+            throws PackageManagerException {
+        if (mPackageLite != null) {
+            return mPackageLite;
+        }
+
+        final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
+        final ParseResult<PackageLite> result =
+                ApkLiteParseUtils.parsePackageLite(input, packageFile, flags);
+        if (result.isError()) {
+            throw new PackageManagerException(PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
+                    result.getErrorMessage(), result.getException());
+        }
+        return result.getResult();
+    }
+
     private static void maybeRenameFile(File from, File to) throws PackageManagerException {
         if (!from.equals(to)) {
             if (!from.renameTo(to)) {
@@ -2366,13 +2422,6 @@
         }
     }
 
-    private static String splitNameToFileName(String splitName) {
-        if (splitName == null) {
-            return "base";
-        }
-        return "split_" + splitName;
-    }
-
     /**
      * Validate install by confirming that all application packages are have
      * consistent package name, version code, and signing certificates.
@@ -2388,6 +2437,8 @@
     @GuardedBy("mLock")
     private void validateApkInstallLocked() throws PackageManagerException {
         ApkLite baseApk = null;
+        PackageLite packageLite = null;
+        mPackageLite = null;
         mPackageName = null;
         mVersionCode = -1;
         mSigningDetails = PackageParser.SigningDetails.UNKNOWN;
@@ -2431,6 +2482,7 @@
 
         // Verify that all staged packages are internally consistent
         final ArraySet<String> stagedSplits = new ArraySet<>();
+        final ArrayMap<String, PackageParser.ApkLite> splitApks = new ArrayMap<>();
         ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
         for (File addedFile : addedFiles) {
             ParseResult<ApkLite> result = ApkLiteParseUtils.parseApkLite(input.reset(),
@@ -2458,8 +2510,7 @@
             assertApkConsistentLocked(String.valueOf(addedFile), apk);
 
             // Take this opportunity to enforce uniform naming
-            final String fileName = splitNameToFileName(apk.splitName);
-            final String targetName = fileName + APK_FILE_EXTENSION;
+            final String targetName = ApkLiteParseUtils.splitNameToFileName(apk);
             if (!FileUtils.isValidExtFilename(targetName)) {
                 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                         "Invalid filename: " + targetName);
@@ -2483,6 +2534,8 @@
             if (apk.splitName == null) {
                 mResolvedBaseFile = targetFile;
                 baseApk = apk;
+            } else {
+                splitApks.put(apk.splitName, apk);
             }
         }
 
@@ -2506,14 +2559,8 @@
                 mVersionCode = pkgInfo.getLongVersionCode();
             }
             if (mSigningDetails == PackageParser.SigningDetails.UNKNOWN) {
-                try {
-                    mSigningDetails = ApkSignatureVerifier.unsafeGetCertsWithoutVerification(
-                            pkgInfo.applicationInfo.sourceDir,
-                            PackageParser.SigningDetails.SignatureSchemeVersion.JAR);
-                } catch (PackageParserException e) {
-                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
-                            "Couldn't obtain signatures from base APK");
-                }
+                mSigningDetails = unsafeGetCertsWithoutVerification(
+                        pkgInfo.applicationInfo.sourceDir);
             }
         }
 
@@ -2548,6 +2595,17 @@
                 throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT,
                         "Missing split for " + mPackageName);
             }
+            // For mode full install, we compose package lite for future usage instead of
+            // re-parsing it again and again.
+            final ParseResult<PackageLite> pkgLiteResult =
+                    ApkLiteParseUtils.composePackageLiteFromApks(input.reset(), stageDir, baseApk,
+                            splitApks, true);
+            if (pkgLiteResult.isError()) {
+                throw new PackageManagerException(pkgLiteResult.getErrorCode(),
+                        pkgLiteResult.getErrorMessage(), pkgLiteResult.getException());
+            }
+            mPackageLite = pkgLiteResult.getResult();
+            packageLite = mPackageLite;
         } else {
             final ApplicationInfo appInfo = pkgInfo.applicationInfo;
             ParseResult<PackageLite> pkgLiteResult = ApkLiteParseUtils.parsePackageLite(
@@ -2557,22 +2615,20 @@
                         pkgLiteResult.getErrorMessage(), pkgLiteResult.getException());
             }
             final PackageLite existing = pkgLiteResult.getResult();
-            ParseResult<ApkLite> apkLiteResult = ApkLiteParseUtils.parseApkLite(input.reset(),
-                    new File(appInfo.getBaseCodePath()),
-                    PackageParser.PARSE_COLLECT_CERTIFICATES);
-            if (apkLiteResult.isError()) {
-                throw new PackageManagerException(PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
-                        apkLiteResult.getErrorMessage(), apkLiteResult.getException());
+            packageLite = existing;
+            assertPackageConsistentLocked("Existing", existing.packageName,
+                    existing.getLongVersionCode());
+            final PackageParser.SigningDetails signingDetails =
+                    unsafeGetCertsWithoutVerification(existing.baseCodePath);
+            if (!mSigningDetails.signaturesMatchExactly(signingDetails)) {
+                throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+                        "Existing signatures are inconsistent");
             }
-            final ApkLite existingBase = apkLiteResult.getResult();
-
-            assertApkConsistentLocked("Existing base", existingBase);
 
             // Inherit base if not overridden.
             if (mResolvedBaseFile == null) {
                 mResolvedBaseFile = new File(appInfo.getBaseCodePath());
                 inheritFileLocked(mResolvedBaseFile);
-                baseApk = existingBase;
             }
 
             // Inherit splits if not overridden.
@@ -2659,7 +2715,7 @@
                 }
             }
             // For the case of split required, failed if no splits existed
-            if (baseApk.isSplitRequired) {
+            if (packageLite.isSplitRequired) {
                 final int existingSplits = ArrayUtils.size(existing.splitNames);
                 final boolean allSplitsRemoved = (existingSplits == removeSplitList.size());
                 final boolean onlyBaseFileStaged = (stagedSplits.size() == 1
@@ -2670,7 +2726,7 @@
                 }
             }
         }
-        if (baseApk.useEmbeddedDex) {
+        if (packageLite.useEmbeddedDex) {
             for (File file : mResolvedStagedFiles) {
                 if (file.getName().endsWith(".apk")
                         && !DexManager.auditUncompressedDexInApk(file.getPath())) {
@@ -2683,7 +2739,7 @@
 
         final boolean isInstallerShell = (mInstallerUid == Process.SHELL_UID);
         if (isInstallerShell && isIncrementalInstallation() && mIncrementalFileStorages != null) {
-            if (!baseApk.debuggable && !baseApk.profilableByShell) {
+            if (!packageLite.debuggable && !packageLite.profilableByShell) {
                 mIncrementalFileStorages.disableReadLogs();
             }
         }
@@ -2838,26 +2894,43 @@
     @GuardedBy("mLock")
     private void assertApkConsistentLocked(String tag, ApkLite apk)
             throws PackageManagerException {
-        if (!mPackageName.equals(apk.packageName)) {
-            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag + " package "
-                    + apk.packageName + " inconsistent with " + mPackageName);
-        }
-        if (params.appPackageName != null && !params.appPackageName.equals(apk.packageName)) {
-            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag
-                    + " specified package " + params.appPackageName
-                    + " inconsistent with " + apk.packageName);
-        }
-        if (mVersionCode != apk.getLongVersionCode()) {
-            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag
-                    + " version code " + apk.versionCode + " inconsistent with "
-                    + mVersionCode);
-        }
+        assertPackageConsistentLocked(tag, apk.packageName, apk.getLongVersionCode());
         if (!mSigningDetails.signaturesMatchExactly(apk.signingDetails)) {
             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                     tag + " signatures are inconsistent");
         }
     }
 
+    @GuardedBy("mLock")
+    private void assertPackageConsistentLocked(String tag, String packageName,
+            long versionCode) throws PackageManagerException {
+        if (!mPackageName.equals(packageName)) {
+            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag + " package "
+                    + packageName + " inconsistent with " + mPackageName);
+        }
+        if (params.appPackageName != null && !params.appPackageName.equals(packageName)) {
+            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag
+                    + " specified package " + params.appPackageName
+                    + " inconsistent with " + packageName);
+        }
+        if (mVersionCode != versionCode) {
+            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag
+                    + " version code " + versionCode + " inconsistent with "
+                    + mVersionCode);
+        }
+    }
+
+    private PackageParser.SigningDetails unsafeGetCertsWithoutVerification(String path)
+            throws PackageManagerException {
+        try {
+            return ApkSignatureVerifier.unsafeGetCertsWithoutVerification(path,
+                    PackageParser.SigningDetails.SignatureSchemeVersion.JAR);
+        } catch (PackageParserException e) {
+            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+                    "Couldn't obtain signatures from APK : " + path);
+        }
+    }
+
     /**
      * Determine if creating hard links between source and destination is
      * possible. That is, do they all live on the same underlying device.
@@ -2989,8 +3062,10 @@
         Slog.d(TAG, "Copied " + fromFiles.size() + " files into " + toDir);
     }
 
-    private void extractNativeLibraries(File packageDir, String abiOverride, boolean inherit)
+    private void extractNativeLibraries(PackageLite packageLite, File packageDir,
+            String abiOverride, boolean inherit)
             throws PackageManagerException {
+        Objects.requireNonNull(packageLite);
         final File libDir = new File(packageDir, NativeLibraryHelper.LIB_DIR_NAME);
         if (!inherit) {
             // Start from a clean slate
@@ -2999,7 +3074,7 @@
 
         NativeLibraryHelper.Handle handle = null;
         try {
-            handle = NativeLibraryHelper.Handle.create(packageDir);
+            handle = NativeLibraryHelper.Handle.create(packageLite);
             final int res = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libDir,
                     abiOverride, isIncrementalInstallation());
             if (res != INSTALL_SUCCEEDED) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8fc9cb7..72dad61 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -152,6 +152,7 @@
 import android.app.admin.IDevicePolicyManager;
 import android.app.admin.SecurityLog;
 import android.app.backup.IBackupManager;
+import android.app.role.RoleManager;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledAfter;
 import android.content.BroadcastReceiver;
@@ -379,6 +380,8 @@
 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
 import com.android.server.pm.parsing.pkg.PackageImpl;
 import com.android.server.pm.parsing.pkg.ParsedPackage;
+import com.android.server.pm.permission.LegacyPermissionManagerInternal;
+import com.android.server.pm.permission.LegacyPermissionManagerService;
 import com.android.server.pm.permission.Permission;
 import com.android.server.pm.permission.PermissionManagerService;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
@@ -448,7 +451,6 @@
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
-import java.util.function.Supplier;
 
 /**
  * Keep track of all those APKs everywhere.
@@ -696,10 +698,15 @@
     public static final int REASON_FIRST_BOOT = 0;
     public static final int REASON_BOOT = 1;
     public static final int REASON_INSTALL = 2;
-    public static final int REASON_BACKGROUND_DEXOPT = 3;
-    public static final int REASON_AB_OTA = 4;
-    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
-    public static final int REASON_SHARED = 6;
+    public static final int REASON_INSTALL_FAST = 3;
+    public static final int REASON_INSTALL_BULK = 4;
+    public static final int REASON_INSTALL_BULK_SECONDARY = 5;
+    public static final int REASON_INSTALL_BULK_DOWNGRADED = 6;
+    public static final int REASON_INSTALL_BULK_SECONDARY_DOWNGRADED = 7;
+    public static final int REASON_BACKGROUND_DEXOPT = 8;
+    public static final int REASON_AB_OTA = 9;
+    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 10;
+    public static final int REASON_SHARED = 11;
 
     public static final int REASON_LAST = REASON_SHARED;
 
@@ -732,8 +739,6 @@
     private static final int INCREMENTAL_STORAGE_UNHEALTHY_TIMEOUT_MS = 7000;
     private static final int INCREMENTAL_STORAGE_UNHEALTHY_MONITORING_MS = 60000;
 
-    final ServiceThread mHandlerThread;
-
     final Handler mHandler;
 
     private final ProcessLoggingHandler mProcessLoggingHandler;
@@ -761,12 +766,14 @@
     final Installer mInstaller;
 
     /** Directory where installed applications are stored */
-    private static final File sAppInstallDir =
-            new File(Environment.getDataDirectory(), "app");
+    private final File mAppInstallDir;
     /** Directory where installed application's 32-bit native libraries are copied. */
     @VisibleForTesting
-    static final File sAppLib32InstallDir =
-            new File(Environment.getDataDirectory(), "app-lib");
+    final File mAppLib32InstallDir;
+
+    private static File getAppLib32InstallDir() {
+        return new File(Environment.getDataDirectory(), "app-lib");
+    }
 
     // ----------------------------------------------------------------
 
@@ -832,6 +839,11 @@
 
     boolean mFirstBoot;
 
+    private final boolean mIsEngBuild;
+    private final boolean mIsUserDebugBuild;
+    private final String mIncrementalVersion;
+
+
     PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
 
     @GuardedBy("mAvailableFeatures")
@@ -866,6 +878,8 @@
 
     private final Injector mInjector;
 
+    private final SystemWrapper mSystemWrapper;
+
     /**
      * The list of all system partitions that may contain packages in ascending order of
      * specificity (the more generic, the earlier in the list a partition appears).
@@ -896,6 +910,10 @@
             T produce(Injector injector, PackageManagerService packageManager);
         }
 
+        interface ProducerWithArgument<T, R> {
+            T produce(Injector injector, PackageManagerService packageManager, R argument);
+        }
+
         interface ServiceProducer {
             <T> T produce(Class<T> c);
         }
@@ -924,6 +942,8 @@
         private final Object mInstallLock;
         private final Handler mBackgroundHandler;
         private final Executor mBackgroundExecutor;
+        private final List<ScanPartition> mSystemPartitions;
+
 
         // ----- producers -----
         private final Singleton<ComponentResolver> mComponentResolverProducer;
@@ -940,13 +960,25 @@
         private final Singleton<ViewCompiler> mViewCompilerProducer;
         private final Singleton<IPermissionManager> mPermissionManagerProducer;
         private final Singleton<IncrementalManager> mIncrementalManagerProducer;
+        private final Singleton<DefaultAppProvider> mDefaultAppProviderProducer;
+        private final Singleton<DisplayMetrics> mDisplayMetricsProducer;
+        private final Producer<PackageParser2> mScanningCachingPackageParserProducer;
+        private final Producer<PackageParser2> mScanningPackageParserProducer;
+        private final Producer<PackageParser2> mPreparingPackageParserProducer;
+        private final Singleton<PackageInstallerService> mPackageInstallerServiceProducer;
+        private final ProducerWithArgument<InstantAppResolverConnection, ComponentName>
+                mInstantAppResolverConnectionProducer;
+        private final Singleton<LegacyPermissionManagerInternal>
+                mLegacyPermissionManagerInternalProducer;
         private final SystemWrapper mSystemWrapper;
         private final ServiceProducer mGetLocalServiceProducer;
         private final ServiceProducer mGetSystemServiceProducer;
+        private final Singleton<ModuleInfoProvider> mModuleInfoProviderProducer;
 
         Injector(Context context, Object lock, Installer installer,
                 Object installLock, PackageAbiHelper abiHelper,
                 Handler backgroundHandler,
+                List<ScanPartition> systemPartitions,
                 Producer<ComponentResolver> componentResolverProducer,
                 Producer<PermissionManagerServiceInternal> permissionManagerServiceProducer,
                 Producer<UserManagerService> userManagerProducer,
@@ -961,6 +993,16 @@
                 Producer<IPermissionManager> permissionManagerProducer,
                 Producer<ViewCompiler> viewCompilerProducer,
                 Producer<IncrementalManager> incrementalManagerProducer,
+                Producer<DefaultAppProvider> defaultAppProviderProducer,
+                Producer<DisplayMetrics> displayMetricsProducer,
+                Producer<PackageParser2> scanningCachingPackageParserProducer,
+                Producer<PackageParser2> scanningPackageParserProducer,
+                Producer<PackageParser2> preparingPackageParserProducer,
+                Producer<PackageInstallerService> packageInstallerServiceProducer,
+                ProducerWithArgument<InstantAppResolverConnection, ComponentName> 
+                        instantAppResolverConnectionProducer,
+                Producer<ModuleInfoProvider> moduleInfoProviderProducer,
+                Producer<LegacyPermissionManagerInternal> legacyPermissionManagerInternalProducer,
                 SystemWrapper systemWrapper,
                 ServiceProducer getLocalServiceProducer,
                 ServiceProducer getSystemServiceProducer) {
@@ -971,6 +1013,7 @@
             mInstallLock = installLock;
             mBackgroundHandler = backgroundHandler;
             mBackgroundExecutor = new HandlerExecutor(backgroundHandler);
+            mSystemPartitions = systemPartitions;
             mComponentResolverProducer = new Singleton<>(componentResolverProducer);
             mPermissionManagerServiceProducer = new Singleton<>(permissionManagerServiceProducer);
             mUserManagerProducer = new Singleton<>(userManagerProducer);
@@ -985,6 +1028,16 @@
             mPermissionManagerProducer = new Singleton<>(permissionManagerProducer);
             mViewCompilerProducer = new Singleton<>(viewCompilerProducer);
             mIncrementalManagerProducer = new Singleton<>(incrementalManagerProducer);
+            mDefaultAppProviderProducer = new Singleton<>(defaultAppProviderProducer);
+            mDisplayMetricsProducer = new Singleton<>(displayMetricsProducer);
+            mScanningCachingPackageParserProducer = scanningCachingPackageParserProducer;
+            mScanningPackageParserProducer = scanningPackageParserProducer;
+            mPreparingPackageParserProducer = preparingPackageParserProducer;
+            mPackageInstallerServiceProducer = new Singleton<>(packageInstallerServiceProducer);
+            mInstantAppResolverConnectionProducer = instantAppResolverConnectionProducer;
+            mModuleInfoProviderProducer = new Singleton<>(moduleInfoProviderProducer);
+            mLegacyPermissionManagerInternalProducer = new Singleton<>(
+                    legacyPermissionManagerInternalProducer);
             mSystemWrapper = systemWrapper;
             mGetLocalServiceProducer = getLocalServiceProducer;
             mGetSystemServiceProducer = getSystemServiceProducer;
@@ -1010,6 +1063,10 @@
             return mInstallLock;
         }
 
+        public List<ScanPartition> getSystemPartitions() {
+            return mSystemPartitions;
+        }
+
         public UserManagerService getUserManagerService() {
             return mUserManagerProducer.get(this, mPackageManager);
         }
@@ -1082,6 +1139,10 @@
             return mBackgroundExecutor;
         }
 
+        public DisplayMetrics getDisplayMetrics() {
+            return mDisplayMetricsProducer.get(this, mPackageManager);
+        }
+
         public <T> T getLocalService(Class<T> c) {
             return mGetLocalServiceProducer.produce(c);
         }
@@ -1097,53 +1158,67 @@
         public IncrementalManager getIncrementalManager() {
             return mIncrementalManagerProducer.get(this, mPackageManager);
         }
+
+        public DefaultAppProvider getDefaultAppProvider() {
+            return mDefaultAppProviderProducer.get(this, mPackageManager);
+        }
+
+        public PackageParser2 getScanningCachingPackageParser() {
+            return mScanningCachingPackageParserProducer.produce(this, mPackageManager);
+        }
+        public PackageParser2 getScanningPackageParser() {
+            return mScanningPackageParserProducer.produce(this, mPackageManager);
+        }
+        public PackageParser2 getPreparingPackageParser() {
+            return mPreparingPackageParserProducer.produce(this, mPackageManager);
+        }
+
+        public PackageInstallerService getPackageInstallerService() {
+            return mPackageInstallerServiceProducer.get(this, mPackageManager);
+        }
+
+        public InstantAppResolverConnection getInstantAppResolverConnection(
+                ComponentName instantAppResolverComponent) {
+            return mInstantAppResolverConnectionProducer.produce(
+                    this, mPackageManager, instantAppResolverComponent);
+        }
+
+        public ModuleInfoProvider getModuleInfoProvider() {
+            return mModuleInfoProviderProducer.get(this, mPackageManager);
+        }
+
+        public LegacyPermissionManagerInternal getLegacyPermissionManagerInternal() {
+            return mLegacyPermissionManagerInternalProducer.get(this, mPackageManager);
+        }
     }
 
     /** Provides an abstraction to static access to system state. */
     public interface SystemWrapper {
-        /** @see SystemProperties#get(String) */
-        String getProperty(String key);
-        /** @see SystemProperties#getInt(String, int) */
-        int getPropertyInt(String key, int defValue);
-        /** @see SystemProperties#getBoolean(String, boolean) */
-        boolean getPropertyBoolean(String key, boolean defValue);
-        /** @see SystemProperties#digestOf(String...) */
-        String digestOfProperties(@NonNull String... keys);
-        /** @see SystemProperties#set(String, String) */
-        void setProperty(String key, String value);
-        /** @see Build.VERSION#SDK_INT */
-        int getSdkInt();
+        void disablePackageCaches();
+        void enablePackageCaches();
     }
 
     private static class DefaultSystemWrapper implements SystemWrapper {
+
         @Override
-        public String getProperty(String key) {
-            return SystemProperties.get(key);
+        public void disablePackageCaches() {
+            // disable all package caches that shouldn't apply within system server
+            PackageManager.disableApplicationInfoCache();
+            PackageManager.disablePackageInfoCache();
+            ApplicationPackageManager.invalidateGetPackagesForUidCache();
+            ApplicationPackageManager.disableGetPackagesForUidCache();
+            ApplicationPackageManager.invalidateHasSystemFeatureCache();
+
+            // Avoid invalidation-thrashing by preventing cache invalidations from causing property
+            // writes if the cache isn't enabled yet.  We re-enable writes later when we're
+            // done initializing.
+            PackageManager.corkPackageInfoCache();
         }
 
         @Override
-        public int getPropertyInt(String key, int defValue) {
-            return SystemProperties.getInt(key, defValue);
-        }
-
-        @Override
-        public boolean getPropertyBoolean(String key, boolean defValue) {
-            return SystemProperties.getBoolean(key, defValue);
-        }
-
-        @Override
-        public String digestOfProperties(String... keys) {
-            return SystemProperties.digestOf(keys);
-        }
-
-        @Override
-        public void setProperty(String key, String value) {
-            SystemProperties.set(key, value);
-        }
-
-        @Override
-        public int getSdkInt() {
-            return Build.VERSION.SDK_INT;
+        public void enablePackageCaches() {
+            // Uncork cache invalidations and allow clients to cache package information.
+            PackageManager.uncorkPackageInfoCache();
         }
     }
 
@@ -1154,13 +1229,13 @@
         public ArtManagerService artManagerService;
         public @Nullable String configuratorPackage;
         public int defParseFlags;
+        public DefaultAppProvider defaultAppProvider;
         public DexManager dexManager;
         public List<ScanPartition> dirsToScanAsSystem;
         public @Nullable String documenterPackage;
         public boolean factoryTest;
         public ArrayMap<String, FeatureInfo> availableFeatures;
         public Handler handler;
-        public ServiceThread handlerThread;
         public @Nullable String incidentReportApproverPackage;
         public IncrementalManager incrementalManager;
         public PackageInstallerService installerService;
@@ -1173,6 +1248,7 @@
         public boolean isPreNupgrade;
         public boolean isPreQupgrade;
         public boolean isUpgrade;
+        public LegacyPermissionManagerInternal legacyPermissionManagerInternal;
         public DisplayMetrics Metrics;
         public ModuleInfoProvider moduleInfoProvider;
         public MoveCallbacks moveCallbacks;
@@ -1206,6 +1282,13 @@
         public ArrayMap<String, AndroidPackage> packages;
         public boolean enableFreeCacheV2;
         public int sdkVersion;
+        public SystemWrapper systemWrapper;
+        public File appInstallDir;
+        public File appLib32InstallDir;
+        public boolean isEngBuild;
+        public boolean isUserDebugBuild;
+        public int sdkInt = Build.VERSION.SDK_INT;
+        public String incrementalVersion = Build.VERSION.INCREMENTAL;
     }
 
     private final AppsFilter mAppsFilter;
@@ -1307,6 +1390,10 @@
 
     private final IncrementalManager mIncrementalManager;
 
+    private final DefaultAppProvider mDefaultAppProvider;
+
+    private final LegacyPermissionManagerInternal mLegacyPermissionManager;
+
     private final PackageProperty mPackageProperty = new PackageProperty();
 
     private static class IFVerificationParams {
@@ -1803,7 +1890,7 @@
                             for (int index = 0; i < size && index < numComponents; index++) {
                                 packages[i] = componentsToBroadcast.keyAt(index);
                                 components[i] = componentsToBroadcast.valueAt(index);
-                                final PackageSetting ps = mSettings.mPackages.get(packages[i]);
+                                final PackageSetting ps = mSettings.getPackageLPr(packages[i]);
                                 uids[i] = (ps != null)
                                         ? UserHandle.getUid(packageUserId, ps.appId)
                                         : -1;
@@ -2310,7 +2397,7 @@
                 synchronized (mLock) {
                     newBroadcastAllowList = mAppsFilter.getVisibilityAllowList(
                             getPackageSettingInternal(res.name, Process.SYSTEM_UID),
-                            updateUserIds, mSettings.mPackages);
+                            updateUserIds, mSettings.getPackagesLocked());
                 }
                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                         extras, 0 /*flags*/,
@@ -2747,6 +2834,7 @@
         Injector injector = new Injector(
                 context, lock, installer, installLock, new PackageAbiHelperImpl(),
                 backgroundHandler,
+                SYSTEM_PARTITIONS,
                 (i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock),
                 (i, pm) -> PermissionManagerService.create(context),
                 (i, pm) -> new UserManagerService(context, pm,
@@ -2768,12 +2856,38 @@
                 (i, pm) -> (IPermissionManager) ServiceManager.getService("permissionmgr"),
                 (i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()),
                 (i, pm) -> (IncrementalManager)
-                        pm.mContext.getSystemService(Context.INCREMENTAL_SERVICE),
+                        i.getContext().getSystemService(Context.INCREMENTAL_SERVICE),
+                (i, pm) -> new DefaultAppProvider(() -> context.getSystemService(
+                        RoleManager.class)),
+                (i, pm) -> new DisplayMetrics(),
+                (i, pm) -> new PackageParser2(pm.mSeparateProcesses, pm.mOnlyCore,
+                        i.getDisplayMetrics(), pm.mCacheDir,
+                        pm.mPackageParserCallback) /* scanningCachingPackageParserProducer */,
+                (i, pm) -> new PackageParser2(pm.mSeparateProcesses, pm.mOnlyCore,
+                        i.getDisplayMetrics(), null,
+                        pm.mPackageParserCallback) /* scanningPackageParserProducer */,
+                (i, pm) -> new PackageParser2(pm.mSeparateProcesses, false, i.getDisplayMetrics(),
+                        null, pm.mPackageParserCallback) /* preparingPackageParserProducer */,
+                // Prepare a supplier of package parser for the staging manager to parse apex file
+                // during the staging installation.
+                (i, pm) -> new PackageInstallerService(
+                        i.getContext(), pm, i::getScanningPackageParser),
+                (i, pm, cn) -> new InstantAppResolverConnection(
+                        i.getContext(), cn, Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE),
+                (i, pm) -> new ModuleInfoProvider(i.getContext(), pm),
+                (i, pm) -> LegacyPermissionManagerService.create(i.getContext()),
                 new DefaultSystemWrapper(),
                 LocalServices::getService,
                 context::getSystemService);
 
-        PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest);
+
+        if (Build.VERSION.SDK_INT <= 0) {
+            Slog.w(TAG, "**** ro.build.version.sdk not set!");
+        }
+
+        PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
+                Build.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG, Build.VERSION.SDK_INT,
+                Build.VERSION.INCREMENTAL);
         t.traceEnd(); // "create package manager"
 
         final CompatChange.ChangeListener selinuxChangeListener = packageName -> {
@@ -2833,11 +2947,6 @@
         }
     }
 
-    private static void getDefaultDisplayMetrics(
-            DisplayManager displayManager, DisplayMetrics metrics) {
-        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
-    }
-
     /**
      * Requests that files preopted on a secondary system partition be copied to the data partition
      * if possible.  Note that the actual copying of the files is accomplished by init for security
@@ -2847,14 +2956,13 @@
     private static void requestCopyPreoptedFiles(Injector injector) {
         final int WAIT_TIME_MS = 100;
         final String CP_PREOPT_PROPERTY = "sys.cppreopt";
-        if (injector.getSystemWrapper().getPropertyInt("ro.cp_system_other_odex", 0) == 1) {
-            injector.getSystemWrapper().setProperty(CP_PREOPT_PROPERTY, "requested");
+        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
+            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
             // We will wait for up to 100 seconds.
             final long timeStart = SystemClock.uptimeMillis();
             final long timeEnd = timeStart + 100 * 1000;
             long timeNow = timeStart;
-            while (!injector.getSystemWrapper()
-                    .getProperty(CP_PREOPT_PROPERTY).equals("finished")) {
+            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
                 try {
                     Thread.sleep(WAIT_TIME_MS);
                 } catch (InterruptedException e) {
@@ -2862,7 +2970,7 @@
                 }
                 timeNow = SystemClock.uptimeMillis();
                 if (timeNow > timeEnd) {
-                    injector.getSystemWrapper().setProperty(CP_PREOPT_PROPERTY, "timed-out");
+                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
                     Slog.wtf(TAG, "cppreopt did not finish!");
                     break;
                 }
@@ -2939,16 +3047,16 @@
         mPermissionManager = injector.getPermissionManagerServiceInternal();
         mSettings = injector.getSettings();
         mUserManager = injector.getUserManagerService();
-
         mApexManager = testParams.apexManager;
         mArtManagerService = testParams.artManagerService;
         mAvailableFeatures = testParams.availableFeatures;
         mDefParseFlags = testParams.defParseFlags;
+        mDefaultAppProvider = testParams.defaultAppProvider;
+        mLegacyPermissionManager = testParams.legacyPermissionManagerInternal;
         mDexManager = testParams.dexManager;
         mDirsToScanAsSystem = testParams.dirsToScanAsSystem;
         mFactoryTest = testParams.factoryTest;
         mHandler = testParams.handler;
-        mHandlerThread = testParams.handlerThread;
         mIncrementalManager = testParams.incrementalManager;
         mInstallerService = testParams.installerService;
         mInstantAppRegistry = testParams.instantAppRegistry;
@@ -2993,49 +3101,46 @@
         mServicesExtensionPackageName = testParams.servicesExtensionPackageName;
         mSharedSystemSharedLibraryPackageName = testParams.sharedSystemSharedLibraryPackageName;
         mOverlayConfigSignaturePackage = testParams.overlayConfigSignaturePackage;
-
         mResolveComponentName = testParams.resolveComponentName;
         mPackages.putAll(testParams.packages);
         mEnableFreeCacheV2 = testParams.enableFreeCacheV2;
         mSdkVersion = testParams.sdkVersion;
+        mSystemWrapper = testParams.systemWrapper;
+        mAppInstallDir = testParams.appInstallDir;
+        mAppLib32InstallDir = testParams.appLib32InstallDir;
+        mIsEngBuild = testParams.isEngBuild;
+        mIsUserDebugBuild = testParams.isUserDebugBuild;
+        mIncrementalVersion = testParams.incrementalVersion;
     }
 
-    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
-        PackageManager.disableApplicationInfoCache();
-        PackageManager.disablePackageInfoCache();
-        ApplicationPackageManager.invalidateGetPackagesForUidCache();
-        ApplicationPackageManager.disableGetPackagesForUidCache();
-        ApplicationPackageManager.invalidateHasSystemFeatureCache();
-
-        // Avoid invalidation-thrashing by preventing cache invalidations from causing property
-        // writes if the cache isn't enabled yet.  We re-enable writes later when we're
-        // done initializing.
-        PackageManager.corkPackageInfoCache();
+    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest,
+            final String buildFingerprint, final boolean isEngBuild,
+            final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
+        mIsEngBuild = isEngBuild;
+        mIsUserDebugBuild = isUserDebugBuild;
+        mSdkVersion = sdkVersion;
+        mIncrementalVersion = incrementalVersion;
+        mInjector = injector;
+        mInjector.getSystemWrapper().disablePackageCaches();
 
         final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
                 Trace.TRACE_TAG_PACKAGE_MANAGER);
         mPendingBroadcasts = new PendingPackageBroadcasts();
 
-        mInjector = injector;
         mInjector.bootstrap(this);
         mLock = injector.getLock();
         mInstallLock = injector.getInstallLock();
         LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                 SystemClock.uptimeMillis());
-        mSdkVersion = injector.getSystemWrapper().getSdkInt();
-
-        if (mSdkVersion <= 0) {
-            Slog.w(TAG, "**** ro.build.version.sdk not set!");
-        }
+        mSystemWrapper = injector.getSystemWrapper();
 
         mContext = injector.getContext();
         mFactoryTest = factoryTest;
         mOnlyCore = onlyCore;
-        mMetrics = new DisplayMetrics();
+        mMetrics = injector.getDisplayMetrics();
         mInstaller = injector.getInstaller();
-        mEnableFreeCacheV2 =
-                injector.getSystemWrapper().getPropertyBoolean("fw.free_cache_v2", true);
+        mEnableFreeCacheV2 = SystemProperties.getBoolean("fw.free_cache_v2", true);
 
         // Create sub-components that provide services / data. Order here is important.
         t.traceBegin("createSubComponents");
@@ -3051,6 +3156,8 @@
         mSettings = injector.getSettings();
         mPermissionManagerService = injector.getPermissionManagerService();
         mIncrementalManager = mInjector.getIncrementalManager();
+        mDefaultAppProvider = mInjector.getDefaultAppProvider();
+        mLegacyPermissionManager = mInjector.getLegacyPermissionManagerInternal();
         PlatformCompat platformCompat = mInjector.getCompatibility();
         mPackageParserCallback = new PackageParser2.Callback() {
             @Override
@@ -3086,8 +3193,8 @@
                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
         t.traceEnd();
 
-        String separateProcesses =
-                injector.getSystemWrapper().getProperty("debug.separate_processes");
+        String separateProcesses = SystemProperties.get("debug.separate_processes");
+
         if (separateProcesses != null && separateProcesses.length() > 0) {
             if ("*".equals(separateProcesses)) {
                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
@@ -3110,7 +3217,8 @@
         mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
         mViewCompiler = injector.getViewCompiler();
 
-        getDefaultDisplayMetrics(mInjector.getSystemService(DisplayManager.class), mMetrics);
+        mContext.getSystemService(DisplayManager.class)
+                .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);
 
         t.traceBegin("get system config");
         SystemConfig systemConfig = injector.getSystemConfig();
@@ -3132,18 +3240,21 @@
         }
 
         mDirsToScanAsSystem = new ArrayList<>();
-        mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
+        mDirsToScanAsSystem.addAll(injector.getSystemPartitions());
         mDirsToScanAsSystem.addAll(scanPartitions);
         Slog.d(TAG, "Directories scanned as system partitions: " + mDirsToScanAsSystem);
 
+        mAppInstallDir = new File(Environment.getDataDirectory(), "app");
+        mAppLib32InstallDir = getAppLib32InstallDir();
+
         // CHECKSTYLE:OFF IndentationCheck
         synchronized (mInstallLock) {
         // writer
         synchronized (mLock) {
-            mHandlerThread = new ServiceThread(TAG,
+            HandlerThread handlerThread = new ServiceThread(TAG,
                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
-            mHandlerThread.start();
-            mHandler = new PackageHandler(mHandlerThread.getLooper());
+            handlerThread.start();
+            mHandler = new PackageHandler(handlerThread.getLooper());
             mProcessLoggingHandler = new ProcessLoggingHandler();
             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
             mInstantAppRegistry = new InstantAppRegistry(this, mPermissionManager);
@@ -3188,12 +3299,13 @@
 
             // Clean up orphaned packages for which the code path doesn't exist
             // and they are an update to a system app - caused by bug/32321269
-            final int packageSettingCount = mSettings.mPackages.size();
+            final ArrayMap<String, PackageSetting> packageSettings = mSettings.getPackagesLocked();
+            final int packageSettingCount = packageSettings.size();
             for (int i = packageSettingCount - 1; i >= 0; i--) {
-                PackageSetting ps = mSettings.mPackages.valueAt(i);
+                PackageSetting ps = packageSettings.valueAt(i);
                 if (!isExternal(ps) && (ps.getPath() == null || !ps.getPath().exists())
                         && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
-                    mSettings.mPackages.removeAt(i);
+                    packageSettings.removeAt(i);
                     mSettings.enableSystemPackageLPw(ps.name);
                 }
             }
@@ -3228,9 +3340,10 @@
             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
 
             final VersionInfo ver = mSettings.getInternalVersion();
-            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
+            mIsUpgrade =
+                    !buildFingerprint.equals(ver.fingerprint);
             if (mIsUpgrade) {
-                logCriticalInfo(Log.INFO,
+                PackageManagerServiceUtils.logCriticalInfo(Log.INFO,
                         "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
             }
 
@@ -3248,13 +3361,13 @@
             // Save the names of pre-existing packages prior to scanning, so we can determine
             // which system packages are completely new due to an upgrade.
             if (isDeviceUpgrading()) {
-                mExistingPackages = new ArraySet<>(mSettings.mPackages.size());
-                for (PackageSetting ps : mSettings.mPackages.values()) {
+                mExistingPackages = new ArraySet<>(packageSettings.size());
+                for (PackageSetting ps : packageSettings.values()) {
                     mExistingPackages.add(ps.name);
                 }
             }
 
-            mCacheDir = preparePackageParserCache(injector);
+            mCacheDir = preparePackageParserCache(mIsEngBuild);
 
             // Set flag to monitor and not change apk file paths when
             // scanning install directories.
@@ -3267,8 +3380,7 @@
             final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR;
             final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
 
-            PackageParser2 packageParser = new PackageParser2(mSeparateProcesses, mOnlyCore,
-                    mMetrics, mCacheDir, mPackageParserCallback);
+            PackageParser2 packageParser = injector.getScanningCachingPackageParser();
 
             ExecutorService executorService = ParallelPackageParser.makeExecutorService();
             // Prepare apex package info before scanning APKs, these information are needed when
@@ -3331,8 +3443,8 @@
 
                 // Iterates PackageSettings in reversed order because the item could be removed
                 // during the iteration.
-                for (int index = mSettings.mPackages.size() - 1; index >= 0; index--) {
-                    final PackageSetting ps = mSettings.mPackages.valueAt(index);
+                for (int index = packageSettings.size() - 1; index >= 0; index--) {
+                    final PackageSetting ps = packageSettings.valueAt(index);
 
                     /*
                      * If this is not a system app, it can't be a
@@ -3413,7 +3525,7 @@
             if (!mOnlyCore) {
                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                         SystemClock.uptimeMillis());
-                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
+                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
                         packageParser, executorService);
 
             }
@@ -3470,7 +3582,7 @@
                     // previously scanned and known to the system], but, we don't have
                     // a package [ie. there was an error scanning it from the /data
                     // partition], completely remove the package data.
-                    final PackageSetting ps = mSettings.mPackages.get(packageName);
+                    final PackageSetting ps = mSettings.getPackageLPr(packageName);
                     if (ps != null && mPackages.get(packageName) == null) {
                         removePackageDataLIF(ps, userIds, null, 0, false);
 
@@ -3596,7 +3708,7 @@
 
             // Now that we know all the packages we are keeping,
             // read and update their last usage times.
-            mPackageUsage.read(mSettings.mPackages);
+            mPackageUsage.read(packageSettings);
             mCompilerStats.read();
 
             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
@@ -3689,8 +3801,8 @@
             // profile compilation (without waiting to collect a fresh set of profiles).
             if (mIsUpgrade && !mOnlyCore) {
                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
-                for (int i = 0; i < mSettings.mPackages.size(); i++) {
-                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
+                for (int i = 0; i < packageSettings.size(); i++) {
+                    final PackageSetting ps = packageSettings.valueAt(i);
                     if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
                         // No apps are running this early, so no need to freeze
                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
@@ -3706,9 +3818,9 @@
             // their icons in launcher.
             if (!mOnlyCore && mIsPreQUpgrade) {
                 Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
-                int size = mSettings.mPackages.size();
+                int size = packageSettings.size();
                 for (int i = 0; i < size; i++) {
-                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
+                    final PackageSetting ps = packageSettings.valueAt(i);
                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                         continue;
                     }
@@ -3777,23 +3889,16 @@
                 }
             }
 
-            // Prepare a supplier of package parser for the staging manager to parse apex file
-            // during the staging installation.
-            final Supplier<PackageParser2> apexParserSupplier = () -> new PackageParser2(
-                    mSeparateProcesses, mOnlyCore, mMetrics, null /* cacheDir */,
-                    mPackageParserCallback);
-            mInstallerService = new PackageInstallerService(mContext, this, apexParserSupplier);
-            final Pair<ComponentName, String> instantAppResolverComponent =
-                    getInstantAppResolverLPr();
+            mInstallerService = mInjector.getPackageInstallerService();
+            final ComponentName instantAppResolverComponent = getInstantAppResolverLPr();
             if (instantAppResolverComponent != null) {
                 if (DEBUG_INSTANT) {
                     Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
                 }
-                mInstantAppResolverConnection = new InstantAppResolverConnection(
-                        mContext, instantAppResolverComponent.first,
-                        instantAppResolverComponent.second);
+                mInstantAppResolverConnection =
+                        mInjector.getInstantAppResolverConnection(instantAppResolverComponent);
                 mInstantAppResolverSettingsComponent =
-                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
+                        getInstantAppResolverSettingsLPr(instantAppResolverComponent);
             } else {
                 mInstantAppResolverConnection = null;
                 mInstantAppResolverSettingsComponent = null;
@@ -3823,10 +3928,8 @@
         } // synchronized (mInstallLock)
         // CHECKSTYLE:ON IndentationCheck
 
-        mModuleInfoProvider = new ModuleInfoProvider(mContext, this);
-
-        // Uncork cache invalidations and allow clients to cache package information.
-        PackageManager.uncorkPackageInfoCache();
+        mModuleInfoProvider = mInjector.getModuleInfoProvider();
+        mInjector.getSystemWrapper().enablePackageCaches();
 
         // Now after opening every single application zip, make sure they
         // are all flushed.  Not really needed, but keeps things nice and
@@ -3874,7 +3977,7 @@
                 continue;
             }
             // skip if the package has been disabled by the user
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps != null) {
                 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
                 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
@@ -3899,7 +4002,7 @@
         // disable any stub still left; these failed to install the full application
         for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
             final String pkgName = systemStubPackageNames.get(i);
-            final PackageSetting ps = mSettings.mPackages.get(pkgName);
+            final PackageSetting ps = mSettings.getPackageLPr(pkgName);
             ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                     UserHandle.USER_SYSTEM, "android");
             logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
@@ -3956,7 +4059,7 @@
                 } finally {
                     // Disable the package; the stub by itself is not runnable
                     synchronized (mLock) {
-                        final PackageSetting stubPs = mSettings.mPackages.get(
+                        final PackageSetting stubPs = mSettings.getPackageLPr(
                                 stubPkg.getPackageName());
                         if (stubPs != null) {
                             stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED,
@@ -4076,19 +4179,18 @@
         setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
     }
 
-    private static @Nullable File preparePackageParserCache(Injector injector) {
+    private @Nullable File preparePackageParserCache(boolean forEngBuild) {
         if (!FORCE_PACKAGE_PARSED_CACHE_ENABLED) {
             if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
                 return null;
             }
 
             // Disable package parsing on eng builds to allow for faster incremental development.
-            if (Build.IS_ENG) {
+            if (forEngBuild) {
                 return null;
             }
 
-            if (injector.getSystemWrapper()
-                    .getPropertyBoolean("pm.boot.disable_package_cache", false)) {
+            if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
                 Slog.i(TAG, "Disabling package parser cache due to system property.");
                 return null;
             }
@@ -4104,8 +4206,7 @@
         // identify cached items. In particular, changing the value of certain
         // feature flags should cause us to invalidate any caches.
         final String cacheName = FORCE_PACKAGE_PARSED_CACHE_ENABLED ? "debug"
-                : injector.getSystemWrapper().digestOfProperties(
-                        "ro.build.fingerprint");
+                : SystemProperties.digestOf("ro.build.fingerprint");
 
         // Reconcile cache directories, keeping only what we'd actually use.
         for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) {
@@ -4134,14 +4235,15 @@
         // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
         // that starts with "eng." to signify that this is an engineering build and not
         // destined for release.
-        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
+        if (mIsUserDebugBuild && mIncrementalVersion.startsWith("eng.")) {
             Slog.w(TAG, "Wiping cache directory because the system partition changed.");
 
             // Heuristic: If the /system directory has been modified recently due to an "adb sync"
             // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
             // in general and should not be used for production changes. In this specific case,
             // we know that they will work.
-            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
+            File frameworkDir =
+                    new File(Environment.getRootDirectory(), "framework");
             if (cacheDir.lastModified() < frameworkDir.lastModified()) {
                 FileUtils.deleteContents(cacheBaseDir);
                 cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
@@ -4167,7 +4269,7 @@
     public boolean isDeviceUpgrading() {
         // allow instant applications
         // The system property allows testing ota flow when upgraded to the same image.
-        return mIsUpgrade || mInjector.getSystemWrapper().getPropertyBoolean(
+        return mIsUpgrade || SystemProperties.getBoolean(
                 "persist.pm.mock-upgrade", false /* default */);
     }
 
@@ -4301,15 +4403,15 @@
             return null;
         }
         synchronized (mLock) {
-            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
+            final ComponentName instantAppResolver = getInstantAppResolverLPr();
             if (instantAppResolver == null) {
                 return null;
             }
-            return instantAppResolver.first;
+            return instantAppResolver;
         }
     }
 
-    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
+    private @Nullable ComponentName getInstantAppResolverLPr() {
         final String[] packageArray =
                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
         if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
@@ -4324,8 +4426,7 @@
                 MATCH_DIRECT_BOOT_AWARE
                 | MATCH_DIRECT_BOOT_UNAWARE
                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
-        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
-        final Intent resolverIntent = new Intent(actionName);
+        final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
         List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
                 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
         final int N = resolvers.size();
@@ -4357,7 +4458,7 @@
                 Slog.v(TAG, "Ephemeral resolver found;"
                         + " pkg: " + packageName + ", info:" + info);
             }
-            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
+            return new ComponentName(packageName, info.serviceInfo.name);
         }
         if (DEBUG_INSTANT) {
             Slog.v(TAG, "Ephemeral resolver NOT found");
@@ -4367,7 +4468,7 @@
 
     @GuardedBy("mLock")
     private @Nullable ActivityInfo getInstantAppInstallerLPr() {
-        String[] orderedActions = Build.IS_ENG
+        String[] orderedActions = mIsEngBuild
                 ? new String[]{
                         Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
                         Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
@@ -4378,7 +4479,7 @@
                 MATCH_DIRECT_BOOT_AWARE
                         | MATCH_DIRECT_BOOT_UNAWARE
                         | Intent.FLAG_IGNORE_EPHEMERAL
-                        | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
+                        | (mIsEngBuild ? 0 : MATCH_SYSTEM_ONLY);
         final Intent intent = new Intent();
         intent.addCategory(Intent.CATEGORY_DEFAULT);
         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
@@ -4398,8 +4499,9 @@
         Iterator<ResolveInfo> iter = matches.iterator();
         while (iter.hasNext()) {
             final ResolveInfo rInfo = iter.next();
-            if (checkPermission(Manifest.permission.INSTALL_PACKAGES,
-                    rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || Build.IS_ENG) {
+            if (checkPermission(
+                    Manifest.permission.INSTALL_PACKAGES,
+                    rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || mIsEngBuild) {
                 continue;
             }
             iter.remove();
@@ -4627,7 +4729,7 @@
         enforceCrossUserPermission(callingUid, userId, false, false, "checkPackageStartable");
         final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                 throw new SecurityException("Package " + packageName + " was not found!");
             }
@@ -4743,7 +4845,7 @@
                 return generatePackageInfo(ps, flags, userId);
             }
             if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps == null) return null;
                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                     return null;
@@ -4951,7 +5053,7 @@
             final int callingUserId = UserHandle.getUserId(callingUid);
             final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
             for (int i=names.length-1; i>=0; i--) {
-                final PackageSetting ps = mSettings.mPackages.get(names[i]);
+                final PackageSetting ps = mSettings.getPackageLPr(names[i]);
                 boolean translateName = false;
                 if (ps != null && ps.realName != null) {
                     final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
@@ -4981,7 +5083,7 @@
                 final String cur = mSettings.getRenamedPackageLPr(names[i]);
                 boolean translateName = false;
                 if (cur != null) {
-                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
+                    final PackageSetting ps = mSettings.getPackageLPr(names[i]);
                     final boolean targetIsInstantApp =
                             ps != null && ps.getInstantApp(callingUserId);
                     translateName = !targetIsInstantApp
@@ -5017,7 +5119,7 @@
                 return UserHandle.getUid(userId, p.getUid());
             }
             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps != null && ps.isMatch(flags)
                         && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
                     return UserHandle.getUid(userId, ps.appId);
@@ -5049,7 +5151,7 @@
                 return mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId));
             }
             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps != null && ps.isMatch(flags)
                         && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
                     return mPermissionManager.getGidsForUid(UserHandle.getUid(userId, ps.appId));
@@ -5075,7 +5177,7 @@
     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
             int filterCallingUid, int userId) {
         if (!mUserManager.exists(userId)) return null;
-        PackageSetting ps = mSettings.mPackages.get(packageName);
+        PackageSetting ps = mSettings.getPackageLPr(packageName);
         if (ps != null) {
             if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                 return null;
@@ -5133,7 +5235,7 @@
                     TAG, "getApplicationInfo " + packageName
                     + ": " + p);
             if (p != null) {
-                PackageSetting ps = mSettings.mPackages.get(packageName);
+                PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps == null) return null;
                 if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                     return null;
@@ -5602,7 +5704,7 @@
             if (a == null) {
                 return false;
             }
-            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
+            PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
             if (ps == null) {
                 return false;
             }
@@ -5642,7 +5744,7 @@
             }
 
             if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
-                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
+                PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
                 if (ps == null) return null;
                 if (shouldFilterApplicationLocked(
                         ps, callingUid, component, TYPE_RECEIVER, userId)) {
@@ -5802,9 +5904,9 @@
     private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
             SharedLibraryInfo libInfo, int flags, int userId) {
         List<VersionedPackage> versionedPackages = null;
-        final int packageCount = mSettings.mPackages.size();
+        final int packageCount = mSettings.getPackagesLocked().size();
         for (int i = 0; i < packageCount; i++) {
-            PackageSetting ps = mSettings.mPackages.valueAt(i);
+            PackageSetting ps = mSettings.getPackagesLocked().valueAt(i);
 
             if (ps == null) {
                 continue;
@@ -5863,7 +5965,7 @@
 
             AndroidPackage pkg = mPackages.get(s.getPackageName());
             if (mSettings.isEnabledAndMatchLPr(pkg, s, flags, userId)) {
-                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
+                PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
                 if (ps == null) return null;
                 if (shouldFilterApplicationLocked(
                         ps, callingUid, component, TYPE_SERVICE, userId)) {
@@ -5897,7 +5999,7 @@
             }
 
             if (mSettings.isEnabledAndMatchLPr(pkg, p, flags, userId)) {
-                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
+                PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
                 if (ps == null) return null;
                 if (shouldFilterApplicationLocked(
                         ps, callingUid, component, TYPE_PROVIDER, userId)) {
@@ -6034,7 +6136,7 @@
                 final String packageName = changedPackages.get(i);
                 if (packageName != null) {
                     // Filter out the changes if the calling package should not be able to see it.
-                    final PackageSetting ps = mSettings.mPackages.get(packageName);
+                    final PackageSetting ps = mSettings.getPackageLPr(packageName);
                     if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                         continue;
                     }
@@ -6055,7 +6157,7 @@
             res.addAll(mAvailableFeatures.values());
         }
         final FeatureInfo fi = new FeatureInfo();
-        fi.reqGlEsVersion = mInjector.getSystemWrapper().getPropertyInt("ro.opengles.version",
+        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
                 FeatureInfo.GL_ES_VERSION_UNDEFINED);
         res.add(fi);
 
@@ -6781,7 +6883,7 @@
             for (int n = 0; n < count; n++) {
                 final ResolveInfo info = resolvedActivities.get(n);
                 final String packageName = info.activityInfo.packageName;
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps != null) {
                     // only check domain verification status if the app is not a browser
                     if (!info.handleAllWebDataURI) {
@@ -6863,7 +6965,7 @@
                     // If we have an ephemeral app, use it
                     if (ri.activityInfo.applicationInfo.isInstantApp()) {
                         final String packageName = ri.activityInfo.packageName;
-                        final PackageSetting ps = mSettings.mPackages.get(packageName);
+                        final PackageSetting ps = mSettings.getPackageLPr(packageName);
                         final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
                         final int status = (int)(packedStatus >> 32);
                         if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
@@ -7297,7 +7399,7 @@
 
     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
             String resolvedType, int userId) {
-        CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolvers(userId);
+        CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolver(userId);
         if (resolver != null) {
             return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
         }
@@ -7545,7 +7647,7 @@
             for (int i = instantApps.size() - 1; i >= 0; --i) {
                 final ResolveInfo info = instantApps.get(i);
                 final String packageName = info.activityInfo.packageName;
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps.getInstantApp(userId)) {
                     final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
                     final int status = (int)(packedStatus >> 32);
@@ -7600,7 +7702,7 @@
         if (intent.isWebIntent() && auxiliaryResponse == null) {
             return result;
         }
-        final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
+        final PackageSetting ps = mSettings.getPackageLPr(mInstantAppInstallerActivity.packageName);
         if (ps == null
                 || !ps.readUserState(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
             return result;
@@ -7660,7 +7762,7 @@
                 continue;
             }
             String packageName = riTargetUser.activityInfo.packageName;
-            PackageSetting ps = mSettings.mPackages.get(packageName);
+            PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps == null) {
                 continue;
             }
@@ -7885,7 +7987,7 @@
             for (int n=0; n<count; n++) {
                 ResolveInfo info = candidates.get(n);
                 String packageName = info.activityInfo.packageName;
-                PackageSetting ps = mSettings.mPackages.get(packageName);
+                PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps != null) {
                     // Add to the special match all list (Browser use case)
                     if (info.handleAllWebDataURI) {
@@ -7964,8 +8066,8 @@
                 } else {
                     // Browser/generic handling case.  If there's a default browser, go straight
                     // to that (but only if there is no other higher-priority match).
-                    final String defaultBrowserPackageName =
-                            mPermissionManager.getDefaultBrowser(userId);
+                    final String defaultBrowserPackageName = mDefaultAppProvider.getDefaultBrowser(
+                            userId);
                     int maxMatchPrio = 0;
                     ResolveInfo defaultBrowserMatch = null;
                     final int numCandidates = matchAllList.size();
@@ -8749,8 +8851,8 @@
         synchronized (mLock) {
             ArrayList<PackageInfo> list;
             if (listUninstalled) {
-                list = new ArrayList<>(mSettings.mPackages.size());
-                for (PackageSetting ps : mSettings.mPackages.values()) {
+                list = new ArrayList<>(mSettings.getPackagesLocked().size());
+                for (PackageSetting ps : mSettings.getPackagesLocked().values()) {
                     if (listFactory) {
                         if (!ps.isSystem()) {
                             continue;
@@ -8862,7 +8964,7 @@
             ArrayList<PackageInfo> list = new ArrayList<>();
             boolean[] tmpBools = new boolean[permissions.length];
             if (listUninstalled) {
-                for (PackageSetting ps : mSettings.mPackages.values()) {
+                for (PackageSetting ps : mSettings.getPackagesLocked().values()) {
                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
                             userId);
                 }
@@ -8907,8 +9009,8 @@
         synchronized (mLock) {
             ArrayList<ApplicationInfo> list;
             if (listUninstalled) {
-                list = new ArrayList<>(mSettings.mPackages.size());
-                for (PackageSetting ps : mSettings.mPackages.values()) {
+                list = new ArrayList<>(mSettings.getPackagesLocked().size());
+                for (PackageSetting ps : mSettings.getPackagesLocked().values()) {
                     ApplicationInfo ai;
                     int effectiveFlags = flags;
                     if (ps.isSystem()) {
@@ -9000,7 +9102,7 @@
             if (Process.isIsolated(callingUid)) {
                 callingUid = mIsolatedOwners.get(callingUid);
             }
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             final boolean returnAllowed =
                     ps != null
                     && (isCallerSameApp(packageName, callingUid)
@@ -9099,7 +9201,7 @@
                 if (p.isPersistent()
                         && (!mSafeMode || p.isSystem())
                         && (matchesUnaware || matchesAware)) {
-                    PackageSetting ps = mSettings.mPackages.get(p.getPackageName());
+                    PackageSetting ps = mSettings.getPackageLPr(p.getPackageName());
                     if (ps != null) {
                         ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
                                 ps.readUserState(userId), userId, ps);
@@ -9144,7 +9246,7 @@
             if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
                 return null;
             }
-            final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(providerInfo.packageName);
             final ComponentName component =
                     new ComponentName(providerInfo.packageName, providerInfo.name);
             if (shouldFilterApplicationLocked(ps, callingUid, component, TYPE_PROVIDER, userId)) {
@@ -9184,7 +9286,7 @@
                 if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
                     continue;
                 }
-                final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(providerInfo.packageName);
                 final ComponentName component =
                         new ComponentName(providerInfo.packageName, providerInfo.name);
                 if (shouldFilterApplicationLocked(
@@ -9213,7 +9315,7 @@
             final int callingUid = Binder.getCallingUid();
             final int callingUserId = UserHandle.getUserId(callingUid);
             String packageName = component.getPackageName();
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             AndroidPackage pkg = mPackages.get(packageName);
             if (ps == null || pkg == null) return null;
             if (shouldFilterApplicationLocked(
@@ -9445,8 +9547,7 @@
 
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
         final ParsedPackage parsedPackage;
-        try (PackageParser2 pp = new PackageParser2(mSeparateProcesses, mOnlyCore, mMetrics, null,
-                mPackageParserCallback)) {
+        try (PackageParser2 pp = mInjector.getScanningPackageParser()) {
             parsedPackage = pp.parsePackage(scanFile, parseFlags, false);
         } catch (PackageParserException e) {
             throw PackageManagerException.from(e);
@@ -9740,7 +9841,7 @@
                                             pkgName, getSettingsVersionForPackage(parsedPackage)),
                                     Collections.singletonMap(pkgName,
                                             getSharedLibLatestVersionSetting(scanResult))),
-                            mSettings.mKeySetManagerService, mInjector);
+                            mSettings.getKeySetManagerService(), mInjector);
                     appIdCreated = optimisticallyRegisterAppId(scanResult);
                     commitReconciledScanResultLocked(
                             reconcileResult.get(pkgName), mUserManager.getUserIds());
@@ -10051,7 +10152,7 @@
         List<PackageSetting> pkgSettings;
         synchronized (mLock) {
             pkgSettings = PackageManagerServiceUtils.getPackagesForDexopt(
-                    mSettings.mPackages.values(), this);
+                    mSettings.getPackagesLocked().values(), this);
         }
 
         List<AndroidPackage> pkgs = new ArrayList<>(pkgSettings.size());
@@ -10196,7 +10297,7 @@
                 pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
             }
 
-            if (mInjector.getSystemWrapper().getPropertyBoolean(PRECOMPILE_LAYOUTS, false)) {
+            if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
                 mArtManagerService.compileLayouts(pkg);
             }
 
@@ -10409,7 +10510,7 @@
                 // Package could not be found. Report failure.
                 return PackageDexOptimizer.DEX_OPT_FAILED;
             }
-            mPackageUsage.maybeWriteAsync(mSettings.mPackages);
+            mPackageUsage.maybeWriteAsync(mSettings.getPackagesLocked());
             mCompilerStats.maybeWriteAsync();
         }
         final long callingId = Binder.clearCallingIdentity();
@@ -10639,7 +10740,7 @@
         PackageWatchdog.getInstance(mContext).writeNow();
 
         synchronized (mLock) {
-            mPackageUsage.writeNow(mSettings.mPackages);
+            mPackageUsage.writeNow(mSettings.getPackagesLocked());
 
             // This is the last chance to write out pending restriction settings
             if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
@@ -10769,7 +10870,7 @@
     private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
         final PackageSetting ps;
         synchronized (mLock) {
-            ps = mSettings.mPackages.get(pkg.getPackageName());
+            ps = mSettings.getPackageLPr(pkg.getPackageName());
         }
         for (int realUserId : resolveUserIds(userId)) {
             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
@@ -10793,7 +10894,7 @@
     private void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
         final PackageSetting ps;
         synchronized (mLock) {
-            ps = mSettings.mPackages.get(pkg.getPackageName());
+            ps = mSettings.getPackageLPr(pkg.getPackageName());
         }
         for (int realUserId : resolveUserIds(userId)) {
             final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
@@ -11173,7 +11274,7 @@
     }
 
     private int getVendorPartitionVersion() {
-        final String version = mInjector.getSystemWrapper().getProperty("ro.vndk.version");
+        final String version = SystemProperties.get("ro.vndk.version");
         if (!version.isEmpty()) {
             try {
                 return Integer.parseInt(version);
@@ -11384,7 +11485,7 @@
                 // to allowlist their privileged permissions just like other
                 // priv-apps.
                 synchronized (mLock) {
-                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
+                    PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
                     if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
                             pkg.getSigningDetails().signatures)
                             != PackageManager.SIGNATURE_MATCH)) {
@@ -11506,6 +11607,7 @@
             parsedPackage.setVersionCode(mSdkVersion)
                     .setVersionCodeMajor(0);
         }
+
         final AndroidPackage oldPkg = request.oldPkg;
         final @ParseFlags int parseFlags = request.parseFlags;
         final @ScanFlags int scanFlags = request.scanFlags;
@@ -11545,7 +11647,7 @@
         if (reconciledPkg.installArgs != null) {
             InstallSource installSource = reconciledPkg.installArgs.installSource;
             if (installSource.initiatingPackageName != null) {
-                final PackageSetting ips = mSettings.mPackages.get(
+                final PackageSetting ips = mSettings.getPackageLPr(
                         installSource.initiatingPackageName);
                 if (ips != null) {
                     installSource = installSource.setInitiatingPackageSignatures(
@@ -11575,7 +11677,7 @@
                     reconciledPkg.collectedSharedLibraryInfos, allUsers);
         }
 
-        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+        final KeySetManagerService ksms = mSettings.getKeySetManagerService();
         if (reconciledPkg.removeAppKeySetData) {
             ksms.removeAppKeySetDataLPw(pkg.getPackageName());
         }
@@ -11937,12 +12039,13 @@
         final String cpuAbiOverride = deriveAbiOverride(request.cpuAbiOverride);
         final boolean isUpdatedSystemApp = pkgSetting.getPkgState().isUpdatedSystemApp();
 
+        final File appLib32InstallDir = getAppLib32InstallDir();
         if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
             if (needToDeriveAbi) {
                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
                 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
                         packageAbiHelper.derivePackageAbi(parsedPackage, isUpdatedSystemApp,
-                                cpuAbiOverride);
+                                cpuAbiOverride, appLib32InstallDir);
                 derivedAbi.first.applyTo(parsedPackage);
                 derivedAbi.second.applyTo(parsedPackage);
                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -11960,7 +12063,7 @@
                     abis.applyTo(pkgSetting);
                     final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
                             packageAbiHelper.deriveNativeLibraryPaths(parsedPackage,
-                                    isUpdatedSystemApp, sAppLib32InstallDir);
+                                    isUpdatedSystemApp, appLib32InstallDir);
                     nativeLibraryPaths.applyTo(parsedPackage);
                 }
             } else {
@@ -11972,7 +12075,7 @@
 
                 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
                         packageAbiHelper.deriveNativeLibraryPaths(parsedPackage,
-                                isUpdatedSystemApp, sAppLib32InstallDir);
+                                isUpdatedSystemApp, appLib32InstallDir);
                 nativeLibraryPaths.applyTo(parsedPackage);
 
                 if (DEBUG_ABI_SELECTION) {
@@ -11998,7 +12101,7 @@
             // package path (after the rename away from the stage path).
             final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
                     packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isUpdatedSystemApp,
-                            sAppLib32InstallDir);
+                            appLib32InstallDir);
             nativeLibraryPaths.applyTo(parsedPackage);
         }
 
@@ -12293,7 +12396,7 @@
         }
 
         // Make sure we're not adding any bogus keyset info
-        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+        final KeySetManagerService ksms = mSettings.getKeySetManagerService();
         ksms.assertScannedPackageValid(pkg);
 
         synchronized (mLock) {
@@ -12511,7 +12614,7 @@
                 }
                 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
                     // Exempt SharedUsers signed with the platform key.
-                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
+                    PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
                     if (!comparePackageSignatures(platformPkgSetting,
                             pkg.getSigningDetails().signatures)) {
                         throw new PackageManagerException("Apps that share a user with a " +
@@ -12685,7 +12788,7 @@
                 continue;
             }
             for (VersionedPackage dependentPackage : dependents) {
-                final PackageSetting ps = mSettings.mPackages.get(
+                final PackageSetting ps = mSettings.getPackageLPr(
                         dependentPackage.getPackageName());
                 if (ps != null) {
                     ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
@@ -12844,7 +12947,6 @@
 
         synchronized (mLock) {
             // We don't expect installation to fail beyond this point
-
             // Add the new setting to mSettings
             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
             // Add the new setting to mPackages
@@ -12854,7 +12956,7 @@
             }
 
             // Add the package's KeySets to the global KeySetManagerService
-            KeySetManagerService ksms = mSettings.mKeySetManagerService;
+            KeySetManagerService ksms = mSettings.getKeySetManagerService();
             ksms.addScannedPackageLPw(pkg);
 
             mComponentResolver.addAllComponents(pkg, chatty);
@@ -13329,7 +13431,7 @@
                 packageName, extras, 0, null, null, userIds, instantUserIds,
                 mAppsFilter.getVisibilityAllowList(
                         getPackageSettingInternal(packageName, Process.SYSTEM_UID),
-                        userIds, mSettings.mPackages));
+                        userIds, mSettings.getPackagesLocked()));
         if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
             mHandler.post(() -> {
                         for (int userId : userIds) {
@@ -13400,7 +13502,7 @@
             boolean sendRemoved = false;
             // writer
             synchronized (mLock) {
-                pkgSetting = mSettings.mPackages.get(packageName);
+                pkgSetting = mSettings.getPackageLPr(packageName);
                 if (pkgSetting == null) {
                     return false;
                 }
@@ -13466,7 +13568,7 @@
         }
 
         synchronized (mLock) {
-            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+            final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
             if (pkgSetting == null || !pkgSetting.isSystem()) {
                 return;
             }
@@ -13493,7 +13595,7 @@
         }
 
         synchronized (mLock) {
-            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+            final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
             // The target app should always be in system
             if (pkgSetting == null || !pkgSetting.isSystem()) {
                 return false;
@@ -13580,7 +13682,7 @@
         try {
             // writer
             synchronized (mLock) {
-                ps = mSettings.mPackages.get(packageName);
+                ps = mSettings.getPackageLPr(packageName);
                 if (ps == null) {
                     return true;
                 }
@@ -13641,7 +13743,7 @@
 
             // writer
             synchronized (mLock) {
-                pkgSetting = mSettings.mPackages.get(packageName);
+                pkgSetting = mSettings.getPackageLPr(packageName);
                 if (pkgSetting == null) {
                     return PackageManager.INSTALL_FAILED_INVALID_URI;
                 }
@@ -13791,7 +13893,7 @@
             final String packageName = packageNames[i];
             final PackageSetting pkgSetting;
             synchronized (mLock) {
-                pkgSetting = mSettings.mPackages.get(packageName);
+                pkgSetting = mSettings.getPackageLPr(packageName);
                 if (pkgSetting == null
                         || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
                     Slog.w(TAG, "Could not find package setting for package: " + packageName
@@ -13889,7 +13991,7 @@
             }
             final PackageSetting pkgSetting;
             synchronized (mLock) {
-                pkgSetting = mSettings.mPackages.get(packageName);
+                pkgSetting = mSettings.getPackageLPr(packageName);
                 if (pkgSetting == null
                         || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
                     Slog.w(TAG, "Could not find package setting for package: " + packageName
@@ -13942,7 +14044,7 @@
 
     private Bundle getSuspendedPackageAppExtrasInternal(String packageName, int userId) {
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps == null) {
                 return null;
             }
@@ -13997,7 +14099,7 @@
         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
                 false /* checkShell */, "isPackageSuspendedForUser for user " + userId);
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                 throw new IllegalArgumentException("Unknown target package: " + packageName);
             }
@@ -14015,7 +14117,7 @@
 
     boolean isSuspendingAnyPackages(String suspendingPackage, int userId) {
         synchronized (mLock) {
-            for (final PackageSetting ps : mSettings.mPackages.values()) {
+            for (final PackageSetting ps : mSettings.getPackagesLocked().values()) {
                 if (ps.isSuspendedBy(suspendingPackage, userId)) {
                     return true;
                 }
@@ -14041,7 +14143,7 @@
         final IntArray unsuspendedUids = new IntArray();
         synchronized (mLock) {
             for (String packageName : packagesToChange) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps != null && ps.getSuspended(userId)) {
                     ps.removeSuspension(suspendingPackagePredicate, userId);
                     if (!ps.getSuspended(userId)) {
@@ -14082,7 +14184,7 @@
         final IntArray changedUids = new IntArray();
         synchronized (mLock) {
             for (String packageName : packagesToChange) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps != null && ps.getDistractionFlags(userId) != 0) {
                     ps.setDistractionFlags(0, userId);
                     changedPackages.add(ps.name);
@@ -14138,7 +14240,7 @@
                 continue;
             }
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(packageNames[i]);
+                final PackageSetting ps = mSettings.getPackageLPr(packageNames[i]);
                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                     Slog.w(TAG, "Could not find package setting for package: " + packageNames[i]);
                     unactionablePackages.add(packageNames[i]);
@@ -14162,8 +14264,8 @@
         final boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId);
         final long callingId = Binder.clearCallingIdentity();
         try {
-            final String activeLauncherPackageName = mPermissionManager.getDefaultHome(userId);
-            final String dialerPackageName = mPermissionManager.getDefaultDialer(userId);
+            final String activeLauncherPackageName = mDefaultAppProvider.getDefaultHome(userId);
+            final String dialerPackageName = mDefaultAppProvider.getDefaultDialer(userId);
             for (int i = 0; i < packageNames.length; i++) {
                 canSuspend[i] = false;
                 final String packageName = packageNames[i];
@@ -14485,7 +14587,7 @@
             // Check if the developer wants to skip verification for ADB installs
             if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
                 synchronized (mLock) {
-                    if (mSettings.mPackages.get(pkgInfoLite.packageName) == null) {
+                    if (mSettings.getPackageLPr(pkgInfoLite.packageName) == null) {
                         // Always verify fresh install
                         return true;
                     }
@@ -14552,7 +14654,7 @@
             return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
         }
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps == null
                     || shouldFilterApplicationLocked(
                     ps, callingUid, UserHandle.getUserId(callingUid))) {
@@ -14569,7 +14671,7 @@
 
         boolean result = false;
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (shouldFilterApplicationLocked(
                     ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
                 return false;
@@ -14590,7 +14692,7 @@
             return ParceledListSlice.emptyList();
         }
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (shouldFilterApplicationLocked(ps, callingUid, UserHandle.getUserId(callingUid))) {
                 return ParceledListSlice.emptyList();
             }
@@ -14655,7 +14757,7 @@
         }
         // writer
         synchronized (mLock) {
-            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
+            PackageSetting targetPackageSetting = mSettings.getPackageLPr(targetPackage);
             if (targetPackageSetting == null
                     || shouldFilterApplicationLocked(
                             targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
@@ -14664,7 +14766,7 @@
 
             PackageSetting installerPackageSetting;
             if (installerPackageName != null) {
-                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
+                installerPackageSetting = mSettings.getPackageLPr(installerPackageName);
                 if (installerPackageSetting == null) {
                     throw new IllegalArgumentException("Unknown installer package: "
                             + installerPackageName);
@@ -14706,7 +14808,7 @@
             String targetInstallerPackageName =
                     targetPackageSetting.installSource.installerPackageName;
             PackageSetting targetInstallerPkgSetting = targetInstallerPackageName == null ? null :
-                    mSettings.mPackages.get(targetInstallerPackageName);
+                    mSettings.getPackageLPr(targetInstallerPackageName);
 
             if (targetInstallerPkgSetting != null) {
                 if (compareSignatures(callerSignature,
@@ -14757,7 +14859,7 @@
         mInjector.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
                 callerPackageName);
         synchronized (mLock) {
-            PackageSetting ps = mSettings.mPackages.get(packageName);
+            PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps == null) {
                 throw new IllegalArgumentException("Unknown target package " + packageName);
             }
@@ -15211,10 +15313,12 @@
         final int autoRevokePermissionsMode;
         final PackageParser.SigningDetails signingDetails;
         final int installReason;
+        final int mInstallScenario;
         @Nullable MultiPackageInstallParams mParentInstallParams;
         final boolean forceQueryableOverride;
         final int mDataLoaderType;
         final long requiredInstalledVersionCode;
+        final PackageLite mPackageLite;
 
         InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
                 int installFlags, InstallSource installSource, String volumeUuid,
@@ -15233,19 +15337,23 @@
             this.autoRevokePermissionsMode = MODE_DEFAULT;
             this.signingDetails = PackageParser.SigningDetails.UNKNOWN;
             this.installReason = PackageManager.INSTALL_REASON_UNKNOWN;
+            this.mInstallScenario = PackageManager.INSTALL_SCENARIO_DEFAULT;
             this.forceQueryableOverride = false;
             this.mDataLoaderType = DataLoaderType.NONE;
             this.requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST;
+            this.mPackageLite = null;
         }
 
         InstallParams(File stagedDir, IPackageInstallObserver2 observer,
                 PackageInstaller.SessionParams sessionParams, InstallSource installSource,
-                UserHandle user, SigningDetails signingDetails, int installerUid) {
+                UserHandle user, SigningDetails signingDetails, int installerUid,
+                PackageLite packageLite) {
             super(user);
             origin = OriginInfo.fromStagedFile(stagedDir);
             move = null;
             installReason = fixUpInstallReason(
                     installSource.installerPackageName, installerUid, sessionParams.installReason);
+            mInstallScenario = sessionParams.installScenario;
             this.observer = observer;
             installFlags = sessionParams.installFlags;
             this.installSource = installSource;
@@ -15259,6 +15367,7 @@
             mDataLoaderType = (sessionParams.dataLoaderParams != null)
                     ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
             requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
+            mPackageLite = packageLite;
         }
 
         @Override
@@ -15343,7 +15452,8 @@
                     try {
                         mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
                         pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
-                                origin.resolvedPath, installFlags, packageAbiOverride);
+                                mPackageLite, origin.resolvedPath, installFlags,
+                                packageAbiOverride);
                     } catch (InstallerException e) {
                         Slog.w(TAG, "Failed to free cache", e);
                     }
@@ -15404,7 +15514,7 @@
          */
         public void handleStartCopy() {
             PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
-                    origin.resolvedPath, installFlags, packageAbiOverride);
+                    mPackageLite, origin.resolvedPath, installFlags, packageAbiOverride);
 
             // For staged session, there is a delay between its verification and install. Device
             // state can change within this delay and hence we need to re-verify certain conditions.
@@ -15524,9 +15634,11 @@
         private boolean mWaitForEnableRollbackToComplete;
         private int mRet;
 
+        final PackageLite mPackageLite;
+
         VerificationParams(UserHandle user, File stagedDir, IPackageInstallObserver2 observer,
                 PackageInstaller.SessionParams sessionParams, InstallSource installSource,
-                int installerUid, SigningDetails signingDetails, int sessionId) {
+                int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite) {
             super(user);
             origin = OriginInfo.fromStagedFile(stagedDir);
             this.observer = observer;
@@ -15544,6 +15656,7 @@
             mDataLoaderType = (sessionParams.dataLoaderParams != null)
                     ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
             mSessionId = sessionId;
+            mPackageLite = lite;
         }
 
         @Override
@@ -15561,7 +15674,7 @@
             }
 
             PackageInfoLite pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
-                    origin.resolvedPath, installFlags, packageAbiOverride);
+                    mPackageLite, origin.resolvedPath, installFlags, packageAbiOverride);
 
             mRet = verifyReplacingVersionCode(pkgLite, requiredInstalledVersionCode, installFlags);
             if (mRet != INSTALL_SUCCEEDED) {
@@ -15969,6 +16082,7 @@
         final int traceCookie;
         final PackageParser.SigningDetails signingDetails;
         final int installReason;
+        final int mInstallScenario;
         final boolean forceQueryableOverride;
         final int mDataLoaderType;
 
@@ -15984,7 +16098,8 @@
                 List<String> whitelistedRestrictedPermissions,
                 int autoRevokePermissionsMode,
                 String traceMethod, int traceCookie, SigningDetails signingDetails,
-                int installReason, boolean forceQueryableOverride, int dataLoaderType) {
+                int installReason, int installScenario, boolean forceQueryableOverride,
+                int dataLoaderType) {
             this.origin = origin;
             this.move = move;
             this.installFlags = installFlags;
@@ -16001,6 +16116,7 @@
             this.traceCookie = traceCookie;
             this.signingDetails = signingDetails;
             this.installReason = installReason;
+            this.mInstallScenario = installScenario;
             this.forceQueryableOverride = forceQueryableOverride;
             this.mDataLoaderType = dataLoaderType;
         }
@@ -16013,7 +16129,8 @@
                     params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
                     params.autoRevokePermissionsMode,
                     params.traceMethod, params.traceCookie, params.signingDetails,
-                    params.installReason, params.forceQueryableOverride, params.mDataLoaderType);
+                    params.installReason, params.mInstallScenario, params.forceQueryableOverride,
+                    params.mDataLoaderType);
         }
 
         abstract int copyApk();
@@ -16102,8 +16219,8 @@
             super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
                     null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
                     PackageParser.SigningDetails.UNKNOWN,
-                    PackageManager.INSTALL_REASON_UNKNOWN, false,
-                    DataLoaderType.NONE);
+                    PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.INSTALL_SCENARIO_DEFAULT,
+                    false, DataLoaderType.NONE);
             this.codeFile = (codePath != null) ? new File(codePath) : null;
         }
 
@@ -16490,7 +16607,7 @@
             // For system-bundled packages, we assume that installing an upgraded version
             // of the package implies that the user actually wants to run that new code,
             // so we enable the package.
-            final PackageSetting ps = mSettings.mPackages.get(pkgName);
+            final PackageSetting ps = mSettings.getPackageLPr(pkgName);
             final int userId = installArgs.user.getIdentifier();
             if (ps != null) {
                 if (pkg.isSystem()) {
@@ -16535,7 +16652,7 @@
                                 // TODO(146804378): Support overlaying static shared libraries
                                 continue;
                             }
-                            final PackageSetting libPs = mSettings.mPackages.get(
+                            final PackageSetting libPs = mSettings.getPackageLPr(
                                     sharedLib.getPackageName());
                             if (libPs == null) {
                                 continue;
@@ -16948,8 +17065,7 @@
                                 && compareSignatures(sharedUserSignatures,
                                 parsedPackage.getSigningDetails().signatures)
                                         != PackageManager.SIGNATURE_MATCH) {
-                            if (injector.getSystemWrapper()
-                                    .getPropertyInt("ro.product.first_api_level", 0) <= 29) {
+                            if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
                                 // Mismatched signatures is an error and silently skipping system
                                 // packages will likely break the device in unforeseen ways.
                                 // However, we allow the device to boot anyway because, prior to Q,
@@ -17139,7 +17255,7 @@
                 reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();
 
                 res.removedInfo.broadcastAllowList = mAppsFilter.getVisibilityAllowList(
-                                reconciledPkg.pkgSetting, request.mAllUsers, mSettings.mPackages);
+                        reconciledPkg.pkgSetting, request.mAllUsers, mSettings.getPackagesLocked());
                 if (reconciledPkg.prepareResult.system) {
                     // Remove existing system package
                     removePackageLI(oldPackage, true);
@@ -17163,7 +17279,7 @@
                         executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
                                 true, request.mAllUsers, false, parsedPackage);
                     } catch (SystemDeleteException e) {
-                        if (Build.IS_ENG) {
+                        if (mIsEngBuild) {
                             throw new RuntimeException("Unexpected failure", e);
                             // ignore; not possible for non-system app
                         }
@@ -17184,7 +17300,7 @@
                     }
 
                     // Update the in-memory copy of the previous code paths.
-                    PackageSetting ps1 = mSettings.mPackages.get(
+                    PackageSetting ps1 = mSettings.getPackageLPr(
                             reconciledPkg.prepareResult.existingPackage.getPackageName());
                     if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP)
                             == 0) {
@@ -17213,7 +17329,7 @@
             AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg, request.mAllUsers);
             updateSettingsLI(pkg, reconciledPkg.installArgs, request.mAllUsers, res);
 
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps != null) {
                 res.newUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
                 ps.setUpdateAvailable(false /*updateAvailable*/);
@@ -17323,7 +17439,7 @@
                 try {
                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
                     reconciledPackages = reconcilePackagesLocked(
-                            reconcileRequest, mSettings.mKeySetManagerService, mInjector);
+                            reconcileRequest, mSettings.getKeySetManagerService(), mInjector);
                 } catch (ReconcileFailure e) {
                     for (InstallRequest request : requests) {
                         request.installResult.setError("Reconciliation failed...", e);
@@ -17430,6 +17546,26 @@
                     resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),
                     /* updateReferenceProfileContent= */ true);
 
+            // Compute the compilation reason from the installation scenario.
+            final int compilationReason = mDexManager.getCompilationReasonForInstallScenario(
+                    reconciledPkg.installArgs.mInstallScenario);
+
+            // Construct the DexoptOptions early to see if we should skip running dexopt.
+            //
+            // Do not run PackageDexOptimizer through the local performDexOpt
+            // method because `pkg` may not be in `mPackages` yet.
+            //
+            // Also, don't fail application installs if the dexopt step fails.
+            final boolean isBackupOrRestore =
+                    reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_RESTORE
+                    || reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_SETUP;
+
+            final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
+                    | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE
+                    | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);
+            DexoptOptions dexoptOptions =
+                    new DexoptOptions(packageName, compilationReason, dexoptFlags);
+
             // Check whether we need to dexopt the app.
             //
             // NOTE: it is IMPORTANT to call dexopt:
@@ -17450,34 +17586,28 @@
             // continuous progress to the useur instead of mysteriously blocking somewhere in the
             // middle of running an instant app. The default behaviour can be overridden
             // via gservices.
+            //
+            // Furthermore, dexopt may be skipped, depending on the install scenario and current
+            // state of the device.
+            //
+            // TODO(b/174695087): instantApp and onIncremental should be removed and their install
+            //       path moved to SCENARIO_FAST.
             final boolean performDexopt =
                     (!instantApp || Global.getInt(mContext.getContentResolver(),
                     Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
                     && !pkg.isDebuggable()
-                    && (!onIncremental);
+                    && (!onIncremental)
+                    && dexoptOptions.isCompilationEnabled();
 
             if (performDexopt) {
                 // Compile the layout resources.
-                if (mInjector.getSystemWrapper().getPropertyBoolean(PRECOMPILE_LAYOUTS, false)) {
+                if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
                     mViewCompiler.compileLayouts(pkg);
                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                 }
 
                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
-                // Do not run PackageDexOptimizer through the local performDexOpt
-                // method because `pkg` may not be in `mPackages` yet.
-                //
-                // Also, don't fail application installs if the dexopt step fails.
-                int flags = DexoptOptions.DEXOPT_BOOT_COMPLETE
-                        | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
-                if (reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_RESTORE
-                        || reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_SETUP) {
-                    flags |= DexoptOptions.DEXOPT_FOR_RESTORE;
-                }
-                DexoptOptions dexoptOptions = new DexoptOptions(packageName,
-                        REASON_INSTALL,
-                        flags);
                 ScanResult result = reconciledPkg.scanResult;
 
                 // This mirrors logic from commitReconciledScanResultLocked, where the library files
@@ -17801,7 +17931,7 @@
 
         final SigningDetails sourceSigningDetails = (sourcePackageSetting == null
                 ? SigningDetails.UNKNOWN : sourcePackageSetting.getSigningDetails());
-        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+        final KeySetManagerService ksms = mSettings.getKeySetManagerService();
         if (sourcePackageName.equals(parsedPackage.getPackageName())
                 && (ksms.shouldCheckUpgradeKeySetLocked(
                 sourcePackageSetting, scanFlags))) {
@@ -17885,8 +18015,7 @@
 
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
         final ParsedPackage parsedPackage;
-        try (PackageParser2 pp = new PackageParser2(mSeparateProcesses, false, mMetrics, null,
-                mPackageParserCallback)) {
+        try (PackageParser2 pp = mInjector.getPreparingPackageParser()) {
             parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
             AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
         } catch (PackageParserException e) {
@@ -17935,8 +18064,8 @@
             if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
                 parsedPackage.setSigningDetails(args.signingDetails);
             } else {
-                parsedPackage.setSigningDetails(
-                        ParsingPackageUtils.getSigningDetails(parsedPackage, false /* skipVerify */));
+                parsedPackage.setSigningDetails(ParsingPackageUtils.getSigningDetails(
+                        parsedPackage, false /* skipVerify */));
             }
         } catch (PackageParserException e) {
             throw new PrepareFailure("Failed collect during installPackageLI", e);
@@ -18000,7 +18129,7 @@
                 }
             }
 
-            PackageSetting ps = mSettings.mPackages.get(pkgName);
+            PackageSetting ps = mSettings.getPackageLPr(pkgName);
             if (ps != null) {
                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
 
@@ -18019,7 +18148,7 @@
                 // Quick validity check that we're signed correctly if updating;
                 // we'll check this again later when scanning, but we want to
                 // bail early here before tripping over redefined permissions.
-                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+                final KeySetManagerService ksms = mSettings.getKeySetManagerService();
                 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
                     if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
                         throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
@@ -18200,7 +18329,7 @@
             scanFlags |= SCAN_MOVE;
 
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(pkgName);
+                final PackageSetting ps = mSettings.getPackageLPr(pkgName);
                 if (ps == null) {
                     res.setError(INSTALL_FAILED_INTERNAL_ERROR,
                             "Missing settings for moved package " + pkgName);
@@ -18229,7 +18358,7 @@
                 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
                         derivedAbi = mInjector.getAbiHelper().derivePackageAbi(parsedPackage,
                         isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
-                        abiOverride);
+                        abiOverride, mAppLib32InstallDir);
                 derivedAbi.first.applyTo(parsedPackage);
                 derivedAbi.second.applyTo(parsedPackage);
             } catch (PackageManagerException pme) {
@@ -18298,11 +18427,11 @@
                                 "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
                     }
 
-                    ps = mSettings.mPackages.get(pkgName11);
+                    ps = mSettings.getPackageLPr(pkgName11);
                     disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
 
                     // verify signatures are valid
-                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+                    final KeySetManagerService ksms = mSettings.getKeySetManagerService();
                     if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
                         if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) {
                             throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
@@ -18505,7 +18634,7 @@
         ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
         if (legacyMode) {
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
+                final PackageSetting ps = mSettings.getPackageLPr(pkg.getPackageName());
                 if (ps != null && ps.isPrivileged()) {
                     fsverityCandidates.put(pkg.getBaseApkPath(), null);
                     if (pkg.getSplitCodePaths() != null) {
@@ -18923,7 +19052,7 @@
         // Queue up an async operation since the package deletion may take a little while.
         mHandler.post(() -> {
             int returnCode;
-            final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
+            final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
             boolean doDeletePackage = true;
             if (ps != null) {
                 final boolean targetIsInstantApp =
@@ -19201,7 +19330,7 @@
         int[] allUsers;
         /** enabled state of the uninstalled application */
         synchronized (mLock) {
-            uninstalledPs = mSettings.mPackages.get(packageName);
+            uninstalledPs = mSettings.getPackageLPr(packageName);
             if (uninstalledPs == null) {
                 Slog.w(TAG, "Not removing non-existent package " + packageName);
                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
@@ -19500,7 +19629,7 @@
                 synchronized (mLock) {
                     clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true);
                     clearDefaultBrowserIfNeeded(packageName);
-                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
+                    mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName);
                     mAppsFilter.removePackage(getPackageSetting(packageName));
                     removedAppId = mSettings.removePackageLPw(packageName);
                     if (outInfo != null) {
@@ -19650,7 +19779,7 @@
                 // We've re-installed the stub; make sure it's disabled here. If package was
                 // originally enabled, we'll install the compressed version of the application
                 // and re-enable it afterward.
-                final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.getPackageName());
+                final PackageSetting stubPs = mSettings.getPackageLPr(deletedPkg.getPackageName());
                 if (stubPs != null) {
                     int userId = action.user == null
                             ? UserHandle.USER_ALL : action.user.getIdentifier();
@@ -19706,7 +19835,7 @@
 
         // writer
         synchronized (mLock) {
-            PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
+            PackageSetting ps = mSettings.getPackageLPr(pkg.getPackageName());
 
             final boolean applyUserRestrictions = origUserHandles != null;
             if (applyUserRestrictions) {
@@ -19799,7 +19928,7 @@
     @Override
     public boolean getBlockUninstallForUser(String packageName, int userId) {
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps == null || shouldFilterApplicationLocked(ps, Binder.getCallingUid(), userId)) {
                 return false;
             }
@@ -19811,7 +19940,7 @@
     public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
         enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
         synchronized (mLock) {
-            PackageSetting ps = mSettings.mPackages.get(packageName);
+            PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps == null) {
                 Log.w(TAG, "Package doesn't exist: " + packageName);
                 return false;
@@ -19879,7 +20008,7 @@
             ParsedPackage replacingPackage) {
         final DeletePackageAction action;
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
             action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user);
         }
@@ -20169,7 +20298,7 @@
         PackageSetting ps;
         synchronized (mLock) {
             pkg = mPackages.get(packageName);
-            ps = mSettings.mPackages.get(packageName);
+            ps = mSettings.getPackageLPr(packageName);
             if (pkg == null) {
                 if (ps != null) {
                     pkg = ps.pkg;
@@ -20306,7 +20435,7 @@
     private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
         final PackageSetting ps;
         synchronized (mLock) {
-            ps = mSettings.mPackages.get(packageName);
+            ps = mSettings.getPackageLPr(packageName);
             if (ps == null) {
                 Slog.w(TAG, "Failed to find settings for " + packageName);
                 return false;
@@ -20613,10 +20742,10 @@
     }
 
     private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
-        final String defaultBrowserPackageName = mPermissionManager.getDefaultBrowser(userId);
+        final String defaultBrowserPackageName = mDefaultAppProvider.getDefaultBrowser(userId);
         if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
             if (packageName.equals(defaultBrowserPackageName)) {
-                mPermissionManager.setDefaultBrowser(null, true, true, userId);
+                mDefaultAppProvider.setDefaultBrowser(null, true, userId);
             }
         }
     }
@@ -20631,14 +20760,13 @@
             // If this browser is restored from user's backup, do not clear
             // default-browser state for this user
             if (installReason != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
-                mPermissionManager.setDefaultBrowser(null, true, true, userId);
+                mDefaultAppProvider.setDefaultBrowser(null, true, userId);
             }
         }
 
         // We may also need to apply pending (restored) runtime permission grants
         // within these users.
-        mPermissionManager.restoreDelayedRuntimePermissions(packageName,
-                UserHandle.of(userId));
+        mPermissionManager.restoreDelayedRuntimePermissions(packageName, userId);
 
         // Persistent preferred activity might have came into effect due to this
         // install.
@@ -20670,7 +20798,7 @@
             // significant refactoring to keep all default apps in the package
             // manager (cleaner but more work) or have the services provide
             // callbacks to the package manager to request a default app reset.
-            mPermissionManager.setDefaultBrowser(null, true, true, userId);
+            mDefaultAppProvider.setDefaultBrowser(null, true, userId);
             resetNetworkPolicies(userId);
             synchronized (mLock) {
                 scheduleWritePackageRestrictionsLocked(userId);
@@ -20904,8 +21032,7 @@
                             defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
                         }
                         if (defaultBrowser != null) {
-                            mPermissionManager
-                                    .setDefaultBrowser(defaultBrowser, false, false, userId1);
+                            mDefaultAppProvider.setDefaultBrowser(defaultBrowser, false, userId1);
                         }
                     });
         } catch (Exception e) {
@@ -21145,7 +21272,7 @@
         }
         allHomeCandidates.addAll(resolveInfos);
 
-        final String packageName = mPermissionManager.getDefaultHome(userId);
+        final String packageName = mDefaultAppProvider.getDefaultHome(userId);
         if (packageName == null) {
             return null;
         }
@@ -21199,7 +21326,7 @@
         final String packageName = preferredResolveInfo != null
                 && preferredResolveInfo.activityInfo != null
                 ? preferredResolveInfo.activityInfo.packageName : null;
-        final String currentPackageName = mPermissionManager.getDefaultHome(userId);
+        final String currentPackageName = mDefaultAppProvider.getDefaultHome(userId);
         if (TextUtils.equals(currentPackageName, packageName)) {
             return false;
         }
@@ -21214,12 +21341,12 @@
             // Keep the default home package in RoleManager.
             return false;
         }
-        mPermissionManager.setDefaultHome(packageName, userId, (successful) -> {
-            if (successful) {
-                postPreferredActivityChangedBroadcast(userId);
-            }
-        });
-        return true;
+        return mDefaultAppProvider.setDefaultHome(packageName, userId, mContext.getMainExecutor(),
+                successful -> {
+                    if (successful) {
+                        postPreferredActivityChangedBroadcast(userId);
+                    }
+                });
     }
 
     @Override
@@ -21482,7 +21609,7 @@
     public void setUpdateAvailable(String packageName, boolean updateAvailable) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
         synchronized (mLock) {
-            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+            final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
             if (pkgSetting != null) {
                 pkgSetting.setUpdateAvailable(updateAvailable);
             }
@@ -21607,7 +21734,7 @@
 
         // reader
         synchronized (mLock) {
-            pkgSetting = mSettings.mPackages.get(packageName);
+            pkgSetting = mSettings.getPackageLPr(packageName);
             if (pkgSetting == null) {
                 if (!isCallerInstantApp) {
                     if (className == null) {
@@ -21871,7 +21998,7 @@
                 return;
             }
             broadcastAllowList = isInstantApp ? null : mAppsFilter.getVisibilityAllowList(setting,
-                    userIds, mSettings.mPackages);
+                    userIds, mSettings.getPackagesLocked());
         }
         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
                 userIds, instantUserIds, broadcastAllowList);
@@ -21891,7 +22018,7 @@
                 true /* checkShell */, "stop package");
         // writer
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (!shouldFilterApplicationLocked(ps, callingUid, userId)
                     && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
                             allowedByPermission, callingUid, userId)) {
@@ -21910,7 +22037,7 @@
             }
             String installerPackageName = installSource.installerPackageName;
             if (installerPackageName != null) {
-                final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
+                final PackageSetting ps = mSettings.getPackageLPr(installerPackageName);
                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
                         UserHandle.getUserId(callingUid))) {
                     installerPackageName = null;
@@ -21939,7 +22066,7 @@
 
             installerPackageName = installSource.installerPackageName;
             if (installerPackageName != null) {
-                final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
+                final PackageSetting ps = mSettings.getPackageLPr(installerPackageName);
                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                     installerPackageName = null;
                 }
@@ -21964,7 +22091,7 @@
                     initiatingPackageName = installerPackageName;
                 } else {
                     initiatingPackageName = installSource.initiatingPackageName;
-                    final PackageSetting ps = mSettings.mPackages.get(initiatingPackageName);
+                    final PackageSetting ps = mSettings.getPackageLPr(initiatingPackageName);
                     if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                         initiatingPackageName = null;
                     }
@@ -21973,7 +22100,7 @@
 
             originatingPackageName = installSource.originatingPackageName;
             if (originatingPackageName != null) {
-                final PackageSetting ps = mSettings.mPackages.get(originatingPackageName);
+                final PackageSetting ps = mSettings.getPackageLPr(originatingPackageName);
                 if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                     originatingPackageName = null;
                 }
@@ -22006,7 +22133,7 @@
     @GuardedBy("mLock")
     @Nullable
     private InstallSource getInstallSourceLocked(String packageName, int callingUid) {
-        final PackageSetting ps = mSettings.mPackages.get(packageName);
+        final PackageSetting ps = mSettings.getPackageLPr(packageName);
 
         // Installer info for Apex is not stored in PackageManager
         if (ps == null && mApexManager.isApexPackage(packageName)) {
@@ -22165,6 +22292,24 @@
 
         mPermissionManager.systemReady();
 
+        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
+        for (int userId : UserManagerService.getInstance().getUserIds()) {
+            if (mPmInternal.isPermissionUpgradeNeeded(userId)) {
+                grantPermissionsUserIds = ArrayUtils.appendInt(
+                        grantPermissionsUserIds, userId);
+            }
+        }
+        // If we upgraded grant all default permissions before kicking off.
+        for (int userId : grantPermissionsUserIds) {
+            mLegacyPermissionManager.grantDefaultPermissions(userId);
+        }
+        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
+            // If we did not grant default permissions, we preload from this the
+            // default permission exceptions lazily to ensure we don't hit the
+            // disk on a new user creation.
+            mLegacyPermissionManager.scheduleReadDefaultPermissionExceptions();
+        }
+
         if (mInstantAppResolverConnection != null) {
             mContext.registerReceiver(new BroadcastReceiver() {
                 @Override
@@ -22669,13 +22814,14 @@
                     && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
                     && packageName == null) {
                 pw.println();
-                int count = mSettings.mPackages.size();
+                int count = mSettings.getPackagesLocked().size();
                 if (count == 0) {
                     pw.println("No applications!");
                     pw.println();
                 } else {
                     final String prefix = "  ";
-                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
+                    Collection<PackageSetting> allPackageSettings =
+                            mSettings.getPackagesLocked().values();
                     if (allPackageSettings.size() == 0) {
                         pw.println("No domain preferred apps!");
                         pw.println();
@@ -22732,7 +22878,7 @@
             }
 
             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
-                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
+                mSettings.getKeySetManagerService().dumpLPr(pw, packageName, dumpState);
             }
 
             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
@@ -22863,7 +23009,7 @@
         if (ArrayUtils.isEmpty(apkList)) {
            return;
         }
-        String sku = mInjector.getSystemWrapper().getProperty("ro.boot.hardware.sku");
+        String sku = SystemProperties.get("ro.boot.hardware.sku");
         if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
             return;
         }
@@ -22959,7 +23105,7 @@
         ipw.increaseIndent();
         Collection<PackageSetting> pkgSettings;
         if (packageName != null) {
-            PackageSetting targetPkgSetting = mSettings.mPackages.get(packageName);
+            PackageSetting targetPkgSetting = mSettings.getPackageLPr(packageName);
             if (targetPkgSetting != null) {
                 pkgSettings = Collections.singletonList(targetPkgSetting);
             } else {
@@ -22967,7 +23113,7 @@
                 return;
             }
         } else {
-            pkgSettings = mSettings.mPackages.values();
+            pkgSettings = mSettings.getPackagesLocked().values();
         }
 
         for (PackageSetting pkgSetting : pkgSettings) {
@@ -23268,7 +23414,7 @@
             // Normalize package name to handle renamed packages
             packageName = normalizePackageNameLPr(packageName);
 
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (ps == null) {
                 throw new PackageManagerException("Package " + packageName + " is unknown");
             } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
@@ -23285,9 +23431,9 @@
     private List<String> collectAbsoluteCodePaths() {
         synchronized (mLock) {
             List<String> codePaths = new ArrayList<>();
-            final int packageCount = mSettings.mPackages.size();
+            final int packageCount = mSettings.getPackagesLocked().size();
             for (int i = 0; i < packageCount; i++) {
-                final PackageSetting ps = mSettings.mPackages.valueAt(i);
+                final PackageSetting ps = mSettings.getPackagesLocked().valueAt(i);
                 codePaths.add(ps.getPath().getAbsolutePath());
             }
             return codePaths;
@@ -23489,7 +23635,7 @@
     private void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
         final PackageSetting ps;
         synchronized (mLock) {
-            ps = mSettings.mPackages.get(pkg.getPackageName());
+            ps = mSettings.getPackageLPr(pkg.getPackageName());
             mSettings.writeKernelMappingLPr(ps);
         }
 
@@ -23566,7 +23712,7 @@
 
         final PackageSetting ps;
         synchronized (mLock) {
-            ps = mSettings.mPackages.get(pkg.getPackageName());
+            ps = mSettings.getPackageLPr(pkg.getPackageName());
         }
         final String volumeUuid = pkg.getVolumeUuid();
         final String packageName = pkg.getPackageName();
@@ -23761,7 +23907,7 @@
                 mPackageName = packageName;
                 mWeFroze = mFrozenPackages.add(mPackageName);
 
-                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
+                final PackageSetting ps = mSettings.getPackageLPr(mPackageName);
                 if (ps != null) {
                     killApplication(ps.name, ps.appId, userId, killReason);
                 }
@@ -23843,7 +23989,7 @@
         // reader
         synchronized (mLock) {
             final AndroidPackage pkg = mPackages.get(packageName);
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (pkg == null
                     || ps == null
                     || shouldFilterApplicationLocked(ps, callingUid, user.getIdentifier())) {
@@ -24174,9 +24320,9 @@
     private void removeUnusedPackagesLPw(UserManagerService userManager, final int userId) {
         final boolean DEBUG_CLEAN_APKS = false;
         int [] users = userManager.getUserIds();
-        final int numPackages = mSettings.mPackages.size();
+        final int numPackages = mSettings.getPackagesLocked().size();
         for (int index = 0; index < numPackages; index++) {
-            final PackageSetting ps = mSettings.mPackages.valueAt(index);
+            final PackageSetting ps = mSettings.getPackagesLocked().valueAt(index);
             if (ps.pkg == null) {
                 continue;
             }
@@ -24245,14 +24391,9 @@
             Slog.d(TAG, "onNewUserCreated(id=" + userId
                     + ", convertedFromPreCreated=" + convertedFromPreCreated + ")");
         }
-        if (!convertedFromPreCreated) {
-            mPermissionManager.onNewUserCreated(userId);
-            return;
-        }
-        if (!readPermissionStateForUser(userId)) {
-            // Could not read the existing permissions, re-grant them.
-            Slog.i(TAG, "re-granting permissions for pre-created user " + userId);
-            mPermissionManager.onNewUserCreated(userId);
+        if (!convertedFromPreCreated || !readPermissionStateForUser(userId)) {
+            mPermissionManager.onUserCreated(userId);
+            mLegacyPermissionManager.grantDefaultPermissions(userId);
         }
     }
 
@@ -24345,7 +24486,7 @@
                 Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
-            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+            final KeySetManagerService ksms = mSettings.getKeySetManagerService();
             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
         }
     }
@@ -24374,7 +24515,7 @@
                     && Process.SYSTEM_UID != callingUid) {
                 throw new SecurityException("May not access signing KeySet of other apps.");
             }
-            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+            final KeySetManagerService ksms = mSettings.getKeySetManagerService();
             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
         }
     }
@@ -24398,7 +24539,7 @@
             }
             IBinder ksh = ks.getToken();
             if (ksh instanceof KeySetHandle) {
-                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+                final KeySetManagerService ksms = mSettings.getKeySetManagerService();
                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
             }
             return false;
@@ -24424,7 +24565,7 @@
             }
             IBinder ksh = ks.getToken();
             if (ksh instanceof KeySetHandle) {
-                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
+                final KeySetManagerService ksms = mSettings.getKeySetManagerService();
                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
             }
             return false;
@@ -24433,7 +24574,7 @@
 
     @GuardedBy("mLock")
     private void deletePackageIfUnusedLPr(final String packageName) {
-        PackageSetting ps = mSettings.mPackages.get(packageName);
+        PackageSetting ps = mSettings.getPackageLPr(packageName);
         if (ps == null) {
             return;
         }
@@ -24769,7 +24910,7 @@
 
         @Override
         public boolean isPlatformSigned(String packageName) {
-            PackageSetting packageSetting = mSettings.mPackages.get(packageName);
+            PackageSetting packageSetting = mSettings.getPackageLPr(packageName);
             if (packageSetting == null) {
                 return false;
             }
@@ -24969,7 +25110,7 @@
         private String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
             switch (knownPackage) {
                 case PackageManagerInternal.PACKAGE_BROWSER:
-                    return new String[]{mPermissionManager.getDefaultBrowser(userId)};
+                    return new String[] { mDefaultAppProvider.getDefaultBrowser(userId) };
                 case PackageManagerInternal.PACKAGE_INSTALLER:
                     return filterOnlySystemPackages(mRequiredInstallerPackage);
                 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
@@ -25058,7 +25199,7 @@
         @Override
         public long getCeDataInode(String packageName, int userId) {
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 if (ps != null) {
                     return ps.getCeDataInode(userId);
                 }
@@ -25069,7 +25210,7 @@
         @Override
         public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 final Bundle allExtras = new Bundle();
                 if (ps != null) {
                     final PackageUserState pus = ps.readUserState(userId);
@@ -25091,7 +25232,7 @@
         @Override
         public boolean isPackageSuspended(String packageName, int userId) {
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 return (ps != null) ? ps.getSuspended(userId) : false;
             }
         }
@@ -25136,7 +25277,7 @@
         @Override
         public String getSuspendingPackage(String suspendedPackage, int userId) {
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
+                final PackageSetting ps = mSettings.getPackageLPr(suspendedPackage);
                 if (ps != null) {
                     final PackageUserState pus = ps.readUserState(userId);
                     if (pus.suspended) {
@@ -25158,7 +25299,7 @@
         public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
                 String suspendingPackage, int userId) {
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
+                final PackageSetting ps = mSettings.getPackageLPr(suspendedPackage);
                 if (ps != null) {
                     final PackageUserState pus = ps.readUserState(userId);
                     if (pus.suspended) {
@@ -25174,7 +25315,7 @@
         @Override
         public int getDistractingPackageRestrictions(String packageName, int userId) {
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 return (ps != null) ? ps.getDistractionFlags(userId) : RESTRICTION_NONE;
             }
         }
@@ -25270,7 +25411,7 @@
         @Override
         public boolean isPackageEphemeral(int userId, String packageName) {
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(packageName);
+                final PackageSetting ps = mSettings.getPackageLPr(packageName);
                 return ps != null ? ps.getInstantApp(userId) : false;
             }
         }
@@ -25461,7 +25602,7 @@
                             continue;
                         }
                         for (VersionedPackage dependent : dependents) {
-                            final PackageSetting ps = mSettings.mPackages.get(
+                            final PackageSetting ps = mSettings.getPackageLPr(
                                     dependent.getPackageName());
                             if (ps == null) {
                                 continue;
@@ -25472,7 +25613,7 @@
                     }
                 }
 
-                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
+                final PackageSetting ps = mSettings.getPackageLPr(targetPackageName);
                 ps.setOverlayPaths(overlayPaths, userId);
 
                 outUpdatedPackageNames.add(targetPackageName);
@@ -25542,7 +25683,7 @@
         @Override
         public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
             synchronized (mLock) {
-                final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
+                final PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
                 return ps != null && !PackageManagerService.this.shouldFilterApplicationLocked(
                         ps, callingUid, component, TYPE_UNKNOWN, userId);
             }
@@ -25608,8 +25749,8 @@
         @Override
         public void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
             synchronized (mLock) {
-                for (int index = 0; index < mSettings.mPackages.size(); index++) {
-                    actionLocked.accept(mSettings.mPackages.valueAt(index));
+                for (int index = 0; index < mSettings.getPackagesLocked().size(); index++) {
+                    actionLocked.accept(mSettings.getPackagesLocked().valueAt(index));
                 }
             }
         }
@@ -25785,7 +25926,7 @@
                     return false;
                 }
                 final PackageSetting installerPackageSetting =
-                        mSettings.mPackages.get(packageSetting.installSource.installerPackageName);
+                        mSettings.getPackageLPr(packageSetting.installSource.installerPackageName);
                 return installerPackageSetting != null
                         && UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
             }
@@ -25799,18 +25940,6 @@
         }
 
         @Override
-        public void setReadExternalStorageEnforced(boolean enforced) {
-            synchronized (mLock) {
-                if (mSettings.mReadExternalStorageEnforced != null
-                        && mSettings.mReadExternalStorageEnforced == enforced) {
-                    return;
-                }
-                mSettings.mReadExternalStorageEnforced = enforced ? Boolean.TRUE : Boolean.FALSE;
-                writeSettingsLPrTEMP();
-            }
-        }
-
-        @Override
         public void setIntegrityVerificationResult(int verificationId, int verificationResult) {
             final Message msg = mHandler.obtainMessage(INTEGRITY_VERIFICATION_COMPLETE);
             msg.arg1 = verificationId;
@@ -25886,7 +26015,7 @@
                 PackageManagerInternal.InstalledLoadingProgressCallback callback) {
             final PackageSetting ps;
             synchronized (mLock) {
-                ps = mSettings.mPackages.get(packageName);
+                ps = mSettings.getPackageLPr(packageName);
                 if (ps == null) {
                     Slog.w(TAG, "Failed unregistering loading progress callback. Package "
                             + packageName + " is not installed");
@@ -25949,7 +26078,7 @@
     @GuardedBy("mLock")
     @NonNull
     private String[] getSharedUserPackagesForPackageLocked(String packageName, int userId) {
-        final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
+        final PackageSetting packageSetting = mSettings.getPackageLPr(packageName);
         if (packageSetting == null || !packageSetting.isSharedUser()) {
             return EmptyArray.STRING;
         }
@@ -26026,7 +26155,7 @@
         synchronized (mLock) {
             packageName = resolveInternalPackageNameInternalLocked(
                     packageName, PackageManager.VERSION_CODE_HIGHEST, callingUid);
-            return mSettings.mPackages.get(packageName);
+            return mSettings.getPackageLPr(packageName);
         }
     }
 
@@ -26117,7 +26246,7 @@
         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
                 false /* checkShell */, "get install reason");
         synchronized (mLock) {
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            final PackageSetting ps = mSettings.getPackageLPr(packageName);
             if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                 return PackageManager.INSTALL_REASON_UNKNOWN;
             }
@@ -26290,7 +26419,7 @@
         long currentTimeInMillis = System.currentTimeMillis();
         synchronized (mLock) {
             for (AndroidPackage pkg : mPackages.values()) {
-                PackageSetting ps =  mSettings.mPackages.get(pkg.getPackageName());
+                PackageSetting ps =  mSettings.getPackageLPr(pkg.getPackageName());
                 if (ps == null) {
                     continue;
                 }
@@ -26402,7 +26531,7 @@
 
     @Override
     public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
-        boolean changed = mSettings.mPackages.get(packageName)
+        boolean changed = mSettings.getPackageLPr(packageName)
                 .setMimeGroup(mimeGroup, mimeTypes);
 
         if (changed) {
@@ -26412,7 +26541,7 @@
 
     @Override
     public List<String> getMimeGroup(String packageName, String mimeGroup) {
-        return mSettings.mPackages.get(packageName).getMimeGroup(mimeGroup);
+        return mSettings.getPackageLPr(packageName).getMimeGroup(mimeGroup);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index 5fc5bac..9cd55a6 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -18,6 +18,8 @@
 
 import android.os.SystemProperties;
 
+import com.android.server.pm.dex.DexoptOptions;
+
 import dalvik.system.DexFile;
 
 /**
@@ -26,10 +28,22 @@
 public class PackageManagerServiceCompilerMapping {
     // Names for compilation reasons.
     public static final String REASON_STRINGS[] = {
-            "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "inactive", "shared"
+        "first-boot",
+        "boot",
+        "install",
+        "install-fast",
+        "install-bulk",
+        "install-bulk-secondary",
+        "install-bulk-downgraded",
+        "install-bulk-secondary-downgraded",
+        "bg-dexopt",
+        "ab-ota",
+        "inactive",
+        // "shared" must be the last entry
+        "shared"
     };
 
-    static final int REASON_SHARED_INDEX = 6;
+    static final int REASON_SHARED_INDEX = REASON_STRINGS.length - 1;
 
     // Static block to ensure the strings array is of the right length.
     static {
@@ -53,8 +67,9 @@
     // exception in case the reason or value are invalid.
     private static String getAndCheckValidity(int reason) {
         String sysPropValue = SystemProperties.get(getSystemPropertyName(reason));
-        if (sysPropValue == null || sysPropValue.isEmpty() ||
-                !DexFile.isValidCompilerFilter(sysPropValue)) {
+        if (sysPropValue == null || sysPropValue.isEmpty()
+                || !(sysPropValue.equals(DexoptOptions.COMPILER_FILTER_NOOP)
+                        || DexFile.isValidCompilerFilter(sysPropValue))) {
             throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid "
                     + "(reason " + REASON_STRINGS[reason] + ")");
         } else if (!isFilterAllowedForReason(reason, sysPropValue)) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 9f1d656..c77eda1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -819,8 +819,8 @@
     /**
      * Parse given package and return minimal details.
      */
-    public static PackageInfoLite getMinimalPackageInfo(Context context, String packagePath,
-            int flags, String abiOverride) {
+    public static PackageInfoLite getMinimalPackageInfo(Context context,
+            PackageParser.PackageLite pkg, String packagePath, int flags, String abiOverride) {
         final PackageInfoLite ret = new PackageInfoLite();
         if (packagePath == null) {
             Slog.i(TAG, "Invalid package file " + packagePath);
@@ -829,14 +829,10 @@
         }
 
         final File packageFile = new File(packagePath);
-        final PackageParser.PackageLite pkg;
         final long sizeBytes;
         try {
-            pkg = PackageParser.parsePackageLite(packageFile, 0);
             sizeBytes = PackageHelper.calculateInstalledSize(pkg, abiOverride);
-        } catch (PackageParserException | IOException e) {
-            Slog.w(TAG, "Failed to parse package at " + packagePath + ": " + e);
-
+        } catch (IOException e) {
             if (!packageFile.exists()) {
                 ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_URI;
             } else {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 9720819a..318b229 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -553,7 +553,8 @@
                                     + apkLiteResult.getErrorMessage(),
                             apkLiteResult.getException());
                 }
-                PackageLite pkgLite = new PackageLite(null, apkLiteResult.getResult(), null, null,
+                final ApkLite apkLite = apkLiteResult.getResult();
+                PackageLite pkgLite = new PackageLite(null, apkLite.codePath, apkLite, null, null,
                         null, null, null, null);
                 sessionSize += PackageHelper.calculateInstalledSize(pkgLite,
                         params.sessionParams.abiOverride, fd.getFileDescriptor());
@@ -2323,7 +2324,7 @@
             getErrPrintWriter().println("Error: no enforcement specified");
             return 1;
         }
-        mPermissionManager.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
+        // Permissions are always enforced now.
         return 0;
     }
 
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index f47b4b4..2d5034e 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -362,8 +362,6 @@
         }
     }
 
-    Boolean mReadExternalStorageEnforced;
-
     /** Device identity for the purpose of package verification. */
     private VerifierDeviceIdentity mVerifierDeviceIdentity;
 
@@ -475,6 +473,14 @@
         return mPackages.get(pkgName);
     }
 
+    ArrayMap<String, PackageSetting> getPackagesLocked() {
+        return mPackages;
+    }
+
+    KeySetManagerService getKeySetManagerService() {
+        return mKeySetManagerService;
+    }
+
     String getRenamedPackageLPr(String pkgName) {
         return mRenamedPackages.get(pkgName);
     }
@@ -1969,28 +1975,28 @@
                     serializer.attributeLong(null, ATTR_CE_DATA_INODE, ustate.ceDataInode);
                 }
                 if (!ustate.installed) {
-                    serializer.attribute(null, ATTR_INSTALLED, "false");
+                    serializer.attributeBoolean(null, ATTR_INSTALLED, false);
                 }
                 if (ustate.stopped) {
-                    serializer.attribute(null, ATTR_STOPPED, "true");
+                    serializer.attributeBoolean(null, ATTR_STOPPED, true);
                 }
                 if (ustate.notLaunched) {
-                    serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
+                    serializer.attributeBoolean(null, ATTR_NOT_LAUNCHED, true);
                 }
                 if (ustate.hidden) {
-                    serializer.attribute(null, ATTR_HIDDEN, "true");
+                    serializer.attributeBoolean(null, ATTR_HIDDEN, true);
                 }
                 if (ustate.distractionFlags != 0) {
                     serializer.attributeInt(null, ATTR_DISTRACTION_FLAGS, ustate.distractionFlags);
                 }
                 if (ustate.suspended) {
-                    serializer.attribute(null, ATTR_SUSPENDED, "true");
+                    serializer.attributeBoolean(null, ATTR_SUSPENDED, true);
                 }
                 if (ustate.instantApp) {
-                    serializer.attribute(null, ATTR_INSTANT_APP, "true");
+                    serializer.attributeBoolean(null, ATTR_INSTANT_APP, true);
                 }
                 if (ustate.virtualPreload) {
-                    serializer.attribute(null, ATTR_VIRTUAL_PRELOAD, "true");
+                    serializer.attributeBoolean(null, ATTR_VIRTUAL_PRELOAD, true);
                 }
                 if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
                     serializer.attributeInt(null, ATTR_ENABLED, ustate.enabled);
@@ -2334,13 +2340,6 @@
                 serializer.endTag(null, "verifier");
             }
 
-            if (mReadExternalStorageEnforced != null) {
-                serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
-                serializer.attribute(
-                        null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
-                serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
-            }
-
             serializer.startTag(null, "permission-trees");
             mPermissions.writePermissionTrees(serializer);
             serializer.endTag(null, "permission-trees");
@@ -2731,7 +2730,7 @@
             serializer.attributeInt(null, "sharedUserId", pkg.appId);
         }
         if (pkg.uidError) {
-            serializer.attribute(null, "uidError", "true");
+            serializer.attributeBoolean(null, "uidError", true);
         }
         InstallSource installSource = pkg.installSource;
         if (installSource.installerPackageName != null) {
@@ -2742,13 +2741,13 @@
                     installSource.installerAttributionTag);
         }
         if (installSource.isOrphaned) {
-            serializer.attribute(null, "isOrphaned", "true");
+            serializer.attributeBoolean(null, "isOrphaned", true);
         }
         if (installSource.initiatingPackageName != null) {
             serializer.attribute(null, "installInitiator", installSource.initiatingPackageName);
         }
         if (installSource.isInitiatingPackageUninstalled) {
-            serializer.attribute(null, "installInitiatorUninstalled", "true");
+            serializer.attributeBoolean(null, "installInitiatorUninstalled", true);
         }
         if (installSource.originatingPackageName != null) {
             serializer.attribute(null, "installOriginator", installSource.originatingPackageName);
@@ -2760,16 +2759,16 @@
             serializer.attributeInt(null, "categoryHint", pkg.categoryHint);
         }
         if (pkg.updateAvailable) {
-            serializer.attribute(null, "updateAvailable", "true");
+            serializer.attributeBoolean(null, "updateAvailable", true);
         }
         if (pkg.forceQueryableOverride) {
-            serializer.attribute(null, "forceQueryable", "true");
+            serializer.attributeBoolean(null, "forceQueryable", true);
         }
         if (pkg.isPackageStartable()) {
-            serializer.attribute(null, "isStartable", "true");
+            serializer.attributeBoolean(null, "isStartable", true);
         }
         if (pkg.isPackageLoading()) {
-            serializer.attribute(null, "isLoading", "true");
+            serializer.attributeBoolean(null, "isLoading", true);
         }
 
         writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
@@ -2951,9 +2950,7 @@
                                 + e.getMessage());
                     }
                 } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
-                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
-                    mReadExternalStorageEnforced =
-                            "1".equals(enforcement) ? Boolean.TRUE : Boolean.FALSE;
+                    // No longer used.
                 } else if (tagName.equals("keyset-settings")) {
                     mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs);
                 } else if (TAG_VERSION.equals(tagName)) {
@@ -3500,14 +3497,14 @@
         String systemStr = null;
         String installerPackageName = null;
         String installerAttributionTag = null;
-        String isOrphaned = null;
+        boolean isOrphaned = false;
         String installOriginatingPackageName = null;
         String installInitiatingPackageName = null;
-        String installInitiatorUninstalled = null;
+        boolean installInitiatorUninstalled = false;
         String volumeUuid = null;
-        String updateAvailable = null;
+        boolean updateAvailable = false;
         int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
-        String uidError = null;
+        boolean uidError = false;
         int pkgFlags = 0;
         int pkgPrivateFlags = 0;
         long timeStamp = 0;
@@ -3515,14 +3512,14 @@
         long lastUpdateTime = 0;
         PackageSetting packageSetting = null;
         long versionCode = 0;
-        String installedForceQueryable = null;
-        String isStartable = null;
-        String isLoading = null;
+        boolean installedForceQueryable = false;
+        boolean isStartable = false;
+        boolean isLoading = false;
         try {
             name = parser.getAttributeValue(null, ATTR_NAME);
             realName = parser.getAttributeValue(null, "realName");
             userId = parser.getAttributeInt(null, "userId", 0);
-            uidError = parser.getAttributeValue(null, "uidError");
+            uidError = parser.getAttributeBoolean(null, "uidError", false);
             sharedUserId = parser.getAttributeInt(null, "sharedUserId", 0);
             codePathStr = parser.getAttributeValue(null, "codePath");
 
@@ -3532,10 +3529,10 @@
             primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
             secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
             cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
-            updateAvailable = parser.getAttributeValue(null, "updateAvailable");
-            installedForceQueryable = parser.getAttributeValue(null, "forceQueryable");
-            isStartable = parser.getAttributeValue(null, "isStartable");
-            isLoading = parser.getAttributeValue(null, "isLoading");
+            updateAvailable = parser.getAttributeBoolean(null, "updateAvailable", false);
+            installedForceQueryable = parser.getAttributeBoolean(null, "forceQueryable", false);
+            isStartable = parser.getAttributeBoolean(null, "isStartable", false);
+            isLoading = parser.getAttributeBoolean(null, "isLoading", false);
 
             if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
                 primaryCpuAbiString = legacyCpuAbiString;
@@ -3544,11 +3541,11 @@
             versionCode = parser.getAttributeLong(null, "version", 0);
             installerPackageName = parser.getAttributeValue(null, "installer");
             installerAttributionTag = parser.getAttributeValue(null, "installerAttributionTag");
-            isOrphaned = parser.getAttributeValue(null, "isOrphaned");
+            isOrphaned = parser.getAttributeBoolean(null, "isOrphaned", false);
             installInitiatingPackageName = parser.getAttributeValue(null, "installInitiator");
             installOriginatingPackageName = parser.getAttributeValue(null, "installOriginator");
-            installInitiatorUninstalled = parser.getAttributeValue(null,
-                    "installInitiatorUninstalled");
+            installInitiatorUninstalled = parser.getAttributeBoolean(null,
+                    "installInitiatorUninstalled", false);
             volumeUuid = parser.getAttributeValue(null, "volumeUuid");
             categoryHint = parser.getAttributeInt(null, "categoryHint",
                     ApplicationInfo.CATEGORY_UNDEFINED);
@@ -3670,21 +3667,20 @@
                             + userId + " at " + parser.getPositionDescription());
         }
         if (packageSetting != null) {
-            packageSetting.uidError = "true".equals(uidError);
+            packageSetting.uidError = uidError;
             InstallSource installSource = InstallSource.create(
                     installInitiatingPackageName, installOriginatingPackageName,
-                    installerPackageName, installerAttributionTag, "true".equals(isOrphaned),
-                    "true".equals(installInitiatorUninstalled));
+                    installerPackageName, installerAttributionTag, isOrphaned,
+                    installInitiatorUninstalled);
             packageSetting.installSource = installSource;
             packageSetting.volumeUuid = volumeUuid;
             packageSetting.categoryHint = categoryHint;
             packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
             packageSetting.primaryCpuAbiString = primaryCpuAbiString;
             packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
-            packageSetting.updateAvailable = "true".equals(updateAvailable);
-            packageSetting.forceQueryableOverride = "true".equals(installedForceQueryable);
-            packageSetting.incrementalStates = new IncrementalStates("true".equals(isStartable),
-                    "true".equals(isLoading));
+            packageSetting.updateAvailable = updateAvailable;
+            packageSetting.forceQueryableOverride = installedForceQueryable;
+            packageSetting.incrementalStates = new IncrementalStates(isStartable, isLoading);
             // Handle legacy string here for single-user mode
             final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
             if (enabledStr != null) {
@@ -3914,7 +3910,7 @@
         {
             name = parser.getAttributeValue(null, ATTR_NAME);
             int userId = parser.getAttributeInt(null, "userId", 0);
-            if ("true".equals(parser.getAttributeValue(null, "system"))) {
+            if (parser.getAttributeBoolean(null, "system", false)) {
                 pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
             }
             if (name == null) {
@@ -4893,8 +4889,7 @@
             DumpState dumpState) {
         LegacyPermissionSettings.dumpPermissions(pw, packageName, permissionNames,
                 mPermissionDataProvider.getLegacyPermissions(),
-                mPermissionDataProvider.getAllAppOpPermissionPackages(),
-                (mReadExternalStorageEnforced == Boolean.TRUE), dumpState);
+                mPermissionDataProvider.getAllAppOpPermissionPackages(), true, dumpState);
     }
 
     void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
@@ -5554,7 +5549,8 @@
         return mPreferredActivities.get(userId);
     }
 
-    CrossProfileIntentResolver getCrossProfileIntentResolvers(int userId) {
+    @Nullable
+    CrossProfileIntentResolver getCrossProfileIntentResolver(int userId) {
         return mCrossProfileIntentResolvers.get(userId);
     }
 
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index 7d48d0a..e913829 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -30,6 +30,14 @@
       ]
     },
     {
+      "name": "FrameworksMockingServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.pm."
+        }
+      ]
+    },
+    {
       "name": "CtsContentTestCases",
       "options": [
         {
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index 47d0a3d5..c182d68 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -57,6 +57,20 @@
     }
 
     /**
+     * Listener for user lifecycle events.
+     *
+     * <p><b>NOTE: </b>implementations MUST not block the current thread.
+     */
+    public interface UserLifecycleListener {
+
+        /** Called when a new user is created. */
+        default void onUserCreated(UserInfo user) {}
+
+        /** Called when an existing user is removed. */
+        default void onUserRemoved(UserInfo user) {}
+    }
+
+    /**
      * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to set
      * restrictions enforced by the user.
      *
@@ -97,6 +111,12 @@
     /** Remove a {@link UserRestrictionsListener}. */
     public abstract void removeUserRestrictionsListener(UserRestrictionsListener listener);
 
+    /** Adds a {@link UserLifecycleListener}. */
+    public abstract void addUserLifecycleListener(UserLifecycleListener listener);
+
+    /** Removes a {@link UserLifecycleListener}. */
+    public abstract void removeUserLifecycleListener(UserLifecycleListener listener);
+
     /**
      * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to update
      * whether the device is managed by device owner.
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index cc814bcc..ccbf73c 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -110,6 +110,7 @@
 import com.android.server.LockGuard;
 import com.android.server.SystemService;
 import com.android.server.am.UserState;
+import com.android.server.pm.UserManagerInternal.UserLifecycleListener;
 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
 import com.android.server.storage.DeviceStorageMonitorInternal;
 import com.android.server.utils.TimingsTraceAndSlog;
@@ -438,6 +439,9 @@
     private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners =
             new ArrayList<>();
 
+    @GuardedBy("mUserRemovedListeners")
+    private final ArrayList<UserLifecycleListener> mUserLifecycleListeners = new ArrayList<>();
+
     private final LockPatternUtils mLockPatternUtils;
 
     private final String ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK =
@@ -2918,16 +2922,16 @@
             serializer.attribute(null,  ATTR_ICON_PATH, userInfo.iconPath);
         }
         if (userInfo.partial) {
-            serializer.attribute(null, ATTR_PARTIAL, "true");
+            serializer.attributeBoolean(null, ATTR_PARTIAL, true);
         }
         if (userInfo.preCreated) {
-            serializer.attribute(null, ATTR_PRE_CREATED, "true");
+            serializer.attributeBoolean(null, ATTR_PRE_CREATED, true);
         }
         if (userInfo.convertedFromPreCreated) {
-            serializer.attribute(null, ATTR_CONVERTED_FROM_PRE_CREATED, "true");
+            serializer.attributeBoolean(null, ATTR_CONVERTED_FROM_PRE_CREATED, true);
         }
         if (userInfo.guestToRemove) {
-            serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true");
+            serializer.attributeBoolean(null, ATTR_GUEST_TO_REMOVE, true);
         }
         if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
             serializer.attributeInt(null, ATTR_PROFILE_GROUP_ID, userInfo.profileGroupId);
@@ -3121,22 +3125,10 @@
             profileBadge = parser.getAttributeInt(null, ATTR_PROFILE_BADGE, 0);
             restrictedProfileParentId = parser.getAttributeInt(null,
                     ATTR_RESTRICTED_PROFILE_PARENT_ID, UserInfo.NO_PROFILE_GROUP_ID);
-            String valueString = parser.getAttributeValue(null, ATTR_PARTIAL);
-            if ("true".equals(valueString)) {
-                partial = true;
-            }
-            valueString = parser.getAttributeValue(null, ATTR_PRE_CREATED);
-            if ("true".equals(valueString)) {
-                preCreated = true;
-            }
-            valueString = parser.getAttributeValue(null, ATTR_CONVERTED_FROM_PRE_CREATED);
-            if ("true".equals(valueString)) {
-                converted = true;
-            }
-            valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE);
-            if ("true".equals(valueString)) {
-                guestToRemove = true;
-            }
+            partial = parser.getAttributeBoolean(null, ATTR_PARTIAL, false);
+            preCreated = parser.getAttributeBoolean(null, ATTR_PRE_CREATED, false);
+            converted = parser.getAttributeBoolean(null, ATTR_CONVERTED_FROM_PRE_CREATED, false);
+            guestToRemove = parser.getAttributeBoolean(null, ATTR_GUEST_TO_REMOVE, false);
 
             seedAccountName = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_NAME);
             seedAccountType = parser.getAttributeValue(null, ATTR_SEED_ACCOUNT_TYPE);
@@ -3645,6 +3637,14 @@
     }
 
     private void dispatchUserAdded(@NonNull UserInfo userInfo) {
+        // Notify internal listeners first...
+        synchronized (mUserLifecycleListeners) {
+            for (int i = 0; i < mUserLifecycleListeners.size(); i++) {
+                mUserLifecycleListeners.get(i).onUserCreated(userInfo);
+            }
+        }
+
+        //...then external ones
         Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
         addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id);
         // Also, add the UserHandle for mainline modules which can't use the @hide
@@ -4030,13 +4030,19 @@
             user = getUserInfoLU(userId);
         }
         if (user != null && user.preCreated) {
-            Slog.i(LOG_TAG, "Removing a precreated user with user id: " + userId);
+            Slog.i(LOG_TAG, "Removing a pre-created user with user id: " + userId);
             // Don't want to fire ACTION_USER_REMOVED, so cleanup the state and exit early.
             LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
             removeUserState(userId);
             return;
         }
 
+        synchronized (mUserLifecycleListeners) {
+            for (int i = 0; i < mUserLifecycleListeners.size(); i++) {
+                mUserLifecycleListeners.get(i).onUserRemoved(user);
+            }
+        }
+
         // Let other services shutdown any activity and clean up their state before completely
         // wiping the user's system directory and removing from the user list
         final long ident = Binder.clearCallingIdentity();
@@ -4257,10 +4263,9 @@
         if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
             String key = parser.getAttributeValue(null, ATTR_KEY);
             String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE);
-            String multiple = parser.getAttributeValue(null, ATTR_MULTIPLE);
-            if (multiple != null) {
+            int count = parser.getAttributeInt(null, ATTR_MULTIPLE, -1);
+            if (count != -1) {
                 values.clear();
-                int count = Integer.parseInt(multiple);
                 while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
                     if (type == XmlPullParser.START_TAG
                             && parser.getName().equals(TAG_VALUE)) {
@@ -4973,6 +4978,15 @@
             pw.println("  System user allocations: " + mUser0Allocations.get());
         }
 
+        pw.println();
+        pw.println("Number of listeners for");
+        synchronized (mUserRestrictionsListeners) {
+            pw.println("  restrictions: " + mUserRestrictionsListeners.size());
+        }
+        synchronized (mUserLifecycleListeners) {
+            pw.println("  user lifecycle events: " + mUserLifecycleListeners.size());
+        }
+
         // Dump UserTypes
         pw.println();
         pw.println("User types version: " + mUserTypeVersion);
@@ -5091,6 +5105,20 @@
         }
 
         @Override
+        public void addUserLifecycleListener(UserLifecycleListener listener) {
+            synchronized (mUserLifecycleListeners) {
+                mUserLifecycleListeners.add(listener);
+            }
+        }
+
+        @Override
+        public void removeUserLifecycleListener(UserLifecycleListener listener) {
+            synchronized (mUserLifecycleListeners) {
+                mUserLifecycleListeners.remove(listener);
+            }
+        }
+
+        @Override
         public void setDeviceManaged(boolean isManaged) {
             synchronized (mUsersLock) {
                 mIsDeviceManaged = isManaged;
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 0ac3030..51dff40 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -344,7 +344,7 @@
             }
             if (USER_RESTRICTIONS.contains(key)) {
                 if (restrictions.getBoolean(key)) {
-                    serializer.attribute(null, key, "true");
+                    serializer.attributeBoolean(null, key, true);
                 }
                 continue;
             }
@@ -360,9 +360,9 @@
     public static void readRestrictions(TypedXmlPullParser parser, Bundle restrictions) {
         restrictions.clear();
         for (String key : USER_RESTRICTIONS) {
-            final String value = parser.getAttributeValue(null, key);
-            if (value != null) {
-                restrictions.putBoolean(key, Boolean.parseBoolean(value));
+            final boolean value = parser.getAttributeBoolean(null, key, false);
+            if (value) {
+                restrictions.putBoolean(key, true);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java
index 1d3aecd..1ffbf60 100644
--- a/services/core/java/com/android/server/pm/UserTypeFactory.java
+++ b/services/core/java/com/android/server/pm/UserTypeFactory.java
@@ -30,6 +30,7 @@
 import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
 import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
 import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
+import static android.os.UserManager.USER_TYPE_PROFILE_TEST;
 import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS;
 
 import static com.android.server.pm.UserTypeDetails.UNLIMITED_NUMBER_OF_USERS;
@@ -37,6 +38,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.UserManager;
 import android.util.ArrayMap;
@@ -98,6 +100,9 @@
         builders.put(USER_TYPE_FULL_DEMO, getDefaultTypeFullDemo());
         builders.put(USER_TYPE_FULL_RESTRICTED, getDefaultTypeFullRestricted());
         builders.put(USER_TYPE_SYSTEM_HEADLESS, getDefaultTypeSystemHeadless());
+        if (Build.IS_DEBUGGABLE) {
+            builders.put(USER_TYPE_PROFILE_TEST, getDefaultTypeProfileTest());
+        }
 
         return builders;
     }
@@ -132,6 +137,37 @@
     }
 
     /**
+     * Returns the Builder for the default {@link UserManager#USER_TYPE_PROFILE_TEST}
+     * configuration (for userdebug builds). For now it just uses managed profile badges.
+     */
+    private static UserTypeDetails.Builder getDefaultTypeProfileTest() {
+        final Bundle restrictions = new Bundle();
+        restrictions.putBoolean(UserManager.DISALLOW_FUN, true);
+
+        return new UserTypeDetails.Builder()
+                .setName(USER_TYPE_PROFILE_TEST)
+                .setBaseType(FLAG_PROFILE)
+                .setMaxAllowedPerParent(2)
+                .setLabel(0)
+                .setIconBadge(com.android.internal.R.drawable.ic_corp_icon_badge_case)
+                .setBadgePlain(com.android.internal.R.drawable.ic_corp_badge_case)
+                .setBadgeNoBackground(com.android.internal.R.drawable.ic_corp_badge_no_background)
+                .setBadgeLabels(
+                        com.android.internal.R.string.managed_profile_label_badge,
+                        com.android.internal.R.string.managed_profile_label_badge_2,
+                        com.android.internal.R.string.managed_profile_label_badge_3)
+                .setBadgeColors(
+                        com.android.internal.R.color.profile_badge_1,
+                        com.android.internal.R.color.profile_badge_2,
+                        com.android.internal.R.color.profile_badge_3)
+                .setDarkThemeBadgeColors(
+                        com.android.internal.R.color.profile_badge_1_dark,
+                        com.android.internal.R.color.profile_badge_2_dark,
+                        com.android.internal.R.color.profile_badge_3_dark)
+                .setDefaultRestrictions(restrictions);
+    }
+
+    /**
      * Returns the Builder for the default {@link UserManager#USER_TYPE_FULL_SECONDARY}
      * configuration.
      */
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index fadd0c8..139654e 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -579,6 +579,8 @@
     // Constants used for logging compilation reason to TRON.
     // DO NOT CHANGE existing values.
     //
+    // In the below constants, the abbreviation DM stands for "DEX metadata".
+    //
     // NOTE: '-1' value is reserved for the case where we cannot produce a valid
     // PackageOptimizationInfo because the ArtManagerInternal is not ready to be used by the
     // ActivityMetricsLoggers.
@@ -591,7 +593,18 @@
     private static final int TRON_COMPILATION_REASON_AB_OTA = 6;
     private static final int TRON_COMPILATION_REASON_INACTIVE = 7;
     private static final int TRON_COMPILATION_REASON_SHARED = 8;
-    private static final int TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA = 9;
+    private static final int TRON_COMPILATION_REASON_INSTALL_WITH_DM = 9;
+    private static final int TRON_COMPILATION_REASON_INSTALL_FAST = 10;
+    private static final int TRON_COMPILATION_REASON_INSTALL_BULK = 11;
+    private static final int TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY = 12;
+    private static final int TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED = 13;
+    private static final int TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED = 14;
+    private static final int TRON_COMPILATION_REASON_INSTALL_FAST_WITH_DM = 15;
+    private static final int TRON_COMPILATION_REASON_INSTALL_BULK_WITH_DM = 16;
+    private static final int TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_WITH_DM = 17;
+    private static final int TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED_WITH_DM = 18;
+    private static final int
+            TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED_WITH_DM = 19;
 
     // The annotation to add as a suffix to the compilation reason when dexopt was
     // performed with dex metadata.
@@ -611,10 +624,30 @@
             case "ab-ota" : return TRON_COMPILATION_REASON_AB_OTA;
             case "inactive" : return TRON_COMPILATION_REASON_INACTIVE;
             case "shared" : return TRON_COMPILATION_REASON_SHARED;
-            // This is a special marker for dex metadata installation that does not
+            case "install-fast" :
+                return TRON_COMPILATION_REASON_INSTALL_FAST;
+            case "install-bulk" :
+                return TRON_COMPILATION_REASON_INSTALL_BULK;
+            case "install-bulk-secondary" :
+                return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY;
+            case "install-bulk-downgraded" :
+                return TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED;
+            case "install-bulk-secondary-downgraded" :
+                return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED;
+            // These are special markers for dex metadata installation that do not
             // have an equivalent as a system property.
             case "install" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION :
-                return TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA;
+                return TRON_COMPILATION_REASON_INSTALL_WITH_DM;
+            case "install-fast" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION :
+                return TRON_COMPILATION_REASON_INSTALL_FAST_WITH_DM;
+            case "install-bulk" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION :
+                return TRON_COMPILATION_REASON_INSTALL_BULK_WITH_DM;
+            case "install-bulk-secondary" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION :
+                return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_WITH_DM;
+            case "install-bulk-downgraded" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION :
+                return TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED_WITH_DM;
+            case "install-bulk-secondary-downgraded" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION :
+                return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED_WITH_DM;
             default: return TRON_COMPILATION_REASON_UNKNOWN;
         }
     }
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 3074250..cc6d80a 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -27,8 +27,11 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.PackagePartitions;
+import android.os.BatteryManager;
 import android.os.FileUtils;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -107,6 +110,13 @@
     @GuardedBy("mInstallLock")
     private final Installer mInstaller;
 
+    private BatteryManager mBatteryManager = null;
+    private PowerManager mPowerManager = null;
+
+    // An integer percentage value used to determine when the device is considered to be on low
+    // power for compilation purposes.
+    private final int mCriticalBatteryLevel;
+
     // Possible outcomes of a dex search.
     private static int DEX_SEARCH_NOT_FOUND = 0;  // dex file not found
     private static int DEX_SEARCH_FOUND_PRIMARY = 1;  // dex file is the primary/base apk
@@ -123,6 +133,23 @@
         mInstaller = installer;
         mInstallLock = installLock;
         mDynamicCodeLogger = new DynamicCodeLogger(pms, installer);
+
+        // This is currently checked to handle tests that pass in a null context.
+        // TODO(b/174783329): Modify the tests to pass in a mocked Context, PowerManager,
+        //      and BatteryManager.
+        if (mContext != null) {
+            mPowerManager = mContext.getSystemService(PowerManager.class);
+
+            if (mPowerManager == null) {
+                Slog.wtf(TAG, "Power Manager is unavailable at time of Dex Manager start");
+            }
+
+            mCriticalBatteryLevel = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_criticalBatteryWarningLevel);
+        } else {
+            // This value will never be used as the Battery Manager null check will fail first.
+            mCriticalBatteryLevel = 0;
+        }
     }
 
     public DynamicCodeLogger getDynamicCodeLogger() {
@@ -905,6 +932,74 @@
         }
     }
 
+    /**
+     * Translates install scenarios into compilation reasons.  This process can be influenced
+     * by the state of the device.
+     */
+    public int getCompilationReasonForInstallScenario(int installScenario) {
+        // Compute the compilation reason from the installation scenario.
+
+        boolean resourcesAreCritical = areBatteryThermalOrMemoryCritical();
+        switch (installScenario) {
+            case PackageManager.INSTALL_SCENARIO_DEFAULT: {
+                return PackageManagerService.REASON_INSTALL;
+            }
+            case PackageManager.INSTALL_SCENARIO_FAST: {
+                return PackageManagerService.REASON_INSTALL_FAST;
+            }
+            case PackageManager.INSTALL_SCENARIO_BULK: {
+                if (resourcesAreCritical) {
+                    return PackageManagerService.REASON_INSTALL_BULK_DOWNGRADED;
+                } else {
+                    return PackageManagerService.REASON_INSTALL_BULK;
+                }
+            }
+            case PackageManager.INSTALL_SCENARIO_BULK_SECONDARY: {
+                if (resourcesAreCritical) {
+                    return PackageManagerService.REASON_INSTALL_BULK_SECONDARY_DOWNGRADED;
+                } else {
+                    return PackageManagerService.REASON_INSTALL_BULK_SECONDARY;
+                }
+            }
+            default: {
+                throw new IllegalArgumentException("Invalid installation scenario");
+            }
+        }
+    }
+
+    /**
+     * Fetches the battery manager object and caches it if it hasn't been fetched already.
+     */
+    private BatteryManager getBatteryManager() {
+        if (mBatteryManager == null) {
+            mBatteryManager = mContext.getSystemService(BatteryManager.class);
+        }
+
+        return mBatteryManager;
+    }
+
+    /**
+     * Returns true if the battery level, device temperature, or memory usage are considered to be
+     * in a critical state.
+     */
+    private boolean areBatteryThermalOrMemoryCritical() {
+        BatteryManager batteryManager = getBatteryManager();
+        boolean isBtmCritical = (batteryManager != null
+                && batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_STATUS)
+                    == BatteryManager.BATTERY_STATUS_DISCHARGING
+                && batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
+                    <= mCriticalBatteryLevel)
+                || (mPowerManager != null
+                    && mPowerManager.getCurrentThermalStatus()
+                        >= PowerManager.THERMAL_STATUS_SEVERE);
+
+        if (DEBUG) {
+            Log.d(TAG, "Battery, thermal, or memory are critical: " + isBtmCritical);
+        }
+
+        return isBtmCritical;
+    }
+
     public static class RegisterDexModuleResult {
         public RegisterDexModuleResult() {
             this(false, null);
diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
index 68f3886..ea23316 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
@@ -65,6 +65,12 @@
     // or device setup and should be scheduled appropriately.
     public static final int DEXOPT_FOR_RESTORE = 1 << 11; // TODO(b/135202722): remove
 
+    /**
+     * A value indicating that dexopt shouldn't be run.  This string is only used when loading
+     * filters from the `pm.dexopt.install*` properties and is not propagated to dex2oat.
+     */
+    public static final String COMPILER_FILTER_NOOP = "skip";
+
     // The name of package to optimize.
     private final String mPackageName;
 
@@ -176,6 +182,10 @@
         return mCompilationReason;
     }
 
+    public boolean isCompilationEnabled() {
+        return !mCompilerFilter.equals(COMPILER_FILTER_NOOP);
+    }
+
     /**
      * Creates a new set of DexoptOptions which are the same with the exception of the compiler
      * filter (set to the given value).
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 1656472..44a2187 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -41,8 +41,9 @@
 import android.os.Build;
 import android.os.Environment;
 import android.os.Handler;
-import android.os.Looper;
+import android.os.HandlerThread;
 import android.os.Message;
+import android.os.Process;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.permission.PermissionManager;
@@ -67,8 +68,9 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.XmlUtils;
 import com.android.server.LocalServices;
-import com.android.server.pm.permission.PermissionManagerServiceInternal.PackagesProvider;
-import com.android.server.pm.permission.PermissionManagerServiceInternal.SyncAdapterPackagesProvider;
+import com.android.server.ServiceThread;
+import com.android.server.pm.permission.LegacyPermissionManagerInternal.PackagesProvider;
+import com.android.server.pm.permission.LegacyPermissionManagerInternal.SyncAdapterPackagesProvider;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -96,7 +98,7 @@
  * to have an interface defined in the package manager but have the impl next to other
  * policy stuff like PhoneWindowManager
  */
-public final class DefaultPermissionGrantPolicy {
+final class DefaultPermissionGrantPolicy {
     private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars
     private static final boolean DEBUG = false;
 
@@ -291,9 +293,12 @@
         }
     };
 
-    DefaultPermissionGrantPolicy(Context context, Looper looper) {
+    DefaultPermissionGrantPolicy(@NonNull Context context) {
         mContext = context;
-        mHandler = new Handler(looper) {
+        HandlerThread handlerThread = new ServiceThread(TAG,
+                Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
+        handlerThread.start();
+        mHandler = new Handler(handlerThread.getLooper()) {
             @Override
             public void handleMessage(Message msg) {
                 if (msg.what == MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS) {
@@ -998,12 +1003,6 @@
         }
     }
 
-    public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
-        Log.i(TAG, "Granting permissions to default browser for user:" + userId);
-        grantPermissionsToSystemPackage(NO_PM_CACHE, packageName, userId,
-                FOREGROUND_LOCATION_PERMISSIONS);
-    }
-
     private String getDefaultSystemHandlerActivityPackage(PackageManagerWrapper pm,
             String intentAction, int userId) {
         return getDefaultSystemHandlerActivityPackage(pm, new Intent(intentAction), userId);
diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermission.java b/services/core/java/com/android/server/pm/permission/LegacyPermission.java
index 6a4eb63..ca3a2e2 100644
--- a/services/core/java/com/android/server/pm/permission/LegacyPermission.java
+++ b/services/core/java/com/android/server/pm/permission/LegacyPermission.java
@@ -167,16 +167,12 @@
 
     private static int readInt(@NonNull TypedXmlPullParser parser, @Nullable String namespace,
             @NonNull String name, int defaultValue) {
-        final String value = parser.getAttributeValue(namespace, name);
-        if (value == null) {
-            return defaultValue;
-        }
         try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException e) {
+            return parser.getAttributeInt(namespace, name);
+        } catch (Exception ignored) {
             PackageManagerService.reportSettingsProblem(Log.WARN,
                     "Error in package manager settings: attribute " + name
-                            + " has bad integer value " + value + " at "
+                            + " has bad integer value at "
                             + parser.getPositionDescription());
             return defaultValue;
         }
diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerInternal.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerInternal.java
new file mode 100644
index 0000000..a098484
--- /dev/null
+++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerInternal.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.pm.permission;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+
+/**
+ * The internal interface for {@link LegacyPermissionManagerService}.
+ */
+public interface LegacyPermissionManagerInternal {
+    /**
+     * Sets the dialer application packages provider.
+     * @param provider The provider.
+     */
+    void setDialerAppPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Set the location extra packages provider.
+     * @param provider The packages provider.
+     */
+    void setLocationExtraPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the location provider packages provider.
+     * @param provider The packages provider.
+     */
+    void setLocationPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the SIM call manager packages provider.
+     * @param provider The provider.
+     */
+    void setSimCallManagerPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the SMS application packages provider.
+     * @param provider The provider.
+     */
+    void setSmsAppPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the sync adapter packages provider.
+     * @param provider The provider.
+     */
+    void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider);
+
+    /**
+     * Sets the Use Open Wifi packages provider.
+     * @param provider The packages provider.
+     */
+    void setUseOpenWifiAppPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the voice interaction packages provider.
+     * @param provider The packages provider.
+     */
+    void setVoiceInteractionPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Requests granting of the default permissions to the current default Use Open Wifi app.
+     * @param packageName The default use open wifi package name.
+     * @param userId The user for which to grant the permissions.
+     */
+    void grantDefaultPermissionsToDefaultSimCallManager(@NonNull String packageName,
+            @UserIdInt int userId);
+
+    /**
+     * Requests granting of the default permissions to the current default Use Open Wifi app.
+     * @param packageName The default use open wifi package name.
+     * @param userId The user for which to grant the permissions.
+     */
+    void grantDefaultPermissionsToDefaultUseOpenWifiApp(@NonNull String packageName,
+            @UserIdInt int userId);
+
+    /**
+     * Grant the default permissions for a user.
+     *
+     * @param userId the user ID
+     */
+    void grantDefaultPermissions(@UserIdInt int userId);
+
+    /**
+     * Schedule reading the default permission exceptions file.
+     */
+    void scheduleReadDefaultPermissionExceptions();
+
+    // TODO(zhanghai): The following methods should be moved to a new AIDL to support
+    //  the legacy PermissionManager directly in a later CL.
+
+    /**
+     * Grant default permissions to currently active LUI app
+     * @param packageName The package name for the LUI app
+     * @param userId The user ID
+     */
+    void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId);
+
+    /**
+     * Revoke default permissions to currently active LUI app
+     * @param packageNames The package names for the LUI apps
+     * @param userId The user ID
+     */
+    void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId);
+
+    /**
+     * Grant default permissions to currently active Ims services
+     * @param packageNames The package names for the Ims services
+     * @param userId The user ID
+     */
+    void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId);
+
+    /**
+     * Grant default permissions to currently enabled telephony data services
+     * @param packageNames The package name for the services
+     * @param userId The user ID
+     */
+    void grantDefaultPermissionsToEnabledTelephonyDataServices(String[] packageNames, int userId);
+
+    /**
+     * Revoke default permissions to currently active telephony data services
+     * @param packageNames The package name for the services
+     * @param userId The IDhandle
+     */
+    void revokeDefaultPermissionsFromDisabledTelephonyDataServices(String[] packageNames,
+            int userId);
+
+    /**
+     * Grant default permissions to currently enabled carrier apps
+     * @param packageNames Package names of the apps to be granted permissions
+     * @param userId The user ID
+     */
+    void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId);
+
+    /**
+     * Provider for package names.
+     */
+    interface PackagesProvider {
+        /**
+         * Gets the packages for a given user.
+         * @param userId The user id.
+         * @return The package names.
+         */
+        String[] getPackages(int userId);
+    }
+
+    /**
+     * Provider for package names.
+     */
+    interface SyncAdapterPackagesProvider {
+        /**
+         * Gets the sync adapter packages for given authority and user.
+         * @param authority The authority.
+         * @param userId The user id.
+         * @return The package names.
+         */
+        String[] getPackages(String authority, int userId);
+    }
+}
diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
new file mode 100644
index 0000000..0c0a8df
--- /dev/null
+++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.pm.permission;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Binder;
+
+import com.android.server.LocalServices;
+import com.android.server.pm.PackageManagerServiceUtils;
+
+/**
+ * Legacy permission manager service.
+ */
+public class LegacyPermissionManagerService {
+    @NonNull
+    private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
+
+    /**
+     * Get or create an instance of this class for use by other components.
+     * <p>
+     * This method is not thread-safe.
+     *
+     * @param context the {@link Context}
+     * @return the internal instance
+     */
+    @NonNull
+    public static LegacyPermissionManagerInternal create(@NonNull Context context) {
+        LegacyPermissionManagerInternal legacyPermissionManagerInternal = LocalServices.getService(
+                LegacyPermissionManagerInternal.class);
+        if (legacyPermissionManagerInternal == null) {
+            new LegacyPermissionManagerService(context);
+            legacyPermissionManagerInternal = LocalServices.getService(
+                    LegacyPermissionManagerInternal.class);
+        }
+        return legacyPermissionManagerInternal;
+    }
+
+    private LegacyPermissionManagerService(@NonNull Context context) {
+        mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(context);
+        LocalServices.addService(LegacyPermissionManagerInternal.class, new Internal());
+    }
+
+    private class Internal implements LegacyPermissionManagerInternal {
+        @Override
+        public void setDialerAppPackagesProvider(PackagesProvider provider) {
+            mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
+        }
+
+        @Override
+        public void setLocationExtraPackagesProvider(PackagesProvider provider) {
+            mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
+        }
+
+        @Override
+        public void setLocationPackagesProvider(PackagesProvider provider) {
+            mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
+        }
+
+        @Override
+        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
+            mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
+        }
+
+        @Override
+        public void setSmsAppPackagesProvider(PackagesProvider provider) {
+            mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
+        }
+
+        @Override
+        public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
+            mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
+        }
+
+        @Override
+        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
+            mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
+        }
+
+        @Override
+        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
+            mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
+        }
+
+        @Override
+        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
+            mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultSimCallManager(
+                    packageName, userId);
+        }
+
+        @Override
+        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
+            mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
+                    packageName, userId);
+        }
+
+        @Override
+        public void grantDefaultPermissions(int userId) {
+            mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
+        }
+
+        @Override
+        public void scheduleReadDefaultPermissionExceptions() {
+            mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
+        }
+
+        // TODO(zhanghai): The following methods should be moved to a new AIDL to support
+        //  the legacy PermissionManager directly in a later CL.
+
+        @Override
+        public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                    "grantDefaultPermissionsToActiveLuiApp", callingUid);
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
+        }
+
+        @Override
+        public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                    "revokeDefaultPermissionsFromLuiApps", callingUid);
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
+        }
+
+        @Override
+        public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                    "grantDefaultPermissionsToEnabledImsServices", callingUid);
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
+        }
+
+        @Override
+        public void grantDefaultPermissionsToEnabledTelephonyDataServices(
+                String[] packageNames, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                    "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToEnabledTelephonyDataServices(packageNames, userId));
+        }
+
+        @Override
+        public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+                String[] packageNames, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                    "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .revokeDefaultPermissionsFromDisabledTelephonyDataServices(packageNames,
+                            userId));
+        }
+
+        @Override
+        public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                    "grantPermissionsToEnabledCarrierApps", callingUid);
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/permission/OWNERS b/services/core/java/com/android/server/pm/permission/OWNERS
index 0e88862..6e67830 100644
--- a/services/core/java/com/android/server/pm/permission/OWNERS
+++ b/services/core/java/com/android/server/pm/permission/OWNERS
@@ -1,7 +1,7 @@
 moltmann@google.com
 zhanghai@google.com
-per-file DefaultPermissionGrantPolicy.java = hackbod@android.com
-per-file DefaultPermissionGrantPolicy.java = jsharkey@android.com
+per-file DefaultPermissionGrantPolicy.java = hackbod@google.com
+per-file DefaultPermissionGrantPolicy.java = jsharkey@google.com
 per-file DefaultPermissionGrantPolicy.java = svetoslavganov@google.com
 per-file DefaultPermissionGrantPolicy.java = toddke@google.com
 per-file DefaultPermissionGrantPolicy.java = yamasani@google.com
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 48e18f1..389010a 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -114,8 +114,6 @@
 import android.permission.PermissionControllerManager;
 import android.permission.PermissionManager;
 import android.permission.PermissionManagerInternal;
-import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
-import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -138,6 +136,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IntPair;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.TriFunction;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
@@ -145,15 +144,12 @@
 import com.android.server.SystemConfig;
 import com.android.server.Watchdog;
 import com.android.server.pm.ApexManager;
-import com.android.server.pm.PackageManagerServiceUtils;
 import com.android.server.pm.PackageSetting;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.pm.UserManagerService;
 import com.android.server.pm.parsing.PackageInfoUtils;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
-import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
-import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
-import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.OnRuntimePermissionStateChangedListener;
 import com.android.server.policy.PermissionPolicyInternal;
 import com.android.server.policy.SoftRestrictedPermissionPolicy;
 
@@ -176,7 +172,7 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import java.util.function.Consumer;
+import java.util.function.BiFunction;
 
 /**
  * Manages all permissions and handles permissions related tasks.
@@ -242,9 +238,6 @@
     private final SparseArray<OneTimePermissionUserManager> mOneTimePermissionUserManagers =
             new SparseArray<>();
 
-    /** Default permission policy to provide proper behaviour out-of-the-box */
-    private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
-
     /** App ops manager */
     private final AppOpsManager mAppOpsManager;
 
@@ -304,15 +297,6 @@
     @NonNull
     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
 
-    @GuardedBy("mLock")
-    private DefaultBrowserProvider mDefaultBrowserProvider;
-
-    @GuardedBy("mLock")
-    private DefaultDialerProvider mDefaultDialerProvider;
-
-    @GuardedBy("mLock")
-    private DefaultHomeProvider mDefaultHomeProvider;
-
     // TODO: Take a look at the methods defined in the callback.
     // The callback was initially created to support the split between permission
     // manager and the package manager. However, it's started to be used for other
@@ -402,8 +386,6 @@
         mHandler = new Handler(mHandlerThread.getLooper());
         Watchdog.getInstance().addThread(mHandler);
 
-        mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
-                context, mHandlerThread.getLooper());
         SystemConfig systemConfig = SystemConfig.getInstance();
         mSystemPermissions = systemConfig.getSystemPermissions();
         mGlobalGids = systemConfig.getGlobalGids();
@@ -2018,145 +2000,41 @@
     }
 
     @Override
-    public String getDefaultBrowser(int userId) {
-        final int callingUid = Binder.getCallingUid();
-        if (UserHandle.getUserId(callingUid) != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
-        }
-        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
-            return null;
-        }
-        DefaultBrowserProvider provider;
-        synchronized (mLock) {
-            provider = mDefaultBrowserProvider;
-        }
-        return provider != null ? provider.getDefaultBrowser(userId) : null;
-    }
-
-    @Override
-    public boolean setDefaultBrowser(String packageName, int userId) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
-        }
-        return setDefaultBrowserInternal(packageName, false, true, userId);
-    }
-
-    private boolean setDefaultBrowserInternal(String packageName, boolean async,
-            boolean doGrant, int userId) {
-        if (userId == UserHandle.USER_ALL) {
-            return false;
-        }
-        DefaultBrowserProvider provider;
-        synchronized (mLock) {
-            provider = mDefaultBrowserProvider;
-        }
-        if (provider == null) {
-            return false;
-        }
-        if (async) {
-            provider.setDefaultBrowserAsync(packageName, userId);
-        } else {
-            if (!provider.setDefaultBrowser(packageName, userId)) {
-                return false;
-            }
-        }
-        if (doGrant && packageName != null) {
-            mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
-                    userId);
-        }
-        return true;
-    }
-
-    @Override
     public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        PackageManagerServiceUtils
-                .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
-        Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
-                .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
+        LocalServices.getService(LegacyPermissionManagerInternal.class)
+                .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId);
     }
 
     @Override
     public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
-                "grantDefaultPermissionsToEnabledImsServices", callingUid);
-        Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
-                .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
+        LocalServices.getService(LegacyPermissionManagerInternal.class)
+                .grantDefaultPermissionsToEnabledImsServices(packageNames, userId);
     }
 
     @Override
     public void grantDefaultPermissionsToEnabledTelephonyDataServices(
             String[] packageNames, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
-                "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
-        Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
-                .grantDefaultPermissionsToEnabledTelephonyDataServices(packageNames, userId));
+        LocalServices.getService(LegacyPermissionManagerInternal.class)
+                .grantDefaultPermissionsToEnabledTelephonyDataServices(packageNames, userId);
     }
 
     @Override
     public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
             String[] packageNames, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
-                "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
-        Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
-                .revokeDefaultPermissionsFromDisabledTelephonyDataServices(packageNames, userId));
+        LocalServices.getService(LegacyPermissionManagerInternal.class)
+                .revokeDefaultPermissionsFromDisabledTelephonyDataServices(packageNames, userId);
     }
 
     @Override
     public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        PackageManagerServiceUtils
-                .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
-        Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
-                .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
+        LocalServices.getService(LegacyPermissionManagerInternal.class)
+                .grantDefaultPermissionsToActiveLuiApp(packageName, userId);
     }
 
     @Override
     public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
-        final int callingUid = Binder.getCallingUid();
-        PackageManagerServiceUtils
-                .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
-        Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
-                .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
-    }
-
-    @Override
-    public void setPermissionEnforced(String permName, boolean enforced) {
-        // TODO: Now that we no longer change GID for storage, this should to away.
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
-                "setPermissionEnforced");
-        if (READ_EXTERNAL_STORAGE.equals(permName)) {
-            mPackageManagerInt.setReadExternalStorageEnforced(enforced);
-            // kill any non-foreground processes so we restart them and
-            // grant/revoke the GID.
-            final IActivityManager am = ActivityManager.getService();
-            if (am != null) {
-                final long token = Binder.clearCallingIdentity();
-                try {
-                    am.killProcessesBelowForeground("setPermissionEnforcement");
-                } catch (RemoteException e) {
-                } finally {
-                    Binder.restoreCallingIdentity(token);
-                }
-            }
-        } else {
-            throw new IllegalArgumentException("No selective enforcement for " + permName);
-        }
-    }
-
-    /** @deprecated */
-    @Override
-    @Deprecated
-    public boolean isPermissionEnforced(String permName) {
-        // allow instant applications
-        return true;
+        LocalServices.getService(LegacyPermissionManagerInternal.class)
+                .revokeDefaultPermissionsFromLuiApps(packageNames, userId);
     }
 
     /**
@@ -2263,19 +2141,20 @@
      *
      * <p>Can not be called on main thread.
      *
-     * @param user The user the data should be extracted for
+     * @param userId The user ID the data should be extracted for
      *
      * @return The state as a xml file
      */
-    private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
+    @Nullable
+    private byte[] backupRuntimePermissions(@UserIdInt int userId) {
         CompletableFuture<byte[]> backup = new CompletableFuture<>();
-        mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
-                backup::complete);
+        mPermissionControllerManager.getRuntimePermissionBackup(UserHandle.of(userId),
+                mContext.getMainExecutor(), backup::complete);
 
         try {
             return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
         } catch (InterruptedException | ExecutionException  | TimeoutException e) {
-            Slog.e(TAG, "Cannot create permission backup for " + user, e);
+            Slog.e(TAG, "Cannot create permission backup for user " + userId, e);
             return null;
         }
     }
@@ -2287,13 +2166,14 @@
      * applied via {@link #restoreDelayedRuntimePermissions}.
      *
      * @param backup The state as an xml file
-     * @param user The user the data should be restored for
+     * @param userId The user ID the data should be restored for
      */
-    private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
+    private void restoreRuntimePermissions(@NonNull byte[] backup, @UserIdInt int userId) {
         synchronized (mLock) {
-            mHasNoDelayedPermBackup.delete(user.getIdentifier());
+            mHasNoDelayedPermBackup.delete(userId);
         }
-        mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup, user);
+        mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup,
+                UserHandle.of(userId));
     }
 
     /**
@@ -2302,24 +2182,24 @@
      * <p>Can not be called on main thread.
      *
      * @param packageName The package that is newly installed
-     * @param user The user the package is installed for
+     * @param userId The user ID the package is installed for
      *
      * @see #restoreRuntimePermissions
      */
     private void restoreDelayedRuntimePermissions(@NonNull String packageName,
-            @NonNull UserHandle user) {
+            @UserIdInt int userId) {
         synchronized (mLock) {
-            if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
+            if (mHasNoDelayedPermBackup.get(userId, false)) {
                 return;
             }
         }
-        mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName, user,
-                mContext.getMainExecutor(), (hasMoreBackup) -> {
+        mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName,
+                UserHandle.of(userId), mContext.getMainExecutor(), (hasMoreBackup) -> {
                     if (hasMoreBackup) {
                         return;
                     }
                     synchronized (mLock) {
-                        mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
+                        mHasNoDelayedPermBackup.put(userId, true);
                     }
                 });
     }
@@ -2360,6 +2240,32 @@
         }
     }
 
+    private void startShellPermissionIdentityDelegationInternal(int uid,
+            @NonNull String packageName, @Nullable List<String> permissionNames) {
+        synchronized (mLock) {
+            final CheckPermissionDelegate oldDelegate = mCheckPermissionDelegate;
+            if (oldDelegate != null && oldDelegate.getDelegatedUid() != uid) {
+                throw new SecurityException(
+                        "Shell can delegate permissions only to one UID at a time");
+            }
+            final ShellDelegate delegate = new ShellDelegate(uid, packageName, permissionNames);
+            setCheckPermissionDelegateLocked(delegate);
+        }
+    }
+
+    private void stopShellPermissionIdentityDelegationInternal() {
+        synchronized (mLock) {
+            setCheckPermissionDelegateLocked(null);
+        }
+    }
+
+    private void setCheckPermissionDelegateLocked(@Nullable CheckPermissionDelegate delegate) {
+        if (delegate != null || mCheckPermissionDelegate != null) {
+            PackageManager.invalidatePackageInfoCache();
+        }
+        mCheckPermissionDelegate = delegate;
+    }
+
     /**
      * If the app is updated, and has scoped storage permissions, then it is possible that the
      * app updated in an attempt to get unscoped storage. If so, revoke all storage permissions.
@@ -4621,24 +4527,6 @@
 
         mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
         mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
-
-        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
-        for (int userId : UserManagerService.getInstance().getUserIds()) {
-            if (mPackageManagerInt.isPermissionUpgradeNeeded(userId)) {
-                grantPermissionsUserIds = ArrayUtils.appendInt(
-                        grantPermissionsUserIds, userId);
-            }
-        }
-        // If we upgraded grant all default permissions before kicking off.
-        for (int userId : grantPermissionsUserIds) {
-            mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
-        }
-        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
-            // If we did not grant default permissions, we preload from this the
-            // default permission exceptions lazily to ensure we don't hit the
-            // disk on a new user creation.
-            mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
-        }
     }
 
     private static String getVolumeUuidForPackage(AndroidPackage pkg) {
@@ -5098,7 +4986,7 @@
         }
     }
 
-    private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
+    private class PermissionManagerServiceInternalImpl implements PermissionManagerServiceInternal {
         @Override
         public void systemReady() {
             PermissionManagerService.this.systemReady();
@@ -5123,6 +5011,7 @@
         }
         @Override
         public void onUserRemoved(@UserIdInt int userId) {
+            Preconditions.checkArgumentNonNegative(userId, "userId");
             PermissionManagerService.this.onUserRemoved(userId);
         }
         @NonNull
@@ -5202,20 +5091,26 @@
             return matchingPermissions;
         }
 
+        @Nullable
         @Override
-        public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
-            return PermissionManagerService.this.backupRuntimePermissions(user);
+        public byte[] backupRuntimePermissions(@UserIdInt int userId) {
+            Preconditions.checkArgumentNonNegative(userId, "userId");
+            return PermissionManagerService.this.backupRuntimePermissions(userId);
         }
 
         @Override
-        public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
-            PermissionManagerService.this.restoreRuntimePermissions(backup, user);
+        public void restoreRuntimePermissions(@NonNull byte[] backup, @UserIdInt int userId) {
+            Objects.requireNonNull(backup, "backup");
+            Preconditions.checkArgumentNonNegative(userId, "userId");
+            PermissionManagerService.this.restoreRuntimePermissions(backup, userId);
         }
 
         @Override
         public void restoreDelayedRuntimePermissions(@NonNull String packageName,
-                @NonNull UserHandle user) {
-            PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
+                @UserIdInt int userId) {
+            Objects.requireNonNull(packageName, "packageName");
+            Preconditions.checkArgumentNonNegative(userId, "userId");
+            PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, userId);
         }
 
         @Override
@@ -5233,163 +5128,23 @@
         }
 
         @Override
-        public CheckPermissionDelegate getCheckPermissionDelegate() {
-            synchronized (mLock) {
-                return mCheckPermissionDelegate;
-            }
+        public void startShellPermissionIdentityDelegation(int uid, @NonNull String packageName,
+                @Nullable List<String> permissionNames) {
+            Objects.requireNonNull(packageName, "packageName");
+            startShellPermissionIdentityDelegationInternal(uid, packageName, permissionNames);
         }
 
         @Override
-        public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
-            synchronized (mLock) {
-                if (delegate != null || mCheckPermissionDelegate != null) {
-                    PackageManager.invalidatePackageInfoCache();
-                }
-                mCheckPermissionDelegate = delegate;
-            }
+        public void stopShellPermissionIdentityDelegation() {
+            stopShellPermissionIdentityDelegationInternal();
         }
 
         @Override
-        public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
-            synchronized (mLock) {
-                mDefaultBrowserProvider = provider;
-            }
-        }
-
-        @Override
-        public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
-                int userId) {
-            setDefaultBrowserInternal(packageName, async, doGrant, userId);
-        }
-
-        @Override
-        public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
-            synchronized (mLock) {
-                mDefaultDialerProvider = provider;
-            }
-        }
-
-        @Override
-        public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
-            synchronized (mLock) {
-                mDefaultHomeProvider = provider;
-            }
-        }
-
-        @Override
-        public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
-            if (userId == UserHandle.USER_ALL) {
-                return;
-            }
-            DefaultHomeProvider provider;
-            synchronized (mLock) {
-                provider = mDefaultHomeProvider;
-            }
-            if (provider == null) {
-                return;
-            }
-            provider.setDefaultHomeAsync(packageName, userId, callback);
-        }
-
-        @Override
-        public void setDialerAppPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
-        }
-
-        @Override
-        public void setLocationExtraPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
-        }
-
-        @Override
-        public void setLocationPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
-        }
-
-        @Override
-        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
-        }
-
-        @Override
-        public void setSmsAppPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
-        }
-
-        @Override
-        public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
-            mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
-        }
-
-        @Override
-        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
-        }
-
-        @Override
-        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
-        }
-
-        @Override
-        public String getDefaultBrowser(int userId) {
-            DefaultBrowserProvider provider;
-            synchronized (mLock) {
-                provider = mDefaultBrowserProvider;
-            }
-            return provider != null ? provider.getDefaultBrowser(userId) : null;
-        }
-
-        @Override
-        public String getDefaultDialer(int userId) {
-            DefaultDialerProvider provider;
-            synchronized (mLock) {
-                provider = mDefaultDialerProvider;
-            }
-            return provider != null ? provider.getDefaultDialer(userId) : null;
-        }
-
-        @Override
-        public String getDefaultHome(int userId) {
-            DefaultHomeProvider provider;
-            synchronized (mLock) {
-                provider = mDefaultHomeProvider;
-            }
-            return provider != null ? provider.getDefaultHome(userId) : null;
-        }
-
-        @Override
-        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
-            mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultSimCallManager(
-                    packageName, userId);
-        }
-
-        @Override
-        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
-            mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
-                    packageName, userId);
-        }
-
-        @Override
-        public void onNewUserCreated(int userId) {
+        public void onUserCreated(@UserIdInt int userId) {
+            Preconditions.checkArgumentNonNegative(userId, "userId");
             // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
             PermissionManagerService.this.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL,
                     true, mDefaultPermissionCallback);
-            mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
-        }
-
-        @Override
-        public void retainHardAndSoftRestrictedPermissions(@NonNull List<String> permissionNames) {
-            synchronized (mLock) {
-                Iterator<String> iterator = permissionNames.iterator();
-                while (iterator.hasNext()) {
-                    final String permissionName = iterator.next();
-                    final Permission permission = mRegistry.getPermission(permissionName);
-                    if (permission == null || !permission.isHardOrSoftRestricted()) {
-                        iterator.remove();
-                    }
-                }
-            }
         }
 
         @Override
@@ -5545,6 +5300,102 @@
     }
 
     /**
+     * Interface to intercept permission checks and optionally pass through to the original
+     * implementation.
+     */
+    private interface CheckPermissionDelegate {
+        /**
+         * Get the UID whose permission checks is being delegated.
+         *
+         * @return the UID
+         */
+        int getDelegatedUid();
+
+        /**
+         * Check whether the given package has been granted the specified permission.
+         *
+         * @param permissionName the name of the permission to be checked
+         * @param packageName the name of the package to be checked
+         * @param userId the user ID
+         * @param superImpl the original implementation that can be delegated to
+         * @return {@link android.content.pm.PackageManager.PERMISSION_GRANTED} if the package has
+         * the permission, or {@link android.content.pm.PackageManager.PERMISSION_DENITED} otherwise
+         *
+         * @see android.content.pm.PackageManager#checkPermission(String, String)
+         */
+        int checkPermission(@NonNull String permissionName, @NonNull String packageName,
+                @UserIdInt int userId,
+                @NonNull TriFunction<String, String, Integer, Integer> superImpl);
+
+        /**
+         * Check whether the given UID has been granted the specified permission.
+         *
+         * @param permissionName the name of the permission to be checked
+         * @param uid the UID to be checked
+         * @param superImpl the original implementation that can be delegated to
+         * @return {@link android.content.pm.PackageManager.PERMISSION_GRANTED} if the package has
+         * the permission, or {@link android.content.pm.PackageManager.PERMISSION_DENITED} otherwise
+         */
+        int checkUidPermission(@NonNull String permissionName, int uid,
+                BiFunction<String, Integer, Integer> superImpl);
+    }
+
+    private class ShellDelegate implements CheckPermissionDelegate {
+        private final int mDelegatedUid;
+        @NonNull
+        private final String mDelegatedPackageName;
+        @Nullable
+        private final List<String> mDelegatedPermissionNames;
+
+        public ShellDelegate(int delegatedUid, @NonNull String delegatedPackageName,
+                @Nullable List<String> delegatedPermissionNames) {
+            mDelegatedUid = delegatedUid;
+            mDelegatedPackageName = delegatedPackageName;
+            mDelegatedPermissionNames = delegatedPermissionNames;
+        }
+
+        @Override
+        public int getDelegatedUid() {
+            return mDelegatedUid;
+        }
+
+        @Override
+        public int checkPermission(@NonNull String permissionName, @NonNull String packageName,
+                int userId, @NonNull TriFunction<String, String, Integer, Integer> superImpl) {
+            if (mDelegatedPackageName.equals(packageName)
+                    && isDelegatedPermission(permissionName)) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(permissionName, "com.android.shell", userId);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(permissionName, packageName, userId);
+        }
+
+        @Override
+        public int checkUidPermission(@NonNull String permissionName, int uid,
+                @NonNull BiFunction<String, Integer, Integer> superImpl) {
+            if (uid == mDelegatedUid && isDelegatedPermission(permissionName)) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(permissionName, Process.SHELL_UID);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(permissionName, uid);
+        }
+
+        private boolean isDelegatedPermission(@NonNull String permissionName) {
+            // null permissions means all permissions are targeted
+            return mDelegatedPermissionNames == null
+                    || mDelegatedPermissionNames.contains(permissionName);
+        }
+    }
+
+    /**
      * Allows injection of services and method responses to facilitate testing.
      *
      * <p>Test classes can create a mock of this class and pass it to the PermissionManagerService
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index f924651..0817d4f 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -30,119 +30,31 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
-import java.util.function.Consumer;
 
 /**
  * Internal interfaces services.
  *
- * TODO: Should be merged into PermissionManagerInternal, but currently uses internal classes.
+ * TODO: Move into module.
  */
-public abstract class PermissionManagerServiceInternal extends PermissionManagerInternal
-        implements LegacyPermissionDataProvider {
+public interface PermissionManagerServiceInternal extends PermissionManagerInternal,
+        LegacyPermissionDataProvider {
     /**
-     * Provider for package names.
+     * Adds a listener for runtime permission state (permissions or flags) changes.
+     *
+     * @param listener The listener.
      */
-    public interface PackagesProvider {
-
-        /**
-         * Gets the packages for a given user.
-         * @param userId The user id.
-         * @return The package names.
-         */
-        String[] getPackages(int userId);
-    }
+    void addOnRuntimePermissionStateChangedListener(
+            @NonNull OnRuntimePermissionStateChangedListener listener);
 
     /**
-     * Provider for package names.
+     * Removes a listener for runtime permission state (permissions or flags) changes.
+     *
+     * @param listener The listener.
      */
-    public interface SyncAdapterPackagesProvider {
+    void removeOnRuntimePermissionStateChangedListener(
+            @NonNull OnRuntimePermissionStateChangedListener listener);
 
-        /**
-         * Gets the sync adapter packages for given authority and user.
-         * @param authority The authority.
-         * @param userId The user id.
-         * @return The package names.
-         */
-        String[] getPackages(String authority, int userId);
-    }
-
-    /**
-     * Provider for default browser
-     */
-    public interface DefaultBrowserProvider {
-
-        /**
-         * Get the package name of the default browser.
-         *
-         * @param userId the user id
-         *
-         * @return the package name of the default browser, or {@code null} if none
-         */
-        @Nullable
-        String getDefaultBrowser(@UserIdInt int userId);
-
-        /**
-         * Set the package name of the default browser.
-         *
-         * @param packageName package name of the default browser, or {@code null} to remove
-         * @param userId the user id
-         *
-         * @return whether the default browser was successfully set.
-         */
-        boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId);
-
-        /**
-         * Set the package name of the default browser asynchronously.
-         *
-         * @param packageName package name of the default browser, or {@code null} to remove
-         * @param userId the user id
-         */
-        void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId);
-    }
-
-    /**
-     * Provider for default dialer
-     */
-    public interface DefaultDialerProvider {
-
-        /**
-         * Get the package name of the default dialer.
-         *
-         * @param userId the user id
-         *
-         * @return the package name of the default dialer, or {@code null} if none
-         */
-        @Nullable
-        String getDefaultDialer(@UserIdInt int userId);
-    }
-
-    /**
-     * Provider for default home
-     */
-    public interface DefaultHomeProvider {
-
-        /**
-         * Get the package name of the default home.
-         *
-         * @param userId the user id
-         *
-         * @return the package name of the default home, or {@code null} if none
-         */
-        @Nullable
-        String getDefaultHome(@UserIdInt int userId);
-
-        /**
-         * Set the package name of the default home.
-         *
-         * @param packageName package name of the default home, or {@code null} to remove
-         * @param userId the user id
-         * @param callback the callback made after the default home as been updated
-         */
-        void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId,
-                @NonNull Consumer<Boolean> callback);
-    }
-
-    public abstract void systemReady();
+    void systemReady();
 
     /**
      * Get whether permission review is required for a package.
@@ -152,7 +64,7 @@
      * @return whether permission review is required
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    public abstract boolean isPermissionsReviewRequired(@NonNull String packageName,
+    boolean isPermissionsReviewRequired(@NonNull String packageName,
             @UserIdInt int userId);
 
     /**
@@ -167,7 +79,7 @@
      * @param allPackages All currently known packages
      * @param callback Callback to call after permission changes
      */
-    public abstract void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdate);
+    void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdate);
 
     /**
      * Reset the runtime permission state changes for a package.
@@ -178,7 +90,7 @@
      * @param userId the user ID
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    public abstract void resetRuntimePermissions(@NonNull AndroidPackage pkg,
+    void resetRuntimePermissions(@NonNull AndroidPackage pkg,
             @UserIdInt int userId);
 
     /**
@@ -187,7 +99,7 @@
      * @param userId the user ID
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    public abstract void resetAllRuntimePermissions(@UserIdInt int userId);
+    void resetAllRuntimePermissions(@UserIdInt int userId);
 
     /**
      * Read legacy permission state from package settings.
@@ -196,7 +108,7 @@
      * {@code PackageSetting} which is a implementation detail that permission should not know.
      * Instead, it should retrieve the legacy state via a defined API.
      */
-    public abstract void readLegacyPermissionStateTEMP();
+    void readLegacyPermissionStateTEMP();
 
     /**
      * Write legacy permission state to package settings.
@@ -204,12 +116,7 @@
      * TODO(zhanghai): This is a temporary method and should be removed once we migrated persistence
      * for permission.
      */
-    public abstract void writeLegacyPermissionStateTEMP();
-
-    /**
-     * Notify that a user has been removed and its permission state should be removed as well.
-     */
-    public abstract void onUserRemoved(@UserIdInt int userId);
+    void writeLegacyPermissionStateTEMP();
 
     /**
      * Get all the permissions granted to a package.
@@ -220,8 +127,7 @@
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
     @NonNull
-    public abstract Set<String> getGrantedPermissions(@NonNull String packageName,
-            @UserIdInt int userId);
+    Set<String> getGrantedPermissions(@NonNull String packageName, @UserIdInt int userId);
 
     /**
      * Get the GIDs of a permission.
@@ -232,7 +138,7 @@
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
     @NonNull
-    public abstract int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId);
+    int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId);
 
     /**
      * Get the packages that have requested an app op permission.
@@ -242,172 +148,40 @@
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
     @NonNull
-    public abstract String[] getAppOpPermissionPackages(@NonNull String permissionName);
+    String[] getAppOpPermissionPackages(@NonNull String permissionName);
 
     /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
     @Nullable
-    public abstract Permission getPermissionTEMP(@NonNull String permName);
+    Permission getPermissionTEMP(@NonNull String permName);
 
     /** Get all permissions that have a certain protection */
-    public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtection(
+    @NonNull
+    ArrayList<PermissionInfo> getAllPermissionsWithProtection(
             @PermissionInfo.Protection int protection);
 
     /** Get all permissions that have certain protection flags */
-    public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags(
+    @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags(
             @PermissionInfo.ProtectionFlags int protectionFlags);
 
     /**
-     * Returns the delegate used to influence permission checking.
+     * Start delegate the permission identity of the shell UID to the given UID.
      *
-     * @return The delegate instance.
+     * @param uid the UID to delegate shell permission identity to
+     * @param packageName the name of the package to delegate shell permission identity to
+     * @param permissionNames the names of the permissions to delegate shell permission identity
+     *                       for, or {@code null} for all permissions
      */
-    public abstract @Nullable CheckPermissionDelegate getCheckPermissionDelegate();
+    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+    void startShellPermissionIdentityDelegation(int uid,
+            @NonNull String packageName, @Nullable List<String> permissionNames);
 
     /**
-     * Sets the delegate used to influence permission checking.
+     * Stop delegating the permission identity of the shell UID.
      *
-     * @param delegate A delegate instance or {@code null} to clear.
+     * @see #startShellPermissionIdentityDelegation(int, String, List)
      */
-    public abstract void setCheckPermissionDelegate(@Nullable CheckPermissionDelegate delegate);
-
-    /**
-     * Sets the dialer application packages provider.
-     * @param provider The provider.
-     */
-    public abstract void setDialerAppPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Set the location extra packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract  void setLocationExtraPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the location provider packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract void setLocationPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the SIM call manager packages provider.
-     * @param provider The provider.
-     */
-    public abstract void setSimCallManagerPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the SMS application packages provider.
-     * @param provider The provider.
-     */
-    public abstract void setSmsAppPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the sync adapter packages provider.
-     * @param provider The provider.
-     */
-    public abstract void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider);
-
-    /**
-     * Sets the Use Open Wifi packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract void setUseOpenWifiAppPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the voice interaction packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the default browser provider.
-     *
-     * @param provider the provider
-     */
-    public abstract void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider);
-
-    /**
-     * Sets the package name of the default browser provider for the given user.
-     *
-     * @param packageName The package name of the default browser or {@code null}
-     *          to clear the default browser
-     * @param async If {@code true}, set the default browser asynchronously,
-     *          otherwise set it synchronously
-     * @param doGrant If {@code true} and if {@code packageName} is not {@code null},
-     *          perform default permission grants on the browser, otherwise skip the
-     *          default permission grants.
-     * @param userId The user to set the default browser for.
-     */
-    public abstract void setDefaultBrowser(@Nullable String packageName, boolean async,
-            boolean doGrant, @UserIdInt int userId);
-
-    /**
-     * Sets the default dialer provider.
-     *
-     * @param provider the provider
-     */
-    public abstract void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider);
-
-    /**
-     * Sets the default home provider.
-     *
-     * @param provider the provider
-     */
-    public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider);
-
-    /**
-     * Asynchronously sets the package name of the default home provider for the given user.
-     *
-     * @param packageName The package name of the default home or {@code null}
-     *          to clear the default browser
-     * @param userId The user to set the default browser for
-     * @param callback Invoked after the default home has been set
-     */
-    public abstract void setDefaultHome(@Nullable String packageName, @UserIdInt int userId,
-            @NonNull Consumer<Boolean> callback);
-
-    /**
-     * Returns the default browser package name for the given user.
-     */
-    @Nullable
-    public abstract String getDefaultBrowser(@UserIdInt int userId);
-
-    /**
-     * Returns the default dialer package name for the given user.
-     */
-    @Nullable
-    public abstract String getDefaultDialer(@UserIdInt int userId);
-
-    /**
-     * Returns the default home package name for the given user.
-     */
-    @Nullable
-    public abstract String getDefaultHome(@UserIdInt int userId);
-
-    /**
-     * Requests granting of the default permissions to the current default Use Open Wifi app.
-     * @param packageName The default use open wifi package name.
-     * @param userId The user for which to grant the permissions.
-     */
-    public abstract void grantDefaultPermissionsToDefaultSimCallManager(
-            @NonNull String packageName, @UserIdInt int userId);
-
-    /**
-     * Requests granting of the default permissions to the current default Use Open Wifi app.
-     * @param packageName The default use open wifi package name.
-     * @param userId The user for which to grant the permissions.
-     */
-    public abstract void grantDefaultPermissionsToDefaultUseOpenWifiApp(
-            @NonNull String packageName, @UserIdInt int userId);
-
-    /** Called when a new user has been created. */
-    public abstract void onNewUserCreated(@UserIdInt int userId);
-
-    /**
-     * Removes invalid permissions which are not {@link PermissionInfo#FLAG_HARD_RESTRICTED} or
-     * {@link PermissionInfo#FLAG_SOFT_RESTRICTED} from the input.
-     */
-    public abstract void retainHardAndSoftRestrictedPermissions(
-            @NonNull List<String> permissionNames);
+    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+    void stopShellPermissionIdentityDelegation();
 
     /**
      * Read legacy permissions from legacy permission settings.
@@ -416,8 +190,7 @@
      * {@code LegacyPermissionSettings} which is a implementation detail that permission should not
      * know. Instead, it should retrieve the legacy permissions via a defined API.
      */
-    public abstract void readLegacyPermissionsTEMP(
-            @NonNull LegacyPermissionSettings legacyPermissionSettings);
+    void readLegacyPermissionsTEMP(@NonNull LegacyPermissionSettings legacyPermissionSettings);
 
     /**
      * Write legacy permissions to legacy permission settings.
@@ -425,8 +198,23 @@
      * TODO(zhanghai): This is a temporary method and should be removed once we migrated persistence
      * for permission.
      */
-    public abstract void writeLegacyPermissionsTEMP(
-            @NonNull LegacyPermissionSettings legacyPermissionSettings);
+    void writeLegacyPermissionsTEMP(@NonNull LegacyPermissionSettings legacyPermissionSettings);
+
+    /**
+     * Callback when a user has been created.
+     *
+     * @param userId the created user ID
+     */
+    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+    void onUserCreated(@UserIdInt int userId);
+
+    /**
+     * Callback when a user has been removed.
+     *
+     * @param userId the removed user ID
+     */
+    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+    void onUserRemoved(@UserIdInt int userId);
 
     /**
      * Callback when a package has been added.
@@ -436,7 +224,7 @@
      * @param oldPkg the old package, or {@code null} if none
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    public abstract void onPackageAdded(@NonNull AndroidPackage pkg, boolean isInstantApp,
+    void onPackageAdded(@NonNull AndroidPackage pkg, boolean isInstantApp,
             @Nullable AndroidPackage oldPkg);
 
     /**
@@ -447,8 +235,8 @@
      * @param userId the user ID this package is installed for
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    public abstract void onPackageInstalled(@NonNull AndroidPackage pkg,
-            @NonNull PackageInstalledParams params, @UserIdInt int userId);
+    void onPackageInstalled(@NonNull AndroidPackage pkg, @NonNull PackageInstalledParams params,
+            @UserIdInt int userId);
 
     /**
      * Callback when a package has been removed.
@@ -456,7 +244,7 @@
      * @param pkg the removed package
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    public abstract void onPackageRemoved(@NonNull AndroidPackage pkg);
+    void onPackageRemoved(@NonNull AndroidPackage pkg);
 
     /**
      * Callback when a package has been uninstalled.
@@ -473,9 +261,8 @@
      * @param userId the user ID the package is uninstalled for
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    public abstract void onPackageUninstalled(@NonNull String packageName, int appId,
-            @Nullable AndroidPackage pkg, @NonNull List<AndroidPackage> sharedUserPkgs,
-            @UserIdInt int userId);
+    void onPackageUninstalled(@NonNull String packageName, int appId, @Nullable AndroidPackage pkg,
+            @NonNull List<AndroidPackage> sharedUserPkgs, @UserIdInt int userId);
 
     /**
      * Check whether a permission can be propagated to instant app.
@@ -483,7 +270,23 @@
      * @param permissionName the name of the permission
      * @return whether the permission can be propagated
      */
-    public abstract boolean canPropagatePermissionToInstantApp(@NonNull String permissionName);
+    boolean canPropagatePermissionToInstantApp(@NonNull String permissionName);
+
+    /**
+     * Listener for package permission state (permissions or flags) changes.
+     */
+    interface OnRuntimePermissionStateChangedListener {
+
+        /**
+         * Called when the runtime permission state (permissions or flags) changed.
+         *
+         * @param packageName The package for which the change happened.
+         * @param userId the user id for which the change happened.
+         */
+        @Nullable
+        void onRuntimePermissionStateChanged(@NonNull String packageName,
+                @UserIdInt int userId);
+    }
 
     /**
      * The permission-related parameters passed in for package installation.
@@ -491,7 +294,7 @@
      * @see android.content.pm.PackageInstaller.SessionParams
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    public static final class PackageInstalledParams {
+    final class PackageInstalledParams {
         /**
          * A static instance whose parameters are all in their default state.
          */
diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
index 321bb8c..cc1f8d6 100644
--- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
+++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
@@ -158,7 +158,6 @@
         // switch there is no need to register for a callback.
         boolean shouldListenToLidSwitch = false;
 
-        final SensorManager sensorManager = mContext.getSystemService(SensorManager.class);
         // The set of Sensor(s) that this instance should register to receive SensorEvent(s) from.
         final ArraySet<Sensor> sensorsToListenTo = new ArraySet<>();
 
@@ -182,19 +181,10 @@
             List<SensorCondition> sensorConditions = conditions.getSensor();
             for (int j = 0; j < sensorConditions.size(); j++) {
                 SensorCondition sensorCondition = sensorConditions.get(j);
-                final int expectedSensorType = sensorCondition.getType().intValue();
+                final String expectedSensorType = sensorCondition.getType();
                 final String expectedSensorName = sensorCondition.getName();
 
-                List<Sensor> sensors = sensorManager.getSensorList(expectedSensorType);
-                Sensor foundSensor = null;
-                for (int sensorIndex = 0; sensorIndex < sensors.size(); sensorIndex++) {
-                    Sensor sensor = sensors.get(sensorIndex);
-                    if (sensor.getName().equals(expectedSensorName)) {
-                        foundSensor = sensor;
-                        break;
-                    }
-                }
-
+                final Sensor foundSensor = findSensor(expectedSensorType, expectedSensorName);
                 if (foundSensor == null) {
                     throw new IllegalStateException("Failed to find Sensor with type: "
                             + expectedSensorType + " and name: " + expectedSensorName);
@@ -221,12 +211,33 @@
             inputManager.registerLidSwitchCallback(this);
         }
 
+        final SensorManager sensorManager = mContext.getSystemService(SensorManager.class);
         for (int i = 0; i < sensorsToListenTo.size(); i++) {
             Sensor sensor = sensorsToListenTo.valueAt(i);
             sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST);
         }
     }
 
+    @Nullable
+    private Sensor findSensor(String type, String name) {
+        final SensorManager sensorManager = mContext.getSystemService(SensorManager.class);
+        final List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
+        for (int sensorIndex = 0; sensorIndex < sensors.size(); sensorIndex++) {
+            final Sensor sensor = sensors.get(sensorIndex);
+            final String sensorType = sensor.getStringType();
+            final String sensorName = sensor.getName();
+
+            if (sensorType == null || sensorName == null) {
+                continue;
+            }
+
+            if (sensorType.equals(type) && sensorName.equals(name)) {
+                return sensor;
+            }
+        }
+        return null;
+    }
+
     @Override
     public void setListener(Listener listener) {
         synchronized (mLock) {
diff --git a/services/core/java/com/android/server/policy/KeyCombinationManager.java b/services/core/java/com/android/server/policy/KeyCombinationManager.java
new file mode 100644
index 0000000..84ac124
--- /dev/null
+++ b/services/core/java/com/android/server/policy/KeyCombinationManager.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.policy;
+
+import static android.view.KeyEvent.KEYCODE_POWER;
+
+import android.os.SystemClock;
+import android.util.SparseLongArray;
+import android.view.KeyEvent;
+
+import com.android.internal.util.ToBooleanFunction;
+
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+/**
+ * Handles a mapping of two keys combination.
+ */
+public class KeyCombinationManager {
+    private static final String TAG = "KeyCombinationManager";
+
+    // Store the received down time of keycode.
+    private final SparseLongArray mDownTimes = new SparseLongArray(2);
+    private final ArrayList<TwoKeysCombinationRule> mRules = new ArrayList();
+
+    // Selected rules according to current key down.
+    private final ArrayList<TwoKeysCombinationRule> mActiveRules = new ArrayList();
+    // The rule has been triggered by current keys.
+    private TwoKeysCombinationRule mTriggeredRule;
+
+    // Keys in a key combination must be pressed within this interval of each other.
+    private static final long COMBINE_KEY_DELAY_MILLIS = 150;
+
+    /**
+     *  Rule definition for two keys combination.
+     *  E.g : define volume_down + power key.
+     *  <pre class="prettyprint">
+     *  TwoKeysCombinationRule rule =
+     *      new TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN, KEYCODE_POWER) {
+     *           boolean preCondition() { // check if it needs to intercept key }
+     *           void execute() { // trigger action }
+     *           void cancel() { // cancel action }
+     *       };
+     *  </pre>
+     */
+    abstract static class TwoKeysCombinationRule {
+        private int mKeyCode1;
+        private int mKeyCode2;
+
+        TwoKeysCombinationRule(int keyCode1, int keyCode2) {
+            mKeyCode1 = keyCode1;
+            mKeyCode2 = keyCode2;
+        }
+
+        boolean preCondition() {
+            return true;
+        }
+
+        boolean shouldInterceptKey(int keyCode) {
+            return preCondition() && (keyCode == mKeyCode1 || keyCode == mKeyCode2);
+        }
+
+        boolean shouldInterceptKeys(SparseLongArray downTimes) {
+            final long now = SystemClock.uptimeMillis();
+            if (downTimes.get(mKeyCode1) > 0
+                    && downTimes.get(mKeyCode2) > 0
+                    && now <= downTimes.get(mKeyCode1) + COMBINE_KEY_DELAY_MILLIS
+                    && now <= downTimes.get(mKeyCode2) + COMBINE_KEY_DELAY_MILLIS) {
+                return true;
+            }
+            return false;
+        }
+
+        abstract void execute();
+        abstract void cancel();
+
+        @Override
+        public String toString() {
+            return "KeyCode1 = " + KeyEvent.keyCodeToString(mKeyCode1)
+                    + ", KeyCode2 = " +  KeyEvent.keyCodeToString(mKeyCode2);
+        }
+    }
+
+    public KeyCombinationManager() {
+    }
+
+    void addRule(TwoKeysCombinationRule rule) {
+        mRules.add(rule);
+    }
+
+    /**
+     * Check if the key event could be triggered by combine key rule before dispatching to a window.
+     */
+    void interceptKey(KeyEvent event, boolean interactive) {
+        final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
+        final int keyCode = event.getKeyCode();
+        final int count = mActiveRules.size();
+        final long eventTime = event.getEventTime();
+
+        if (interactive && down) {
+            if (mDownTimes.size() > 0) {
+                if (count > 0
+                        && eventTime > mDownTimes.valueAt(0) + COMBINE_KEY_DELAY_MILLIS) {
+                    // exceed time from first key down.
+                    forAllRules(mActiveRules, (rule)-> rule.cancel());
+                    mActiveRules.clear();
+                    return;
+                } else if (count == 0) { // has some key down but no active rule exist.
+                    return;
+                }
+            }
+
+            if (mDownTimes.get(keyCode) == 0) {
+                mDownTimes.put(keyCode, eventTime);
+            } else {
+                // ignore old key, maybe a repeat key.
+                return;
+            }
+
+            if (mDownTimes.size() == 1) {
+                mTriggeredRule = null;
+                // check first key and pick active rules.
+                forAllRules(mRules, (rule)-> {
+                    if (rule.shouldInterceptKey(keyCode)) {
+                        mActiveRules.add(rule);
+                    }
+                });
+            } else {
+                // Ignore if rule already triggered.
+                if (mTriggeredRule != null) {
+                    return;
+                }
+
+                // check if second key can trigger rule, or remove the non-match rule.
+                forAllActiveRules((rule) -> {
+                    if (!rule.shouldInterceptKeys(mDownTimes)) {
+                        return false;
+                    }
+                    rule.execute();
+                    mTriggeredRule = rule;
+                    return true;
+                });
+                mActiveRules.clear();
+                if (mTriggeredRule != null) {
+                    mActiveRules.add(mTriggeredRule);
+                }
+            }
+        } else {
+            mDownTimes.delete(keyCode);
+            for (int index = count - 1; index >= 0; index--) {
+                final TwoKeysCombinationRule rule = mActiveRules.get(index);
+                if (rule.shouldInterceptKey(keyCode)) {
+                    rule.cancel();
+                    mActiveRules.remove(index);
+                }
+            }
+        }
+    }
+
+    /**
+     * Return the interceptTimeout to tell InputDispatcher when is ready to deliver to window.
+     */
+    long getKeyInterceptTimeout(int keyCode) {
+        if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) {
+            return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS;
+        }
+        return 0;
+    }
+
+    /**
+     * True if the key event had been handled.
+     */
+    boolean isKeyConsumed(KeyEvent event) {
+        if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) {
+            return false;
+        }
+        return mTriggeredRule != null && mTriggeredRule.shouldInterceptKey(event.getKeyCode());
+    }
+
+    /**
+     * True if power key is the candidate.
+     */
+    boolean isPowerKeyIntercepted() {
+        if (forAllActiveRules((rule) -> rule.shouldInterceptKey(KEYCODE_POWER))) {
+            // return false if only if power key pressed.
+            return mDownTimes.size() > 1 || mDownTimes.get(KEYCODE_POWER) == 0;
+        }
+        return false;
+    }
+
+    /**
+     * Traverse each item of rules.
+     */
+    private void forAllRules(
+            ArrayList<TwoKeysCombinationRule> rules, Consumer<TwoKeysCombinationRule> callback) {
+        final int count = rules.size();
+        for (int index = 0; index < count; index++) {
+            final TwoKeysCombinationRule rule = rules.get(index);
+            callback.accept(rule);
+        }
+    }
+
+    /**
+     * Traverse each item of active rules until some rule can be applied, otherwise return false.
+     */
+    private boolean forAllActiveRules(ToBooleanFunction<TwoKeysCombinationRule> callback) {
+        final int count = mActiveRules.size();
+        for (int index = 0; index < count; index++) {
+            final TwoKeysCombinationRule rule = mActiveRules.get(index);
+            if (callback.apply(rule)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/services/core/java/com/android/server/policy/OWNERS b/services/core/java/com/android/server/policy/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/services/core/java/com/android/server/policy/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 8beec35eb..ea985df 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -35,7 +35,13 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.Display.STATE_OFF;
+import static android.view.KeyEvent.KEYCODE_BACK;
+import static android.view.KeyEvent.KEYCODE_DPAD_CENTER;
+import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
+import static android.view.KeyEvent.KEYCODE_POWER;
 import static android.view.KeyEvent.KEYCODE_UNKNOWN;
+import static android.view.KeyEvent.KEYCODE_VOLUME_DOWN;
+import static android.view.KeyEvent.KEYCODE_VOLUME_UP;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
@@ -202,6 +208,7 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemServiceManager;
 import com.android.server.inputmethod.InputMethodManagerInternal;
+import com.android.server.policy.KeyCombinationManager.TwoKeysCombinationRule;
 import com.android.server.policy.keyguard.KeyguardServiceDelegate;
 import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
 import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback;
@@ -405,7 +412,7 @@
     private boolean mEnableCarDockHomeCapture = true;
 
     boolean mBootMessageNeedsHiding;
-    KeyguardServiceDelegate mKeyguardDelegate;
+    private KeyguardServiceDelegate mKeyguardDelegate;
     private boolean mKeyguardBound;
     final Runnable mWindowManagerDrawCallback = new Runnable() {
         @Override
@@ -422,8 +429,8 @@
         }
     };
 
-    GlobalActions mGlobalActions;
-    Handler mHandler;
+    private GlobalActions mGlobalActions;
+    private Handler mHandler;
 
     // FIXME This state is shared between the input reader and handler thread.
     // Technically it's broken and buggy but it has been like this for many years
@@ -547,34 +554,14 @@
     private boolean mGoToSleepOnButtonPressTheaterMode;
 
     // Screenshot trigger states
-    // Time to volume and power must be pressed within this interval of each other.
-    private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150;
     // Increase the chord delay when taking a screenshot from the keyguard
     private static final float KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER = 2.5f;
-    private boolean mScreenshotChordEnabled;
-    private boolean mScreenshotChordVolumeDownKeyTriggered;
-    private long mScreenshotChordVolumeDownKeyTime;
-    private boolean mScreenshotChordVolumeDownKeyConsumed;
-    private boolean mA11yShortcutChordVolumeUpKeyTriggered;
-    private long mA11yShortcutChordVolumeUpKeyTime;
-    private boolean mA11yShortcutChordVolumeUpKeyConsumed;
-
-    private boolean mScreenshotChordPowerKeyTriggered;
-    private long mScreenshotChordPowerKeyTime;
 
     // Ringer toggle should reuse timing and triggering from screenshot power and a11y vol up
-    private int mRingerToggleChord = VOLUME_HUSH_OFF;
+    int mRingerToggleChord = VOLUME_HUSH_OFF;
 
     private static final long BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS = 1000;
 
-    private boolean mBugreportTvKey1Pressed;
-    private boolean mBugreportTvKey2Pressed;
-    private boolean mBugreportTvScheduled;
-
-    private boolean mAccessibilityTvKey1Pressed;
-    private boolean mAccessibilityTvKey2Pressed;
-    private boolean mAccessibilityTvScheduled;
-
     /* The number of steps between min and max brightness */
     private static final int BRIGHTNESS_STEPS = 10;
 
@@ -603,6 +590,8 @@
 
     private int mPowerButtonSuppressionDelayMillis = POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS;
 
+    private KeyCombinationManager mKeyCombinationManager;
+
     private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
     private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
     private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
@@ -900,15 +889,6 @@
 
         mWindowManagerFuncs.onPowerKeyDown(interactive);
 
-        // Latch power key state to detect screenshot chord.
-        if (interactive && !mScreenshotChordPowerKeyTriggered
-                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
-            mScreenshotChordPowerKeyTriggered = true;
-            mScreenshotChordPowerKeyTime = event.getDownTime();
-            interceptScreenshotChord();
-            interceptRingerToggleChord();
-        }
-
         // Stop ringing or end call if configured to do so when power is pressed.
         TelecomManager telecomManager = getTelecommService();
         boolean hungUp = false;
@@ -946,9 +926,8 @@
 
         // If the power key has still not yet been handled, then detect short
         // press, long press, or multi press and decide what to do.
-        mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered
-                || mA11yShortcutChordVolumeUpKeyTriggered || gesturedServiceIntercepted
-                || handledByPowerManager;
+        mPowerKeyHandled = hungUp || gesturedServiceIntercepted
+                || handledByPowerManager || mKeyCombinationManager.isPowerKeyIntercepted();
         if (!mPowerKeyHandled) {
             if (interactive) {
                 // When interactive, we're already awake.
@@ -1004,8 +983,6 @@
 
     private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
         final boolean handled = canceled || mPowerKeyHandled;
-        mScreenshotChordPowerKeyTriggered = false;
-        cancelPendingScreenshotChordAction();
         cancelPendingPowerKeyAction();
 
         if (!handled) {
@@ -1315,52 +1292,22 @@
     }
 
     private void interceptScreenshotChord() {
-        if (mScreenshotChordEnabled
-                && mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered
-                && !mA11yShortcutChordVolumeUpKeyTriggered) {
-            final long now = SystemClock.uptimeMillis();
-            if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
-                    && now <= mScreenshotChordPowerKeyTime
-                            + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
-                mScreenshotChordVolumeDownKeyConsumed = true;
-                cancelPendingPowerKeyAction();
-                mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
-                mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_CHORD);
-                mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay());
-            }
-        }
+        mHandler.removeCallbacks(mScreenshotRunnable);
+        mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
+        mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_CHORD);
+        mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay());
     }
 
     private void interceptAccessibilityShortcutChord() {
-        if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(isKeyguardLocked())
-                && mScreenshotChordVolumeDownKeyTriggered && mA11yShortcutChordVolumeUpKeyTriggered
-                && !mScreenshotChordPowerKeyTriggered) {
-            final long now = SystemClock.uptimeMillis();
-            if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
-                    && now <= mA11yShortcutChordVolumeUpKeyTime
-                    + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
-                mScreenshotChordVolumeDownKeyConsumed = true;
-                mA11yShortcutChordVolumeUpKeyConsumed = true;
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT),
-                        getAccessibilityShortcutTimeout());
-            }
-        }
+        mHandler.removeMessages(MSG_ACCESSIBILITY_SHORTCUT);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT),
+                getAccessibilityShortcutTimeout());
     }
 
     private void interceptRingerToggleChord() {
-        if (mRingerToggleChord != Settings.Secure.VOLUME_HUSH_OFF
-                && mScreenshotChordPowerKeyTriggered && mA11yShortcutChordVolumeUpKeyTriggered) {
-            final long now = SystemClock.uptimeMillis();
-            if (now <= mA11yShortcutChordVolumeUpKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
-                    && now <= mScreenshotChordPowerKeyTime
-                    + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
-                mA11yShortcutChordVolumeUpKeyConsumed = true;
-                cancelPendingPowerKeyAction();
-
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RINGER_TOGGLE_CHORD),
-                        getRingerToggleChordDelay());
-            }
-        }
+        mHandler.removeMessages(MSG_RINGER_TOGGLE_CHORD);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RINGER_TOGGLE_CHORD),
+                getRingerToggleChordDelay());
     }
 
     private long getAccessibilityShortcutTimeout() {
@@ -1942,9 +1889,6 @@
         mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_safeModeEnabledVibePattern);
 
-        mScreenshotChordEnabled = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_enableScreenshotChord);
-
         mGlobalKeyManager = new GlobalKeyManager(mContext);
 
         // Controls rotation and the like.
@@ -1980,6 +1924,92 @@
                         mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged();
                     }
                 });
+        initKeyCombinationRules();
+    }
+
+    private void initKeyCombinationRules() {
+        mKeyCombinationManager = new KeyCombinationManager();
+        final boolean screenshotChordEnabled = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_enableScreenshotChord);
+
+        if (screenshotChordEnabled) {
+            mKeyCombinationManager.addRule(
+                    new TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN, KEYCODE_POWER) {
+                        @Override
+                        void execute() {
+                            cancelPendingPowerKeyAction();
+                            interceptScreenshotChord();
+                        }
+                        @Override
+                        void cancel() {
+                            cancelPendingScreenshotChordAction();
+                        }
+                    });
+        }
+
+        mKeyCombinationManager.addRule(
+                new TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN, KEYCODE_VOLUME_UP) {
+                    @Override
+                    boolean preCondition() {
+                        return mAccessibilityShortcutController
+                                .isAccessibilityShortcutAvailable(isKeyguardLocked());
+                    }
+                    @Override
+                    void execute() {
+                        interceptAccessibilityShortcutChord();
+                    }
+                    @Override
+                    void cancel() {
+                        cancelPendingAccessibilityShortcutAction();
+                    }
+                });
+
+        mKeyCombinationManager.addRule(
+                new TwoKeysCombinationRule(KEYCODE_VOLUME_UP, KEYCODE_POWER) {
+                    @Override
+                    boolean preCondition() {
+                        return mRingerToggleChord != VOLUME_HUSH_OFF;
+                    }
+                    @Override
+                    void execute() {
+                        cancelPendingPowerKeyAction();
+                        interceptRingerToggleChord();
+                    }
+                    @Override
+                    void cancel() {
+                        cancelPendingRingerToggleChordAction();
+                    }
+                });
+
+        if (mHasFeatureLeanback) {
+            mKeyCombinationManager.addRule(
+                    new TwoKeysCombinationRule(KEYCODE_BACK, KEYCODE_DPAD_DOWN) {
+                        @Override
+                        void execute() {
+                            cancelPendingBackKeyAction();
+                            interceptAccessibilityGestureTv();
+                        }
+
+                        @Override
+                        void cancel() {
+                            cancelAccessibilityGestureTv();
+                        }
+                    });
+
+            mKeyCombinationManager.addRule(
+                    new TwoKeysCombinationRule(KEYCODE_DPAD_CENTER, KEYCODE_BACK) {
+                        @Override
+                        void execute() {
+                            cancelPendingBackKeyAction();
+                            interceptBugreportGestureTv();
+                        }
+
+                        @Override
+                        void cancel() {
+                            cancelBugreportGestureTv();
+                        }
+                    });
+        }
     }
 
     /**
@@ -2383,15 +2413,6 @@
             wm = (WindowManager) context.getSystemService(WINDOW_SERVICE);
             view = win.getDecorView();
 
-            // Ignore to show splash screen if the decorView is not opaque.
-            if (!view.isOpaque()) {
-                if (DEBUG_SPLASH_SCREEN) {
-                    Slog.d(TAG, "addSplashScreen: the view of " + packageName
-                            + " is not opaque, cancel it");
-                }
-                return null;
-            }
-
             if (DEBUG_SPLASH_SCREEN) Slog.d(TAG, "Adding splash screen window for "
                 + packageName + " / " + appToken + ": " + (view.getParent() != null ? view : null));
 
@@ -2552,70 +2573,15 @@
                     + repeatCount + " keyguardOn=" + keyguardOn + " canceled=" + canceled);
         }
 
-        // If we think we might have a volume down & power key chord on the way
-        // but we're not sure, then tell the dispatcher to wait a little while and
-        // try again later before dispatching.
-        if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
-            if (mScreenshotChordVolumeDownKeyTriggered && !mScreenshotChordPowerKeyTriggered) {
-                final long now = SystemClock.uptimeMillis();
-                final long timeoutTime = mScreenshotChordVolumeDownKeyTime
-                        + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
-                if (now < timeoutTime) {
-                    return timeoutTime - now;
-                }
-            }
-            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
-                    && mScreenshotChordVolumeDownKeyConsumed) {
-                if (!down) {
-                    mScreenshotChordVolumeDownKeyConsumed = false;
-                }
-                return -1;
-            }
+        if (mKeyCombinationManager.isKeyConsumed(event)) {
+            return -1;
         }
 
-        // If an accessibility shortcut might be partially complete, hold off dispatching until we
-        // know if it is complete or not
-        if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(false)
-                && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
-            if (mScreenshotChordVolumeDownKeyTriggered ^ mA11yShortcutChordVolumeUpKeyTriggered) {
-                final long now = SystemClock.uptimeMillis();
-                final long timeoutTime = (mScreenshotChordVolumeDownKeyTriggered
-                        ? mScreenshotChordVolumeDownKeyTime : mA11yShortcutChordVolumeUpKeyTime)
-                        + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
-                if (now < timeoutTime) {
-                    return timeoutTime - now;
-                }
-            }
-            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mScreenshotChordVolumeDownKeyConsumed) {
-                if (!down) {
-                    mScreenshotChordVolumeDownKeyConsumed = false;
-                }
-                return -1;
-            }
-            if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mA11yShortcutChordVolumeUpKeyConsumed) {
-                if (!down) {
-                    mA11yShortcutChordVolumeUpKeyConsumed = false;
-                }
-                return -1;
-            }
-        }
-
-        // If a ringer toggle chord could be on the way but we're not sure, then tell the dispatcher
-        // to wait a little while and try again later before dispatching.
-        if (mRingerToggleChord != VOLUME_HUSH_OFF && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
-            if (mA11yShortcutChordVolumeUpKeyTriggered && !mScreenshotChordPowerKeyTriggered) {
-                final long now = SystemClock.uptimeMillis();
-                final long timeoutTime = mA11yShortcutChordVolumeUpKeyTime
-                        + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
-                if (now < timeoutTime) {
-                    return timeoutTime - now;
-                }
-            }
-            if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mA11yShortcutChordVolumeUpKeyConsumed) {
-                if (!down) {
-                    mA11yShortcutChordVolumeUpKeyConsumed = false;
-                }
-                return -1;
+        if ((flags & KeyEvent.FLAG_FALLBACK) == 0) {
+            final long now = SystemClock.uptimeMillis();
+            final long interceptTimeout = mKeyCombinationManager.getKeyInterceptTimeout(keyCode);
+            if (now < interceptTimeout) {
+                return interceptTimeout - now;
             }
         }
 
@@ -2774,8 +2740,6 @@
         } else if (keyCode == KeyEvent.KEYCODE_TAB && event.isMetaPressed()) {
             // Pass through keyboard navigation keys.
             return 0;
-        } else if (mHasFeatureLeanback && interceptBugreportGestureTv(keyCode, down)) {
-            return -1;
         } else if (keyCode == KeyEvent.KEYCODE_ALL_APPS) {
             if (!down) {
                 mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
@@ -2978,53 +2942,30 @@
     /**
      * TV only: recognizes a remote control gesture for capturing a bug report.
      */
-    private boolean interceptBugreportGestureTv(int keyCode, boolean down) {
+    private void interceptBugreportGestureTv() {
+        mHandler.removeMessages(MSG_BUGREPORT_TV);
         // The bugreport capture chord is a long press on DPAD CENTER and BACK simultaneously.
-        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
-            mBugreportTvKey1Pressed = down;
-        } else if (keyCode == KeyEvent.KEYCODE_BACK) {
-            mBugreportTvKey2Pressed = down;
-        }
+        Message msg = Message.obtain(mHandler, MSG_BUGREPORT_TV);
+        msg.setAsynchronous(true);
+        mHandler.sendMessageDelayed(msg, BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS);
+    }
 
-        if (mBugreportTvKey1Pressed && mBugreportTvKey2Pressed) {
-            if (!mBugreportTvScheduled) {
-                mBugreportTvScheduled = true;
-                Message msg = Message.obtain(mHandler, MSG_BUGREPORT_TV);
-                msg.setAsynchronous(true);
-                mHandler.sendMessageDelayed(msg, BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS);
-            }
-        } else if (mBugreportTvScheduled) {
-            mHandler.removeMessages(MSG_BUGREPORT_TV);
-            mBugreportTvScheduled = false;
-        }
-
-        return mBugreportTvScheduled;
+    private void cancelBugreportGestureTv() {
+        mHandler.removeMessages(MSG_BUGREPORT_TV);
     }
 
     /**
      * TV only: recognizes a remote control gesture as Accessibility shortcut.
      * Shortcut: Long press (BACK + DPAD_DOWN)
      */
-    private boolean interceptAccessibilityGestureTv(int keyCode, boolean down) {
-        if (keyCode == KeyEvent.KEYCODE_BACK) {
-            mAccessibilityTvKey1Pressed = down;
-        } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
-            mAccessibilityTvKey2Pressed = down;
-        }
-
-        if (mAccessibilityTvKey1Pressed && mAccessibilityTvKey2Pressed) {
-            if (!mAccessibilityTvScheduled) {
-                mAccessibilityTvScheduled = true;
-                Message msg = Message.obtain(mHandler, MSG_ACCESSIBILITY_TV);
-                msg.setAsynchronous(true);
-                mHandler.sendMessageDelayed(msg, getAccessibilityShortcutTimeout());
-            }
-        } else if (mAccessibilityTvScheduled) {
-            mHandler.removeMessages(MSG_ACCESSIBILITY_TV);
-            mAccessibilityTvScheduled = false;
-        }
-
-        return mAccessibilityTvScheduled;
+    private void interceptAccessibilityGestureTv() {
+        mHandler.removeMessages(MSG_ACCESSIBILITY_TV);
+        Message msg = Message.obtain(mHandler, MSG_ACCESSIBILITY_TV);
+        msg.setAsynchronous(true);
+        mHandler.sendMessageDelayed(msg, getAccessibilityShortcutTimeout());
+    }
+    private void cancelAccessibilityGestureTv() {
+        mHandler.removeMessages(MSG_ACCESSIBILITY_TV);
     }
 
     private void requestBugreportForTv() {
@@ -3547,16 +3488,14 @@
         final int displayId = event.getDisplayId();
         final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
 
-        // If screen is off then we treat the case where the keyguard is open but hidden
-        // the same as if it were open and in front.
-        // This will prevent any keys other than the power button from waking the screen
-        // when the keyguard is hidden by another activity.
-        final boolean keyguardActive = (mKeyguardDelegate == null ? false :
-                                            (interactive ?
-                                                isKeyguardShowingAndNotOccluded() :
-                                                mKeyguardDelegate.isShowing()));
-
         if (DEBUG_INPUT) {
+            // If screen is off then we treat the case where the keyguard is open but hidden
+            // the same as if it were open and in front.
+            // This will prevent any keys other than the power button from waking the screen
+            // when the keyguard is hidden by another activity.
+            final boolean keyguardActive = (mKeyguardDelegate != null
+                    && (interactive ? isKeyguardShowingAndNotOccluded() :
+                    mKeyguardDelegate.isShowing()));
             Log.d(TAG, "interceptKeyTq keycode=" + keyCode
                     + " interactive=" + interactive + " keyguardActive=" + keyguardActive
                     + " policyFlags=" + Integer.toHexString(policyFlags));
@@ -3581,7 +3520,7 @@
                 // Reset the pending key
                 mPendingWakeKey = PENDING_KEY_NULL;
             }
-        } else if (!interactive && shouldDispatchInputWhenNonInteractive(displayId, keyCode)) {
+        } else if (shouldDispatchInputWhenNonInteractive(displayId, keyCode)) {
             // If we're currently dozing with the screen on and the keyguard showing, pass the key
             // to the application but preserve its wake key status to make sure we still move
             // from dozing to fully interactive if we would normally go from off to fully
@@ -3613,6 +3552,10 @@
             return result;
         }
 
+        if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+            mKeyCombinationManager.interceptKey(event, interactive);
+        }
+
         // Enable haptics if down and virtual key without multiple repetitions. If this is a hard
         // virtual key such as a navigation bar button, only vibrate if flag is enabled.
         final boolean isNavBarVirtKey = ((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY) != 0);
@@ -3640,46 +3583,6 @@
             case KeyEvent.KEYCODE_VOLUME_DOWN:
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_MUTE: {
-                if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
-                    if (down) {
-                        // Any activity on the vol down button stops the ringer toggle shortcut
-                        cancelPendingRingerToggleChordAction();
-
-                        if (interactive && !mScreenshotChordVolumeDownKeyTriggered
-                                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
-                            mScreenshotChordVolumeDownKeyTriggered = true;
-                            mScreenshotChordVolumeDownKeyTime = event.getDownTime();
-                            mScreenshotChordVolumeDownKeyConsumed = false;
-                            cancelPendingPowerKeyAction();
-                            interceptScreenshotChord();
-                            interceptAccessibilityShortcutChord();
-                        }
-                    } else {
-                        mScreenshotChordVolumeDownKeyTriggered = false;
-                        cancelPendingScreenshotChordAction();
-                        cancelPendingAccessibilityShortcutAction();
-                    }
-                } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
-                    if (down) {
-                        if (interactive && !mA11yShortcutChordVolumeUpKeyTriggered
-                                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
-                            mA11yShortcutChordVolumeUpKeyTriggered = true;
-                            mA11yShortcutChordVolumeUpKeyTime = event.getDownTime();
-                            mA11yShortcutChordVolumeUpKeyConsumed = false;
-                            cancelPendingPowerKeyAction();
-                            cancelPendingScreenshotChordAction();
-                            cancelPendingRingerToggleChordAction();
-
-                            interceptAccessibilityShortcutChord();
-                            interceptRingerToggleChord();
-                        }
-                    } else {
-                        mA11yShortcutChordVolumeUpKeyTriggered = false;
-                        cancelPendingScreenshotChordAction();
-                        cancelPendingAccessibilityShortcutAction();
-                        cancelPendingRingerToggleChordAction();
-                    }
-                }
                 if (down) {
                     sendSystemKeyToStatusBarAsync(event.getKeyCode());
 
@@ -3784,7 +3687,6 @@
                         KeyEvent.actionToString(event.getAction()),
                         mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
                 // Any activity on the power button stops the accessibility shortcut
-                cancelPendingAccessibilityShortcutAction();
                 result &= ~ACTION_PASS_TO_USER;
                 isWakeKey = false; // wake-up will be handled separately
                 if (down) {
@@ -3922,22 +3824,6 @@
             }
         }
 
-        // Intercept the Accessibility keychord for TV (DPAD_DOWN + Back) before the keyevent is
-        // processed through interceptKeyEventBeforeDispatch since Talkback may consume this event
-        // before it has a chance to reach that method.
-        if (mHasFeatureLeanback) {
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_DPAD_DOWN:
-                case KeyEvent.KEYCODE_BACK: {
-                    boolean handled = interceptAccessibilityGestureTv(keyCode, down);
-                    if (handled) {
-                        result &= ~ACTION_PASS_TO_USER;
-                    }
-                    break;
-                }
-            }
-        }
-
         // Intercept the Accessibility keychord (CTRL + ALT + Z) for keyboard users.
         if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(isKeyguardLocked())) {
             switch (keyCode) {
@@ -5388,14 +5274,6 @@
                 pw.print(!mAllowLockscreenWhenOnDisplays.isEmpty());
                 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
                 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
-        if (mHasFeatureLeanback) {
-            pw.print(prefix);
-            pw.print("mAccessibilityTvKey1Pressed="); pw.println(mAccessibilityTvKey1Pressed);
-            pw.print(prefix);
-            pw.print("mAccessibilityTvKey2Pressed="); pw.println(mAccessibilityTvKey2Pressed);
-            pw.print(prefix);
-            pw.print("mAccessibilityTvScheduled="); pw.println(mAccessibilityTvScheduled);
-        }
 
         mGlobalKeyManager.dump(prefix, pw);
 
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index 1e4e0a6..68d038b 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -368,12 +368,6 @@
         }
     }
 
-    boolean setAdaptivePolicyLocked(String settings, String deviceSpecificSettings, int reason) {
-        return setAdaptivePolicyLocked(
-                BatterySaverPolicy.Policy.fromSettings(settings, deviceSpecificSettings),
-                reason);
-    }
-
     boolean setAdaptivePolicyLocked(BatterySaverPolicyConfig config, int reason) {
         return setAdaptivePolicyLocked(BatterySaverPolicy.Policy.fromConfig(config), reason);
     }
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
index ccd4e0f..8eb66cd 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
@@ -26,6 +26,7 @@
 import android.os.PowerManager;
 import android.os.PowerManager.ServiceType;
 import android.os.PowerSaveState;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -48,6 +49,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Class to decide whether to turn on battery saver mode for specific services.
@@ -57,60 +59,81 @@
  *
  * Test: atest com.android.server.power.batterysaver.BatterySaverPolicyTest
  */
-public class BatterySaverPolicy extends ContentObserver {
+public class BatterySaverPolicy extends ContentObserver implements
+        DeviceConfig.OnPropertiesChangedListener {
     private static final String TAG = "BatterySaverPolicy";
 
     static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE.
 
-    private static final String KEY_GPS_MODE = "gps_mode";
-    private static final String KEY_VIBRATION_DISABLED = "vibration_disabled";
-    private static final String KEY_ANIMATION_DISABLED = "animation_disabled";
-    private static final String KEY_SOUNDTRIGGER_DISABLED = "soundtrigger_disabled";
+    @VisibleForTesting
+    static final String KEY_LOCATION_MODE = "location_mode";
+    @VisibleForTesting
+    static final String KEY_DISABLE_VIBRATION = "disable_vibration";
+    @VisibleForTesting
+    static final String KEY_DISABLE_ANIMATION = "disable_animation";
+    @VisibleForTesting
+    static final String KEY_DISABLE_SOUNDTRIGGER = "disable_soundtrigger";
 
     /**
-     * Disable turning on the network firewall when Battery Saver is turned on.
-     * If set to false, the firewall WILL be turned on when Battery Saver is turned on.
-     * If set to true, the firewall WILL NOT be turned on when Battery Saver is turned on.
+     * Turn on the network firewall when Battery Saver is turned on.
+     * If set to false, the firewall WILL NOT be turned on when Battery Saver is turned on.
+     * If set to true, the firewall WILL be turned on when Battery Saver is turned on.
      */
-    private static final String KEY_ACTIVATE_FIREWALL_DISABLED = "firewall_disabled";
+    @VisibleForTesting
+    static final String KEY_ENABLE_FIREWALL = "enable_firewall";
 
     /**
-     * Disable turning on the special low power screen brightness dimming when Battery Saver is
+     * Turn on the special low power screen brightness dimming when Battery Saver is
      * turned on.
-     * If set to false, the screen brightness dimming WILL be turned on by Battery Saver.
-     * If set to true, the screen brightness WILL NOT be turned on by Battery Saver.
+     * If set to false, the screen brightness dimming WILL NOT be turned on by Battery Saver.
+     * If set to true, the screen brightness WILL be turned on by Battery Saver.
      */
-    private static final String KEY_ADJUST_BRIGHTNESS_DISABLED = "adjust_brightness_disabled";
+    @VisibleForTesting
+    static final String KEY_ENABLE_BRIGHTNESS_ADJUSTMENT = "enable_brightness_adjustment";
 
     /**
-     * Disable turning on Data Saver when Battery Saver is turned on.
-     * If set to false, Data Saver WILL be turned on when Battery Saver is turned on.
-     * If set to true, Data Saver WILL NOT be turned on when Battery Saver is turned on.
+     * Turn on Data Saver when Battery Saver is turned on.
+     * If set to false, Data Saver WILL NOT be turned on when Battery Saver is turned on.
+     * If set to true, Data Saver WILL be turned on when Battery Saver is turned on.
      */
-    private static final String KEY_ACTIVATE_DATASAVER_DISABLED = "datasaver_disabled";
+    @VisibleForTesting
+    static final String KEY_ENABLE_DATASAVER = "enable_datasaver";
 
     /**
      * {@code true} if the Policy should advertise to the rest of the system that battery saver
      * is enabled. This advertising could cause other system components to change their
      * behavior. This will not affect other policy flags and what they change.
      */
-    private static final String KEY_ADVERTISE_IS_ENABLED = "advertise_is_enabled";
+    @VisibleForTesting
+    static final String KEY_ADVERTISE_IS_ENABLED = "advertise_is_enabled";
 
-    private static final String KEY_LAUNCH_BOOST_DISABLED = "launch_boost_disabled";
-    private static final String KEY_ADJUST_BRIGHTNESS_FACTOR = "adjust_brightness_factor";
-    private static final String KEY_FULLBACKUP_DEFERRED = "fullbackup_deferred";
-    private static final String KEY_KEYVALUE_DEFERRED = "keyvaluebackup_deferred";
-    private static final String KEY_FORCE_ALL_APPS_STANDBY = "force_all_apps_standby";
-    private static final String KEY_FORCE_BACKGROUND_CHECK = "force_background_check";
-    private static final String KEY_OPTIONAL_SENSORS_DISABLED = "optional_sensors_disabled";
-    private static final String KEY_AOD_DISABLED = "aod_disabled";
+    @VisibleForTesting
+    static final String KEY_DISABLE_LAUNCH_BOOST = "disable_launch_boost";
+    @VisibleForTesting
+    static final String KEY_ADJUST_BRIGHTNESS_FACTOR = "adjust_brightness_factor";
+    @VisibleForTesting
+    static final String KEY_DEFER_FULL_BACKUP = "defer_full_backup";
+    @VisibleForTesting
+    static final String KEY_DEFER_KEYVALUE_BACKUP = "defer_keyvalue_backup";
+    @VisibleForTesting
+    static final String KEY_FORCE_ALL_APPS_STANDBY = "force_all_apps_standby";
+    @VisibleForTesting
+    static final String KEY_FORCE_BACKGROUND_CHECK = "force_background_check";
+    @VisibleForTesting
+    static final String KEY_DISABLE_OPTIONAL_SENSORS = "disable_optional_sensors";
+    @VisibleForTesting
+    static final String KEY_DISABLE_AOD = "disable_aod";
     // Go into deep Doze as soon as the screen turns off.
-    private static final String KEY_QUICK_DOZE_ENABLED = "quick_doze_enabled";
-    private static final String KEY_ENABLE_NIGHT_MODE = "enable_night_mode";
+    @VisibleForTesting
+    static final String KEY_ENABLE_QUICK_DOZE = "enable_quick_doze";
+    @VisibleForTesting
+    static final String KEY_ENABLE_NIGHT_MODE = "enable_night_mode";
 
     private static final String KEY_CPU_FREQ_INTERACTIVE = "cpufreq-i";
     private static final String KEY_CPU_FREQ_NONINTERACTIVE = "cpufreq-n";
 
+    private static final String KEY_SUFFIX_ADAPTIVE = "_adaptive";
+
     @VisibleForTesting
     static final Policy OFF_POLICY = new Policy(
             1f,    /* adjustBrightnessFactor */
@@ -173,10 +196,7 @@
     private String mDeviceSpecificSettingsSource; // For dump() only.
 
     @GuardedBy("mLock")
-    private String mAdaptiveSettings;
-
-    @GuardedBy("mLock")
-    private String mAdaptiveDeviceSpecificSettings;
+    private DeviceConfig.Properties mLastDeviceConfigProperties;
 
     /**
      * A short string describing which battery saver is now enabled, which we dump in the eventlog.
@@ -261,10 +281,6 @@
                 Settings.Global.BATTERY_SAVER_CONSTANTS), false, this);
         mContentResolver.registerContentObserver(Settings.Global.getUriFor(
                 Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS), false, this);
-        mContentResolver.registerContentObserver(Settings.Global.getUriFor(
-                Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS), false, this);
-        mContentResolver.registerContentObserver(Settings.Global.getUriFor(
-                Settings.Global.BATTERY_SAVER_ADAPTIVE_DEVICE_SPECIFIC_CONSTANTS), false, this);
 
         final AccessibilityManager acm = mContext.getSystemService(AccessibilityManager.class);
 
@@ -277,6 +293,10 @@
         mAutomotiveProjectionActive.initialize(
                 uiModeManager.getActiveProjectionTypes() != UiModeManager.PROJECTION_TYPE_NONE);
 
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BATTERY_SAVER,
+                mContext.getMainExecutor(), this);
+        mLastDeviceConfigProperties =
+                DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BATTERY_SAVER);
         onChange(true, null);
     }
 
@@ -305,7 +325,7 @@
 
     /**
      * Notifies listeners of a policy change on the handler thread only if the current policy level
-     * is not {@link POLICY_LEVEL_OFF}.
+     * is not {@link #POLICY_LEVEL_OFF}.
      */
     private void maybeNotifyListenersOfPolicyChange() {
         final BatterySaverPolicyListener[] listeners;
@@ -330,6 +350,55 @@
         refreshSettings();
     }
 
+    @Override
+    public void onPropertiesChanged(DeviceConfig.Properties properties) {
+        // Need to get all of the flags atomically.
+        mLastDeviceConfigProperties =
+                DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BATTERY_SAVER);
+        Policy newAdaptivePolicy = null;
+        Policy newFullPolicy = null;
+
+        boolean changed = false;
+
+        synchronized (mLock) {
+            for (String name : properties.getKeyset()) {
+                if (name == null) {
+                    continue;
+                }
+                if (name.endsWith(KEY_SUFFIX_ADAPTIVE)) {
+                    if (newAdaptivePolicy == null) {
+                        newAdaptivePolicy = Policy.fromSettings("", "",
+                                mLastDeviceConfigProperties, KEY_SUFFIX_ADAPTIVE,
+                                DEFAULT_ADAPTIVE_POLICY);
+                    }
+                } else if (newFullPolicy == null) {
+                    newFullPolicy = Policy.fromSettings(mSettings, mDeviceSpecificSettings,
+                            mLastDeviceConfigProperties, null, DEFAULT_FULL_POLICY);
+                }
+            }
+
+            if (newFullPolicy != null && !mFullPolicy.equals(newFullPolicy)) {
+                mFullPolicy = newFullPolicy;
+                changed |= (mPolicyLevel == POLICY_LEVEL_FULL);
+            }
+
+            if (newAdaptivePolicy != null && !mAdaptivePolicy.equals(newAdaptivePolicy)) {
+                mDefaultAdaptivePolicy = newAdaptivePolicy;
+                // This will override any config set by an external source. This should be fine
+                // for now.
+                // TODO(119261320): make sure it doesn't override what's set externally
+                mAdaptivePolicy = mDefaultAdaptivePolicy;
+                changed |= (mPolicyLevel == POLICY_LEVEL_ADAPTIVE);
+            }
+
+            updatePolicyDependenciesLocked();
+        }
+
+        if (changed) {
+            maybeNotifyListenersOfPolicyChange();
+        }
+    }
+
     private void refreshSettings() {
         synchronized (mLock) {
             // Load the non-device-specific setting.
@@ -349,13 +418,7 @@
                 mDeviceSpecificSettingsSource = "(overlay)";
             }
 
-            final String adaptiveSetting =
-                    getGlobalSetting(Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS);
-            final String adaptiveDeviceSpecificSetting = getGlobalSetting(
-                    Settings.Global.BATTERY_SAVER_ADAPTIVE_DEVICE_SPECIFIC_CONSTANTS);
-
-            if (!updateConstantsLocked(setting, deviceSpecificSetting,
-                    adaptiveSetting, adaptiveDeviceSpecificSetting)) {
+            if (!updateConstantsLocked(setting, deviceSpecificSetting)) {
                 // Nothing of note changed.
                 return;
             }
@@ -366,47 +429,34 @@
 
     @GuardedBy("mLock")
     @VisibleForTesting
-    void updateConstantsLocked(final String setting, final String deviceSpecificSetting) {
-        updateConstantsLocked(setting, deviceSpecificSetting, "", "");
-    }
-
     /** @return true if the currently active policy changed. */
-    private boolean updateConstantsLocked(String setting, String deviceSpecificSetting,
-            String adaptiveSetting, String adaptiveDeviceSpecificSetting) {
+    boolean updateConstantsLocked(String setting, String deviceSpecificSetting) {
         setting = TextUtils.emptyIfNull(setting);
         deviceSpecificSetting = TextUtils.emptyIfNull(deviceSpecificSetting);
-        adaptiveSetting = TextUtils.emptyIfNull(adaptiveSetting);
-        adaptiveDeviceSpecificSetting = TextUtils.emptyIfNull(adaptiveDeviceSpecificSetting);
 
         if (setting.equals(mSettings)
-                && deviceSpecificSetting.equals(mDeviceSpecificSettings)
-                && adaptiveSetting.equals(mAdaptiveSettings)
-                && adaptiveDeviceSpecificSetting.equals(mAdaptiveDeviceSpecificSettings)) {
+                && deviceSpecificSetting.equals(mDeviceSpecificSettings)) {
             return false;
         }
 
         mSettings = setting;
         mDeviceSpecificSettings = deviceSpecificSetting;
-        mAdaptiveSettings = adaptiveSetting;
-        mAdaptiveDeviceSpecificSettings = adaptiveDeviceSpecificSetting;
 
         if (DEBUG) {
             Slog.i(TAG, "mSettings=" + mSettings);
             Slog.i(TAG, "mDeviceSpecificSettings=" + mDeviceSpecificSettings);
-            Slog.i(TAG, "mAdaptiveSettings=" + mAdaptiveSettings);
-            Slog.i(TAG, "mAdaptiveDeviceSpecificSettings=" + mAdaptiveDeviceSpecificSettings);
         }
 
         boolean changed = false;
         Policy newFullPolicy = Policy.fromSettings(setting, deviceSpecificSetting,
-                DEFAULT_FULL_POLICY);
+                mLastDeviceConfigProperties, null, DEFAULT_FULL_POLICY);
         if (mPolicyLevel == POLICY_LEVEL_FULL && !mFullPolicy.equals(newFullPolicy)) {
             changed = true;
         }
         mFullPolicy = newFullPolicy;
 
-        mDefaultAdaptivePolicy = Policy.fromSettings(adaptiveSetting, adaptiveDeviceSpecificSetting,
-                DEFAULT_ADAPTIVE_POLICY);
+        mDefaultAdaptivePolicy = Policy.fromSettings("", "",
+                mLastDeviceConfigProperties, KEY_SUFFIX_ADAPTIVE, DEFAULT_ADAPTIVE_POLICY);
         if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE
                 && !mAdaptivePolicy.equals(mDefaultAdaptivePolicy)) {
             changed = true;
@@ -509,7 +559,7 @@
          * {@code true} if full backup is deferred in battery saver mode.
          *
          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
-         * @see #KEY_FULLBACKUP_DEFERRED
+         * @see #KEY_DEFER_FULL_BACKUP
          */
         public final boolean deferFullBackup;
 
@@ -517,7 +567,7 @@
          * {@code true} if key value backup is deferred in battery saver mode.
          *
          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
-         * @see #KEY_KEYVALUE_DEFERRED
+         * @see #KEY_DEFER_KEYVALUE_BACKUP
          */
         public final boolean deferKeyValueBackup;
 
@@ -525,7 +575,7 @@
          * {@code true} if animation is disabled in battery saver mode.
          *
          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
-         * @see #KEY_ANIMATION_DISABLED
+         * @see #KEY_DISABLE_ANIMATION
          */
         public final boolean disableAnimation;
 
@@ -549,7 +599,7 @@
          * in battery saver mode.
          *
          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
-         * @see #KEY_SOUNDTRIGGER_DISABLED
+         * @see #KEY_DISABLE_SOUNDTRIGGER
          */
         public final boolean disableSoundTrigger;
 
@@ -557,7 +607,7 @@
          * {@code true} if vibration is disabled in battery saver mode.
          *
          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
-         * @see #KEY_VIBRATION_DISABLED
+         * @see #KEY_DISABLE_VIBRATION
          */
         public final boolean disableVibration;
 
@@ -566,7 +616,7 @@
          * mode.
          *
          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
-         * @see #KEY_ADJUST_BRIGHTNESS_DISABLED
+         * @see #KEY_ENABLE_BRIGHTNESS_ADJUSTMENT
          */
         public final boolean enableAdjustBrightness;
 
@@ -574,7 +624,7 @@
          * {@code true} if data saver should be turned on in battery saver mode.
          *
          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
-         * @see #KEY_ACTIVATE_DATASAVER_DISABLED
+         * @see #KEY_ENABLE_DATASAVER
          */
         public final boolean enableDataSaver;
 
@@ -582,7 +632,7 @@
          * {@code true} if network policy firewall should be turned on in battery saver mode.
          *
          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
-         * @see #KEY_ACTIVATE_FIREWALL_DISABLED
+         * @see #KEY_ENABLE_FIREWALL
          */
         public final boolean enableFirewall;
 
@@ -627,7 +677,7 @@
          * previously called gpsMode.
          *
          * @see Settings.Global#BATTERY_SAVER_CONSTANTS
-         * @see #KEY_GPS_MODE
+         * @see #KEY_LOCATION_MODE
          */
         public final int locationMode;
 
@@ -745,13 +795,17 @@
             );
         }
 
-        static Policy fromSettings(String settings, String deviceSpecificSettings) {
-            return fromSettings(settings, deviceSpecificSettings, OFF_POLICY);
+        @VisibleForTesting
+        static Policy fromSettings(String settings, String deviceSpecificSettings,
+                DeviceConfig.Properties properties, String configSuffix) {
+            return fromSettings(settings, deviceSpecificSettings, properties, configSuffix,
+                    OFF_POLICY);
         }
 
-        static Policy fromSettings(String settings, String deviceSpecificSettings,
-                Policy defaultPolicy) {
+        private static Policy fromSettings(String settings, String deviceSpecificSettings,
+                DeviceConfig.Properties properties, String configSuffix, Policy defaultPolicy) {
             final KeyValueListParser parser = new KeyValueListParser(',');
+            configSuffix = TextUtils.emptyIfNull(configSuffix);
 
             // Device-specific parameters.
             try {
@@ -771,40 +825,63 @@
                 Slog.wtf(TAG, "Bad battery saver constants: " + settings);
             }
 
-            float adjustBrightnessFactor = parser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR,
-                    defaultPolicy.adjustBrightnessFactor);
-            boolean advertiseIsEnabled = parser.getBoolean(KEY_ADVERTISE_IS_ENABLED,
-                    defaultPolicy.advertiseIsEnabled);
-            boolean deferFullBackup = parser.getBoolean(KEY_FULLBACKUP_DEFERRED,
-                    defaultPolicy.deferFullBackup);
-            boolean deferKeyValueBackup = parser.getBoolean(KEY_KEYVALUE_DEFERRED,
-                    defaultPolicy.deferKeyValueBackup);
-            boolean disableAnimation = parser.getBoolean(KEY_ANIMATION_DISABLED,
-                    defaultPolicy.disableAnimation);
-            boolean disableAod = parser.getBoolean(KEY_AOD_DISABLED, defaultPolicy.disableAod);
-            boolean disableLaunchBoost = parser.getBoolean(KEY_LAUNCH_BOOST_DISABLED,
-                    defaultPolicy.disableLaunchBoost);
-            boolean disableOptionalSensors = parser.getBoolean(KEY_OPTIONAL_SENSORS_DISABLED,
-                    defaultPolicy.disableOptionalSensors);
-            boolean disableSoundTrigger = parser.getBoolean(KEY_SOUNDTRIGGER_DISABLED,
-                    defaultPolicy.disableSoundTrigger);
-            boolean disableVibrationConfig = parser.getBoolean(KEY_VIBRATION_DISABLED,
-                    defaultPolicy.disableVibration);
-            boolean enableAdjustBrightness = !parser.getBoolean(KEY_ADJUST_BRIGHTNESS_DISABLED,
-                    !defaultPolicy.enableAdjustBrightness);
-            boolean enableDataSaver = !parser.getBoolean(KEY_ACTIVATE_DATASAVER_DISABLED,
-                    !defaultPolicy.enableDataSaver);
-            boolean enableFirewall = !parser.getBoolean(KEY_ACTIVATE_FIREWALL_DISABLED,
-                    !defaultPolicy.enableFirewall);
-            boolean enableNightMode = parser.getBoolean(KEY_ENABLE_NIGHT_MODE,
-                    defaultPolicy.enableNightMode);
-            boolean enableQuickDoze = parser.getBoolean(KEY_QUICK_DOZE_ENABLED,
-                    defaultPolicy.enableQuickDoze);
-            boolean forceAllAppsStandby = parser.getBoolean(KEY_FORCE_ALL_APPS_STANDBY,
-                    defaultPolicy.forceAllAppsStandby);
-            boolean forceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK,
-                    defaultPolicy.forceBackgroundCheck);
-            int locationMode = parser.getInt(KEY_GPS_MODE, defaultPolicy.locationMode);
+            // The Settings value overrides everything, since that will be set by the user.
+            // The DeviceConfig value takes second place, with the default as the last choice.
+            final float adjustBrightnessFactor = parser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR,
+                    properties.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR + configSuffix,
+                            defaultPolicy.adjustBrightnessFactor));
+            final boolean advertiseIsEnabled = parser.getBoolean(KEY_ADVERTISE_IS_ENABLED,
+                    properties.getBoolean(KEY_ADVERTISE_IS_ENABLED + configSuffix,
+                            defaultPolicy.advertiseIsEnabled));
+            final boolean deferFullBackup = parser.getBoolean(KEY_DEFER_FULL_BACKUP,
+                    properties.getBoolean(KEY_DEFER_FULL_BACKUP + configSuffix,
+                            defaultPolicy.deferFullBackup));
+            final boolean deferKeyValueBackup = parser.getBoolean(KEY_DEFER_KEYVALUE_BACKUP,
+                    properties.getBoolean(KEY_DEFER_KEYVALUE_BACKUP + configSuffix,
+                            defaultPolicy.deferKeyValueBackup));
+            final boolean disableAnimation = parser.getBoolean(KEY_DISABLE_ANIMATION,
+                    properties.getBoolean(KEY_DISABLE_ANIMATION + configSuffix,
+                            defaultPolicy.disableAnimation));
+            final boolean disableAod = parser.getBoolean(KEY_DISABLE_AOD,
+                    properties.getBoolean(KEY_DISABLE_AOD + configSuffix,
+                            defaultPolicy.disableAod));
+            final boolean disableLaunchBoost = parser.getBoolean(KEY_DISABLE_LAUNCH_BOOST,
+                    properties.getBoolean(KEY_DISABLE_LAUNCH_BOOST + configSuffix,
+                            defaultPolicy.disableLaunchBoost));
+            final boolean disableOptionalSensors = parser.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS,
+                    properties.getBoolean(KEY_DISABLE_OPTIONAL_SENSORS + configSuffix,
+                            defaultPolicy.disableOptionalSensors));
+            final boolean disableSoundTrigger = parser.getBoolean(KEY_DISABLE_SOUNDTRIGGER,
+                    properties.getBoolean(KEY_DISABLE_SOUNDTRIGGER + configSuffix,
+                            defaultPolicy.disableSoundTrigger));
+            final boolean disableVibrationConfig = parser.getBoolean(KEY_DISABLE_VIBRATION,
+                    properties.getBoolean(KEY_DISABLE_VIBRATION + configSuffix,
+                            defaultPolicy.disableVibration));
+            final boolean enableBrightnessAdjustment = parser.getBoolean(
+                    KEY_ENABLE_BRIGHTNESS_ADJUSTMENT,
+                    properties.getBoolean(KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + configSuffix,
+                            defaultPolicy.enableAdjustBrightness));
+            final boolean enableDataSaver = parser.getBoolean(KEY_ENABLE_DATASAVER,
+                    properties.getBoolean(KEY_ENABLE_DATASAVER + configSuffix,
+                            defaultPolicy.enableDataSaver));
+            final boolean enableFirewall = parser.getBoolean(KEY_ENABLE_FIREWALL,
+                    properties.getBoolean(KEY_ENABLE_FIREWALL + configSuffix,
+                            defaultPolicy.enableFirewall));
+            final boolean enableNightMode = parser.getBoolean(KEY_ENABLE_NIGHT_MODE,
+                    properties.getBoolean(KEY_ENABLE_NIGHT_MODE + configSuffix,
+                            defaultPolicy.enableNightMode));
+            final boolean enableQuickDoze = parser.getBoolean(KEY_ENABLE_QUICK_DOZE,
+                    properties.getBoolean(KEY_ENABLE_QUICK_DOZE + configSuffix,
+                            defaultPolicy.enableQuickDoze));
+            final boolean forceAllAppsStandby = parser.getBoolean(KEY_FORCE_ALL_APPS_STANDBY,
+                    properties.getBoolean(KEY_FORCE_ALL_APPS_STANDBY + configSuffix,
+                            defaultPolicy.forceAllAppsStandby));
+            final boolean forceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK,
+                    properties.getBoolean(KEY_FORCE_BACKGROUND_CHECK + configSuffix,
+                            defaultPolicy.forceBackgroundCheck));
+            final int locationMode = parser.getInt(KEY_LOCATION_MODE,
+                    properties.getInt(KEY_LOCATION_MODE + configSuffix,
+                            defaultPolicy.locationMode));
 
             return new Policy(
                     adjustBrightnessFactor,
@@ -818,7 +895,7 @@
                     disableSoundTrigger,
                     /* disableVibration */
                     disableVibrationConfig,
-                    enableAdjustBrightness,
+                    enableBrightnessAdjustment,
                     enableDataSaver,
                     enableFirewall,
                     enableNightMode,
@@ -1049,16 +1126,18 @@
             ipw.increaseIndent();
             ipw.println("value: " + mDeviceSpecificSettings);
             ipw.decreaseIndent();
-
-            ipw.println("Adaptive Settings: " + Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS);
+            ipw.println("DeviceConfig: " + DeviceConfig.NAMESPACE_BATTERY_SAVER);
             ipw.increaseIndent();
-            ipw.println("value: " + mAdaptiveSettings);
-            ipw.decreaseIndent();
-            ipw.println("Adaptive Device Specific Settings: "
-                    + Settings.Global.BATTERY_SAVER_ADAPTIVE_DEVICE_SPECIFIC_CONSTANTS);
-            ipw.increaseIndent();
-            ipw.println("value: " + mAdaptiveDeviceSpecificSettings);
-            ipw.decreaseIndent();
+            final Set<String> keys = mLastDeviceConfigProperties.getKeyset();
+            if (keys.size() == 0) {
+                ipw.println("N/A");
+            } else {
+                for (final String key : keys) {
+                    ipw.print(key);
+                    ipw.print(": ");
+                    ipw.println(mLastDeviceConfigProperties.getString(key, null));
+                }
+            }
 
             ipw.println("mAccessibilityEnabled=" + mAccessibilityEnabled.get());
             ipw.println("mAutomotiveProjectionActive=" + mAutomotiveProjectionActive.get());
@@ -1078,22 +1157,22 @@
         pw.println("Policy '" + label + "'");
         pw.increaseIndent();
         pw.println(KEY_ADVERTISE_IS_ENABLED + "=" + p.advertiseIsEnabled);
-        pw.println(KEY_VIBRATION_DISABLED + "=" + p.disableVibration);
-        pw.println(KEY_ANIMATION_DISABLED + "=" + p.disableAnimation);
-        pw.println(KEY_FULLBACKUP_DEFERRED + "=" + p.deferFullBackup);
-        pw.println(KEY_KEYVALUE_DEFERRED + "=" + p.deferKeyValueBackup);
-        pw.println(KEY_ACTIVATE_FIREWALL_DISABLED + "=" + !p.enableFirewall);
-        pw.println(KEY_ACTIVATE_DATASAVER_DISABLED + "=" + !p.enableDataSaver);
-        pw.println(KEY_LAUNCH_BOOST_DISABLED + "=" + p.disableLaunchBoost);
-        pw.println(KEY_ADJUST_BRIGHTNESS_DISABLED + "=" + !p.enableAdjustBrightness);
+        pw.println(KEY_DISABLE_VIBRATION + "=" + p.disableVibration);
+        pw.println(KEY_DISABLE_ANIMATION + "=" + p.disableAnimation);
+        pw.println(KEY_DEFER_FULL_BACKUP + "=" + p.deferFullBackup);
+        pw.println(KEY_DEFER_KEYVALUE_BACKUP + "=" + p.deferKeyValueBackup);
+        pw.println(KEY_ENABLE_FIREWALL + "=" + p.enableFirewall);
+        pw.println(KEY_ENABLE_DATASAVER + "=" + p.enableDataSaver);
+        pw.println(KEY_DISABLE_LAUNCH_BOOST + "=" + p.disableLaunchBoost);
+        pw.println(KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + "=" + p.enableAdjustBrightness);
         pw.println(KEY_ADJUST_BRIGHTNESS_FACTOR + "=" + p.adjustBrightnessFactor);
-        pw.println(KEY_GPS_MODE + "=" + p.locationMode);
+        pw.println(KEY_LOCATION_MODE + "=" + p.locationMode);
         pw.println(KEY_FORCE_ALL_APPS_STANDBY + "=" + p.forceAllAppsStandby);
         pw.println(KEY_FORCE_BACKGROUND_CHECK + "=" + p.forceBackgroundCheck);
-        pw.println(KEY_OPTIONAL_SENSORS_DISABLED + "=" + p.disableOptionalSensors);
-        pw.println(KEY_AOD_DISABLED + "=" + p.disableAod);
-        pw.println(KEY_SOUNDTRIGGER_DISABLED + "=" + p.disableSoundTrigger);
-        pw.println(KEY_QUICK_DOZE_ENABLED + "=" + p.enableQuickDoze);
+        pw.println(KEY_DISABLE_OPTIONAL_SENSORS + "=" + p.disableOptionalSensors);
+        pw.println(KEY_DISABLE_AOD + "=" + p.disableAod);
+        pw.println(KEY_DISABLE_SOUNDTRIGGER + "=" + p.disableSoundTrigger);
+        pw.println(KEY_ENABLE_QUICK_DOZE + "=" + p.enableQuickDoze);
         pw.println(KEY_ENABLE_NIGHT_MODE + "=" + p.enableNightMode);
 
         pw.println("Interactive File values:");
diff --git a/services/core/java/com/android/server/powerstats/OWNERS b/services/core/java/com/android/server/powerstats/OWNERS
new file mode 100644
index 0000000..d68066b
--- /dev/null
+++ b/services/core/java/com/android/server/powerstats/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/power/OWNERS
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index ab6ada2..eb15c80 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -71,7 +71,6 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.pm.UserManagerInternal;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileDescriptor;
@@ -83,7 +82,6 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import java.util.function.Consumer;
 
 /**
  * Service for role management.
@@ -162,12 +160,6 @@
 
         LocalServices.addService(RoleManagerInternal.class, new Internal());
 
-        PermissionManagerServiceInternal permissionManagerInternal =
-                LocalServices.getService(PermissionManagerServiceInternal.class);
-        permissionManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider());
-        permissionManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider());
-        permissionManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider());
-
         registerUserRemovedReceiver();
     }
 
@@ -657,12 +649,78 @@
                     resultReceiver);
         }
 
+        @Nullable
         @Override
-        public String getDefaultSmsPackage(int userId) {
+        public String getBrowserRoleHolder(@UserIdInt int userId) {
+            final int callingUid = Binder.getCallingUid();
+            if (UserHandle.getUserId(callingUid) != userId) {
+                getContext().enforceCallingOrSelfPermission(
+                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+            }
+            final PackageManagerInternal packageManager = LocalServices.getService(
+                    PackageManagerInternal.class);
+            if (packageManager.getInstantAppPackageName(callingUid) != null) {
+                return null;
+            }
+
             final long identity = Binder.clearCallingIdentity();
             try {
-                return CollectionUtils.firstOrNull(
-                        getRoleHoldersAsUser(RoleManager.ROLE_SMS, userId));
+                return CollectionUtils.firstOrNull(getRoleHoldersAsUser(RoleManager.ROLE_BROWSER,
+                        userId));
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @Override
+        public boolean setBrowserRoleHolder(@Nullable String packageName, @UserIdInt int userId) {
+            final Context context = getContext();
+            context.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+            if (UserHandle.getCallingUserId() != userId) {
+                context.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+            }
+
+            if (!mUserManagerInternal.exists(userId)) {
+                return false;
+            }
+
+            final AndroidFuture<Void> future = new AndroidFuture<>();
+            final RemoteCallback callback = new RemoteCallback(result -> {
+                boolean successful = result != null;
+                if (successful) {
+                    future.complete(null);
+                } else {
+                    future.completeExceptionally(new RuntimeException());
+                }
+            });
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                if (packageName != null) {
+                    addRoleHolderAsUser(RoleManager.ROLE_BROWSER, packageName, 0, userId, callback);
+                } else {
+                    clearRoleHoldersAsUser(RoleManager.ROLE_BROWSER, 0, userId, callback);
+                }
+                try {
+                    future.get(5, TimeUnit.SECONDS);
+                } catch (InterruptedException | ExecutionException | TimeoutException e) {
+                    Slog.e(LOG_TAG, "Exception while setting default browser: " + packageName, e);
+                    return false;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+
+            return true;
+        }
+
+        @Override
+        public String getSmsRoleHolder(int userId) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                return CollectionUtils.firstOrNull(getRoleHoldersAsUser(RoleManager.ROLE_SMS,
+                        userId));
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -718,100 +776,4 @@
             return getOrCreateUserState(userId).getRolesAndHolders();
         }
     }
-
-    private class DefaultBrowserProvider implements
-            PermissionManagerServiceInternal.DefaultBrowserProvider {
-
-        @Nullable
-        @Override
-        public String getDefaultBrowser(@UserIdInt int userId) {
-            return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders(
-                    RoleManager.ROLE_BROWSER));
-        }
-
-        @Override
-        public boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) {
-            AndroidFuture<Void> future = new AndroidFuture<>();
-            RemoteCallback callback = new RemoteCallback(result -> {
-                boolean successful = result != null;
-                if (successful) {
-                    future.complete(null);
-                } else {
-                    future.completeExceptionally(new RuntimeException());
-                }
-            });
-            if (packageName != null) {
-                getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER,
-                        packageName, 0, callback);
-            } else {
-                getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0,
-                        callback);
-            }
-            try {
-                future.get(5, TimeUnit.SECONDS);
-                return true;
-            } catch (InterruptedException | ExecutionException | TimeoutException e) {
-                Slog.e(LOG_TAG, "Exception while setting default browser: " + packageName, e);
-                return false;
-            }
-        }
-
-        @Override
-        public void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId) {
-            RemoteCallback callback = new RemoteCallback(result -> {
-                boolean successful = result != null;
-                if (!successful) {
-                    Slog.e(LOG_TAG, "Failed to set default browser: " + packageName);
-                }
-            });
-            if (packageName != null) {
-                getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER,
-                        packageName, 0, callback);
-            } else {
-                getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0,
-                        callback);
-            }
-        }
-    }
-
-    private class DefaultDialerProvider implements
-            PermissionManagerServiceInternal.DefaultDialerProvider {
-
-        @Nullable
-        @Override
-        public String getDefaultDialer(@UserIdInt int userId) {
-            return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders(
-                    RoleManager.ROLE_DIALER));
-        }
-    }
-
-    private class DefaultHomeProvider implements
-            PermissionManagerServiceInternal.DefaultHomeProvider {
-
-        @Nullable
-        @Override
-        public String getDefaultHome(@UserIdInt int userId) {
-            return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders(
-                    RoleManager.ROLE_HOME));
-        }
-
-        @Override
-        public void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId,
-                @NonNull Consumer<Boolean> callback) {
-            RemoteCallback remoteCallback = new RemoteCallback(result -> {
-                boolean successful = result != null;
-                if (!successful) {
-                    Slog.e(LOG_TAG, "Failed to set default home: " + packageName);
-                }
-                callback.accept(successful);
-            });
-            if (packageName != null) {
-                getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_HOME,
-                        packageName, 0, remoteCallback);
-            } else {
-                getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_HOME, 0,
-                        remoteCallback);
-            }
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/rollback/OWNERS b/services/core/java/com/android/server/rollback/OWNERS
new file mode 100644
index 0000000..7feb85f
--- /dev/null
+++ b/services/core/java/com/android/server/rollback/OWNERS
@@ -0,0 +1 @@
+olilan@google.com
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index 63ed416..d9b6702 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -581,9 +581,18 @@
                             ParcelFileDescriptor.MODE_READ_ONLY)) {
                         final long token = Binder.clearCallingIdentity();
                         try {
-                            session.write(packageCodePath.getName(), 0,
-                                    packageCodePath.length(),
-                                    fd);
+                            boolean fallbackToCopy = false;
+                            try {
+                                // Populate apk/apex files using hard links to avoid copy
+                                session.stageViaHardLink(packageCodePath.getAbsolutePath());
+                            } catch (Exception ignore) {
+                                fallbackToCopy = true;
+                            }
+                            if (fallbackToCopy) {
+                                session.write(packageCodePath.getName(), 0,
+                                        packageCodePath.length(),
+                                        fd);
+                            }
                         } finally {
                             Binder.restoreCallingIdentity(token);
                         }
diff --git a/services/core/java/com/android/server/slice/OWNERS b/services/core/java/com/android/server/slice/OWNERS
new file mode 100644
index 0000000..3d0859f
--- /dev/null
+++ b/services/core/java/com/android/server/slice/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/slice/OWNERS
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index ee9694f..ee0e5ba 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -256,11 +256,6 @@
                 }
             }
         }
-        // Fallback to allowing uri permissions through.
-        if (mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
-                == PERMISSION_GRANTED) {
-            return PackageManager.PERMISSION_GRANTED;
-        }
         return PackageManager.PERMISSION_DENIED;
     }
 
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index d3b1ac6..cf20cf4 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -502,6 +502,8 @@
                         synchronized (mProcessSystemIonHeapSizeLock) {
                             return pullProcessSystemIonHeapSizeLocked(atomTag, data);
                         }
+                    case FrameworkStatsLog.SYSTEM_MEMORY:
+                        return pullSystemMemory(atomTag, data);
                     case FrameworkStatsLog.TEMPERATURE:
                         synchronized (mTemperatureLock) {
                             return pullTemperatureLocked(atomTag, data);
@@ -796,6 +798,7 @@
         registerSystemIonHeapSize();
         registerIonHeapSize();
         registerProcessSystemIonHeapSize();
+        registerSystemMemory();
         registerTemperature();
         registerCoolingDevice();
         registerBinderCallsStats();
@@ -1913,6 +1916,30 @@
         return StatsManager.PULL_SUCCESS;
     }
 
+    private void registerSystemMemory() {
+        int tagId = FrameworkStatsLog.SYSTEM_MEMORY;
+        mStatsManager.setPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl
+        );
+    }
+
+    int pullSystemMemory(int atomTag, List<StatsEvent> pulledData) {
+        SystemMemoryUtil.Metrics metrics = SystemMemoryUtil.getMetrics();
+        pulledData.add(
+                FrameworkStatsLog.buildStatsEvent(
+                        atomTag,
+                        metrics.unreclaimableSlabKb,
+                        metrics.vmallocUsedKb,
+                        metrics.pageTablesKb,
+                        metrics.kernelStackKb,
+                        metrics.totalIonKb,
+                        metrics.unaccountedKb));
+        return StatsManager.PULL_SUCCESS;
+    }
+
     private void registerTemperature() {
         int tagId = FrameworkStatsLog.TEMPERATURE;
         mStatsManager.setPullAtomCallback(
diff --git a/services/core/java/com/android/server/stats/pull/SystemMemoryUtil.java b/services/core/java/com/android/server/stats/pull/SystemMemoryUtil.java
new file mode 100644
index 0000000..99fc7c1
--- /dev/null
+++ b/services/core/java/com/android/server/stats/pull/SystemMemoryUtil.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.stats.pull;
+
+import android.os.Debug;
+
+/**
+ * Snapshots system-wide memory stats and computes unaccounted memory.
+ * Thread-safe.
+ */
+final class SystemMemoryUtil {
+    private SystemMemoryUtil() {}
+
+    static Metrics getMetrics() {
+        int totalIonKb = (int) Debug.getIonHeapsSizeKb();
+
+        long[] mInfos = new long[Debug.MEMINFO_COUNT];
+        Debug.getMemInfo(mInfos);
+
+        long kReclaimableKb = mInfos[Debug.MEMINFO_KRECLAIMABLE];
+        // Note: MEMINFO_KRECLAIMABLE includes MEMINFO_SLAB_RECLAIMABLE and ION pools.
+        // Fall back to using MEMINFO_SLAB_RECLAIMABLE in case of older kernels that do
+        // not include KReclaimable meminfo field.
+        if (kReclaimableKb == 0) {
+            kReclaimableKb = mInfos[Debug.MEMINFO_SLAB_RECLAIMABLE];
+        }
+
+        long accountedKb = mInfos[Debug.MEMINFO_FREE]
+                + mInfos[Debug.MEMINFO_ZRAM_TOTAL]
+                + mInfos[Debug.MEMINFO_BUFFERS]
+                + mInfos[Debug.MEMINFO_ACTIVE]
+                + mInfos[Debug.MEMINFO_INACTIVE]
+                + mInfos[Debug.MEMINFO_UNEVICTABLE]
+                + mInfos[Debug.MEMINFO_SLAB_UNRECLAIMABLE]
+                + kReclaimableKb
+                + mInfos[Debug.MEMINFO_VM_ALLOC_USED]
+                + mInfos[Debug.MEMINFO_PAGE_TABLES]
+                + Math.max(totalIonKb, 0);
+
+        if (!Debug.isVmapStack()) {
+            // See b/146088882
+            accountedKb += mInfos[Debug.MEMINFO_KERNEL_STACK];
+        }
+
+        Metrics result = new Metrics();
+        result.unreclaimableSlabKb = (int) mInfos[Debug.MEMINFO_SLAB_UNRECLAIMABLE];
+        result.vmallocUsedKb = (int) mInfos[Debug.MEMINFO_VM_ALLOC_USED];
+        result.pageTablesKb = (int) mInfos[Debug.MEMINFO_PAGE_TABLES];
+        result.kernelStackKb = (int) mInfos[Debug.MEMINFO_KERNEL_STACK];
+        result.totalIonKb = totalIonKb;
+        result.unaccountedKb = (int) (mInfos[Debug.MEMINFO_TOTAL] - accountedKb);
+        return result;
+    }
+
+    static final class Metrics {
+        public int unreclaimableSlabKb;
+        public int vmallocUsedKb;
+        public int pageTablesKb;
+        public int kernelStackKb;
+        public int totalIonKb;
+        public int unaccountedKb;
+    }
+}
diff --git a/services/core/java/com/android/server/statusbar/OWNERS b/services/core/java/com/android/server/statusbar/OWNERS
new file mode 100644
index 0000000..2e96c97
--- /dev/null
+++ b/services/core/java/com/android/server/statusbar/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/OWNERS
diff --git a/services/core/java/com/android/server/storage/OWNERS b/services/core/java/com/android/server/storage/OWNERS
new file mode 100644
index 0000000..6f9dbea
--- /dev/null
+++ b/services/core/java/com/android/server/storage/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/os/storage/OWNERS
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index 52ad893..f0c96e1 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -42,7 +42,7 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.pm.UserManagerService;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.permission.LegacyPermissionManagerInternal;
 
 /**
  * Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup
@@ -65,8 +65,8 @@
                 ServiceManager.addService(Context.TELECOM_SERVICE, telecomService.asBinder());
 
                 synchronized (mLock) {
-                    final PermissionManagerServiceInternal permissionManager =
-                            LocalServices.getService(PermissionManagerServiceInternal.class);
+                    final LegacyPermissionManagerInternal permissionManager =
+                            LocalServices.getService(LegacyPermissionManagerInternal.class);
                     if (mDefaultSimCallManagerRequests != null) {
                         if (mDefaultSimCallManagerRequests != null) {
                             TelecomManager telecomManager =
@@ -165,8 +165,8 @@
 
 
     private void registerDefaultAppProviders() {
-        final PermissionManagerServiceInternal permissionManager =
-                LocalServices.getService(PermissionManagerServiceInternal.class);
+        final LegacyPermissionManagerInternal permissionManager =
+                LocalServices.getService(LegacyPermissionManagerInternal.class);
 
         // Set a callback for the permission grant policy to query the default sms app.
         permissionManager.setSmsAppPackagesProvider(userId -> {
@@ -244,15 +244,16 @@
     }
 
     private void updateSimCallManagerPermissions(int userId) {
-        final PermissionManagerServiceInternal permissionManager =
-                LocalServices.getService(PermissionManagerServiceInternal.class);
+        final LegacyPermissionManagerInternal permissionManager =
+                LocalServices.getService(LegacyPermissionManagerInternal.class);
         TelecomManager telecomManager =
             (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
         PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
         if (phoneAccount != null) {
             Slog.i(TAG, "updating sim call manager permissions for userId:" + userId);
             String packageName = phoneAccount.getComponentName().getPackageName();
-            permissionManager.grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
+            permissionManager.grantDefaultPermissionsToDefaultSimCallManager(packageName,
+                    userId);
         }
     }
 }
diff --git a/services/core/java/com/android/server/textclassifier/OWNERS b/services/core/java/com/android/server/textclassifier/OWNERS
new file mode 100644
index 0000000..46b3cb8
--- /dev/null
+++ b/services/core/java/com/android/server/textclassifier/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/textclassifier/OWNERS
diff --git a/services/core/java/com/android/server/timedetector/OWNERS b/services/core/java/com/android/server/timedetector/OWNERS
new file mode 100644
index 0000000..09447a9
--- /dev/null
+++ b/services/core/java/com/android/server/timedetector/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/timezone/OWNERS
diff --git a/services/core/java/com/android/server/timezone/OWNERS b/services/core/java/com/android/server/timezone/OWNERS
new file mode 100644
index 0000000..09447a9
--- /dev/null
+++ b/services/core/java/com/android/server/timezone/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/timezone/OWNERS
diff --git a/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java b/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java
index 118899a..1867ee2 100644
--- a/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java
+++ b/services/core/java/com/android/server/timezonedetector/GeolocationTimeZoneSuggestion.java
@@ -61,7 +61,7 @@
  */
 public final class GeolocationTimeZoneSuggestion {
 
-    @NonNull private final List<String> mZoneIds;
+    @Nullable private final List<String> mZoneIds;
     @Nullable private ArrayList<String> mDebugInfo;
 
     public GeolocationTimeZoneSuggestion(@Nullable List<String> zoneIds) {
diff --git a/services/core/java/com/android/server/timezonedetector/OWNERS b/services/core/java/com/android/server/timezonedetector/OWNERS
new file mode 100644
index 0000000..09447a9
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/timezone/OWNERS
diff --git a/services/core/java/com/android/server/trust/OWNERS b/services/core/java/com/android/server/trust/OWNERS
new file mode 100644
index 0000000..b039c4b
--- /dev/null
+++ b/services/core/java/com/android/server/trust/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/trust/OWNERS
diff --git a/services/core/java/com/android/server/tv/OWNERS b/services/core/java/com/android/server/tv/OWNERS
new file mode 100644
index 0000000..305027c
--- /dev/null
+++ b/services/core/java/com/android/server/tv/OWNERS
@@ -0,0 +1 @@
+include /media/java/android/media/tv/OWNERS
diff --git a/services/core/java/com/android/server/tv/PersistentDataStore.java b/services/core/java/com/android/server/tv/PersistentDataStore.java
index d3c9b3b..72556a7 100644
--- a/services/core/java/com/android/server/tv/PersistentDataStore.java
+++ b/services/core/java/com/android/server/tv/PersistentDataStore.java
@@ -30,23 +30,17 @@
 import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
-import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 
 import libcore.io.IoUtils;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -246,12 +240,7 @@
             if (parser.getName().equals(TAG_BLOCKED_RATINGS)) {
                 loadBlockedRatingsFromXml(parser);
             } else if (parser.getName().equals(TAG_PARENTAL_CONTROLS)) {
-                String enabled = parser.getAttributeValue(null, ATTR_ENABLED);
-                if (TextUtils.isEmpty(enabled)) {
-                    throw new XmlPullParserException(
-                            "Missing " + ATTR_ENABLED + " attribute on " + TAG_PARENTAL_CONTROLS);
-                }
-                mParentalControlsEnabled = Boolean.parseBoolean(enabled);
+                mParentalControlsEnabled = parser.getAttributeBoolean(null, ATTR_ENABLED);
             }
         }
     }
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 608012e..1754e59 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -84,6 +84,7 @@
 import android.view.Surface;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.DumpUtils;
@@ -1442,8 +1443,8 @@
                 if (sessionState != null) {
                     int state = surface == null
                             ?
-                            FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__SURFACE_ATTACHED
-                            : FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__SURFACE_DETACHED;
+                            FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__SURFACE_DETACHED
+                            : FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__SURFACE_ATTACHED;
                     logTuneStateChanged(state, sessionState,
                             TvInputManagerService.getTvInputState(sessionState, userState));
                 }
@@ -2972,15 +2973,7 @@
                         getUserStateLocked(mCurrentUserId));
                 try {
                     mSessionState.client.onVideoUnavailable(reason, mSessionState.seq);
-                    int loggedReason = reason + FrameworkStatsLog
-                            .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN;
-                    if (loggedReason < FrameworkStatsLog
-                            .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN
-                            || loggedReason > FrameworkStatsLog
-                            .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN) {
-                        loggedReason = FrameworkStatsLog
-                                .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN;
-                    }
+                    int loggedReason = getVideoUnavailableReasonForStatsd(reason);
                     logTuneStateChanged(loggedReason, mSessionState, tvInputState);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in onVideoUnavailable", e);
@@ -3167,6 +3160,21 @@
         }
     }
 
+    @VisibleForTesting
+    static int getVideoUnavailableReasonForStatsd(
+            @TvInputManager.VideoUnavailableReason int reason) {
+        int loggedReason = reason + FrameworkStatsLog
+                .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN;
+        if (loggedReason < FrameworkStatsLog
+                .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN
+                || loggedReason > FrameworkStatsLog
+                .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN) {
+            loggedReason = FrameworkStatsLog
+                    .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN;
+        }
+        return loggedReason;
+    }
+
     private UserState getUserStateLocked(int userId) {
         return mUserStates.get(userId);
     }
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/UseCasePriorityHints.java b/services/core/java/com/android/server/tv/tunerresourcemanager/UseCasePriorityHints.java
index beb11ed..7f49eea 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/UseCasePriorityHints.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/UseCasePriorityHints.java
@@ -192,8 +192,9 @@
         }
     }
 
-    private int readAttributeToInt(String attributeName, TypedXmlPullParser parser) {
-        return Integer.valueOf(parser.getAttributeValue(null, attributeName));
+    private int readAttributeToInt(String attributeName, TypedXmlPullParser parser)
+            throws XmlPullParserException {
+        return parser.getAttributeInt(null, attributeName);
     }
 
     private void addNewUseCasePriority(int useCase, int fgPriority, int bgPriority) {
diff --git a/services/core/java/com/android/server/uri/OWNERS b/services/core/java/com/android/server/uri/OWNERS
new file mode 100644
index 0000000..cdc07ed
--- /dev/null
+++ b/services/core/java/com/android/server/uri/OWNERS
@@ -0,0 +1,3 @@
+jsharkey@android.com
+jsharkey@google.com
+varunshah@google.com
diff --git a/services/core/java/com/android/server/utils/quota/MultiRateLimiter.java b/services/core/java/com/android/server/utils/quota/MultiRateLimiter.java
new file mode 100644
index 0000000..fdbe4b4
--- /dev/null
+++ b/services/core/java/com/android/server/utils/quota/MultiRateLimiter.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.utils.quota;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Can be used to rate limit events per app based on multiple rates at the same time. For example,
+ * it can limit an event to happen only:
+ *
+ * <li>5 times in 20 seconds</li>
+ * and
+ * <li>6 times in 40 seconds</li>
+ * and
+ * <li>10 times in 1 hour</li>
+ *
+ * <p><br>
+ * All listed rates apply at the same time, and the UPTC will be out of quota if it doesn't satisfy
+ * all the given rates. The underlying mechanism used is
+ * {@link com.android.server.utils.quota.CountQuotaTracker}, so all its conditions apply, as well
+ * as an additional constraint: all the user-package-tag combinations (UPTC) are considered to be in
+ * the same {@link com.android.server.utils.quota.Category}.
+ * </p>
+ *
+ * @hide
+ */
+public class MultiRateLimiter {
+
+    private static final CountQuotaTracker[] EMPTY_TRACKER_ARRAY = {};
+
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private final CountQuotaTracker[] mQuotaTrackers;
+
+    private MultiRateLimiter(List<CountQuotaTracker> quotaTrackers) {
+        mQuotaTrackers = quotaTrackers.toArray(EMPTY_TRACKER_ARRAY);
+    }
+
+    /** Record that an event happened and count it towards the given quota. */
+    public void noteEvent(int userId, @NonNull String packageName, @Nullable String tag) {
+        synchronized (mLock) {
+            noteEventLocked(userId, packageName, tag);
+        }
+    }
+
+    /** Check whether the given UPTC is allowed to trigger an event. */
+    public boolean isWithinQuota(int userId, @NonNull String packageName, @Nullable String tag) {
+        synchronized (mLock) {
+            return isWithinQuotaLocked(userId, packageName, tag);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void noteEventLocked(int userId, @NonNull String packageName, @Nullable String tag) {
+        for (CountQuotaTracker quotaTracker : mQuotaTrackers) {
+            quotaTracker.noteEvent(userId, packageName, tag);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private boolean isWithinQuotaLocked(int userId, @NonNull String packageName,
+            @Nullable String tag) {
+        for (CountQuotaTracker quotaTracker : mQuotaTrackers) {
+            if (!quotaTracker.isWithinQuota(userId, packageName, tag)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /** Can create a new {@link MultiRateLimiter}. */
+    public static class Builder {
+
+        private final List<CountQuotaTracker> mQuotaTrackers;
+        private final Context mContext;
+        private final Categorizer mCategorizer;
+        private final Category mCategory;
+        @Nullable private final QuotaTracker.Injector mInjector;
+
+        /**
+         * Creates a new builder and allows to inject an object that can be used
+         * to manipulate elapsed time in tests.
+         */
+        @VisibleForTesting
+        Builder(Context context, QuotaTracker.Injector injector) {
+            this.mQuotaTrackers = new ArrayList<>();
+            this.mContext = context;
+            this.mInjector = injector;
+            this.mCategorizer = Categorizer.SINGLE_CATEGORIZER;
+            this.mCategory = Category.SINGLE_CATEGORY;
+        }
+
+        /** Creates a new builder for {@link MultiRateLimiter}. */
+        public Builder(Context context) {
+            this(context, null);
+        }
+
+        /**
+         * Adds another rate limit to be used in {@link MultiRateLimiter}.
+         *
+         * @param limit The maximum event count an app can have in the rolling time window.
+         * @param windowSize The rolling time window to use when checking quota usage.
+         */
+        public Builder addRateLimit(int limit, Duration windowSize) {
+            CountQuotaTracker countQuotaTracker;
+            if (mInjector != null) {
+                countQuotaTracker = new CountQuotaTracker(mContext, mCategorizer, mInjector);
+            } else {
+                countQuotaTracker = new CountQuotaTracker(mContext, mCategorizer);
+            }
+            countQuotaTracker.setCountLimit(mCategory, limit, windowSize.toMillis());
+            mQuotaTrackers.add(countQuotaTracker);
+            return this;
+        }
+
+        /** Adds another rate limit to be used in {@link MultiRateLimiter}. */
+        public Builder addRateLimit(@NonNull RateLimit rateLimit) {
+            return addRateLimit(rateLimit.mLimit, rateLimit.mWindowSize);
+        }
+
+        /** Adds all given rate limits that will be used in {@link MultiRateLimiter}. */
+        public Builder addRateLimits(@NonNull RateLimit[] rateLimits) {
+            for (RateLimit rateLimit : rateLimits) {
+                addRateLimit(rateLimit);
+            }
+            return this;
+        }
+
+        /**
+         * Return a new {@link com.android.server.utils.quota.MultiRateLimiter} using set rate
+         * limit.
+         */
+        public MultiRateLimiter build() {
+            return new MultiRateLimiter(mQuotaTrackers);
+        }
+    }
+
+    /** Helper class that describes a rate limit. */
+    public static class RateLimit {
+        public final int mLimit;
+        public final Duration mWindowSize;
+
+        /**
+         * @param limit The maximum count of some occurrence in the rolling time window.
+         * @param windowSize The rolling time window to use when checking quota usage.
+         */
+        private RateLimit(int limit, Duration windowSize) {
+            this.mLimit = limit;
+            this.mWindowSize = windowSize;
+        }
+
+        /**
+         * @param limit The maximum count of some occurrence in the rolling time window.
+         * @param windowSize The rolling time window to use when checking quota usage.
+         */
+        public static RateLimit create(int limit, Duration windowSize) {
+            return new RateLimit(limit, windowSize);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/OWNERS b/services/core/java/com/android/server/vibrator/OWNERS
new file mode 100644
index 0000000..7e7335d
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/OWNERS
@@ -0,0 +1 @@
+michaelwr@google.com
diff --git a/services/core/java/com/android/server/wallpaper/OWNERS b/services/core/java/com/android/server/wallpaper/OWNERS
new file mode 100644
index 0000000..8ff0f74
--- /dev/null
+++ b/services/core/java/com/android/server/wallpaper/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/wallpaper/OWNERS
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index c3d5874..3198453 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2984,7 +2984,7 @@
         }
 
         if (wallpaper.allowBackup) {
-            out.attribute(null, "backup", "true");
+            out.attributeBoolean(null, "backup", true);
         }
 
         out.endTag(null, tag);
@@ -3249,7 +3249,7 @@
             wallpaper.primaryColors = new WallpaperColors(primary, secondary, tertiary, colorHints);
         }
         wallpaper.name = parser.getAttributeValue(null, "name");
-        wallpaper.allowBackup = "true".equals(parser.getAttributeValue(null, "backup"));
+        wallpaper.allowBackup = parser.getAttributeBoolean(null, "backup", false);
     }
 
     // Called by SystemBackupAgent after files are restored to disk.
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
new file mode 100644
index 0000000..9f1152c
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -0,0 +1,1046 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.wm;
+
+import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
+
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IMMERSIVE;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
+import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH;
+import static com.android.server.wm.ActivityTaskManagerService.enforceNotIsolatedCaller;
+import static com.android.server.wm.Task.ActivityState.DESTROYED;
+import static com.android.server.wm.Task.ActivityState.DESTROYING;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
+import android.app.IActivityClientController;
+import android.app.PictureInPictureParams;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.service.voice.VoiceInteractionManagerInternal;
+import android.util.Slog;
+import android.view.RemoteAnimationDefinition;
+
+import com.android.internal.app.AssistUtils;
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.server.LocalServices;
+import com.android.server.Watchdog;
+import com.android.server.uri.NeededUriGrants;
+import com.android.server.vr.VrManagerInternal;
+
+import java.util.Arrays;
+
+/**
+ * Server side implementation for the client activity to interact with system.
+ *
+ * @see android.app.ActivityClient
+ */
+class ActivityClientController extends IActivityClientController.Stub {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityClientController" : TAG_ATM;
+    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
+
+    private final ActivityTaskManagerService mService;
+    private final WindowManagerGlobalLock mGlobalLock;
+    private final ActivityTaskSupervisor mTaskSupervisor;
+    private final Context mContext;
+
+    /** Wrapper around VoiceInteractionServiceManager. */
+    private AssistUtils mAssistUtils;
+
+    ActivityClientController(ActivityTaskManagerService service) {
+        mService = service;
+        mGlobalLock = service.mGlobalLock;
+        mTaskSupervisor = service.mTaskSupervisor;
+        mContext = service.mContext;
+    }
+
+    void onSystemReady() {
+        mAssistUtils = new AssistUtils(mContext);
+    }
+
+    @Override
+    public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle");
+                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+                if (r == null) {
+                    return;
+                }
+                mTaskSupervisor.activityIdleInternal(r, false /* fromTimeout */,
+                        false /* processPausingActivities */, config);
+                if (stopProfiling && r.hasProcess()) {
+                    r.app.clearProfilerIfNeeded();
+                }
+            }
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void activityResumed(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        synchronized (mGlobalLock) {
+            ActivityRecord.activityResumedLocked(token);
+        }
+        Binder.restoreCallingIdentity(origId);
+    }
+
+    @Override
+    public void activityTopResumedStateLost() {
+        final long origId = Binder.clearCallingIdentity();
+        synchronized (mGlobalLock) {
+            mTaskSupervisor.handleTopResumedStateReleased(false /* timeout */);
+        }
+        Binder.restoreCallingIdentity(origId);
+    }
+
+    @Override
+    public void activityPaused(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        synchronized (mGlobalLock) {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
+            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+            if (r != null) {
+                r.activityPaused(false);
+            }
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+        Binder.restoreCallingIdentity(origId);
+    }
+
+    @Override
+    public void activityStopped(IBinder token, Bundle icicle, PersistableBundle persistentState,
+            CharSequence description) {
+        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
+
+        // Refuse possible leaked file descriptors.
+        if (icicle != null && icicle.hasFileDescriptors()) {
+            throw new IllegalArgumentException("File descriptors passed in Bundle");
+        }
+
+        final long origId = Binder.clearCallingIdentity();
+
+        String restartingName = null;
+        int restartingUid = 0;
+        final ActivityRecord r;
+        synchronized (mGlobalLock) {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityStopped");
+            r = ActivityRecord.isInStackLocked(token);
+            if (r != null) {
+                if (r.attachedToProcess() && r.isState(Task.ActivityState.RESTARTING_PROCESS)) {
+                    // The activity was requested to restart from
+                    // {@link #restartActivityProcessIfVisible}.
+                    restartingName = r.app.mName;
+                    restartingUid = r.app.mUid;
+                }
+                r.activityStopped(icicle, persistentState, description);
+            }
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+
+        if (restartingName != null) {
+            // In order to let the foreground activity can be restarted with its saved state from
+            // {@link android.app.Activity#onSaveInstanceState}, the kill operation is postponed
+            // until the activity reports stopped with the state. And the activity record will be
+            // kept because the record state is restarting, then the activity will be restarted
+            // immediately if it is still the top one.
+            mTaskSupervisor.removeRestartTimeouts(r);
+            mService.mAmInternal.killProcess(restartingName, restartingUid,
+                    "restartActivityProcess");
+        }
+        mService.mAmInternal.trimApplications();
+
+        Binder.restoreCallingIdentity(origId);
+    }
+
+    @Override
+    public void activityDestroyed(IBinder token) {
+        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
+        final long origId = Binder.clearCallingIdentity();
+        synchronized (mGlobalLock) {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityDestroyed");
+            try {
+                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+                if (r != null) {
+                    r.destroyed("activityDestroyed");
+                }
+            } finally {
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+    }
+
+    @Override
+    public void activityRelaunched(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        synchronized (mGlobalLock) {
+            mTaskSupervisor.activityRelaunchedLocked(token);
+        }
+        Binder.restoreCallingIdentity(origId);
+    }
+
+    @Override
+    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
+            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
+        ProtoLog.v(WM_DEBUG_CONFIGURATION, "Report configuration: %s %s %s",
+                token, Arrays.toString(horizontalSizeConfiguration),
+                Arrays.toString(verticalSizeConfigurations));
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r != null) {
+                r.setSizeConfigurations(horizontalSizeConfiguration, verticalSizeConfigurations,
+                        smallestSizeConfigurations);
+            }
+        }
+    }
+
+    /**
+     * Attempts to move a task backwards in z-order (the order of activities within the task is
+     * unchanged).
+     *
+     * There are several possible results of this call:
+     * - if the task is locked, then we will show the lock toast.
+     * - if there is a task behind the provided task, then that task is made visible and resumed as
+     * this task is moved to the back.
+     * - otherwise, if there are no other tasks in the root task:
+     * - if this task is in the pinned mode, then we remove the task completely, which will
+     * have the effect of moving the task to the top or bottom of the fullscreen root task
+     * (depending on whether it is visible).
+     * - otherwise, we simply return home and hide this task.
+     *
+     * @param token   A reference to the activity we wish to move.
+     * @param nonRoot If false then this only works if the activity is the root
+     *                of a task; if true it will work for any activity in a task.
+     * @return Returns true if the move completed, false if not.
+     */
+    @Override
+    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
+        enforceNotIsolatedCaller("moveActivityTaskToBack");
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
+                final Task task = mService.mRootWindowContainer.anyTaskForId(taskId);
+                if (task != null) {
+                    return ActivityRecord.getStackLocked(token).moveTaskToBack(task);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
+            if (srec != null) {
+                return srec.getRootTask().shouldUpRecreateTaskLocked(srec, destAffinity);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
+            Intent resultData) {
+        final ActivityRecord r;
+        synchronized (mGlobalLock) {
+            r = ActivityRecord.isInStackLocked(token);
+            if (r == null) {
+                return false;
+            }
+        }
+
+        // Carefully collect grants without holding lock.
+        final NeededUriGrants destGrants = mService.collectGrants(destIntent, r);
+        final NeededUriGrants resultGrants = mService.collectGrants(resultData, r.resultTo);
+
+        synchronized (mGlobalLock) {
+            return r.getRootTask().navigateUpTo(
+                    r, destIntent, destGrants, resultCode, resultData, resultGrants);
+        }
+    }
+
+    @Override
+    public boolean releaseActivityInstance(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null || !r.isDestroyable()) {
+                    return false;
+                }
+                r.destroyImmediately("app-req");
+                return r.isState(DESTROYING, DESTROYED);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    /**
+     * This is the internal entry point for handling Activity.finish().
+     *
+     * @param token      The Binder token referencing the Activity we want to finish.
+     * @param resultCode Result code, if any, from this Activity.
+     * @param resultData Result data (Intent), if any, from this Activity.
+     * @param finishTask Whether to finish the task associated with this Activity.
+     * @return Returns true if the activity successfully finished, or false if it is still running.
+     */
+    @Override
+    public boolean finishActivity(IBinder token, int resultCode, Intent resultData,
+            int finishTask) {
+        // Refuse possible leaked file descriptors.
+        if (resultData != null && resultData.hasFileDescriptors()) {
+            throw new IllegalArgumentException("File descriptors passed in Intent");
+        }
+
+        final ActivityRecord r;
+        synchronized (mGlobalLock) {
+            r = ActivityRecord.isInStackLocked(token);
+            if (r == null) {
+                return true;
+            }
+        }
+
+        // Carefully collect grants without holding lock.
+        final NeededUriGrants resultGrants = mService.collectGrants(resultData, r.resultTo);
+
+        synchronized (mGlobalLock) {
+            // Check again in case activity was removed when collecting grants.
+            if (!r.isInHistory()) {
+                return true;
+            }
+
+            // Keep track of the root activity of the task before we finish it.
+            final Task tr = r.getTask();
+            final ActivityRecord rootR = tr.getRootActivity();
+            if (rootR == null) {
+                Slog.w(TAG, "Finishing task with all activities already finished");
+            }
+            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
+            // finish.
+            if (mService.getLockTaskController().activityBlockedFromFinish(r)) {
+                return false;
+            }
+
+            // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
+            // We should consolidate.
+            if (mService.mController != null) {
+                // Find the first activity that is not finishing.
+                final ActivityRecord next =
+                        r.getRootTask().topRunningActivity(token, INVALID_TASK_ID);
+                if (next != null) {
+                    // ask watcher if this is allowed
+                    boolean resumeOK = true;
+                    try {
+                        resumeOK = mService.mController.activityResuming(next.packageName);
+                    } catch (RemoteException e) {
+                        mService.mController = null;
+                        Watchdog.getInstance().setActivityController(null);
+                    }
+
+                    if (!resumeOK) {
+                        Slog.i(TAG, "Not finishing activity because controller resumed");
+                        return false;
+                    }
+                }
+            }
+
+            // Note down that the process has finished an activity and is in background activity
+            // starts grace period.
+            if (r.app != null) {
+                r.app.setLastActivityFinishTimeIfNeeded(SystemClock.uptimeMillis());
+            }
+
+            final long origId = Binder.clearCallingIdentity();
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "finishActivity");
+            try {
+                final boolean res;
+                final boolean finishWithRootActivity =
+                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
+                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
+                        || (finishWithRootActivity && r == rootR)) {
+                    // If requested, remove the task that is associated to this activity only if it
+                    // was the root activity in the task. The result code and data is ignored
+                    // because we don't support returning them across task boundaries. Also, to
+                    // keep backwards compatibility we remove the task from recents when finishing
+                    // task with root activity.
+                    mTaskSupervisor.removeTask(tr, false /*killProcess*/,
+                            finishWithRootActivity, "finish-activity");
+                    res = true;
+                    // Explicitly dismissing the activity so reset its relaunch flag.
+                    r.mRelaunchReason = RELAUNCH_REASON_NONE;
+                } else {
+                    r.finishIfPossible(resultCode, resultData, resultGrants,
+                            "app-request", true /* oomAdj */);
+                    res = r.finishing;
+                    if (!res) {
+                        Slog.i(TAG, "Failed to finish by app-request");
+                    }
+                }
+                return res;
+            } finally {
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+    }
+
+    @Override
+    public boolean finishActivityAffinity(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) {
+                    return false;
+                }
+
+                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
+                // can finish.
+                if (mService.getLockTaskController().activityBlockedFromFinish(r)) {
+                    return false;
+                }
+
+                r.getTask().forAllActivities(activity -> r.finishIfSameAffinity(activity),
+                        r /* boundary */, true /* includeBoundary */,
+                        true /* traverseTopToBottom */);
+                return true;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void finishSubActivity(IBinder token, String resultWho, int requestCode) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) return;
+
+                // TODO: This should probably only loop over the task since you need to be in the
+                // same task to return results.
+                r.getRootTask().forAllActivities(activity -> {
+                    activity.finishIfSubActivity(r /* parent */, resultWho, requestCode);
+                }, true /* traverseTopToBottom */);
+
+                mService.updateOomAdj();
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public boolean isTopOfTask(IBinder token) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            return r != null && r.getTask().getTopNonFinishingActivity() == r;
+        }
+    }
+
+    @Override
+    public boolean willActivityBeVisible(IBinder token) {
+        synchronized (mGlobalLock) {
+            final Task rootTask = ActivityRecord.getStackLocked(token);
+            return rootTask != null && rootTask.willActivityBeVisible(token);
+        }
+    }
+
+    @Override
+    public int getDisplayId(IBinder activityToken) {
+        synchronized (mGlobalLock) {
+            final Task rootTask = ActivityRecord.getStackLocked(activityToken);
+            if (rootTask != null) {
+                final int displayId = rootTask.getDisplayId();
+                return displayId != INVALID_DISPLAY ? displayId : DEFAULT_DISPLAY;
+            }
+            return DEFAULT_DISPLAY;
+        }
+    }
+
+    @Override
+    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
+        synchronized (mGlobalLock) {
+            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
+        }
+    }
+
+    @Override
+    public ComponentName getCallingActivity(IBinder token) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = getCallingRecord(token);
+            return r != null ? r.intent.getComponent() : null;
+        }
+    }
+
+    @Override
+    public String getCallingPackage(IBinder token) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = getCallingRecord(token);
+            return r != null ? r.info.packageName : null;
+        }
+    }
+
+    private static ActivityRecord getCallingRecord(IBinder token) {
+        final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+        return r != null ? r.resultTo : null;
+    }
+
+    @Override
+    public Bundle getActivityOptions(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) {
+                    return null;
+                }
+                final ActivityOptions activityOptions = r.takeOptionsLocked(true /* fromClient */);
+                return activityOptions != null ? activityOptions.toBundle() : null;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r != null) {
+                    r.setRequestedOrientation(requestedOrientation);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public int getRequestedOrientation(IBinder token) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            return r != null
+                    ? r.getRequestedOrientation() : ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+        }
+    }
+
+    @Override
+    public boolean convertFromTranslucent(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                return r != null && r.setOccludesParent(true);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public boolean convertToTranslucent(IBinder token, Bundle options) {
+        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) {
+                    return false;
+                }
+                final ActivityRecord under = r.getTask().getActivityBelow(r);
+                if (under != null) {
+                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
+                }
+                return r.setOccludesParent(false);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public boolean isImmersive(IBinder token) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r == null) {
+                throw new IllegalArgumentException();
+            }
+            return r.immersive;
+        }
+    }
+
+    @Override
+    public void setImmersive(IBinder token, boolean immersive) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r == null) {
+                throw new IllegalArgumentException();
+            }
+            r.immersive = immersive;
+
+            // Update associated state if we're frontmost.
+            if (r.isFocusedActivityOnDisplay()) {
+                ProtoLog.d(WM_DEBUG_IMMERSIVE, "Frontmost changed immersion: %s", r);
+                mService.applyUpdateLockStateLocked(r);
+            }
+        }
+    }
+
+    @Override
+    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ensureValidPictureInPictureActivityParams(
+                        "enterPictureInPictureMode", token, params);
+                return mService.enterPictureInPictureMode(r, params);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ensureValidPictureInPictureActivityParams(
+                        "setPictureInPictureParams", token, params);
+
+                // Only update the saved args from the args that are set.
+                r.setPictureInPictureParams(params);
+                if (r.inPinnedWindowingMode()) {
+                    // If the activity is already in picture-in-picture, update the pinned task now
+                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
+                    // be used the next time the activity enters PiP.
+                    final Task rootTask = r.getRootTask();
+                    rootTask.setPictureInPictureAspectRatio(
+                            r.pictureInPictureArgs.getAspectRatio());
+                    rootTask.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    /**
+     * Checks the state of the system and the activity associated with the given {@param token} to
+     * verify that picture-in-picture is supported for that activity.
+     *
+     * @return the activity record for the given {@param token} if all the checks pass.
+     */
+    private ActivityRecord ensureValidPictureInPictureActivityParams(String caller,
+            IBinder token, PictureInPictureParams params) {
+        if (!mService.mSupportsPictureInPicture) {
+            throw new IllegalStateException(caller
+                    + ": Device doesn't support picture-in-picture mode.");
+        }
+
+        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+        if (r == null) {
+            throw new IllegalStateException(caller
+                    + ": Can't find activity for token=" + token);
+        }
+
+        if (!r.supportsPictureInPicture()) {
+            throw new IllegalStateException(caller
+                    + ": Current activity does not support picture-in-picture.");
+        }
+
+        if (params.hasSetAspectRatio()
+                && !mService.mWindowManager.isValidPictureInPictureAspectRatio(
+                r.mDisplayContent, params.getAspectRatio())) {
+            final float minAspectRatio = mContext.getResources().getFloat(
+                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
+            final float maxAspectRatio = mContext.getResources().getFloat(
+                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
+            throw new IllegalArgumentException(String.format(caller
+                            + ": Aspect ratio is too extreme (must be between %f and %f).",
+                    minAspectRatio, maxAspectRatio));
+        }
+
+        // Truncate the number of actions if necessary.
+        params.truncateActions(ActivityTaskManager.getMaxNumPictureInPictureActions(mContext));
+        return r;
+    }
+
+    @Override
+    public void toggleFreeformWindowingMode(IBinder token) {
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+                if (r == null) {
+                    throw new IllegalArgumentException(
+                            "toggleFreeformWindowingMode: No activity record matching token="
+                                    + token);
+                }
+
+                final Task rootTask = r.getRootTask();
+                if (rootTask == null) {
+                    throw new IllegalStateException("toggleFreeformWindowingMode: the activity "
+                            + "doesn't have a root task");
+                }
+
+                if (!rootTask.inFreeformWindowingMode()
+                        && rootTask.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
+                    throw new IllegalStateException("toggleFreeformWindowingMode: You can only "
+                            + "toggle between fullscreen and freeform.");
+                }
+
+                if (rootTask.inFreeformWindowingMode()) {
+                    rootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+                } else if (!mService.mSizeCompatFreeform && r.inSizeCompatMode()) {
+                    throw new IllegalStateException("Size-compat windows are currently not"
+                            + "freeform-enabled");
+                } else if (rootTask.getParent().inFreeformWindowingMode()) {
+                    // If the window is on a freeform display, set it to undefined. It will be
+                    // resolved to freeform and it can adjust windowing mode when the display mode
+                    // changes in runtime.
+                    rootTask.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+                } else {
+                    rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public void startLockTaskModeByToken(IBinder token) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+            if (r != null) {
+                mService.startLockTaskMode(r.getTask(), false /* isSystemCaller */);
+            }
+        }
+    }
+
+    @Override
+    public void stopLockTaskModeByToken(IBinder token) {
+        mService.stopLockTaskModeInternal(token, false /* isSystemCaller */);
+    }
+
+    @Override
+    public void showLockTaskEscapeMessage(IBinder token) {
+        synchronized (mGlobalLock) {
+            if (ActivityRecord.forTokenLocked(token) != null) {
+                mService.getLockTaskController().showLockTaskToast();
+            }
+        }
+    }
+
+    @Override
+    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r != null) {
+                r.setTaskDescription(td);
+            }
+        }
+    }
+
+    @Override
+    public boolean showAssistFromActivity(IBinder token, Bundle args) {
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord caller = ActivityRecord.forTokenLocked(token);
+                final Task topRootTask = mService.getTopDisplayFocusedRootTask();
+                final ActivityRecord top = topRootTask != null
+                        ? topRootTask.getTopNonFinishingActivity() : null;
+                if (top != caller) {
+                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
+                            + " is not current top " + top);
+                    return false;
+                }
+                if (!top.nowVisible) {
+                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
+                            + " is not visible");
+                    return false;
+                }
+            }
+            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION,
+                    null /* showCallback */, token);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public boolean isRootVoiceInteraction(IBinder token) {
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            return r != null && r.rootVoiceInteraction;
+        }
+    }
+
+    @Override
+    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
+        Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
+        synchronized (mGlobalLock) {
+            final Task topRootTask = mService.getTopDisplayFocusedRootTask();
+            final ActivityRecord activity = topRootTask != null
+                    ? topRootTask.getTopNonFinishingActivity() : null;
+            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
+                throw new SecurityException("Only focused activity can call startVoiceInteraction");
+            }
+            if (mService.mRunningVoice != null || activity.getTask().voiceSession != null
+                    || activity.voiceSession != null) {
+                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
+                return;
+            }
+            if (activity.pendingVoiceInteractionStart) {
+                Slog.w(TAG, "Pending start of voice interaction already.");
+                return;
+            }
+            activity.pendingVoiceInteractionStart = true;
+        }
+        LocalServices.getService(VoiceInteractionManagerInternal.class)
+                .startLocalVoiceInteraction(callingActivity, options);
+    }
+
+    @Override
+    public void stopLocalVoiceInteraction(IBinder callingActivity) {
+        LocalServices.getService(VoiceInteractionManagerInternal.class)
+                .stopLocalVoiceInteraction(callingActivity);
+    }
+
+    @Override
+    public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r != null) {
+                    r.setShowWhenLocked(showWhenLocked);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r != null) {
+                    r.setInheritShowWhenLocked(inheritShowWhenLocked);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r != null) {
+                    r.setTurnScreenOn(turnScreenOn);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r != null) {
+                    r.reportFullyDrawnLocked(restoredFromBundle);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void overridePendingTransition(IBinder token, String packageName,
+            int enterAnim, int exitAnim) {
+        final long origId = Binder.clearCallingIdentity();
+        synchronized (mGlobalLock) {
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r != null && r.isState(Task.ActivityState.RESUMED, Task.ActivityState.PAUSING)) {
+                r.mDisplayContent.mAppTransition.overridePendingAppTransition(
+                        packageName, enterAnim, exitAnim, null, null);
+            }
+        }
+        Binder.restoreCallingIdentity(origId);
+    }
+
+    @Override
+    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
+        mService.enforceSystemHasVrFeature();
+
+        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
+        final ActivityRecord r;
+        synchronized (mGlobalLock) {
+            r = ActivityRecord.isInStackLocked(token);
+        }
+        if (r == null) {
+            throw new IllegalArgumentException();
+        }
+
+        final int err;
+        if ((err = vrService.hasVrPackage(packageName, r.mUserId)) != VrManagerInternal.NO_ERROR) {
+            return err;
+        }
+
+        // Clear the binder calling uid since this path may call moveToTask().
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                r.requestedVrComponent = (enabled) ? packageName : null;
+
+                // Update associated state if this activity is currently focused.
+                if (r.isFocusedActivityOnDisplay()) {
+                    mService.applyUpdateVrModeLocked(r);
+                }
+                return 0;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
+    @Override
+    public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r != null) {
+                    r.setDisablePreviewScreenshots(disable);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
+        mService.mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
+                "registerRemoteAnimations");
+        definition.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid());
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r != null) {
+                    r.registerRemoteAnimations(definition);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void unregisterRemoteAnimations(IBinder token) {
+        mService.mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
+                "unregisterRemoteAnimations");
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r != null) {
+                    r.unregisterRemoteAnimations();
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void onBackPressedOnTaskRoot(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) {
+                    return;
+                }
+                if (mService.mWindowOrganizerController.mTaskOrganizerController
+                        .handleInterceptBackPressedOnTaskRoot(r.getRootTask())) {
+                    // This task is handled by a task organizer that has requested the back pressed
+                    // callback.
+                } else {
+                    moveActivityTaskToBack(token, false /* nonRoot */);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 1b8cc08..743796b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -925,8 +925,9 @@
         if (mVoiceInteraction) {
             pw.println(prefix + "mVoiceInteraction=true");
         }
-        pw.print(prefix); pw.print("mOccludesParent="); pw.print(mOccludesParent);
-        pw.print(" mOrientation="); pw.println(mOrientation);
+        pw.print(prefix); pw.print("mOccludesParent="); pw.println(mOccludesParent);
+        pw.print(prefix); pw.print("mOrientation=");
+        pw.println(ActivityInfo.screenOrientationToString(mOrientation));
         pw.println(prefix + "mVisibleRequested=" + mVisibleRequested
                 + " mVisible=" + mVisible + " mClientVisible=" + mClientVisible
                 + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
@@ -1011,6 +1012,9 @@
             if (info.supportsSizeChanges) {
                 pw.println(prefix + "supportsSizeChanges=true");
             }
+            if (info.configChanges != 0) {
+                pw.println(prefix + "configChanges=0x" + Integer.toHexString(info.configChanges));
+            }
         }
     }
 
@@ -4032,7 +4036,7 @@
                 if (mDisplayContent != null) {
                     mDisplayContent.setLayoutNeeded();
                 }
-                mWmService.mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
+                mWmService.mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, this).sendToTarget();
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 3710120..8298dfd 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -33,8 +33,6 @@
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -62,7 +60,6 @@
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
 import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
 import static android.provider.Settings.System.FONT_SCALE;
-import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
@@ -95,15 +92,8 @@
 import static com.android.server.am.EventLogTags.writeBootProgressEnableScreen;
 import static com.android.server.am.EventLogTags.writeConfigurationChanged;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
@@ -121,8 +111,6 @@
 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_ONLY;
 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
-import static com.android.server.wm.Task.ActivityState.DESTROYED;
-import static com.android.server.wm.Task.ActivityState.DESTROYING;
 import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
@@ -132,7 +120,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions;
@@ -143,6 +130,7 @@
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.Dialog;
+import android.app.IActivityClientController;
 import android.app.IActivityController;
 import android.app.IActivityTaskManager;
 import android.app.IApplicationThread;
@@ -197,7 +185,6 @@
 import android.os.LocaleList;
 import android.os.Looper;
 import android.os.Message;
-import android.os.PersistableBundle;
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
 import android.os.Process;
@@ -237,7 +224,6 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.AssistUtils;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.ProcessMap;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
@@ -249,8 +235,6 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.FrameworkStatsLog;
-import com.android.internal.util.function.pooled.PooledConsumer;
-import com.android.internal.util.function.pooled.PooledFunction;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.AttributeCache;
 import com.android.server.LocalServices;
@@ -271,7 +255,6 @@
 import com.android.server.policy.PermissionPolicyInternal;
 import com.android.server.uri.NeededUriGrants;
 import com.android.server.uri.UriGrantsManagerInternal;
-import com.android.server.vr.VrManagerInternal;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -308,11 +291,6 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
     static final String TAG_ROOT_TASK = TAG + POSTFIX_ROOT_TASK;
     static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
-    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
-    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
-    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
-    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
-    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
 
     // How long we wait until we timeout on key dispatching during instrumentation.
     static final long INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MILLIS = 60 * 1000;
@@ -385,6 +363,7 @@
      */
     final Object mGlobalLockWithoutBoost = mGlobalLock;
     ActivityTaskSupervisor mTaskSupervisor;
+    ActivityClientController mActivityClientController;
     RootWindowContainer mRootWindowContainer;
     WindowManagerService mWindowManager;
     private UserManagerService mUserManager;
@@ -418,9 +397,6 @@
     /** State of external calls telling us if the device is awake or asleep. */
     private boolean mKeyguardShown = false;
 
-    // Wrapper around VoiceInteractionServiceManager
-    private AssistUtils mAssistUtils;
-
     // VoiceInteraction session ID that changes for each new request except when
     // being called for multi-window assist in a single session.
     private int mViSessionId = 1000;
@@ -763,10 +739,10 @@
             final PackageManager pm = mContext.getPackageManager();
             mHasHeavyWeightFeature = pm.hasSystemFeature(FEATURE_CANT_SAVE_STATE);
             mHasLeanbackFeature = pm.hasSystemFeature(FEATURE_LEANBACK);
-            mAssistUtils = new AssistUtils(mContext);
             mVrController.onSystemReady();
             mRecentTasks.onSystemReadyLocked();
             mTaskSupervisor.onSystemReady();
+            mActivityClientController.onSystemReady();
             mBlockActivityAfterHomeEnabled = DeviceConfig.getBoolean(
                     DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                     BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG, false);
@@ -872,6 +848,7 @@
         mCompatModePackages = new CompatModePackages(this, systemDir, mH);
         mPendingIntentController = intentController;
         mTaskSupervisor = createTaskSupervisor();
+        mActivityClientController = new ActivityClientController(this);
 
         mTaskChangeNotificationController =
                 new TaskChangeNotificationController(mGlobalLock, mTaskSupervisor, mH);
@@ -1698,311 +1675,9 @@
         return mAmInternal.getActivityInfoForUser(aInfo, userId);
     }
 
-    /**
-     * This is the internal entry point for handling Activity.finish().
-     *
-     * @param token      The Binder token referencing the Activity we want to finish.
-     * @param resultCode Result code, if any, from this Activity.
-     * @param resultData Result data (Intent), if any, from this Activity.
-     * @param finishTask Whether to finish the task associated with this Activity.
-     * @return Returns true if the activity successfully finished, or false if it is still running.
-     */
     @Override
-    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
-            int finishTask) {
-        // Refuse possible leaked file descriptors
-        if (resultData != null && resultData.hasFileDescriptors()) {
-            throw new IllegalArgumentException("File descriptors passed in Intent");
-        }
-
-        final ActivityRecord r;
-        synchronized (mGlobalLock) {
-            r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return true;
-            }
-        }
-
-        // Carefully collect grants without holding lock
-        final NeededUriGrants resultGrants = collectGrants(resultData, r.resultTo);
-
-        synchronized (mGlobalLock) {
-            // Sanity check in case activity was removed before entering global lock.
-            if (!r.isInHistory()) {
-                return true;
-            }
-
-            // Keep track of the root activity of the task before we finish it
-            final Task tr = r.getTask();
-            final ActivityRecord rootR = tr.getRootActivity();
-            if (rootR == null) {
-                Slog.w(TAG, "Finishing task with all activities already finished");
-            }
-            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
-            // finish.
-            if (getLockTaskController().activityBlockedFromFinish(r)) {
-                return false;
-            }
-
-            // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
-            // We should consolidate.
-            if (mController != null) {
-                // Find the first activity that is not finishing.
-                final ActivityRecord next =
-                        r.getRootTask().topRunningActivity(token, INVALID_TASK_ID);
-                if (next != null) {
-                    // ask watcher if this is allowed
-                    boolean resumeOK = true;
-                    try {
-                        resumeOK = mController.activityResuming(next.packageName);
-                    } catch (RemoteException e) {
-                        mController = null;
-                        Watchdog.getInstance().setActivityController(null);
-                    }
-
-                    if (!resumeOK) {
-                        Slog.i(TAG, "Not finishing activity because controller resumed");
-                        return false;
-                    }
-                }
-            }
-
-            // note down that the process has finished an activity and is in background activity
-            // starts grace period
-            if (r.app != null) {
-                r.app.setLastActivityFinishTimeIfNeeded(SystemClock.uptimeMillis());
-            }
-
-            final long origId = Binder.clearCallingIdentity();
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "finishActivity");
-            try {
-                boolean res;
-                final boolean finishWithRootActivity =
-                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
-                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
-                        || (finishWithRootActivity && r == rootR)) {
-                    // If requested, remove the task that is associated to this activity only if it
-                    // was the root activity in the task. The result code and data is ignored
-                    // because we don't support returning them across task boundaries. Also, to
-                    // keep backwards compatibility we remove the task from recents when finishing
-                    // task with root activity.
-                    mTaskSupervisor.removeTask(tr, false /*killProcess*/,
-                            finishWithRootActivity, "finish-activity");
-                    res = true;
-                    // Explicitly dismissing the activity so reset its relaunch flag.
-                    r.mRelaunchReason = RELAUNCH_REASON_NONE;
-                } else {
-                    r.finishIfPossible(resultCode, resultData, resultGrants,
-                            "app-request", true /* oomAdj */);
-                    res = r.finishing;
-                    if (!res) {
-                        Slog.i(TAG, "Failed to finish by app-request");
-                    }
-                }
-                return res;
-            } finally {
-                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
-    public boolean finishActivityAffinity(IBinder token) {
-        synchronized (mGlobalLock) {
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                ActivityRecord r = ActivityRecord.isInStackLocked(token);
-                if (r == null) {
-                    return false;
-                }
-
-                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
-                // can finish.
-                if (getLockTaskController().activityBlockedFromFinish(r)) {
-                    return false;
-                }
-
-                final PooledFunction p = PooledLambda.obtainFunction(
-                        ActivityRecord::finishIfSameAffinity, r,
-                        PooledLambda.__(ActivityRecord.class));
-                r.getTask().forAllActivities(
-                        p, r, true /*includeBoundary*/, true /*traverseTopToBottom*/);
-                p.recycle();
-
-                return true;
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
-    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle");
-                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-                if (r == null) {
-                    return;
-                }
-                mTaskSupervisor.activityIdleInternal(r, false /* fromTimeout */,
-                        false /* processPausingActivities */, config);
-                if (stopProfiling && r.hasProcess()) {
-                    r.app.clearProfilerIfNeeded();
-                }
-            }
-        } finally {
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    @Override
-    public final void activityResumed(IBinder token) {
-        final long origId = Binder.clearCallingIdentity();
-        synchronized (mGlobalLock) {
-            ActivityRecord.activityResumedLocked(token);
-        }
-        Binder.restoreCallingIdentity(origId);
-    }
-
-    @Override
-    public final void activityTopResumedStateLost() {
-        final long origId = Binder.clearCallingIdentity();
-        synchronized (mGlobalLock) {
-            mTaskSupervisor.handleTopResumedStateReleased(false /* timeout */);
-        }
-        Binder.restoreCallingIdentity(origId);
-    }
-
-    @Override
-    public final void activityPaused(IBinder token) {
-        final long origId = Binder.clearCallingIdentity();
-        synchronized (mGlobalLock) {
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
-            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-            if (r != null) {
-                r.activityPaused(false);
-            }
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-        }
-        Binder.restoreCallingIdentity(origId);
-    }
-
-    @Override
-    public final void activityStopped(IBinder token, Bundle icicle,
-            PersistableBundle persistentState, CharSequence description) {
-        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
-
-        // Refuse possible leaked file descriptors
-        if (icicle != null && icicle.hasFileDescriptors()) {
-            throw new IllegalArgumentException("File descriptors passed in Bundle");
-        }
-
-        final long origId = Binder.clearCallingIdentity();
-
-        String restartingName = null;
-        int restartingUid = 0;
-        final ActivityRecord r;
-        synchronized (mGlobalLock) {
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityStopped");
-            r = ActivityRecord.isInStackLocked(token);
-            if (r != null) {
-                if (r.attachedToProcess()
-                        && r.isState(Task.ActivityState.RESTARTING_PROCESS)) {
-                    // The activity was requested to restart from
-                    // {@link #restartActivityProcessIfVisible}.
-                    restartingName = r.app.mName;
-                    restartingUid = r.app.mUid;
-                }
-                r.activityStopped(icicle, persistentState, description);
-            }
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-        }
-
-        if (restartingName != null) {
-            // In order to let the foreground activity can be restarted with its saved state from
-            // {@link android.app.Activity#onSaveInstanceState}, the kill operation is postponed
-            // until the activity reports stopped with the state. And the activity record will be
-            // kept because the record state is restarting, then the activity will be restarted
-            // immediately if it is still the top one.
-            mTaskSupervisor.removeRestartTimeouts(r);
-            mAmInternal.killProcess(restartingName, restartingUid, "restartActivityProcess");
-        }
-        mAmInternal.trimApplications();
-
-        Binder.restoreCallingIdentity(origId);
-    }
-
-    @Override
-    public final void activityDestroyed(IBinder token) {
-        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
-        synchronized (mGlobalLock) {
-            final long origId = Binder.clearCallingIdentity();
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityDestroyed");
-            try {
-                final ActivityRecord activity = ActivityRecord.forTokenLocked(token);
-                if (activity != null) {
-                    activity.destroyed("activityDestroyed");
-                }
-            } finally {
-                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
-    public final void activityRelaunched(IBinder token) {
-        final long origId = Binder.clearCallingIdentity();
-        synchronized (mGlobalLock) {
-            mTaskSupervisor.activityRelaunchedLocked(token);
-        }
-        Binder.restoreCallingIdentity(origId);
-    }
-
-    @Override
-    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
-        synchronized (mGlobalLock) {
-            ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return;
-            }
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                r.setRequestedOrientation(requestedOrientation);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
-    public int getRequestedOrientation(IBinder token) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            return (r != null)
-                    ? r.getRequestedOrientation() : ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-        }
-    }
-
-    @Override
-    public void setImmersive(IBinder token, boolean immersive) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                throw new IllegalArgumentException();
-            }
-            r.immersive = immersive;
-
-            // update associated state if we're frontmost
-            if (r.isFocusedActivityOnDisplay()) {
-                ProtoLog.d(WM_DEBUG_IMMERSIVE, "Frontmost changed immersion: %s", r);
-                applyUpdateLockStateLocked(r);
-            }
-        }
+    public IActivityClientController getActivityClientController() {
+        return mActivityClientController;
     }
 
     void applyUpdateLockStateLocked(ActivityRecord r) {
@@ -2025,17 +1700,6 @@
     }
 
     @Override
-    public boolean isImmersive(IBinder token) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                throw new IllegalArgumentException();
-            }
-            return r.immersive;
-        }
-    }
-
-    @Override
     public boolean isTopActivityImmersive() {
         enforceNotIsolatedCaller("isTopActivityImmersive");
         synchronized (mGlobalLock) {
@@ -2050,27 +1714,6 @@
     }
 
     @Override
-    public void overridePendingTransition(IBinder token, String packageName,
-            int enterAnim, int exitAnim) {
-        synchronized (mGlobalLock) {
-            ActivityRecord self = ActivityRecord.isInStackLocked(token);
-            if (self == null) {
-                return;
-            }
-
-            final long origId = Binder.clearCallingIdentity();
-
-            if (self.isState(
-                    Task.ActivityState.RESUMED, Task.ActivityState.PAUSING)) {
-                self.mDisplayContent.mAppTransition.overridePendingAppTransition(
-                        packageName, enterAnim, exitAnim, null, null);
-            }
-
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    @Override
     public int getFrontActivityScreenCompatMode() {
         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
         synchronized (mGlobalLock) {
@@ -2125,77 +1768,6 @@
     }
 
     @Override
-    public boolean convertFromTranslucent(IBinder token) {
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-                if (r == null) {
-                    return false;
-                }
-                return r.setOccludesParent(true);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    @Override
-    public boolean convertToTranslucent(IBinder token, Bundle options) {
-        SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-                if (r == null) {
-                    return false;
-                }
-                final ActivityRecord under = r.getTask().getActivityBelow(r);
-                if (under != null) {
-                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
-                }
-                return r.setOccludesParent(false);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    @Override
-    public void notifyActivityDrawn(IBinder token) {
-        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
-        synchronized (mGlobalLock) {
-            ActivityRecord r = mRootWindowContainer.isInAnyTask(token);
-            if (r != null) {
-                r.getRootTask().notifyActivityDrawnLocked(r);
-            }
-        }
-    }
-
-    @Override
-    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
-        synchronized (mGlobalLock) {
-            ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return;
-            }
-            r.reportFullyDrawnLocked(restoredFromBundle);
-        }
-    }
-
-    @Override
-    public int getDisplayId(IBinder activityToken) throws RemoteException {
-        synchronized (mGlobalLock) {
-            final Task stack = ActivityRecord.getStackLocked(activityToken);
-            if (stack != null) {
-                final int displayId = stack.getDisplayId();
-                return displayId != INVALID_DISPLAY ? displayId : DEFAULT_DISPLAY;
-            }
-            return DEFAULT_DISPLAY;
-        }
-    }
-
-    @Override
     public RootTaskInfo getFocusedRootTaskInfo() throws RemoteException {
         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "getFocusedRootTaskInfo()");
         final long ident = Binder.clearCallingIdentity();
@@ -2312,75 +1884,6 @@
     }
 
     @Override
-    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
-            if (srec != null) {
-                return srec.getRootTask().shouldUpRecreateTaskLocked(srec, destAffinity);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
-            Intent resultData) {
-        final ActivityRecord r;
-        synchronized (mGlobalLock) {
-            r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return false;
-            }
-        }
-
-        // Carefully collect grants without holding lock
-        final NeededUriGrants destGrants = collectGrants(destIntent, r);
-        final NeededUriGrants resultGrants = collectGrants(resultData, r.resultTo);
-
-        synchronized (mGlobalLock) {
-            return r.getRootTask().navigateUpTo(
-                    r, destIntent, destGrants, resultCode, resultData, resultGrants);
-        }
-    }
-
-    /**
-     * Attempts to move a task backwards in z-order (the order of activities within the task is
-     * unchanged).
-     *
-     * There are several possible results of this call:
-     * - if the task is locked, then we will show the lock toast
-     * - if there is a task behind the provided task, then that task is made visible and resumed as
-     * this task is moved to the back
-     * - otherwise, if there are no other tasks in the stack:
-     * - if this task is in the pinned stack, then we remove the stack completely, which will
-     * have the effect of moving the task to the top or bottom of the fullscreen stack
-     * (depending on whether it is visible)
-     * - otherwise, we simply return home and hide this task
-     *
-     * @param token   A reference to the activity we wish to move
-     * @param nonRoot If false then this only works if the activity is the root
-     *                of a task; if true it will work for any activity in a task.
-     * @return Returns true if the move completed, false if not.
-     */
-    @Override
-    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
-        enforceNotIsolatedCaller("moveActivityTaskToBack");
-        synchronized (mGlobalLock) {
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
-                final Task task = mRootWindowContainer.anyTaskForId(taskId);
-                if (task != null) {
-                    return ActivityRecord.getStackLocked(token).moveTaskToBack(task);
-                }
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-        return false;
-    }
-
-    @Override
     public Rect getTaskBounds(int taskId) {
         enforceTaskPermission("getTaskBounds()");
         final long ident = Binder.clearCallingIdentity();
@@ -2467,31 +1970,7 @@
         }
     }
 
-    @Override
-    public String getCallingPackage(IBinder token) {
-        synchronized (mGlobalLock) {
-            ActivityRecord r = getCallingRecordLocked(token);
-            return r != null ? r.info.packageName : null;
-        }
-    }
-
-    @Override
-    public ComponentName getCallingActivity(IBinder token) {
-        synchronized (mGlobalLock) {
-            ActivityRecord r = getCallingRecordLocked(token);
-            return r != null ? r.intent.getComponent() : null;
-        }
-    }
-
-    private ActivityRecord getCallingRecordLocked(IBinder token) {
-        ActivityRecord r = ActivityRecord.isInStackLocked(token);
-        if (r == null) {
-            return null;
-        }
-        return r.resultTo;
-    }
-
-    private NeededUriGrants collectGrants(Intent intent, ActivityRecord target) {
+    NeededUriGrants collectGrants(Intent intent, ActivityRecord target) {
         if (target != null) {
             return mUgmInternal.checkGrantUriPermissionFromIntent(intent,
                     Binder.getCallingUid(), target.packageName, target.mUserId);
@@ -2518,25 +1997,6 @@
         }
     }
 
-    @Override
-    public void onBackPressedOnTaskRoot(IBinder token) {
-        synchronized (mGlobalLock) {
-            ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return;
-            }
-            Task stack = r.getRootTask();
-            final TaskOrganizerController taskOrgController =
-                    mWindowOrganizerController.mTaskOrganizerController;
-            if (taskOrgController.handleInterceptBackPressedOnTaskRoot(stack)) {
-                // This task is handled by a task organizer that has requested the back pressed
-                // callback
-            } else {
-                moveActivityTaskToBack(token, false /* nonRoot */);
-            }
-        }
-    }
-
     /**
      * TODO: Add mController hook
      */
@@ -2731,13 +2191,6 @@
         }
     }
 
-    @Override
-    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
-        synchronized (mGlobalLock) {
-            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
-        }
-    }
-
     List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
         return getTasks(maxNum, false /* filterForVisibleRecents */);
     }
@@ -2772,40 +2225,6 @@
     }
 
     @Override
-    public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
-        synchronized (mGlobalLock) {
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                ActivityRecord r = ActivityRecord.isInStackLocked(token);
-                if (r == null) return;
-
-                final PooledConsumer c = PooledLambda.obtainConsumer(
-                        ActivityRecord::finishIfSubActivity, PooledLambda.__(ActivityRecord.class),
-                        r, resultWho, requestCode);
-                // TODO: This should probably only loop over the task since you need to be in the
-                // same task to return results.
-                r.getRootTask().forAllActivities(c);
-                c.recycle();
-
-                updateOomAdj();
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
-    public boolean willActivityBeVisible(IBinder token) {
-        synchronized (mGlobalLock) {
-            Task stack = ActivityRecord.getStackLocked(token);
-            if (stack != null) {
-                return stack.willActivityBeVisible(token);
-            }
-            return false;
-        }
-    }
-
-    @Override
     public void moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop) {
         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "moveTaskToRootTask()");
         synchronized (mGlobalLock) {
@@ -3035,17 +2454,6 @@
     }
 
     @Override
-    public void startLockTaskModeByToken(IBinder token) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-            if (r == null) {
-                return;
-            }
-            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
-        }
-    }
-
-    @Override
     public void startSystemLockTaskMode(int taskId) {
         enforceTaskPermission("startSystemLockTaskMode");
         // This makes inner call to look as if it was initiated by system.
@@ -3060,18 +2468,13 @@
 
                 // When starting lock task mode the stack must be in front and focused
                 task.getRootTask().moveToFront("startSystemLockTaskMode");
-                startLockTaskModeLocked(task, true /* isSystemCaller */);
+                startLockTaskMode(task, true /* isSystemCaller */);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
-    @Override
-    public void stopLockTaskModeByToken(IBinder token) {
-        stopLockTaskModeInternal(token, false /* isSystemCaller */);
-    }
-
     /**
      * This API should be called by SystemUI only when user perform certain action to dismiss
      * lock task mode. We should only dismiss pinned lock task mode in this case.
@@ -3082,8 +2485,8 @@
         stopLockTaskModeInternal(null, true /* isSystemCaller */);
     }
 
-    private void startLockTaskModeLocked(@Nullable Task task, boolean isSystemCaller) {
-        ProtoLog.w(WM_DEBUG_LOCKTASK, "startLockTaskModeLocked: %s", task);
+    void startLockTaskMode(@Nullable Task task, boolean isSystemCaller) {
+        ProtoLog.w(WM_DEBUG_LOCKTASK, "startLockTaskMode: %s", task);
         if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
             return;
         }
@@ -3111,7 +2514,7 @@
         }
     }
 
-    private void stopLockTaskModeInternal(@Nullable IBinder token, boolean isSystemCaller) {
+    void stopLockTaskModeInternal(@Nullable IBinder token, boolean isSystemCaller) {
         final int callingUid = Binder.getCallingUid();
         final long ident = Binder.clearCallingIdentity();
         try {
@@ -3163,34 +2566,6 @@
     }
 
     @Override
-    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
-        synchronized (mGlobalLock) {
-            ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r != null) {
-                r.setTaskDescription(td);
-            }
-        }
-    }
-
-    @Override
-    public Bundle getActivityOptions(IBinder token) {
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-                if (r != null) {
-                    final ActivityOptions activityOptions = r.takeOptionsLocked(
-                            true /* fromClient */);
-                    return activityOptions == null ? null : activityOptions.toBundle();
-                }
-                return null;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    @Override
     public List<IBinder> getAppTasks(String callingPackage) {
         int callingUid = Binder.getCallingUid();
         assertPackageMatchesCallingUid(callingPackage);
@@ -3220,39 +2595,9 @@
     }
 
     @Override
-    public boolean isTopOfTask(IBinder token) {
-        synchronized (mGlobalLock) {
-            ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            return r != null && r.getTask().getTopNonFinishingActivity() == r;
-        }
-    }
-
-    @Override
-    public void notifyLaunchTaskBehindComplete(IBinder token) {
-        mTaskSupervisor.scheduleLaunchTaskBehindComplete(token);
-    }
-
-    @Override
-    public void notifyEnterAnimationComplete(IBinder token) {
-        mH.post(() -> {
-            synchronized (mGlobalLock) {
-                ActivityRecord r = ActivityRecord.forTokenLocked(token);
-                if (r != null && r.attachedToProcess()) {
-                    try {
-                        r.app.getThread().scheduleEnterAnimationComplete(r.appToken);
-                    } catch (RemoteException e) {
-                    }
-                }
-            }
-
-        });
-    }
-
-    /** Called from an app when assist data is ready. */
-    @Override
-    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
-            AssistContent content, Uri referrer) {
-        PendingAssistExtras pae = (PendingAssistExtras) token;
+    public void reportAssistContextExtras(IBinder assistToken, Bundle extras,
+            AssistStructure structure, AssistContent content, Uri referrer) {
+        final PendingAssistExtras pae = (PendingAssistExtras) assistToken;
         synchronized (pae) {
             pae.result = extras;
             pae.structure = structure;
@@ -3440,23 +2785,6 @@
     }
 
     @Override
-    public boolean releaseActivityInstance(IBinder token) {
-        synchronized (mGlobalLock) {
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-                if (r == null || !r.isDestroyable()) {
-                    return false;
-                }
-                r.destroyImmediately("app-req");
-                return r.isState(DESTROYING, DESTROYED);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
     public void releaseSomeActivities(IApplicationThread appInt) {
         synchronized (mGlobalLock) {
             final long origId = Binder.clearCallingIdentity();
@@ -3540,49 +2868,6 @@
         }
     }
 
-    @Override
-    public void toggleFreeformWindowingMode(IBinder token) {
-        synchronized (mGlobalLock) {
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-                if (r == null) {
-                    throw new IllegalArgumentException(
-                            "toggleFreeformWindowingMode: No activity record matching token="
-                                    + token);
-                }
-
-                final Task stack = r.getRootTask();
-                if (stack == null) {
-                    throw new IllegalStateException("toggleFreeformWindowingMode: the activity "
-                            + "doesn't have a stack");
-                }
-
-                if (!stack.inFreeformWindowingMode()
-                        && stack.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
-                    throw new IllegalStateException("toggleFreeformWindowingMode: You can only "
-                            + "toggle between fullscreen and freeform.");
-                }
-
-                if (stack.inFreeformWindowingMode()) {
-                    stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-                } else if (!mSizeCompatFreeform && r.inSizeCompatMode()) {
-                    throw new IllegalStateException("Size-compat windows are currently not"
-                            + "freeform-enabled");
-                } else if (stack.getParent().inFreeformWindowingMode()) {
-                    // If the window is on a freeform display, set it to undefined. It will be
-                    // resolved to freeform and it can adjust windowing mode when the display mode
-                    // changes in runtime.
-                    stack.setWindowingMode(WINDOWING_MODE_UNDEFINED);
-                } else {
-                    stack.setWindowingMode(WINDOWING_MODE_FREEFORM);
-                }
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-    }
-
     /** Sets the task stack listener that gets callbacks when a task stack changes. */
     @Override
     public void registerTaskStackListener(ITaskStackListener listener) {
@@ -3884,42 +3169,6 @@
         return DevicePolicyCache.getInstance().isScreenCaptureAllowed(userId, false);
     }
 
-    @Override
-    public boolean showAssistFromActivity(IBinder token, Bundle args) {
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
-                ActivityRecord top = getTopDisplayFocusedRootTask().getTopNonFinishingActivity();
-                if (top != caller) {
-                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
-                            + " is not current top " + top);
-                    return false;
-                }
-                if (!top.nowVisible) {
-                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
-                            + " is not visible");
-                    return false;
-                }
-            }
-            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
-                    token);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    @Override
-    public boolean isRootVoiceInteraction(IBinder token) {
-        synchronized (mGlobalLock) {
-            ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return false;
-            }
-            return r.rootVoiceInteraction;
-        }
-    }
-
     private void onLocalVoiceInteractionStartedLocked(IBinder activity,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
@@ -4001,17 +3250,6 @@
     }
 
     @Override
-    public void showLockTaskEscapeMessage(IBinder token) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-            if (r == null) {
-                return;
-            }
-            getLockTaskController().showLockTaskToast();
-        }
-    }
-
-    @Override
     public void keyguardGoingAway(int flags) {
         enforceNotIsolatedCaller("keyguardGoingAway");
         final long token = Binder.clearCallingIdentity();
@@ -4025,22 +3263,6 @@
     }
 
     @Override
-    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
-            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
-        ProtoLog.v(WM_DEBUG_CONFIGURATION, "Report configuration: %s %s %s",
-                token, Arrays.toString(horizontalSizeConfiguration),
-                Arrays.toString(verticalSizeConfigurations));
-        synchronized (mGlobalLock) {
-            ActivityRecord record = ActivityRecord.isInStackLocked(token);
-            if (record == null) {
-                return;
-            }
-            record.setSizeConfigurations(horizontalSizeConfiguration,
-                    verticalSizeConfigurations, smallestSizeConfigurations);
-        }
-    }
-
-    @Override
     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
         mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_TASKS,
                 "suppressResizeConfigChanges()");
@@ -4138,100 +3360,6 @@
         return true;
     }
 
-    @Override
-    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
-                        "enterPictureInPictureMode", token, params);
-                return enterPictureInPictureMode(r, params);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    @Override
-    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
-                        "setPictureInPictureParams", token, params);
-
-                // Only update the saved args from the args that are set
-                r.setPictureInPictureParams(params);
-                if (r.inPinnedWindowingMode()) {
-                    // If the activity is already in picture-in-picture, update the pinned stack now
-                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
-                    // be used the next time the activity enters PiP
-                    final Task stack = r.getRootTask();
-                    stack.setPictureInPictureAspectRatio(
-                            r.pictureInPictureArgs.getAspectRatio());
-                    stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    /**
-     * Checks the state of the system and the activity associated with the given {@param token} to
-     * verify that picture-in-picture is supported for that activity.
-     *
-     * @return the activity record for the given {@param token} if all the checks pass.
-     */
-    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
-            IBinder token, PictureInPictureParams params) {
-        if (!mSupportsPictureInPicture) {
-            throw new IllegalStateException(caller
-                    + ": Device doesn't support picture-in-picture mode.");
-        }
-
-        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
-        if (r == null) {
-            throw new IllegalStateException(caller
-                    + ": Can't find activity for token=" + token);
-        }
-
-        if (!r.supportsPictureInPicture()) {
-            throw new IllegalStateException(caller
-                    + ": Current activity does not support picture-in-picture.");
-        }
-
-        if (params.hasSetAspectRatio()
-                && !mWindowManager.isValidPictureInPictureAspectRatio(
-                r.mDisplayContent, params.getAspectRatio())) {
-            final float minAspectRatio = mContext.getResources().getFloat(
-                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
-            final float maxAspectRatio = mContext.getResources().getFloat(
-                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
-            throw new IllegalArgumentException(String.format(caller
-                            + ": Aspect ratio is too extreme (must be between %f and %f).",
-                    minAspectRatio, maxAspectRatio));
-        }
-
-        // Truncate the number of actions if necessary
-        params.truncateActions(ActivityTaskManager.getMaxNumPictureInPictureActions(mContext));
-
-        return r;
-    }
-
-    @Override
-    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
-        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
-        synchronized (mGlobalLock) {
-            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
-            if (r == null) {
-                throw new IllegalArgumentException("Activity does not exist; token="
-                        + activityToken);
-            }
-            return r.getUriPermissionsLocked().getExternalToken();
-        }
-    }
-
     // TODO(b/149338177): remove when CTS no-longer requires it
     @Override
     public void resizePrimarySplitScreen(Rect dockedBounds, Rect tempDockedTaskBounds,
@@ -4304,73 +3432,6 @@
     }
 
     @Override
-    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
-        enforceSystemHasVrFeature();
-
-        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
-
-        ActivityRecord r;
-        synchronized (mGlobalLock) {
-            r = ActivityRecord.isInStackLocked(token);
-        }
-
-        if (r == null) {
-            throw new IllegalArgumentException();
-        }
-
-        int err;
-        if ((err = vrService.hasVrPackage(packageName, r.mUserId)) !=
-                VrManagerInternal.NO_ERROR) {
-            return err;
-        }
-
-        // Clear the binder calling uid since this path may call moveToTask().
-        final long callingId = Binder.clearCallingIdentity();
-        try {
-            synchronized (mGlobalLock) {
-                r.requestedVrComponent = (enabled) ? packageName : null;
-
-                // Update associated state if this activity is currently focused
-                if (r.isFocusedActivityOnDisplay()) {
-                    applyUpdateVrModeLocked(r);
-                }
-                return 0;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
-        }
-    }
-
-    @Override
-    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
-        Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
-        synchronized (mGlobalLock) {
-            ActivityRecord activity = getTopDisplayFocusedRootTask().getTopNonFinishingActivity();
-            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
-                throw new SecurityException("Only focused activity can call startVoiceInteraction");
-            }
-            if (mRunningVoice != null || activity.getTask().voiceSession != null
-                    || activity.voiceSession != null) {
-                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
-                return;
-            }
-            if (activity.pendingVoiceInteractionStart) {
-                Slog.w(TAG, "Pending start of voice interaction already.");
-                return;
-            }
-            activity.pendingVoiceInteractionStart = true;
-        }
-        LocalServices.getService(VoiceInteractionManagerInternal.class)
-                .startLocalVoiceInteraction(callingActivity, options);
-    }
-
-    @Override
-    public void stopLocalVoiceInteraction(IBinder callingActivity) {
-        LocalServices.getService(VoiceInteractionManagerInternal.class)
-                .stopLocalVoiceInteraction(callingActivity);
-    }
-
-    @Override
     public boolean supportsLocalVoiceInteraction() {
         return LocalServices.getService(VoiceInteractionManagerInternal.class)
                 .supportsLocalVoiceInteraction();
@@ -4474,24 +3535,6 @@
     }
 
     @Override
-    public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
-                        + token);
-                return;
-            }
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                r.setDisablePreviewScreenshots(disable);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
     public void invalidateHomeTaskSnapshot(IBinder token) {
         synchronized (mGlobalLock) {
             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
@@ -4532,91 +3575,6 @@
     }
 
     @Override
-    public void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return;
-            }
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                r.setShowWhenLocked(showWhenLocked);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
-    public void setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return;
-            }
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                r.setInheritShowWhenLocked(inheritShowWhenLocked);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
-    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return;
-            }
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                r.setTurnScreenOn(turnScreenOn);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
-    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
-        mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
-                "registerRemoteAnimations");
-        definition.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid());
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return;
-            }
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                r.registerRemoteAnimations(definition);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
-    public void unregisterRemoteAnimations(IBinder token) {
-        mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
-                "unregisterRemoteAnimations");
-        synchronized (mGlobalLock) {
-            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
-            if (r == null) {
-                return;
-            }
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                r.unregisterRemoteAnimations();
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
     public void registerRemoteAnimationForNextActivityStart(String packageName,
             RemoteAnimationAdapter adapter) {
         mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
@@ -4743,7 +3701,7 @@
         return mVrController.shouldDisableNonVrUiLocked();
     }
 
-    private void applyUpdateVrModeLocked(ActivityRecord r) {
+    void applyUpdateVrModeLocked(ActivityRecord r) {
         // VR apps are expected to run in a main display. If an app is turning on VR for
         // itself, but isn't on the main display, then move it there before enabling VR Mode.
         if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
@@ -5097,7 +4055,7 @@
         return mAmInternal.getCurrentUserId();
     }
 
-    private void enforceNotIsolatedCaller(String caller) {
+    static void enforceNotIsolatedCaller(String caller) {
         if (UserHandle.isIsolated(Binder.getCallingUid())) {
             throw new SecurityException("Isolated process not allowed to call " + caller);
         }
diff --git a/services/core/java/com/android/server/wm/AppWarnings.java b/services/core/java/com/android/server/wm/AppWarnings.java
index 55200b5..994f079 100644
--- a/services/core/java/com/android/server/wm/AppWarnings.java
+++ b/services/core/java/com/android/server/wm/AppWarnings.java
@@ -31,16 +31,12 @@
 import android.util.TypedXmlSerializer;
 import android.util.Xml;
 
-import com.android.internal.util.FastXmlSerializer;
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -541,15 +537,7 @@
                             if ("package".equals(tagName)) {
                                 final String name = parser.getAttributeValue(null, "name");
                                 if (name != null) {
-                                    final String flags = parser.getAttributeValue(
-                                            null, "flags");
-                                    int flagsInt = 0;
-                                    if (flags != null) {
-                                        try {
-                                            flagsInt = Integer.parseInt(flags);
-                                        } catch (NumberFormatException e) {
-                                        }
-                                    }
+                                    int flagsInt = parser.getAttributeInt(null, "flags", 0);
                                     mPackageFlags.put(name, flagsInt);
                                 }
                             }
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainerListener.java b/services/core/java/com/android/server/wm/ConfigurationContainerListener.java
index 3d84e17..ce6b7f9 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainerListener.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainerListener.java
@@ -23,7 +23,7 @@
  */
 public interface ConfigurationContainerListener {
 
-    /** {@see ConfigurationContainer#onRequestedOverrideConfigurationChanged} */
+    /** @see ConfigurationContainer#onRequestedOverrideConfigurationChanged */
     default void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {}
 
     /** Called when new merged override configuration is reported. */
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index cd3f322..15483cb 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -174,6 +174,13 @@
             return false;
         }
 
+        if (mDisplayContent.mFocusedApp != null) {
+            // We record the last focused TDA that respects orientation request, check if this
+            // change may affect it.
+            mDisplayContent.onLastFocusedTaskDisplayAreaChanged(
+                    mDisplayContent.mFocusedApp.getDisplayArea());
+        }
+
         // The orientation request from this DA may now be respected.
         if (!ignoreOrientationRequest) {
             return mDisplayContent.updateOrientation();
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
index 7573e92..d4b319a 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
@@ -35,6 +35,7 @@
 import static com.android.server.wm.DisplayAreaPolicyBuilder.HierarchyBuilder;
 
 import android.content.res.Resources;
+import android.os.Bundle;
 import android.text.TextUtils;
 
 import java.util.ArrayList;
@@ -71,6 +72,10 @@
      */
     public abstract void addWindow(WindowToken token);
 
+    /** Gets the {@link DisplayArea} which a {@link WindowToken} is about to be attached to. */
+    public abstract DisplayArea.Tokens getDisplayAreaForWindowToken(int type, Bundle options,
+            boolean ownerCanManageAppTokens, boolean roundedCornerOverlay);
+
     /**
      * Gets the set of {@link DisplayArea} that are created for the given feature to apply to.
      */
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
index bc32206..c8fadf6 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
 import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
 import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
+import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_LAST;
 
 import android.annotation.Nullable;
 import android.os.Bundle;
@@ -136,12 +137,12 @@
     private ArrayList<HierarchyBuilder> mDisplayAreaGroupHierarchyBuilders = new ArrayList<>();
 
     /**
-     * When a window is created, the policy will use this function to select the
-     * {@link RootDisplayArea} to place that window in. The selected root can be either the one of
-     * the {@link #mRootHierarchyBuilder} or the one of any of the
+     * When a window is created, the policy will use this function, which takes window type and
+     * options, to select the {@link RootDisplayArea} to place that window in. The selected root
+     * can be either the one of the {@link #mRootHierarchyBuilder} or the one of any of the
      * {@link #mDisplayAreaGroupHierarchyBuilders}.
      **/
-    @Nullable private BiFunction<WindowToken, Bundle, RootDisplayArea> mSelectRootForWindowFunc;
+    @Nullable private BiFunction<Integer, Bundle, RootDisplayArea> mSelectRootForWindowFunc;
 
     /** Defines the root hierarchy for the whole logical display. */
     DisplayAreaPolicyBuilder setRootHierarchy(HierarchyBuilder rootHierarchyBuilder) {
@@ -161,37 +162,53 @@
 
     /** The policy will use this function to find the root to place windows in. */
     DisplayAreaPolicyBuilder setSelectRootForWindowFunc(
-            BiFunction<WindowToken, Bundle, RootDisplayArea> selectRootForWindowFunc) {
+            BiFunction<Integer, Bundle, RootDisplayArea> selectRootForWindowFunc) {
         mSelectRootForWindowFunc = selectRootForWindowFunc;
         return this;
     }
 
-    /** Makes sure the setting meets the requirement. */
+    /**
+     * Makes sure the setting meets the requirement:
+     * 1. {@link mRootHierarchyBuilder} must be set.
+     * 2. {@link RootDisplayArea} and {@link TaskDisplayArea} must have unique ids.
+     * 3. {@link Feature} below the same {@link RootDisplayArea} must have unique ids.
+     * 4. There must be exactly one {@link HierarchyBuilder} that contains the IME container.
+     * 5. There must be exactly one {@link HierarchyBuilder} that contains the default
+     *    {@link TaskDisplayArea} with id {@link FEATURE_DEFAULT_TASK_CONTAINER}.
+     * 6. None of the ids is greater than {@link FEATURE_VENDOR_LAST}.
+     */
     private void validate() {
         if (mRootHierarchyBuilder == null) {
             throw new IllegalStateException("Root must be set for the display area policy.");
         }
 
-        final Set<Integer> rootIdSet = new ArraySet<>();
-        rootIdSet.add(mRootHierarchyBuilder.mRoot.mFeatureId);
+        final Set<Integer> uniqueIdSet = new ArraySet<>();
+        final Set<Integer> allIdSet = new ArraySet<>();
+        validateIds(mRootHierarchyBuilder, uniqueIdSet, allIdSet);
         boolean containsImeContainer = mRootHierarchyBuilder.mImeContainer != null;
         boolean containsDefaultTda = containsDefaultTaskDisplayArea(mRootHierarchyBuilder);
         for (int i = 0; i < mDisplayAreaGroupHierarchyBuilders.size(); i++) {
             HierarchyBuilder hierarchyBuilder = mDisplayAreaGroupHierarchyBuilders.get(i);
-            if (!rootIdSet.add(hierarchyBuilder.mRoot.mFeatureId)) {
-                throw new IllegalStateException("There should not be two RootDisplayAreas with id "
-                        + hierarchyBuilder.mRoot.mFeatureId);
-            }
+            validateIds(hierarchyBuilder, uniqueIdSet, allIdSet);
+
             if (hierarchyBuilder.mTaskDisplayAreas.isEmpty()) {
                 throw new IllegalStateException(
                         "DisplayAreaGroup must contain at least one TaskDisplayArea.");
             }
 
-            containsImeContainer = containsImeContainer || hierarchyBuilder.mImeContainer != null;
+            if (containsImeContainer) {
+                if (hierarchyBuilder.mImeContainer != null) {
+                    throw new IllegalStateException(
+                            "Only one DisplayArea hierarchy can contain the IME container");
+                }
+            } else {
+                containsImeContainer = hierarchyBuilder.mImeContainer != null;
+            }
+
             if (containsDefaultTda) {
                 if (containsDefaultTaskDisplayArea(hierarchyBuilder)) {
                     throw new IllegalStateException("Only one TaskDisplayArea can have the feature "
-                            + "of FEATURE_DEFAULT_TASK_CONTAINER");
+                            + "id of FEATURE_DEFAULT_TASK_CONTAINER");
                 }
             } else {
                 containsDefaultTda = containsDefaultTaskDisplayArea(hierarchyBuilder);
@@ -203,7 +220,8 @@
         }
 
         if (!containsDefaultTda) {
-            throw new IllegalStateException("There must be a default TaskDisplayArea.");
+            throw new IllegalStateException("There must be a default TaskDisplayArea with id of "
+                    + "FEATURE_DEFAULT_TASK_CONTAINER.");
         }
     }
 
@@ -218,6 +236,67 @@
         return false;
     }
 
+    /**
+     * Makes sure that ids meet requirement.
+     * {@link RootDisplayArea} and {@link TaskDisplayArea} must have unique ids.
+     * {@link Feature} below the same {@link RootDisplayArea} must have unique ids, but
+     * {@link Feature} below different {@link RootDisplayArea} can have the same id so that we can
+     * organize them together.
+     * None of the ids is greater than {@link FEATURE_VENDOR_LAST}
+     *
+     * @param uniqueIdSet ids of {@link RootDisplayArea} and {@link TaskDisplayArea} that must be
+     *                    unique,
+     * @param allIdSet ids of {@link RootDisplayArea}, {@link TaskDisplayArea} and {@link Feature}.
+     */
+    private static void validateIds(HierarchyBuilder displayAreaHierarchy,
+            Set<Integer> uniqueIdSet, Set<Integer> allIdSet) {
+        // Root must have unique id.
+        final int rootId = displayAreaHierarchy.mRoot.mFeatureId;
+        if (!allIdSet.add(rootId) || !uniqueIdSet.add(rootId)) {
+            throw new IllegalStateException(
+                    "RootDisplayArea must have unique id, but id=" + rootId + " is not unique.");
+        }
+        if (rootId > FEATURE_VENDOR_LAST) {
+            throw new IllegalStateException(
+                    "RootDisplayArea should not have an id greater than FEATURE_VENDOR_LAST.");
+        }
+
+        // TDAs must have unique id.
+        for (int i = 0; i < displayAreaHierarchy.mTaskDisplayAreas.size(); i++) {
+            final int taskDisplayAreaId = displayAreaHierarchy.mTaskDisplayAreas.get(i).mFeatureId;
+            if (!allIdSet.add(taskDisplayAreaId) || !uniqueIdSet.add(taskDisplayAreaId)) {
+                throw new IllegalStateException("TaskDisplayArea must have unique id, but id="
+                        + taskDisplayAreaId + " is not unique.");
+            }
+            if (taskDisplayAreaId > FEATURE_VENDOR_LAST) {
+                throw new IllegalStateException("TaskDisplayArea declared in the policy should not"
+                        + "have an id greater than FEATURE_VENDOR_LAST.");
+            }
+        }
+
+        // Features below the same root must have unique ids.
+        final Set<Integer> featureIdSet = new ArraySet<>();
+        for (int i = 0; i < displayAreaHierarchy.mFeatures.size(); i++) {
+            final int featureId = displayAreaHierarchy.mFeatures.get(i).getId();
+            if (uniqueIdSet.contains(featureId)) {
+                throw new IllegalStateException("Feature must not have same id with any "
+                        + "RootDisplayArea or TaskDisplayArea, but id=" + featureId + " is used");
+            }
+            if (!featureIdSet.add(featureId)) {
+                throw new IllegalStateException("Feature below the same root must have unique id, "
+                        + "but id=" + featureId + " is not unique.");
+            }
+            if (featureId > FEATURE_VENDOR_LAST) {
+                throw new IllegalStateException(
+                        "Feature should not have an id greater than FEATURE_VENDOR_LAST.");
+            }
+        }
+
+        // Features below different roots can have the same id so that we can organize them
+        // together.
+        allIdSet.addAll(featureIdSet);
+    }
+
     Result build(WindowManagerService wmService) {
         validate();
 
@@ -576,19 +655,19 @@
 
     static class Result extends DisplayAreaPolicy {
         final List<RootDisplayArea> mDisplayAreaGroupRoots;
-        final BiFunction<WindowToken, Bundle, RootDisplayArea> mSelectRootForWindowFunc;
+        final BiFunction<Integer, Bundle, RootDisplayArea> mSelectRootForWindowFunc;
         private final TaskDisplayArea mDefaultTaskDisplayArea;
 
         Result(WindowManagerService wmService, RootDisplayArea root,
                 List<RootDisplayArea> displayAreaGroupRoots,
-                @Nullable BiFunction<WindowToken, Bundle, RootDisplayArea>
+                @Nullable BiFunction<Integer, Bundle, RootDisplayArea>
                         selectRootForWindowFunc) {
             super(wmService, root);
             mDisplayAreaGroupRoots = Collections.unmodifiableList(displayAreaGroupRoots);
             mSelectRootForWindowFunc = selectRootForWindowFunc == null
                     // Always return the highest level root of the logical display when the func is
                     // not specified.
-                    ? (window, options) -> mRoot
+                    ? (type, options) -> mRoot
                     : selectRootForWindowFunc;
 
             // Cache the default TaskDisplayArea for quick access.
@@ -610,7 +689,8 @@
 
         @VisibleForTesting
         DisplayArea.Tokens findAreaForToken(WindowToken token) {
-            return mSelectRootForWindowFunc.apply(token, token.mOptions).findAreaForToken(token);
+            return mSelectRootForWindowFunc.apply(token.windowType, token.mOptions)
+                    .findAreaForToken(token);
         }
 
         @VisibleForTesting
@@ -648,6 +728,13 @@
         public TaskDisplayArea getDefaultTaskDisplayArea() {
             return mDefaultTaskDisplayArea;
         }
+
+        @Override
+        public DisplayArea.Tokens getDisplayAreaForWindowToken(int type, Bundle options,
+                boolean ownerCanManageAppTokens, boolean roundedCornerOverlay) {
+            return mSelectRootForWindowFunc.apply(type, options).findAreaForToken(type,
+                    ownerCanManageAppTokens, roundedCornerOverlay);
+        }
     }
 
     static class PendingArea {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1d2cd0a..e88f8e3 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -165,6 +165,7 @@
 import android.hardware.display.DisplayManagerInternal;
 import android.metrics.LogMaker;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
@@ -488,8 +489,13 @@
      */
     ActivityRecord mFocusedApp = null;
 
-    /** The last focused {@link TaskDisplayArea} on this display. */
-    private TaskDisplayArea mLastFocusedTaskDisplayArea = null;
+    /**
+     * We only respect the orientation request from apps below this {@link TaskDisplayArea}.
+     * It is the last focused {@link TaskDisplayArea} on this display that handles orientation
+     * request.
+     */
+    @Nullable
+    private TaskDisplayArea mOrientationRequestingTaskDisplayArea = null;
 
     /**
      * The launching activity which is using fixed rotation transformation.
@@ -995,7 +1001,7 @@
         getPendingTransaction().apply();
 
         // Setup the policy and build the display area hierarchy.
-        mDisplayAreaPolicy = mWmService.mDisplayAreaPolicyProvider.instantiate(
+        mDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(
                 mWmService, this /* content */, this /* root */, mImeWindowsContainers);
 
         // Sets the display content for the children.
@@ -3325,7 +3331,7 @@
 
             // Called even if the focused app is not changed in case the app is moved to a different
             // TaskDisplayArea.
-            setLastFocusedTaskDisplayArea(newFocus.getDisplayArea());
+            onLastFocusedTaskDisplayAreaChanged(newFocus.getDisplayArea());
         }
         if (mFocusedApp == newFocus) {
             return false;
@@ -3339,16 +3345,27 @@
     }
 
     /** Called when the focused {@link TaskDisplayArea} on this display may have changed. */
-    @VisibleForTesting
-    void setLastFocusedTaskDisplayArea(@Nullable TaskDisplayArea taskDisplayArea) {
-        if (taskDisplayArea != null) {
-            mLastFocusedTaskDisplayArea = taskDisplayArea;
+    void onLastFocusedTaskDisplayAreaChanged(@Nullable TaskDisplayArea taskDisplayArea) {
+        // Only record the TaskDisplayArea that handles orientation request.
+        if (taskDisplayArea != null && taskDisplayArea.handlesOrientationChangeFromDescendant()) {
+            mOrientationRequestingTaskDisplayArea = taskDisplayArea;
+            return;
+        }
+
+        // If the previous TDA no longer handles orientation request, clear it.
+        if (mOrientationRequestingTaskDisplayArea != null
+                && !mOrientationRequestingTaskDisplayArea
+                .handlesOrientationChangeFromDescendant()) {
+            mOrientationRequestingTaskDisplayArea = null;
         }
     }
 
-    /** Gets the last focused {@link TaskDisplayArea} on this display. */
-    TaskDisplayArea getLastFocusedTaskDisplayArea() {
-        return mLastFocusedTaskDisplayArea;
+    /**
+     * Gets the {@link TaskDisplayArea} that we respect orientation requests from apps below it.
+     */
+    @Nullable
+    TaskDisplayArea getOrientationRequestingTaskDisplayArea() {
+        return mOrientationRequestingTaskDisplayArea;
     }
 
     /** Updates the layer assignment of windows on this display. */
@@ -4775,7 +4792,6 @@
         return getWindowContainers().getSurfaceControl();
     }
 
-    @VisibleForTesting
     DisplayArea.Tokens getImeContainer() {
         return mImeWindowsContainers;
     }
@@ -5683,6 +5699,9 @@
 
         @Override
         public boolean getRequestedVisibility(@InternalInsetsType int type) {
+            if (type == ITYPE_IME) {
+                return getInsetsStateController().getImeSourceProvider().isImeShowing();
+            }
             return mRequestedInsetsState.getSourceOrDefaultVisibility(type);
         }
 
@@ -5728,4 +5747,20 @@
     MagnificationSpec getMagnificationSpec() {
         return mMagnificationSpec;
     }
+
+    DisplayArea getAreaForWindowToken(int windowType, Bundle options,
+            boolean ownerCanManageAppToken, boolean roundedCornerOverlay) {
+        // TODO(b/159767464): figure out how to find an appropriate TDA.
+        if (windowType >= FIRST_APPLICATION_WINDOW && windowType <= LAST_APPLICATION_WINDOW) {
+            return getDefaultTaskDisplayArea();
+        }
+        // Return IME container here because it could be in one of sub RootDisplayAreas depending on
+        // the focused edit text. Also, the RootDisplayArea choosing strategy is implemented by
+        // the server side, but not mSelectRootForWindowFunc customized by OEM.
+        if (windowType == TYPE_INPUT_METHOD || windowType == TYPE_INPUT_METHOD_DIALOG) {
+            return getImeContainer();
+        }
+        return mDisplayAreaPolicy.getDisplayAreaForWindowToken(windowType, options,
+                ownerCanManageAppToken, roundedCornerOverlay);
+    }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 2ddd001..cd02e00 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1427,7 +1427,7 @@
                 : (task != null ? task.getBounds() : null);
         final InsetsState state =
                 mDisplayContent.getInsetsPolicy().getInsetsForWindowMetrics(attrs);
-        computeWindowBounds(attrs, state, outFrame);
+        computeWindowBounds(attrs, state, windowToken, outFrame);
         if (taskBounds != null) {
             outFrame.intersect(taskBounds);
         }
@@ -1714,11 +1714,11 @@
     }
 
     private void computeWindowBounds(WindowManager.LayoutParams attrs, InsetsState state,
-            Rect outBounds) {
+            @Nullable WindowToken windowToken, Rect outBounds) {
         final @InsetsType int typesToFit = attrs.getFitInsetsTypes();
         final @InsetsSide int sidesToFit = attrs.getFitInsetsSides();
         final ArraySet<Integer> types = InsetsState.toInternalType(typesToFit);
-        final Rect dfu = state.getDisplayFrame();
+        final Rect df = windowToken != null ? windowToken.getBounds() : state.getDisplayFrame();
         Insets insets = Insets.of(0, 0, 0, 0);
         for (int i = types.size() - 1; i >= 0; i--) {
             final InsetsSource source = state.peekSource(types.valueAt(i));
@@ -1726,13 +1726,13 @@
                 continue;
             }
             insets = Insets.max(insets, source.calculateInsets(
-                    dfu, attrs.isFitInsetsIgnoringVisibility()));
+                    df, attrs.isFitInsetsIgnoringVisibility()));
         }
         final int left = (sidesToFit & Side.LEFT) != 0 ? insets.left : 0;
         final int top = (sidesToFit & Side.TOP) != 0 ? insets.top : 0;
         final int right = (sidesToFit & Side.RIGHT) != 0 ? insets.right : 0;
         final int bottom = (sidesToFit & Side.BOTTOM) != 0 ? insets.bottom : 0;
-        outBounds.set(dfu.left + left, dfu.top + top, dfu.right - right, dfu.bottom - bottom);
+        outBounds.set(df.left + left, df.top + top, df.right - right, df.bottom - bottom);
     }
 
     /**
@@ -1772,7 +1772,7 @@
         final boolean layoutInsetDecor = (fl & FLAG_LAYOUT_INSET_DECOR) == FLAG_LAYOUT_INSET_DECOR;
 
         final InsetsState state = win.getInsetsState();
-        computeWindowBounds(attrs, state, df);
+        computeWindowBounds(attrs, state, win.mToken, df);
         if (attached == null) {
             pf.set(df);
             if ((pfl & PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME) != 0) {
@@ -1845,7 +1845,6 @@
             // They will later be cropped or shifted using the displayFrame in WindowState,
             // which prevents overlap with the DisplayCutout.
             if (!attachedInParent && !floatingInScreenWindow) {
-                getRotatedWindowBounds(displayFrames, win, sTmpRect);
                 sTmpRect.set(pf);
                 pf.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
                 windowFrames.setParentFrameWasClippedByDisplayCutout(!sTmpRect.equals(pf));
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
index f4fdd73..57c947f 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
@@ -450,12 +450,12 @@
                     out.attributeInt(null, "windowingMode", settingsEntry.mWindowingMode);
                 }
                 if (settingsEntry.mUserRotationMode != null) {
-                    out.attribute(null, "userRotationMode",
-                            settingsEntry.mUserRotationMode.toString());
+                    out.attributeInt(null, "userRotationMode",
+                            settingsEntry.mUserRotationMode);
                 }
                 if (settingsEntry.mUserRotation != null) {
-                    out.attribute(null, "userRotation",
-                            settingsEntry.mUserRotation.toString());
+                    out.attributeInt(null, "userRotation",
+                            settingsEntry.mUserRotation);
                 }
                 if (settingsEntry.mForcedWidth != 0 && settingsEntry.mForcedHeight != 0) {
                     out.attributeInt(null, "forcedWidth", settingsEntry.mForcedWidth);
@@ -465,30 +465,30 @@
                     out.attributeInt(null, "forcedDensity", settingsEntry.mForcedDensity);
                 }
                 if (settingsEntry.mForcedScalingMode != null) {
-                    out.attribute(null, "forcedScalingMode",
-                            settingsEntry.mForcedScalingMode.toString());
+                    out.attributeInt(null, "forcedScalingMode",
+                            settingsEntry.mForcedScalingMode);
                 }
                 if (settingsEntry.mRemoveContentMode != REMOVE_CONTENT_MODE_UNDEFINED) {
                     out.attributeInt(null, "removeContentMode", settingsEntry.mRemoveContentMode);
                 }
                 if (settingsEntry.mShouldShowWithInsecureKeyguard != null) {
-                    out.attribute(null, "shouldShowWithInsecureKeyguard",
-                            settingsEntry.mShouldShowWithInsecureKeyguard.toString());
+                    out.attributeBoolean(null, "shouldShowWithInsecureKeyguard",
+                            settingsEntry.mShouldShowWithInsecureKeyguard);
                 }
                 if (settingsEntry.mShouldShowSystemDecors != null) {
-                    out.attribute(null, "shouldShowSystemDecors",
-                            settingsEntry.mShouldShowSystemDecors.toString());
+                    out.attributeBoolean(null, "shouldShowSystemDecors",
+                            settingsEntry.mShouldShowSystemDecors);
                 }
                 if (settingsEntry.mImePolicy != null) {
                     out.attributeInt(null, "imePolicy", settingsEntry.mImePolicy);
                 }
                 if (settingsEntry.mFixedToUserRotation != null) {
-                    out.attribute(null, "fixedToUserRotation",
-                            settingsEntry.mFixedToUserRotation.toString());
+                    out.attributeInt(null, "fixedToUserRotation",
+                            settingsEntry.mFixedToUserRotation);
                 }
                 if (settingsEntry.mIgnoreOrientationRequest != null) {
-                    out.attribute(null, "ignoreOrientationRequest",
-                            settingsEntry.mIgnoreOrientationRequest.toString());
+                    out.attributeBoolean(null, "ignoreOrientationRequest",
+                            settingsEntry.mIgnoreOrientationRequest);
                 }
                 out.endTag(null, "display");
             }
diff --git a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
index 14880ed..9602880 100644
--- a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
+++ b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import android.app.ActivityTaskManager;
 import android.app.UriGrantsManager;
 import android.content.ClipData;
 import android.net.Uri;
@@ -33,6 +32,7 @@
 class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub
         implements IBinder.DeathRecipient {
 
+    private final WindowManagerGlobalLock mGlobalLock;
     private final int mSourceUid;
     private final String mTargetPackage;
     private final int mMode;
@@ -45,8 +45,9 @@
     private IBinder mPermissionOwnerToken = null;
     private IBinder mTransientToken = null;
 
-    DragAndDropPermissionsHandler(ClipData clipData, int sourceUid, String targetPackage, int mode,
-                                  int sourceUserId, int targetUserId) {
+    DragAndDropPermissionsHandler(WindowManagerGlobalLock lock, ClipData clipData, int sourceUid,
+            String targetPackage, int mode, int sourceUserId, int targetUserId) {
+        mGlobalLock = lock;
         mSourceUid = sourceUid;
         mTargetPackage = targetPackage;
         mMode = mode;
@@ -64,8 +65,7 @@
         mActivityToken = activityToken;
 
         // Will throw if Activity is not found.
-        IBinder permissionOwner = ActivityTaskManager.getService().
-                getUriPermissionOwnerForActivity(mActivityToken);
+        IBinder permissionOwner = getUriPermissionOwnerForActivity(mActivityToken);
 
         doTake(permissionOwner);
     }
@@ -105,8 +105,7 @@
         IBinder permissionOwner = null;
         if (mActivityToken != null) {
             try {
-                permissionOwner = ActivityTaskManager.getService().
-                        getUriPermissionOwnerForActivity(mActivityToken);
+                permissionOwner = getUriPermissionOwnerForActivity(mActivityToken);
             } catch (Exception e) {
                 // Activity is destroyed, permissions already revoked.
                 return;
@@ -126,6 +125,18 @@
         }
     }
 
+    private IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
+        ActivityTaskManagerService.enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
+        synchronized (mGlobalLock) {
+            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
+            if (r == null) {
+                throw new IllegalArgumentException("Activity does not exist; token="
+                        + activityToken);
+            }
+            return r.getUriPermissionsLocked().getExternalToken();
+        }
+    }
+
     @Override
     public void binderDied() {
         try {
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index ad4e64a..86518ea 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -59,7 +59,6 @@
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 
-import com.android.internal.os.SomeArgs;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.view.IDragAndDropPermissions;
 import com.android.server.LocalServices;
@@ -590,7 +589,7 @@
         final DragAndDropPermissionsHandler dragAndDropPermissions;
         if ((mFlags & View.DRAG_FLAG_GLOBAL) != 0 && (mFlags & DRAG_FLAGS_URI_ACCESS) != 0
                 && mData != null) {
-            dragAndDropPermissions = new DragAndDropPermissionsHandler(
+            dragAndDropPermissions = new DragAndDropPermissionsHandler(mService.mGlobalLock,
                     mData,
                     mUid,
                     touchedWin.getOwningPackage(),
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 818d96c..91106ef 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -42,6 +42,7 @@
     private InsetsControlTarget mImeTargetFromIme;
     private Runnable mShowImeRunner;
     private boolean mIsImeLayoutDrawn;
+    private boolean mImeShowing;
 
     ImeInsetsSourceProvider(InsetsSource source,
             InsetsStateController stateController, DisplayContent displayContent) {
@@ -81,6 +82,7 @@
 
                 ProtoLog.i(WM_DEBUG_IME, "call showInsets(ime) on %s",
                         target.getWindow() != null ? target.getWindow().getName() : "");
+                setImeShowing(true);
                 target.showInsets(WindowInsets.Type.ime(), true /* fromIme */);
                 Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "WMS.showImePostLayout", 0);
                 if (target != mImeTargetFromIme && mImeTargetFromIme != null) {
@@ -155,12 +157,14 @@
     @Override
     public void dump(PrintWriter pw, String prefix) {
         super.dump(pw, prefix);
+        pw.print(prefix);
+        pw.print("mImeShowing=");
+        pw.print(mImeShowing);
         if (mImeTargetFromIme != null) {
-            pw.print(prefix);
-            pw.print("showImePostLayout pending for mImeTargetFromIme=");
+            pw.print(" showImePostLayout pending for mImeTargetFromIme=");
             pw.print(mImeTargetFromIme);
-            pw.println();
         }
+        pw.println();
     }
 
     @Override
@@ -173,4 +177,20 @@
         proto.write(IS_IME_LAYOUT_DRAWN, mIsImeLayoutDrawn);
         proto.end(token);
     }
+
+    /**
+     * Sets whether the IME is currently supposed to be showing according to
+     * InputMethodManagerService.
+     */
+    public void setImeShowing(boolean imeShowing) {
+        mImeShowing = imeShowing;
+    }
+
+    /**
+     * Returns whether the IME is currently supposed to be showing according to
+     * InputMethodManagerService.
+     */
+    public boolean isImeShowing() {
+        return mImeShowing;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 0605ed8..28a99825 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -328,7 +328,7 @@
         final Point surfacePosition = getWindowFrameSurfacePosition();
         mAdapter = new ControlAdapter(surfacePosition);
         if (getSource().getType() == ITYPE_IME) {
-            setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
+            setClientVisible(target.getRequestedVisibility(mSource.getType()));
         }
         final Transaction t = mDisplayContent.getPendingTransaction();
         mWin.startAnimation(t, mAdapter, !mClientVisible /* hidden */,
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 52ada47..fd42b24 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -29,7 +29,6 @@
 import android.util.Log;
 import android.util.Slog;
 import android.view.DisplayInfo;
-import android.view.IPinnedStackController;
 import android.view.IPinnedStackListener;
 
 import java.io.PrintWriter;
@@ -63,8 +62,6 @@
     private final PinnedStackListenerDeathHandler mPinnedStackListenerDeathHandler =
             new PinnedStackListenerDeathHandler();
 
-    private final PinnedStackControllerCallback mCallbacks = new PinnedStackControllerCallback();
-
     /** Whether the PiP is entering or leaving. */
     private boolean mIsPipWindowingModeChanging;
 
@@ -86,18 +83,6 @@
     private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
 
     /**
-     * The callback object passed to listeners for them to notify the controller of state changes.
-     */
-    private class PinnedStackControllerCallback extends IPinnedStackController.Stub {
-        @Override
-        public int getDisplayRotation() {
-            synchronized (mService.mGlobalLock) {
-                return mDisplayInfo.rotation;
-            }
-        }
-    }
-
-    /**
      * Handler for the case where the listener dies.
      */
     private class PinnedStackListenerDeathHandler implements IBinder.DeathRecipient {
@@ -141,7 +126,6 @@
     void registerPinnedStackListener(IPinnedStackListener listener) {
         try {
             listener.asBinder().linkToDeath(mPinnedStackListenerDeathHandler, 0);
-            listener.onListenerRegistered(mCallbacks);
             mPinnedStackListener = listener;
             notifyDisplayInfoChanged(mDisplayInfo);
             notifyImeVisibilityChanged(mIsImeShowing, mImeHeight);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 5da668c..16c7226 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -850,7 +850,7 @@
         return w != null && w.mAttrs.type == TYPE_BASE_APPLICATION &&
                 ((w.mActivityRecord != null && mTargetActivityRecord == w.mActivityRecord)
                         || isAnimatingTask(w.getTask()))
-                && isTargetOverWallpaper();
+                && isTargetOverWallpaper() && w.isOnScreen();
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/RootDisplayArea.java b/services/core/java/com/android/server/wm/RootDisplayArea.java
index c4fcea6..393055e 100644
--- a/services/core/java/com/android/server/wm/RootDisplayArea.java
+++ b/services/core/java/com/android/server/wm/RootDisplayArea.java
@@ -106,12 +106,23 @@
     }
 
     /** Finds the {@link DisplayArea.Tokens} that this type of window should be attached to. */
+    @Nullable
     DisplayArea.Tokens findAreaForToken(WindowToken token) {
-        int windowLayerFromType = token.getWindowLayerFromType();
+        return findAreaForToken(token.windowType, token.mOwnerCanManageAppTokens,
+                token.mRoundedCornerOverlay);
+    }
+
+    @Nullable
+    DisplayArea.Tokens findAreaForToken(int windowType, boolean ownerCanManageAppTokens,
+            boolean roundedCornerOverlay) {
+        // TODO(b/159767464): cover TYPE_INPUT_METHOD(_DIALOG) case here. mAreaForLayer doesn't
+        // contain IME container.
+        int windowLayerFromType = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
+                ownerCanManageAppTokens);
         if (windowLayerFromType == APPLICATION_LAYER) {
             throw new IllegalArgumentException(
                     "There shouldn't be WindowToken on APPLICATION_LAYER");
-        } else if (token.mRoundedCornerOverlay) {
+        } else if (roundedCornerOverlay) {
             windowLayerFromType = mAreaForLayer.length - 1;
         }
         return mAreaForLayer[windowLayerFromType];
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 7df2b40..6e0efbf 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -26,7 +26,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.util.DebugUtils;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl;
@@ -388,7 +387,7 @@
         if (DEBUG_ANIM) Slog.i(TAG, "Reparenting to leash");
         final SurfaceControl.Builder builder = animatable.makeAnimationLeash()
                 .setParent(animatable.getAnimationLeashParent())
-                .setName(surface + " - animation-leash")
+                .setName(surface + " - animation-leash of " + animationTypeToString(type))
                 // TODO(b/151665759) Defer reparent calls
                 // We want the leash to be visible immediately because the transaction which shows
                 // the leash may be deferred but the reparent will not. This will cause the leashed
@@ -430,8 +429,7 @@
 
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("mLeash="); pw.print(mLeash);
-        pw.print(" mAnimationType=" + DebugUtils.valueToString(SurfaceAnimator.class,
-                "ANIMATION_TYPE_", mAnimationType));
+        pw.print(" mAnimationType=" + animationTypeToString(mAnimationType));
         pw.println(mAnimationStartDelayed ? " mAnimationStartDelayed=true" : "");
         pw.print(prefix); pw.print("Animation: "); pw.println(mAnimation);
         if (mAnimation != null) {
@@ -513,6 +511,23 @@
     @interface AnimationType {}
 
     /**
+     * Converts {@link AnimationType} to String.
+     */
+    private static String animationTypeToString(@AnimationType int type) {
+        switch (type) {
+            case ANIMATION_TYPE_NONE: return "none";
+            case ANIMATION_TYPE_APP_TRANSITION: return "app_transition";
+            case ANIMATION_TYPE_SCREEN_ROTATION: return "screen_rotation";
+            case ANIMATION_TYPE_DIMMER: return "dimmer";
+            case ANIMATION_TYPE_RECENTS: return "recents_animation";
+            case ANIMATION_TYPE_WINDOW_ANIMATION: return "window_animation";
+            case ANIMATION_TYPE_INSETS_CONTROL: return "insets_animation";
+            case ANIMATION_TYPE_FIXED_TRANSFORM: return "fixed_rotation";
+            default: return "unknown type:" + type;
+        }
+    }
+
+    /**
      * Callback to be passed into {@link AnimationAdapter#startAnimation} to be invoked by the
      * component that is running the animation when the animation is finished.
      */
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 4b65ce0f..00f545c 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -224,7 +224,6 @@
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -4108,7 +4107,7 @@
         if (top == null) return null;
         final ActivityRecord rootActivity = top.getRootActivity();
         return (rootActivity == null || rootActivity.pictureInPictureArgs.empty())
-                ? null : rootActivity.pictureInPictureArgs;
+                ? null : new PictureInPictureParams(rootActivity.pictureInPictureArgs);
     }
 
     void maybeUpdateLetterboxBounds(
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 4498a8c..9425602 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -641,9 +641,7 @@
     @Override
     int getOrientation(int candidate) {
         mLastOrientationSource = null;
-        // Only allow to specify orientation if this TDA is not set to ignore orientation request,
-        // and it has the focus.
-        if (mIgnoreOrientationRequest || !isLastFocused()) {
+        if (!canSpecifyOrientation()) {
             return SCREEN_ORIENTATION_UNSET;
         }
 
@@ -1918,10 +1916,14 @@
         return lastReparentedStack;
     }
 
-    /** Whether this task display area is the last focused one on this logical display. */
+    /** Whether this task display area can request orientation. */
     @VisibleForTesting
-    boolean isLastFocused() {
-        return mDisplayContent.getLastFocusedTaskDisplayArea() == this;
+    boolean canSpecifyOrientation() {
+        // Only allow to specify orientation if this TDA is not set to ignore orientation request,
+        // and it is the last focused one on this logical display that can request orientation
+        // request.
+        return !mIgnoreOrientationRequest
+                && mDisplayContent.getOrientationRequestingTaskDisplayArea() == this;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index cf6468d..adc7a22 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -98,6 +98,7 @@
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -314,6 +315,8 @@
     final SurfaceControl.Transaction mSyncTransaction;
     @SyncState int mSyncState = SYNC_STATE_NONE;
 
+    private final List<WindowContainerListener> mListeners = new ArrayList<>();
+
     WindowContainer(WindowManagerService wms) {
         mWmService = wms;
         mPendingTransaction = wms.mTransactionFactory.get();
@@ -637,6 +640,10 @@
         if (mParent != null) {
             mParent.removeChild(this);
         }
+
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onRemoved();
+        }
     }
 
     /**
@@ -819,6 +826,9 @@
             final WindowContainer child = mChildren.get(i);
             child.onDisplayChanged(dc);
         }
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onDisplayChanged(dc);
+        }
     }
 
     DisplayContent getDisplayContent() {
@@ -1152,10 +1162,10 @@
 
     /**
      * Check if this container or its parent will handle orientation changes from descendants. It's
-     * different from the return value of {@link #onDescendantOrientationChanged(IBinder,
-     * WindowContainer)} in the sense that the return value of this method tells if this
-     * container or its parent will handle the request eventually, while the return value of the
-     * other method is if it handled the request synchronously.
+     * different from the return value of {@link #onDescendantOrientationChanged(WindowContainer)}
+     * in the sense that the return value of this method tells if this container or its parent will
+     * handle the request eventually, while the return value of the other method is if it handled
+     * the request synchronously.
      *
      * @return {@code true} if it handles or will handle orientation change in the future; {@code
      *         false} if it won't handle the change at anytime.
@@ -1221,7 +1231,7 @@
     }
 
     /**
-     * Calls {@link #setOrientation(int, IBinder, WindowContainer)} with {@code null} to the last 2
+     * Calls {@link #setOrientation(int, WindowContainer)} with {@code null} to the last 2
      * parameters.
      *
      * @param orientation the specified orientation.
@@ -3106,4 +3116,19 @@
         mSyncState = SYNC_STATE_NONE;
         prepareSync();
     }
+
+    void registerWindowContainerListener(WindowContainerListener listener) {
+        if (mListeners.contains(listener)) {
+            return;
+        }
+        mListeners.add(listener);
+        // Also register to ConfigurationChangeListener to receive configuration changes.
+        registerConfigurationChangeListener(listener);
+        listener.onDisplayChanged(getDisplayContent());
+    }
+
+    void unregisterWindowContainerListener(WindowContainerListener listener) {
+        mListeners.remove(listener);
+        unregisterConfigurationChangeListener(listener);
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowContainerListener.java b/services/core/java/com/android/server/wm/WindowContainerListener.java
new file mode 100644
index 0000000..ac1fe17
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowContainerListener.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.wm;
+
+/**
+ * Interface for listening to changes in a {@link WindowContainer}. A usage of this listener is
+ * to receive the changes and propagate them to the client side.
+ */
+interface WindowContainerListener extends ConfigurationContainerListener {
+
+    /** @see WindowContainer#onDisplayChanged(DisplayContent) */
+    default void onDisplayChanged(DisplayContent dc) {}
+
+    /** Called when {@link WindowContainer#removeImmediately()} is invoked. */
+    default void onRemoved() {}
+}
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
new file mode 100644
index 0000000..051ece3
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.wm;
+
+import static android.view.Display.INVALID_DISPLAY;
+
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.internal.protolog.ProtoLogGroup.WM_ERROR;
+
+import android.annotation.NonNull;
+import android.app.IWindowToken;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A controller to register/unregister {@link WindowContainerListener} for
+ * {@link android.app.WindowContext}.
+ *
+ * <ul>
+ *   <li>When a {@link android.app.WindowContext} is created, it registers the listener via
+ *     {@link WindowManagerService#registerWindowContextListener(IBinder, int, int, Bundle)}
+ *     automatically.</li>
+ *   <li>When the {@link android.app.WindowContext} adds the first window to the screen via
+ *     {@link android.view.WindowManager#addView(View, ViewGroup.LayoutParams)},
+ *     {@link WindowManagerService} then updates the {@link WindowContextListenerImpl} to listen
+ *     to corresponding {@link WindowToken} via this controller.</li>
+ *   <li>When the {@link android.app.WindowContext} is GCed, it unregisters the previously
+ *     registered listener via
+ *     {@link WindowManagerService#unregisterWindowContextListener(IBinder)}.
+ *     {@link WindowManagerService} is also responsible for removing the
+ *     {@link android.app.WindowContext} created {@link WindowToken}.</li>
+ * </ul>
+ * <p>Note that the listener may be removed earlier than the
+ * {@link #unregisterWindowContainerListener(IBinder)} if the listened {@link WindowContainer} was
+ * removed. An example is that the {@link DisplayArea} is removed when users unfold the
+ * foldable devices. Another example is that the associated external display is detached.</p>
+ */
+class WindowContextListenerController {
+    @VisibleForTesting
+    final Map<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>();
+
+    /**
+     * Registers the listener to a {@code container} which is associated with
+     * a {@code clientToken}, which is a {@link android.app.WindowContext} representation. If the
+     * listener associated with {@code clientToken} hasn't been initialized yet, create one
+     * {@link WindowContextListenerImpl}. Otherwise, the listener associated with
+     * {@code clientToken} switches to listen to the {@code container}.
+     *
+     * @param clientToken the token to associate with the listener
+     * @param container the {@link WindowContainer} which the listener is going to listen to.
+     * @param ownerUid the caller UID
+     */
+    void registerWindowContainerListener(@NonNull IBinder clientToken,
+            @NonNull WindowContainer container, int ownerUid) {
+        WindowContextListenerImpl listener = mListeners.get(clientToken);
+        if (listener == null) {
+            listener = new WindowContextListenerImpl(clientToken, container, ownerUid);
+            listener.register();
+        } else {
+            listener.updateContainer(container);
+        }
+    }
+
+    void unregisterWindowContainerListener(IBinder clientToken) {
+        final WindowContextListenerImpl listener = mListeners.get(clientToken);
+        // Listeners may be removed earlier. An example is the display where the listener is
+        // located is detached. In this case, all window containers on the display, as well as
+        // their listeners will be removed before their listeners are unregistered.
+        if (listener == null) {
+            return;
+        }
+        listener.unregister();
+    }
+
+    boolean assertCallerCanRemoveListener(IBinder clientToken, boolean callerCanManageAppTokens,
+            int callingUid) {
+        final WindowContextListenerImpl listener = mListeners.get(clientToken);
+        if (listener == null) {
+            ProtoLog.i(WM_DEBUG_ADD_REMOVE, "The listener does not exist.");
+            return false;
+        }
+        if (callerCanManageAppTokens) {
+            return true;
+        }
+        if (callingUid != listener.mOwnerUid) {
+            throw new UnsupportedOperationException("Uid mismatch. Caller uid is " + callingUid
+                    + ", while the listener's owner is from " + listener.mOwnerUid);
+        }
+        return true;
+    }
+
+    @VisibleForTesting
+    class WindowContextListenerImpl implements WindowContainerListener {
+        @NonNull private final IBinder mClientToken;
+        private final int mOwnerUid;
+        @NonNull private WindowContainer mContainer;
+
+        private DeathRecipient mDeathRecipient;
+
+        private int mLastReportedDisplay = INVALID_DISPLAY;
+        private Configuration mLastReportedConfig;
+
+        private WindowContextListenerImpl(IBinder clientToken, WindowContainer container,
+                int ownerUid) {
+            mClientToken = clientToken;
+            mContainer = Objects.requireNonNull(container);
+            mOwnerUid = ownerUid;
+
+            final DeathRecipient deathRecipient = new DeathRecipient();
+            try {
+                deathRecipient.linkToDeath();
+                mDeathRecipient = deathRecipient;
+            } catch (RemoteException e) {
+                ProtoLog.e(WM_ERROR, "Could not register window container listener token=%s, "
+                        + "container=%s", mClientToken, mContainer);
+            }
+        }
+
+        /** TEST ONLY: returns the {@link WindowContainer} of the listener */
+        @VisibleForTesting
+        WindowContainer getWindowContainer() {
+            return mContainer;
+        }
+
+        private void updateContainer(WindowContainer newContainer) {
+            if (mContainer.equals(newContainer)) {
+                return;
+            }
+            mContainer.unregisterWindowContainerListener(this);
+            mContainer = newContainer;
+            clear();
+            register();
+        }
+
+        private void register() {
+            if (mDeathRecipient == null) {
+                throw new IllegalStateException("Invalid client token: " + mClientToken);
+            }
+            mListeners.putIfAbsent(mClientToken, this);
+            mContainer.registerWindowContainerListener(this);
+            reportConfigToWindowTokenClient();
+        }
+
+        private void unregister() {
+            mContainer.unregisterWindowContainerListener(this);
+            mListeners.remove(mClientToken);
+        }
+
+        private void clear() {
+            mLastReportedConfig = null;
+            mLastReportedDisplay = INVALID_DISPLAY;
+        }
+
+        @Override
+        public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
+            reportConfigToWindowTokenClient();
+        }
+
+        @Override
+        public void onDisplayChanged(DisplayContent dc) {
+            reportConfigToWindowTokenClient();
+        }
+
+        private void reportConfigToWindowTokenClient() {
+            if (mDeathRecipient == null) {
+                throw new IllegalStateException("Invalid client token: " + mClientToken);
+            }
+
+            if (mLastReportedConfig == null) {
+                mLastReportedConfig = new Configuration();
+            }
+            final Configuration config = mContainer.getConfiguration();
+            final int displayId = mContainer.getDisplayContent().getDisplayId();
+            if (config.equals(mLastReportedConfig) && displayId == mLastReportedDisplay) {
+                // No changes since last reported time.
+                return;
+            }
+
+            mLastReportedConfig.setTo(config);
+            mLastReportedDisplay = displayId;
+
+            IWindowToken windowTokenClient = IWindowToken.Stub.asInterface(mClientToken);
+            try {
+                windowTokenClient.onConfigurationChanged(config, displayId);
+            } catch (RemoteException e) {
+                ProtoLog.w(WM_ERROR, "Could not report config changes to the window token client.");
+            }
+        }
+
+        @Override
+        public void onRemoved() {
+            if (mDeathRecipient == null) {
+                throw new IllegalStateException("Invalid client token: " + mClientToken);
+            }
+            mDeathRecipient.unlinkToDeath();
+            IWindowToken windowTokenClient = IWindowToken.Stub.asInterface(mClientToken);
+            try {
+                windowTokenClient.onWindowTokenRemoved();
+            } catch (RemoteException e) {
+                ProtoLog.w(WM_ERROR, "Could not report token removal to the window token client.");
+            }
+            unregister();
+        }
+
+        private class DeathRecipient implements IBinder.DeathRecipient {
+            @Override
+            public void binderDied() {
+                synchronized (mContainer.mWmService.mGlobalLock) {
+                    mDeathRecipient = null;
+                    unregister();
+                }
+            }
+
+            void linkToDeath() throws RemoteException {
+                mClientToken.linkToDeath(this, 0);
+            }
+
+            void unlinkToDeath() {
+                mClientToken.unlinkToDeath(this, 0);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d4efa8a..8fd342c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -459,7 +459,7 @@
 
     final WindowTracing mWindowTracing;
 
-    final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;
+    private final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
     // TODO: eventually unify all keyguard state in a common place instead of having it spread over
@@ -769,6 +769,8 @@
     final AnrController mAnrController;
 
     private final ImpressionAttestationController mImpressionAttestationController;
+    private final WindowContextListenerController mWindowContextListenerController =
+            new WindowContextListenerController();
 
     @VisibleForTesting
     final class SettingsObserver extends ContentObserver {
@@ -1121,10 +1123,7 @@
             final boolean isRecentsAnimationTarget = getRecentsAnimationController() != null
                     && getRecentsAnimationController().isTargetApp(atoken);
             if (atoken.mLaunchTaskBehind && !isRecentsAnimationTarget) {
-                try {
-                    mActivityTaskManager.notifyLaunchTaskBehindComplete(atoken.token);
-                } catch (RemoteException e) {
-                }
+                mAtmService.mTaskSupervisor.scheduleLaunchTaskBehindComplete(atoken.token);
                 atoken.mLaunchTaskBehind = false;
             } else {
                 atoken.updateReportedVisibilityLocked();
@@ -1132,9 +1131,11 @@
                 // successfully finishes.
                 if (atoken.mEnteringAnimation && !isRecentsAnimationTarget) {
                     atoken.mEnteringAnimation = false;
-                    try {
-                        mActivityTaskManager.notifyEnterAnimationComplete(atoken.token);
-                    } catch (RemoteException e) {
+                    if (atoken != null && atoken.attachedToProcess()) {
+                        try {
+                            atoken.app.getThread().scheduleEnterAnimationComplete(atoken.appToken);
+                        } catch (RemoteException e) {
+                        }
                     }
                 }
             }
@@ -1378,6 +1379,10 @@
         mStartingSurfaceController = new StartingSurfaceController(this);
     }
 
+    DisplayAreaPolicy.Provider getDisplayAreaPolicyProvider() {
+        return mDisplayAreaPolicyProvider;
+    }
+
     private void setGlobalShadowSettings() {
         final TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
         float lightY = a.getDimension(R.styleable.Lighting_lightY, 0);
@@ -2624,6 +2629,10 @@
     }
 
     boolean checkCallingPermission(String permission, String func) {
+        return checkCallingPermission(permission, func, true /* printLog */);
+    }
+
+    boolean checkCallingPermission(String permission, String func, boolean printLog) {
         // Quick check: if the calling permission is me, it's all okay.
         if (Binder.getCallingPid() == myPid()) {
             return true;
@@ -2633,8 +2642,10 @@
                 == PackageManager.PERMISSION_GRANTED) {
             return true;
         }
-        ProtoLog.w(WM_ERROR, "Permission Denial: %s from pid=%d, uid=%d requires %s",
-                func, Binder.getCallingPid(), Binder.getCallingUid(), permission);
+        if (printLog) {
+            ProtoLog.w(WM_ERROR, "Permission Denial: %s from pid=%d, uid=%d requires %s",
+                    func, Binder.getCallingPid(), Binder.getCallingUid(), permission);
+        }
         return false;
     }
 
@@ -2727,6 +2738,52 @@
     }
 
     @Override
+    public boolean registerWindowContextListener(IBinder clientToken, int type, int displayId,
+            Bundle options) {
+        final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
+                "registerWindowContextListener", false /* printLog */);
+        final int callingUid = Binder.getCallingUid();
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
+                if (dc == null) {
+                    ProtoLog.w(WM_ERROR, "registerWindowContextListener: trying to add listener to"
+                            + " a non-existing display:%d", displayId);
+                    return false;
+                }
+                // TODO(b/155340867): Investigate if we still need roundedCornerOverlay after
+                // the feature b/155340867 is completed.
+                final DisplayArea da = dc.getAreaForWindowToken(type, options,
+                        callerCanManageAppTokens, false /* roundedCornerOverlay */);
+                mWindowContextListenerController.registerWindowContainerListener(clientToken, da,
+                        callingUid);
+                return true;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void unregisterWindowContextListener(IBinder clientToken) {
+        final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
+                "unregisterWindowContextListener", false /* printLog */);
+        final int callingUid = Binder.getCallingUid();
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                if (mWindowContextListenerController.assertCallerCanRemoveListener(clientToken,
+                        callerCanManageAppTokens, callingUid)) {
+                    mWindowContextListenerController.unregisterWindowContainerListener(clientToken);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
     public boolean isWindowToken(IBinder binder) {
         synchronized (mGlobalLock) {
             final WindowToken windowToken = mRoot.getWindowToken(binder);
@@ -5108,9 +5165,11 @@
                 }
 
                 case NOTIFY_ACTIVITY_DRAWN: {
-                    try {
-                        mActivityTaskManager.notifyActivityDrawn((IBinder) msg.obj);
-                    } catch (RemoteException e) {
+                    final ActivityRecord activity = (ActivityRecord) msg.obj;
+                    synchronized (mGlobalLock) {
+                        if (activity.isAttached()) {
+                            activity.getRootTask().notifyActivityDrawnLocked(activity);
+                        }
                     }
                     break;
                 }
@@ -7719,6 +7778,9 @@
                     dc.mInputMethodControlTarget.hideInsets(
                             WindowInsets.Type.ime(), true /* fromIme */);
                 }
+                if (dc != null) {
+                    dc.getInsetsStateController().getImeSourceProvider().setImeShowing(false);
+                }
             }
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c318fad..bc8699e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -770,6 +770,9 @@
             }
             mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo(),
                     false /* applyFixedTransformationHint */);
+            // The surface position is going to be unrotated according to the last position.
+            // Make sure the source position is up-to-date.
+            mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y);
             mPendingSeamlessRotate.unrotate(transaction, this);
             getDisplayContent().getDisplayRotation().markForSeamlessRotation(this,
                     true /* seamlesslyRotated */);
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 5ced6a5..34875ed 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -419,6 +419,7 @@
         reportWindowTokenRemovedToClient();
     }
 
+    // TODO(b/159767464): Remove after we migrate to listener approach.
     private void reportWindowTokenRemovedToClient() {
         if (!shouldReportToClient()) {
             return;
diff --git a/services/core/jni/OWNERS b/services/core/jni/OWNERS
index 6f74885..7fc5565 100644
--- a/services/core/jni/OWNERS
+++ b/services/core/jni/OWNERS
@@ -12,3 +12,18 @@
 per-file com_android_server_HardwarePropertiesManagerService.cpp = michaelwr@google.com, santoscordon@google.com
 per-file com_android_server_power_PowerManagerService.* = michaelwr@google.com, santoscordon@google.com
 
+per-file Android.bp = file:platform/build/soong:/OWNERS
+per-file com_android_server_Usb* = file:/services/usb/OWNERS
+per-file com_android_server_Vibrator* = file:/services/core/java/com/android/server/vibrator/OWNERS
+per-file com_android_server_hdmi_* = file:/core/java/android/hardware/hdmi/OWNERS
+per-file com_android_server_input_* = file:/core/java/android/hardware/input/OWNERS
+per-file com_android_server_lights_* = file:/services/core/java/com/android/server/lights/OWNERS
+per-file com_android_server_location_* = file:/location/java/android/location/OWNERS
+per-file com_android_server_locksettings_* = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file com_android_server_net_* = file:/services/core/java/com/android/server/net/OWNERS
+per-file com_android_server_pm_* = file:/services/core/java/com/android/server/pm/OWNERS
+per-file com_android_server_power_* = file:/services/core/java/com/android/server/power/OWNERS
+per-file com_android_server_se_* = file:/core/java/android/se/OWNERS
+per-file com_android_server_security_* = file:/core/java/android/security/OWNERS
+per-file com_android_server_tv_* = file:/media/java/android/media/tv/OWNERS
+per-file com_android_server_vibrator_* = file:/services/core/java/com/android/server/vibrator/OWNERS
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 13450be..404b182 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -149,6 +149,14 @@
     jmethodID getAffineTransform;
 } gTouchCalibrationClassInfo;
 
+static struct {
+    jclass clazz;
+    jmethodID constructor;
+    jmethodID keyAt;
+    jmethodID valueAt;
+    jmethodID size;
+} gSparseArrayClassInfo;
+
 // --- Global functions ---
 
 template<typename T>
@@ -1705,19 +1713,73 @@
             patternObj, nullptr));
     jint* amplitudes = static_cast<jint*>(env->GetPrimitiveArrayCritical(amplitudesObj, nullptr));
 
-    std::vector<VibrationElement> elements(patternSize);
+    VibrationSequence sequence(patternSize);
+    std::vector<int32_t> vibrators = im->getInputManager()->getReader()->getVibratorIds(deviceId);
     for (size_t i = 0; i < patternSize; i++) {
         // VibrationEffect.validate guarantees duration > 0.
         std::chrono::milliseconds duration(patternMillis[i]);
-        elements[i].duration = std::min(duration, MAX_VIBRATE_PATTERN_DELAY_MILLIS);
-        // TODO: (b/161629089) apply channel specific amplitudes from development API.
-        elements[i].channels = {static_cast<uint8_t>(amplitudes[i]),
-                                static_cast<uint8_t>(amplitudes[i])};
+        VibrationElement element(CHANNEL_SIZE);
+        element.duration = std::min(duration, MAX_VIBRATE_PATTERN_DELAY_MILLIS);
+        // Vibrate on both channels
+        for (int32_t channel = 0; channel < vibrators.size(); channel++) {
+            element.addChannel(vibrators[channel], static_cast<uint8_t>(amplitudes[i]));
+        }
+        sequence.addElement(element);
     }
     env->ReleasePrimitiveArrayCritical(patternObj, patternMillis, JNI_ABORT);
     env->ReleasePrimitiveArrayCritical(amplitudesObj, amplitudes, JNI_ABORT);
 
-    im->getInputManager()->getReader()->vibrate(deviceId, elements, repeat, token);
+    im->getInputManager()->getReader()->vibrate(deviceId, sequence, repeat, token);
+}
+
+static void nativeVibrateCombined(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
+                                  jlongArray patternObj, jobject amplitudesObj, jint repeat,
+                                  jint token) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    size_t patternSize = env->GetArrayLength(patternObj);
+
+    if (patternSize > MAX_VIBRATE_PATTERN_SIZE) {
+        ALOGI("Skipped requested vibration because the pattern size is %zu "
+              "which is more than the maximum supported size of %d.",
+              patternSize, MAX_VIBRATE_PATTERN_SIZE);
+        return; // limit to reasonable size
+    }
+    const jlong* patternMillis = env->GetLongArrayElements(patternObj, nullptr);
+
+    std::array<jint*, CHANNEL_SIZE> amplitudesArray;
+    std::array<jint, CHANNEL_SIZE> vibratorIdArray;
+    jint amplSize = env->CallIntMethod(amplitudesObj, gSparseArrayClassInfo.size);
+    if (amplSize > CHANNEL_SIZE) {
+        ALOGE("Can not fit into input device vibration element.");
+        return;
+    }
+
+    for (int i = 0; i < amplSize; i++) {
+        vibratorIdArray[i] = env->CallIntMethod(amplitudesObj, gSparseArrayClassInfo.keyAt, i);
+        jintArray arr = static_cast<jintArray>(
+                env->CallObjectMethod(amplitudesObj, gSparseArrayClassInfo.valueAt, i));
+        amplitudesArray[i] = env->GetIntArrayElements(arr, nullptr);
+        if (env->GetArrayLength(arr) != patternSize) {
+            ALOGE("Amplitude length not equal to pattern length!");
+            return;
+        }
+    }
+
+    VibrationSequence sequence(patternSize);
+    for (size_t i = 0; i < patternSize; i++) {
+        VibrationElement element(CHANNEL_SIZE);
+        // VibrationEffect.validate guarantees duration > 0.
+        std::chrono::milliseconds duration(patternMillis[i]);
+        element.duration = std::min(duration, MAX_VIBRATE_PATTERN_DELAY_MILLIS);
+        for (int32_t channel = 0; channel < CHANNEL_SIZE; channel++) {
+            element.addChannel(vibratorIdArray[channel],
+                               static_cast<uint8_t>(amplitudesArray[channel][i]));
+        }
+        sequence.addElement(element);
+    }
+
+    im->getInputManager()->getReader()->vibrate(deviceId, sequence, repeat, token);
 }
 
 static void nativeCancelVibrate(JNIEnv* /* env */,
@@ -1727,6 +1789,23 @@
     im->getInputManager()->getReader()->cancelVibrate(deviceId, token);
 }
 
+static bool nativeIsVibrating(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    return im->getInputManager()->getReader()->isVibrating(deviceId);
+}
+
+static jintArray nativeGetVibratorIds(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    std::vector<int32_t> vibrators = im->getInputManager()->getReader()->getVibratorIds(deviceId);
+
+    jintArray vibIdArray = env->NewIntArray(vibrators.size());
+    if (vibIdArray != nullptr) {
+        env->SetIntArrayRegion(vibIdArray, 0, vibrators.size(), vibrators.data());
+    }
+    return vibIdArray;
+}
+
 static void nativeReloadKeyboardLayouts(JNIEnv* /* env */,
         jclass /* clazz */, jlong ptr) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1872,7 +1951,11 @@
         {"nativeSetInteractive", "(JZ)V", (void*)nativeSetInteractive},
         {"nativeReloadCalibration", "(J)V", (void*)nativeReloadCalibration},
         {"nativeVibrate", "(JI[J[III)V", (void*)nativeVibrate},
+        {"nativeVibrateCombined", "(JI[JLandroid/util/SparseArray;II)V",
+         (void*)nativeVibrateCombined},
         {"nativeCancelVibrate", "(JII)V", (void*)nativeCancelVibrate},
+        {"nativeIsVibrating", "(JI)Z", (void*)nativeIsVibrating},
+        {"nativeGetVibratorIds", "(JI)[I", (void*)nativeGetVibratorIds},
         {"nativeReloadKeyboardLayouts", "(J)V", (void*)nativeReloadKeyboardLayouts},
         {"nativeReloadDeviceAliases", "(J)V", (void*)nativeReloadDeviceAliases},
         {"nativeDump", "(J)Ljava/lang/String;", (void*)nativeDump},
@@ -2048,6 +2131,15 @@
     GET_METHOD_ID(gTouchCalibrationClassInfo.getAffineTransform, gTouchCalibrationClassInfo.clazz,
             "getAffineTransform", "()[F");
 
+    // SparseArray
+    FIND_CLASS(gSparseArrayClassInfo.clazz, "android/util/SparseArray");
+    gSparseArrayClassInfo.clazz = jclass(env->NewGlobalRef(gSparseArrayClassInfo.clazz));
+    GET_METHOD_ID(gSparseArrayClassInfo.constructor, gSparseArrayClassInfo.clazz, "<init>", "()V");
+    GET_METHOD_ID(gSparseArrayClassInfo.keyAt, gSparseArrayClassInfo.clazz, "keyAt", "(I)I");
+    GET_METHOD_ID(gSparseArrayClassInfo.valueAt, gSparseArrayClassInfo.clazz, "valueAt",
+                  "(I)Ljava/lang/Object;");
+    GET_METHOD_ID(gSparseArrayClassInfo.size, gSparseArrayClassInfo.clazz, "size", "()I");
+
     return 0;
 }
 
diff --git a/services/core/jni/gnss/OWNERS b/services/core/jni/gnss/OWNERS
new file mode 100644
index 0000000..5ac6028
--- /dev/null
+++ b/services/core/jni/gnss/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/location/OWNERS
diff --git a/services/core/xsd/device-state-config/device-state-config.xsd b/services/core/xsd/device-state-config/device-state-config.xsd
index 0d8c08c..5014503 100644
--- a/services/core/xsd/device-state-config/device-state-config.xsd
+++ b/services/core/xsd/device-state-config/device-state-config.xsd
@@ -57,8 +57,8 @@
 
     <xs:complexType name="sensorCondition">
         <xs:sequence>
+            <xs:element name="type" type="xs:string" />
             <xs:element name="name" type="xs:string" />
-            <xs:element name="type" type="xs:positiveInteger" />
             <xs:element name="value" type="numericRange" maxOccurs="unbounded" />
         </xs:sequence>
     </xs:complexType>
diff --git a/services/core/xsd/device-state-config/schema/current.txt b/services/core/xsd/device-state-config/schema/current.txt
index 667d1ad..b396af0 100644
--- a/services/core/xsd/device-state-config/schema/current.txt
+++ b/services/core/xsd/device-state-config/schema/current.txt
@@ -44,10 +44,10 @@
   public class SensorCondition {
     ctor public SensorCondition();
     method public String getName();
-    method public java.math.BigInteger getType();
+    method public String getType();
     method public java.util.List<com.android.server.policy.devicestate.config.NumericRange> getValue();
     method public void setName(String);
-    method public void setType(java.math.BigInteger);
+    method public void setType(String);
   }
 
   public class XmlParser {
diff --git a/services/core/xsd/platform-compat-schema/OWNERS b/services/core/xsd/platform-compat-schema/OWNERS
new file mode 100644
index 0000000..f8c3520
--- /dev/null
+++ b/services/core/xsd/platform-compat-schema/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/compat/OWNERS
diff --git a/services/devicepolicy/OWNERS b/services/devicepolicy/OWNERS
new file mode 100644
index 0000000..e95633a
--- /dev/null
+++ b/services/devicepolicy/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/admin/OWNERS
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
index 1a147b9..a281180 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java
@@ -40,14 +40,14 @@
 import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
 
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
 import com.android.server.pm.UserRestrictionsUtils;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -300,7 +300,7 @@
         return UserHandle.of(UserHandle.getUserId(info.getActivityInfo().applicationInfo.uid));
     }
 
-    void writeToXml(XmlSerializer out)
+    void writeToXml(TypedXmlSerializer out)
             throws IllegalArgumentException, IllegalStateException, IOException {
         out.startTag(null, TAG_POLICIES);
         info.writePoliciesToXml(out);
@@ -413,11 +413,11 @@
         }
         if (isNetworkLoggingEnabled) {
             out.startTag(null, TAG_IS_NETWORK_LOGGING_ENABLED);
-            out.attribute(null, ATTR_VALUE, Boolean.toString(isNetworkLoggingEnabled));
-            out.attribute(null, ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS,
-                    Integer.toString(numNetworkLoggingNotifications));
-            out.attribute(null, ATTR_LAST_NETWORK_LOGGING_NOTIFICATION,
-                    Long.toString(lastNetworkLoggingNotificationTimeMs));
+            out.attributeBoolean(null, ATTR_VALUE, isNetworkLoggingEnabled);
+            out.attributeInt(null, ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS,
+                    numNetworkLoggingNotifications);
+            out.attributeLong(null, ATTR_LAST_NETWORK_LOGGING_NOTIFICATION,
+                    lastNetworkLoggingNotificationTimeMs);
             out.endTag(null, TAG_IS_NETWORK_LOGGING_ENABLED);
         }
         if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
@@ -535,13 +535,13 @@
         }
     }
 
-    void writeTextToXml(XmlSerializer out, String tag, String text) throws IOException {
+    void writeTextToXml(TypedXmlSerializer out, String tag, String text) throws IOException {
         out.startTag(null, tag);
         out.text(text);
         out.endTag(null, tag);
     }
 
-    void writePackageListToXml(XmlSerializer out, String outerTag,
+    void writePackageListToXml(TypedXmlSerializer out, String outerTag,
             List<String> packageList)
             throws IllegalArgumentException, IllegalStateException, IOException {
         if (packageList == null) {
@@ -550,35 +550,35 @@
         writeAttributeValuesToXml(out, outerTag, TAG_PACKAGE_LIST_ITEM, packageList);
     }
 
-    void writeAttributeValueToXml(XmlSerializer out, String tag, String value)
+    void writeAttributeValueToXml(TypedXmlSerializer out, String tag, String value)
             throws IOException {
         out.startTag(null, tag);
         out.attribute(null, ATTR_VALUE, value);
         out.endTag(null, tag);
     }
 
-    void writeAttributeValueToXml(XmlSerializer out, String tag, int value)
+    void writeAttributeValueToXml(TypedXmlSerializer out, String tag, int value)
             throws IOException {
         out.startTag(null, tag);
-        out.attribute(null, ATTR_VALUE, Integer.toString(value));
+        out.attributeInt(null, ATTR_VALUE, value);
         out.endTag(null, tag);
     }
 
-    void writeAttributeValueToXml(XmlSerializer out, String tag, long value)
+    void writeAttributeValueToXml(TypedXmlSerializer out, String tag, long value)
             throws IOException {
         out.startTag(null, tag);
-        out.attribute(null, ATTR_VALUE, Long.toString(value));
+        out.attributeLong(null, ATTR_VALUE, value);
         out.endTag(null, tag);
     }
 
-    void writeAttributeValueToXml(XmlSerializer out, String tag, boolean value)
+    void writeAttributeValueToXml(TypedXmlSerializer out, String tag, boolean value)
             throws IOException {
         out.startTag(null, tag);
-        out.attribute(null, ATTR_VALUE, Boolean.toString(value));
+        out.attributeBoolean(null, ATTR_VALUE, value);
         out.endTag(null, tag);
     }
 
-    void writeAttributeValuesToXml(XmlSerializer out, String outerTag, String innerTag,
+    void writeAttributeValuesToXml(TypedXmlSerializer out, String outerTag, String innerTag,
             @NonNull Collection<String> values) throws IOException {
         out.startTag(null, outerTag);
         for (String value : values) {
@@ -589,7 +589,7 @@
         out.endTag(null, outerTag);
     }
 
-    void readFromXml(XmlPullParser parser, boolean shouldOverridePolicies)
+    void readFromXml(TypedXmlPullParser parser, boolean shouldOverridePolicies)
             throws XmlPullParserException, IOException {
         int outerDepth = parser.getDepth();
         int type;
@@ -606,47 +606,33 @@
                     info.readPoliciesFromXml(parser);
                 }
             } else if (TAG_PASSWORD_QUALITY.equals(tag)) {
-                mPasswordPolicy.quality = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordPolicy.quality = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_MIN_PASSWORD_LENGTH.equals(tag)) {
-                mPasswordPolicy.length = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordPolicy.length = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_PASSWORD_HISTORY_LENGTH.equals(tag)) {
-                passwordHistoryLength = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                passwordHistoryLength = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_MIN_PASSWORD_UPPERCASE.equals(tag)) {
-                mPasswordPolicy.upperCase = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordPolicy.upperCase = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_MIN_PASSWORD_LOWERCASE.equals(tag)) {
-                mPasswordPolicy.lowerCase = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordPolicy.lowerCase = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_MIN_PASSWORD_LETTERS.equals(tag)) {
-                mPasswordPolicy.letters = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordPolicy.letters = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_MIN_PASSWORD_NUMERIC.equals(tag)) {
-                mPasswordPolicy.numeric = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordPolicy.numeric = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_MIN_PASSWORD_SYMBOLS.equals(tag)) {
-                mPasswordPolicy.symbols = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordPolicy.symbols = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) {
-                mPasswordPolicy.nonLetter = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordPolicy.nonLetter = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_PASSWORD_QUALITY_APPLIES_TO_PARENT.equals(tag)) {
-                mPasswordPolicyAppliesToParent = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordPolicyAppliesToParent = parser.getAttributeBoolean(null, ATTR_VALUE);
             } else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) {
-                maximumTimeToUnlock = Long.parseLong(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                maximumTimeToUnlock = parser.getAttributeLong(null, ATTR_VALUE);
             } else if (TAG_STRONG_AUTH_UNLOCK_TIMEOUT.equals(tag)) {
-                strongAuthUnlockTimeout = Long.parseLong(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                strongAuthUnlockTimeout = parser.getAttributeLong(null, ATTR_VALUE);
             } else if (TAG_MAX_FAILED_PASSWORD_WIPE.equals(tag)) {
-                maximumFailedPasswordsForWipe = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                maximumFailedPasswordsForWipe = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_SPECIFIES_GLOBAL_PROXY.equals(tag)) {
-                specifiesGlobalProxy = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                specifiesGlobalProxy = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_GLOBAL_PROXY_SPEC.equals(tag)) {
                 globalProxySpec =
                     parser.getAttributeValue(null, ATTR_VALUE);
@@ -654,48 +640,36 @@
                 globalProxyExclusionList =
                     parser.getAttributeValue(null, ATTR_VALUE);
             } else if (TAG_PASSWORD_EXPIRATION_TIMEOUT.equals(tag)) {
-                passwordExpirationTimeout = Long.parseLong(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                passwordExpirationTimeout = parser.getAttributeLong(null, ATTR_VALUE);
             } else if (TAG_PASSWORD_EXPIRATION_DATE.equals(tag)) {
-                passwordExpirationDate = Long.parseLong(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                passwordExpirationDate = parser.getAttributeLong(null, ATTR_VALUE);
             } else if (TAG_ENCRYPTION_REQUESTED.equals(tag)) {
-                encryptionRequested = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                encryptionRequested = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_TEST_ONLY_ADMIN.equals(tag)) {
-                testOnlyAdmin = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                testOnlyAdmin = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_DISABLE_CAMERA.equals(tag)) {
-                disableCamera = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                disableCamera = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_DISABLE_CALLER_ID.equals(tag)) {
-                disableCallerId = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                disableCallerId = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_DISABLE_CONTACTS_SEARCH.equals(tag)) {
-                disableContactsSearch = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                disableContactsSearch = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_DISABLE_BLUETOOTH_CONTACT_SHARING.equals(tag)) {
-                disableBluetoothContactSharing = Boolean.parseBoolean(parser
-                        .getAttributeValue(null, ATTR_VALUE));
+                disableBluetoothContactSharing =
+                        parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_DISABLE_SCREEN_CAPTURE.equals(tag)) {
-                disableScreenCapture = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                disableScreenCapture = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_REQUIRE_AUTO_TIME.equals(tag)) {
-                requireAutoTime = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                requireAutoTime = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_FORCE_EPHEMERAL_USERS.equals(tag)) {
-                forceEphemeralUsers = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                forceEphemeralUsers = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_IS_NETWORK_LOGGING_ENABLED.equals(tag)) {
-                isNetworkLoggingEnabled = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
-                lastNetworkLoggingNotificationTimeMs = Long.parseLong(
-                        parser.getAttributeValue(null, ATTR_LAST_NETWORK_LOGGING_NOTIFICATION));
-                numNetworkLoggingNotifications = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS));
+                isNetworkLoggingEnabled = parser.getAttributeBoolean(null, ATTR_VALUE, false);
+                lastNetworkLoggingNotificationTimeMs = parser.getAttributeLong(null,
+                        ATTR_LAST_NETWORK_LOGGING_NOTIFICATION);
+                numNetworkLoggingNotifications = parser.getAttributeInt(null,
+                        ATTR_NUM_NETWORK_LOGGING_NOTIFICATIONS);
             } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
-                disabledKeyguardFeatures = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                disabledKeyguardFeatures = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_DISABLE_ACCOUNT_MANAGEMENT.equals(tag)) {
                 readAttributeValues(
                         parser, TAG_ACCOUNT_TYPE, accountTypesWithManagementDisabled);
@@ -721,7 +695,7 @@
                         parser, TAG_RESTRICTION, defaultEnabledRestrictionsAlreadySet);
             } else if (TAG_SHORT_SUPPORT_MESSAGE.equals(tag)) {
                 type = parser.next();
-                if (type == XmlPullParser.TEXT) {
+                if (type == TypedXmlPullParser.TEXT) {
                     shortSupportMessage = parser.getText();
                 } else {
                     Log.w(DevicePolicyManagerService.LOG_TAG,
@@ -729,7 +703,7 @@
                 }
             } else if (TAG_LONG_SUPPORT_MESSAGE.equals(tag)) {
                 type = parser.next();
-                if (type == XmlPullParser.TEXT) {
+                if (type == TypedXmlPullParser.TEXT) {
                     longSupportMessage = parser.getText();
                 } else {
                     Log.w(DevicePolicyManagerService.LOG_TAG,
@@ -740,22 +714,20 @@
                 parentAdmin = new ActiveAdmin(info, /* parent */ true);
                 parentAdmin.readFromXml(parser, shouldOverridePolicies);
             } else if (TAG_ORGANIZATION_COLOR.equals(tag)) {
-                organizationColor = Integer.parseInt(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                organizationColor = parser.getAttributeInt(null, ATTR_VALUE);
             } else if (TAG_ORGANIZATION_NAME.equals(tag)) {
                 type = parser.next();
-                if (type == XmlPullParser.TEXT) {
+                if (type == TypedXmlPullParser.TEXT) {
                     organizationName = parser.getText();
                 } else {
                     Log.w(DevicePolicyManagerService.LOG_TAG,
                             "Missing text when loading organization name");
                 }
             } else if (TAG_IS_LOGOUT_ENABLED.equals(tag)) {
-                isLogoutEnabled = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                isLogoutEnabled = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_START_USER_SESSION_MESSAGE.equals(tag)) {
                 type = parser.next();
-                if (type == XmlPullParser.TEXT) {
+                if (type == TypedXmlPullParser.TEXT) {
                     startUserSessionMessage = parser.getText();
                 } else {
                     Log.w(DevicePolicyManagerService.LOG_TAG,
@@ -763,7 +735,7 @@
                 }
             } else if (TAG_END_USER_SESSION_MESSAGE.equals(tag)) {
                 type = parser.next();
-                if (type == XmlPullParser.TEXT) {
+                if (type == TypedXmlPullParser.TEXT) {
                     endUserSessionMessage = parser.getText();
                 } else {
                     Log.w(DevicePolicyManagerService.LOG_TAG,
@@ -779,24 +751,21 @@
                 mFactoryResetProtectionPolicy = FactoryResetProtectionPolicy.readFromXml(
                             parser);
             } else if (TAG_SUSPEND_PERSONAL_APPS.equals(tag)) {
-                mSuspendPersonalApps = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mSuspendPersonalApps = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_PROFILE_MAXIMUM_TIME_OFF.equals(tag)) {
                 mProfileMaximumTimeOffMillis =
-                        Long.parseLong(parser.getAttributeValue(null, ATTR_VALUE));
+                        parser.getAttributeLong(null, ATTR_VALUE);
             } else if (TAG_PROFILE_OFF_DEADLINE.equals(tag)) {
                 mProfileOffDeadline =
-                        Long.parseLong(parser.getAttributeValue(null, ATTR_VALUE));
+                        parser.getAttributeLong(null, ATTR_VALUE);
             } else if (TAG_ALWAYS_ON_VPN_PACKAGE.equals(tag)) {
                 mAlwaysOnVpnPackage = parser.getAttributeValue(null, ATTR_VALUE);
             } else if (TAG_ALWAYS_ON_VPN_LOCKDOWN.equals(tag)) {
-                mAlwaysOnVpnLockdown = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mAlwaysOnVpnLockdown = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_COMMON_CRITERIA_MODE.equals(tag)) {
-                mCommonCriteriaMode = Boolean.parseBoolean(
-                        parser.getAttributeValue(null, ATTR_VALUE));
+                mCommonCriteriaMode = parser.getAttributeBoolean(null, ATTR_VALUE, false);
             } else if (TAG_PASSWORD_COMPLEXITY.equals(tag)) {
-                mPasswordComplexity = Integer.parseInt(parser.getAttributeValue(null, ATTR_VALUE));
+                mPasswordComplexity = parser.getAttributeInt(null, ATTR_VALUE);
             } else {
                 Slog.w(DevicePolicyManagerService.LOG_TAG, "Unknown admin tag: " + tag);
                 XmlUtils.skipCurrentTag(parser);
@@ -804,14 +773,14 @@
         }
     }
 
-    private List<String> readPackageList(XmlPullParser parser,
+    private List<String> readPackageList(TypedXmlPullParser parser,
             String tag) throws XmlPullParserException, IOException {
         List<String> result = new ArrayList<String>();
         int outerDepth = parser.getDepth();
         int outerType;
-        while ((outerType = parser.next()) != XmlPullParser.END_DOCUMENT
-                && (outerType != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
-            if (outerType == XmlPullParser.END_TAG || outerType == XmlPullParser.TEXT) {
+        while ((outerType = parser.next()) != TypedXmlPullParser.END_DOCUMENT
+                && (outerType != TypedXmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (outerType == TypedXmlPullParser.END_TAG || outerType == TypedXmlPullParser.TEXT) {
                 continue;
             }
             String outerTag = parser.getName();
@@ -832,7 +801,7 @@
     }
 
     private void readAttributeValues(
-            XmlPullParser parser, String tag, Collection<String> result)
+            TypedXmlPullParser parser, String tag, Collection<String> result)
             throws XmlPullParserException, IOException {
         result.clear();
         int outerDepthDAM = parser.getDepth();
@@ -854,7 +823,7 @@
 
     @NonNull
     private ArrayMap<String, TrustAgentInfo> getAllTrustAgentInfos(
-            XmlPullParser parser, String tag) throws XmlPullParserException, IOException {
+            TypedXmlPullParser parser, String tag) throws XmlPullParserException, IOException {
         int outerDepthDAM = parser.getDepth();
         int typeDAM;
         final ArrayMap<String, TrustAgentInfo> result = new ArrayMap<>();
@@ -876,7 +845,7 @@
         return result;
     }
 
-    private TrustAgentInfo getTrustAgentInfo(XmlPullParser parser, String tag)
+    private TrustAgentInfo getTrustAgentInfo(TypedXmlPullParser parser, String tag)
             throws XmlPullParserException, IOException  {
         int outerDepthDAM = parser.getDepth();
         int typeDAM;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java
index 8a585ec..31ba199 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyData.java
@@ -170,24 +170,19 @@
             }
             if (policyData.mUserSetupComplete) {
                 if (VERBOSE_LOG) Slog.v(TAG, "setting " + ATTR_SETUP_COMPLETE + " to true");
-                out.attribute(null, ATTR_SETUP_COMPLETE,
-                        Boolean.toString(true));
+                out.attributeBoolean(null, ATTR_SETUP_COMPLETE, true);
             }
             if (policyData.mPaired) {
-                out.attribute(null, ATTR_DEVICE_PAIRED,
-                        Boolean.toString(true));
+                out.attributeBoolean(null, ATTR_DEVICE_PAIRED, true);
             }
             if (policyData.mDeviceProvisioningConfigApplied) {
-                out.attribute(null, ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED,
-                        Boolean.toString(true));
+                out.attributeBoolean(null, ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED, true);
             }
             if (policyData.mUserProvisioningState != DevicePolicyManager.STATE_USER_UNMANAGED) {
-                out.attribute(null, ATTR_PROVISIONING_STATE,
-                        Integer.toString(policyData.mUserProvisioningState));
+                out.attributeInt(null, ATTR_PROVISIONING_STATE, policyData.mUserProvisioningState);
             }
             if (policyData.mPermissionPolicy != DevicePolicyManager.PERMISSION_POLICY_PROMPT) {
-                out.attribute(null, ATTR_PERMISSION_POLICY,
-                        Integer.toString(policyData.mPermissionPolicy));
+                out.attributeInt(null, ATTR_PERMISSION_POLICY, policyData.mPermissionPolicy);
             }
 
             // Serialize delegations.
@@ -217,13 +212,13 @@
 
             if (policyData.mPasswordOwner >= 0) {
                 out.startTag(null, "password-owner");
-                out.attribute(null, "value", Integer.toString(policyData.mPasswordOwner));
+                out.attributeInt(null, "value", policyData.mPasswordOwner);
                 out.endTag(null, "password-owner");
             }
 
             if (policyData.mFailedPasswordAttempts != 0) {
                 out.startTag(null, "failed-password-attempts");
-                out.attribute(null, "value", Integer.toString(policyData.mFailedPasswordAttempts));
+                out.attributeInt(null, "value", policyData.mFailedPasswordAttempts);
                 out.endTag(null, "failed-password-attempts");
             }
 
@@ -232,8 +227,7 @@
             // security reasons, we don't want to store the full set of active password metrics.
             if (isFdeDevice) {
                 out.startTag(null, TAG_PASSWORD_VALIDITY);
-                out.attribute(null, ATTR_VALUE,
-                        Boolean.toString(policyData.mPasswordValidAtLastCheckpoint));
+                out.attributeBoolean(null, ATTR_VALUE, policyData.mPasswordValidAtLastCheckpoint);
                 out.endTag(null, TAG_PASSWORD_VALIDITY);
             }
 
@@ -252,19 +246,19 @@
 
             if (policyData.mLockTaskFeatures != DevicePolicyManager.LOCK_TASK_FEATURE_NONE) {
                 out.startTag(null, TAG_LOCK_TASK_FEATURES);
-                out.attribute(null, ATTR_VALUE, Integer.toString(policyData.mLockTaskFeatures));
+                out.attributeInt(null, ATTR_VALUE, policyData.mLockTaskFeatures);
                 out.endTag(null, TAG_LOCK_TASK_FEATURES);
             }
 
             if (policyData.mSecondaryLockscreenEnabled) {
                 out.startTag(null, TAG_SECONDARY_LOCK_SCREEN);
-                out.attribute(null, ATTR_VALUE, Boolean.toString(true));
+                out.attributeBoolean(null, ATTR_VALUE, true);
                 out.endTag(null, TAG_SECONDARY_LOCK_SCREEN);
             }
 
             if (policyData.mStatusBarDisabled) {
                 out.startTag(null, TAG_STATUS_BAR);
-                out.attribute(null, ATTR_DISABLED, Boolean.toString(policyData.mStatusBarDisabled));
+                out.attributeBoolean(null, ATTR_DISABLED, policyData.mStatusBarDisabled);
                 out.endTag(null, TAG_STATUS_BAR);
             }
 
@@ -281,29 +275,25 @@
 
             if (policyData.mLastSecurityLogRetrievalTime >= 0) {
                 out.startTag(null, TAG_LAST_SECURITY_LOG_RETRIEVAL);
-                out.attribute(null, ATTR_VALUE,
-                        Long.toString(policyData.mLastSecurityLogRetrievalTime));
+                out.attributeLong(null, ATTR_VALUE, policyData.mLastSecurityLogRetrievalTime);
                 out.endTag(null, TAG_LAST_SECURITY_LOG_RETRIEVAL);
             }
 
             if (policyData.mLastBugReportRequestTime >= 0) {
                 out.startTag(null, TAG_LAST_BUG_REPORT_REQUEST);
-                out.attribute(null, ATTR_VALUE,
-                        Long.toString(policyData.mLastBugReportRequestTime));
+                out.attributeLong(null, ATTR_VALUE, policyData.mLastBugReportRequestTime);
                 out.endTag(null, TAG_LAST_BUG_REPORT_REQUEST);
             }
 
             if (policyData.mLastNetworkLogsRetrievalTime >= 0) {
                 out.startTag(null, TAG_LAST_NETWORK_LOG_RETRIEVAL);
-                out.attribute(null, ATTR_VALUE,
-                        Long.toString(policyData.mLastNetworkLogsRetrievalTime));
+                out.attributeLong(null, ATTR_VALUE, policyData.mLastNetworkLogsRetrievalTime);
                 out.endTag(null, TAG_LAST_NETWORK_LOG_RETRIEVAL);
             }
 
             if (policyData.mAdminBroadcastPending) {
                 out.startTag(null, TAG_ADMIN_BROADCAST_PENDING);
-                out.attribute(null, ATTR_VALUE,
-                        Boolean.toString(policyData.mAdminBroadcastPending));
+                out.attributeBoolean(null, ATTR_VALUE, policyData.mAdminBroadcastPending);
                 out.endTag(null, TAG_ADMIN_BROADCAST_PENDING);
             }
 
@@ -315,8 +305,7 @@
 
             if (policyData.mPasswordTokenHandle != 0) {
                 out.startTag(null, TAG_PASSWORD_TOKEN_HANDLE);
-                out.attribute(null, ATTR_VALUE,
-                        Long.toString(policyData.mPasswordTokenHandle));
+                out.attributeLong(null, ATTR_VALUE, policyData.mPasswordTokenHandle);
                 out.endTag(null, TAG_PASSWORD_TOKEN_HANDLE);
             }
 
@@ -340,7 +329,7 @@
 
             if (policyData.mAppsSuspended) {
                 out.startTag(null, TAG_APPS_SUSPENDED);
-                out.attribute(null, ATTR_VALUE, Boolean.toString(policyData.mAppsSuspended));
+                out.attributeBoolean(null, ATTR_VALUE, policyData.mAppsSuspended);
                 out.endTag(null, TAG_APPS_SUSPENDED);
             }
 
@@ -413,13 +402,13 @@
             if (Boolean.toString(true).equals(deviceProvisioningConfigApplied)) {
                 policy.mDeviceProvisioningConfigApplied = true;
             }
-            String provisioningState = parser.getAttributeValue(null, ATTR_PROVISIONING_STATE);
-            if (!TextUtils.isEmpty(provisioningState)) {
-                policy.mUserProvisioningState = Integer.parseInt(provisioningState);
+            int provisioningState = parser.getAttributeInt(null, ATTR_PROVISIONING_STATE, -1);
+            if (provisioningState != -1) {
+                policy.mUserProvisioningState = provisioningState;
             }
-            String permissionPolicy = parser.getAttributeValue(null, ATTR_PERMISSION_POLICY);
-            if (!TextUtils.isEmpty(permissionPolicy)) {
-                policy.mPermissionPolicy = Integer.parseInt(permissionPolicy);
+            int permissionPolicy = parser.getAttributeInt(null, ATTR_PERMISSION_POLICY, -1);
+            if (permissionPolicy != -1) {
+                policy.mPermissionPolicy = permissionPolicy;
             }
 
             parser.next();
@@ -472,37 +461,34 @@
                         scopes.add(scope);
                     }
                 } else if ("failed-password-attempts".equals(tag)) {
-                    policy.mFailedPasswordAttempts = Integer.parseInt(
-                            parser.getAttributeValue(null, "value"));
+                    policy.mFailedPasswordAttempts = parser.getAttributeInt(null, "value");
                 } else if ("password-owner".equals(tag)) {
-                    policy.mPasswordOwner = Integer.parseInt(
-                            parser.getAttributeValue(null, "value"));
+                    policy.mPasswordOwner = parser.getAttributeInt(null, "value");
                 } else if (TAG_ACCEPTED_CA_CERTIFICATES.equals(tag)) {
                     policy.mAcceptedCaCertificates.add(parser.getAttributeValue(null, ATTR_NAME));
                 } else if (TAG_LOCK_TASK_COMPONENTS.equals(tag)) {
                     policy.mLockTaskPackages.add(parser.getAttributeValue(null, "name"));
                 } else if (TAG_LOCK_TASK_FEATURES.equals(tag)) {
-                    policy.mLockTaskFeatures = Integer.parseInt(
-                            parser.getAttributeValue(null, ATTR_VALUE));
+                    policy.mLockTaskFeatures = parser.getAttributeInt(null, ATTR_VALUE);
                 } else if (TAG_SECONDARY_LOCK_SCREEN.equals(tag)) {
-                    policy.mSecondaryLockscreenEnabled = Boolean.parseBoolean(
-                            parser.getAttributeValue(null, ATTR_VALUE));
+                    policy.mSecondaryLockscreenEnabled =
+                            parser.getAttributeBoolean(null, ATTR_VALUE, false);
                 } else if (TAG_STATUS_BAR.equals(tag)) {
-                    policy.mStatusBarDisabled = Boolean.parseBoolean(
-                            parser.getAttributeValue(null, ATTR_DISABLED));
+                    policy.mStatusBarDisabled =
+                            parser.getAttributeBoolean(null, ATTR_DISABLED, false);
                 } else if (TAG_DO_NOT_ASK_CREDENTIALS_ON_BOOT.equals(tag)) {
                     policy.mDoNotAskCredentialsOnBoot = true;
                 } else if (TAG_AFFILIATION_ID.equals(tag)) {
                     policy.mAffiliationIds.add(parser.getAttributeValue(null, ATTR_ID));
                 } else if (TAG_LAST_SECURITY_LOG_RETRIEVAL.equals(tag)) {
-                    policy.mLastSecurityLogRetrievalTime = Long.parseLong(
-                            parser.getAttributeValue(null, ATTR_VALUE));
+                    policy.mLastSecurityLogRetrievalTime =
+                            parser.getAttributeLong(null, ATTR_VALUE);
                 } else if (TAG_LAST_BUG_REPORT_REQUEST.equals(tag)) {
-                    policy.mLastBugReportRequestTime = Long.parseLong(
-                            parser.getAttributeValue(null, ATTR_VALUE));
+                    policy.mLastBugReportRequestTime =
+                            parser.getAttributeLong(null, ATTR_VALUE);
                 } else if (TAG_LAST_NETWORK_LOG_RETRIEVAL.equals(tag)) {
-                    policy.mLastNetworkLogsRetrievalTime = Long.parseLong(
-                            parser.getAttributeValue(null, ATTR_VALUE));
+                    policy.mLastNetworkLogsRetrievalTime =
+                            parser.getAttributeLong(null, ATTR_VALUE);
                 } else if (TAG_ADMIN_BROADCAST_PENDING.equals(tag)) {
                     String pending = parser.getAttributeValue(null, ATTR_VALUE);
                     policy.mAdminBroadcastPending = Boolean.toString(true).equals(pending);
@@ -515,12 +501,11 @@
                 } else if (TAG_PASSWORD_VALIDITY.equals(tag)) {
                     if (isFdeDevice) {
                         // This flag is only used for FDE devices
-                        policy.mPasswordValidAtLastCheckpoint = Boolean.parseBoolean(
-                                parser.getAttributeValue(null, ATTR_VALUE));
+                        policy.mPasswordValidAtLastCheckpoint =
+                                parser.getAttributeBoolean(null, ATTR_VALUE, false);
                     }
                 } else if (TAG_PASSWORD_TOKEN_HANDLE.equals(tag)) {
-                    policy.mPasswordTokenHandle = Long.parseLong(
-                            parser.getAttributeValue(null, ATTR_VALUE));
+                    policy.mPasswordTokenHandle = parser.getAttributeLong(null, ATTR_VALUE);
                 } else if (TAG_CURRENT_INPUT_METHOD_SET.equals(tag)) {
                     policy.mCurrentInputMethodSet = true;
                 } else if (TAG_OWNER_INSTALLED_CA_CERT.equals(tag)) {
@@ -530,7 +515,7 @@
                             parser.getAttributeValue(null, ATTR_NAME));
                 } else if (TAG_APPS_SUSPENDED.equals(tag)) {
                     policy.mAppsSuspended =
-                            Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_VALUE));
+                            parser.getAttributeBoolean(null, ATTR_VALUE, false);
                 } else {
                     Slog.w(TAG, "Unknown tag: " + tag);
                     XmlUtils.skipCurrentTag(parser);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 513543e..c7dbf95 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -983,17 +983,29 @@
 
     @Override
     public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) {
-        Slog.i(LOG_TAG, "Setting DevicePolicySafetyChecker as " + safetyChecker.getClass());
+        Slog.i(LOG_TAG, "Setting DevicePolicySafetyChecker as " + safetyChecker);
         mSafetyChecker = safetyChecker;
     }
 
     /**
+     * Used by {@link OneTimeSafetyChecker} only.
+     */
+    DevicePolicySafetyChecker getDevicePolicySafetyChecker() {
+        return mSafetyChecker;
+    }
+
+    /**
      * Checks if it's safe to execute the given {@code operation}.
      *
      * @throws UnsafeStateException if it's not safe to execute the operation.
      */
     private void checkCanExecuteOrThrowUnsafe(@DevicePolicyOperation int operation) {
         if (!canExecute(operation)) {
+            if (mSafetyChecker == null) {
+                // Happens on CTS after it's set just once (by OneTimeSafetyChecker)
+                throw new UnsafeStateException(operation);
+            }
+            // Let mSafetyChecker customize it (for example, by explaining how to retry)
             throw mSafetyChecker.newUnsafeStateException(operation);
         }
     }
@@ -1005,6 +1017,15 @@
         return mSafetyChecker == null || mSafetyChecker.isDevicePolicyOperationSafe(operation);
     }
 
+    @Override
+    public void setNextOperationSafety(@DevicePolicyOperation int operation, boolean safe) {
+        Preconditions.checkCallAuthorization(
+                hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS));
+        Slog.i(LOG_TAG, "setNextOperationSafety(" + DevicePolicyManager.operationToString(operation)
+                + ", " + safe + ")");
+        mSafetyChecker = new OneTimeSafetyChecker(this, operation, safe);
+    }
+
     /**
      * Unit test will subclass it to inject mocks.
      */
@@ -2307,7 +2328,8 @@
                     + admin.info.getTagForPolicy(reqPolicy));
         } else {
             throw new SecurityException("No active admin owned by uid "
-                    + callingUid + " for policy #" + reqPolicy);
+                    + callingUid + " for policy #" + reqPolicy + (permission == null ? ""
+                    : ", which doesn't have " + permission));
         }
     }
 
@@ -2367,6 +2389,7 @@
      * If not provided, iterate over all of the active admins in the DevicePolicyData for that user
      * and return the one with the uid specified as parameter, and has the policy specified.
      */
+    @Nullable
     private ActiveAdmin getActiveAdminWithPolicyForUidLocked(ComponentName who, int reqPolicy,
             int uid) {
         ensureLocked();
@@ -5847,7 +5870,11 @@
         // Should include alias in authentication policy
         try (KeyChainConnection connection = KeyChain.bindAsUser(mContext,
                 caller.getUserHandle())) {
-            if (!containsAlias(connection.getService().getCredentialManagementAppPolicy(), alias)) {
+            // The policy will be null if there is no credential management app
+            AppUriAuthenticationPolicy policy =
+                    connection.getService().getCredentialManagementAppPolicy();
+            if (policy == null || policy.getAppAndUriMappings().isEmpty()
+                    || !containsAlias(policy, alias)) {
                 return false;
             }
         } catch (RemoteException | InterruptedException e) {
@@ -6071,10 +6098,14 @@
 
         final ActiveAdmin admin;
         synchronized (getLockObject()) {
-            admin = getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_WIPE_DATA);
+            admin = getActiveAdminWithPolicyForUidLocked(/* who= */ null,
+                    DeviceAdminInfo.USES_POLICY_WIPE_DATA, caller.getUid());
         }
-        Preconditions.checkCallAuthorization(admin != null,
-                "No active admin for user %d", caller.getUserId());
+
+        Preconditions.checkCallAuthorization(
+                (admin != null) || hasCallingOrSelfPermission(permission.MASTER_CLEAR),
+                "No active admin for user %d and caller %d does not hold MASTER_CLEAR permission",
+                caller.getUserId(), caller.getUid());
 
         if (TextUtils.isEmpty(wipeReasonForUser)) {
             if (calledByProfileOwnerOnOrgOwnedDevice && !calledOnParentInstance) {
@@ -6085,7 +6116,10 @@
             }
         }
 
-        int userId = admin.getUserHandle().getIdentifier();
+        int userId = admin != null ? admin.getUserHandle().getIdentifier()
+                : caller.getUserId();
+        Slog.i(LOG_TAG, "wipeDataWithReason(" + wipeReasonForUser + "): admin=" + admin + ", user="
+                + userId);
         if (calledByProfileOwnerOnOrgOwnedDevice) {
             // When wipeData is called on the parent instance, it implies wiping the entire device.
             if (calledOnParentInstance) {
@@ -6108,20 +6142,35 @@
                 });
             }
         }
-
-        DevicePolicyEventLogger
+        DevicePolicyEventLogger event = DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.WIPE_DATA_WITH_REASON)
-                .setAdmin(admin.info.getComponent())
                 .setInt(flags)
                 .setStrings(calledOnParentInstance ? CALLED_FROM_PARENT : NOT_CALLED_FROM_PARENT)
-                .write();
+                ;
+        final String adminName;
+        final ComponentName adminComp;
+        if (admin != null) {
+            adminComp = admin.info.getComponent();
+            adminName = adminComp.flattenToShortString();
+            event.setAdmin(adminComp);
+        } else {
+            adminComp = null;
+            adminName = mInjector.getPackageManager().getPackagesForUid(caller.getUid())[0];
+            Slog.i(LOG_TAG, "Logging wipeData() event admin as " + adminName);
+            event.setAdmin(adminName);
+            if (mInjector.userManagerIsHeadlessSystemUserMode()) {
+                // On headless system user mode, the call is meant to factory reset the whole
+                // device, otherwise the caller could simply remove the current user.
+                userId = UserHandle.USER_SYSTEM;
+            }
+        }
+        event.write();
+
         String internalReason = String.format(
                 "DevicePolicyManager.wipeDataWithReason() from %s, organization-owned? %s",
-                admin.info.getComponent().flattenToShortString(),
-                calledByProfileOwnerOnOrgOwnedDevice);
+                adminName, calledByProfileOwnerOnOrgOwnedDevice);
 
-        wipeDataNoLock(
-                admin.info.getComponent(), flags, internalReason, wipeReasonForUser, userId);
+        wipeDataNoLock(adminComp, flags, internalReason, wipeReasonForUser, userId);
     }
 
     private void wipeDataNoLock(ComponentName admin, int flags, String internalReason,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java
index 0b0aee9..22866b4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerServiceShellCommand.java
@@ -24,6 +24,7 @@
 final class DevicePolicyManagerServiceShellCommand extends ShellCommand {
 
     private static final String CMD_IS_SAFE_OPERATION = "is-operation-safe";
+    private static final String CMD_SET_SAFE_OPERATION = "set-operation-safe";
 
     private final DevicePolicyManagerService mService;
 
@@ -48,6 +49,8 @@
             switch (cmd) {
                 case CMD_IS_SAFE_OPERATION:
                     return runIsSafeOperation(pw);
+                case CMD_SET_SAFE_OPERATION:
+                    return runSetSafeOperation(pw);
                 default:
                     return onInvalidCommand(pw, cmd);
             }
@@ -70,6 +73,9 @@
         pw.printf("    Prints this help text.\n\n");
         pw.printf("  %s <OPERATION_ID>\n", CMD_IS_SAFE_OPERATION);
         pw.printf("    Checks if the give operation is safe \n\n");
+        pw.printf("  %s <OPERATION_ID> <true|false>\n", CMD_SET_SAFE_OPERATION);
+        pw.printf("    Emulates the result of the next call to check if the given operation is safe"
+                + " \n\n");
     }
 
     private int runIsSafeOperation(PrintWriter pw) {
@@ -79,4 +85,13 @@
                 safe ? "SAFE" : "UNSAFE");
         return 0;
     }
+
+    private int runSetSafeOperation(PrintWriter pw) {
+        int operation = Integer.parseInt(getNextArgRequired());
+        boolean safe = getNextArg().equals("true");
+        mService.setNextOperationSafety(operation, safe);
+        pw.printf("Next call to check operation %s will return %s\n",
+                DevicePolicyManager.operationToString(operation), safe ? "SAFE" : "UNSAFE");
+        return 0;
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java b/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java
new file mode 100644
index 0000000..b0f8bfb
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OneTimeSafetyChecker.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.devicepolicy;
+
+import static android.app.admin.DevicePolicyManager.operationToString;
+
+import android.app.admin.DevicePolicyManager.DevicePolicyOperation;
+import android.app.admin.DevicePolicySafetyChecker;
+import android.util.Slog;
+
+import java.util.Objects;
+
+//TODO(b/172376923): add unit tests
+
+/**
+ * {@code DevicePolicySafetyChecker} implementation that overrides the real checker for just
+ * one command.
+ *
+ * <p>Used only for debugging and CTS tests.
+ */
+final class OneTimeSafetyChecker implements DevicePolicySafetyChecker {
+
+    private static final String TAG = OneTimeSafetyChecker.class.getSimpleName();
+
+    private final DevicePolicyManagerService mService;
+    private final DevicePolicySafetyChecker mRealSafetyChecker;
+    private final @DevicePolicyOperation int mOperation;
+    private final boolean mSafe;
+
+    OneTimeSafetyChecker(DevicePolicyManagerService service,
+            @DevicePolicyOperation int operation, boolean safe) {
+        mService = Objects.requireNonNull(service);
+        mOperation = operation;
+        mSafe = safe;
+        mRealSafetyChecker = service.getDevicePolicySafetyChecker();
+        Slog.i(TAG, "Saving real DevicePolicySafetyChecker as " + mRealSafetyChecker);
+    }
+
+    @Override
+    public boolean isDevicePolicyOperationSafe(@DevicePolicyOperation int operation) {
+        String name = operationToString(operation);
+        boolean safe = true;
+        if (operation == mOperation) {
+            safe = mSafe;
+        } else {
+            Slog.wtf(TAG, "invalid call to isDevicePolicyOperationSafe(): asked for " + name
+                    + ", should be " + operationToString(mOperation));
+        }
+        Slog.i(TAG, "isDevicePolicyOperationSafe(" + name + "): returning " + safe
+                + " and restoring DevicePolicySafetyChecker to " + mRealSafetyChecker);
+        mService.setDevicePolicySafetyChecker(mRealSafetyChecker);
+        return safe;
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 8ef6982..79a82b8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -43,22 +43,18 @@
 import android.util.Xml;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
 import com.android.server.LocalServices;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import libcore.io.IoUtils;
 
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
 import java.time.LocalDate;
 import java.util.List;
 import java.util.Map;
@@ -558,11 +554,10 @@
         }
         try {
             InputStream input = new AtomicFile(file).openRead();
-            XmlPullParser parser = Xml.newPullParser();
-            parser.setInput(input, StandardCharsets.UTF_8.name());
+            TypedXmlPullParser parser = Xml.resolvePullParser(input);
             int type;
-            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT) {
-                if (type!=XmlPullParser.START_TAG) {
+            while ((type=parser.next()) != TypedXmlPullParser.END_DOCUMENT) {
+                if (type!=TypedXmlPullParser.START_TAG) {
                     continue;
                 }
 
@@ -581,7 +576,7 @@
                     String profileOwnerName = parser.getAttributeValue(null, ATTR_NAME);
                     String profileOwnerComponentStr =
                             parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
-                    int userId = Integer.parseInt(parser.getAttributeValue(null, ATTR_USERID));
+                    int userId = parser.getAttributeInt(null, ATTR_USERID);
                     OwnerInfo profileOwnerInfo = null;
                     if (profileOwnerComponentStr != null) {
                         ComponentName admin = ComponentName.unflattenFromString(
@@ -781,12 +776,12 @@
 
                 int type;
                 int depth = 0;
-                while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+                while ((type = parser.next()) != TypedXmlPullParser.END_DOCUMENT) {
                     switch (type) {
-                        case XmlPullParser.START_TAG:
+                        case TypedXmlPullParser.START_TAG:
                             depth++;
                             break;
-                        case XmlPullParser.END_TAG:
+                        case TypedXmlPullParser.END_TAG:
                             depth--;
                             // fallthrough
                         default:
@@ -813,9 +808,9 @@
             }
         }
 
-        abstract void writeInner(XmlSerializer out) throws IOException;
+        abstract void writeInner(TypedXmlSerializer out) throws IOException;
 
-        abstract boolean readInner(XmlPullParser parser, int depth, String tag);
+        abstract boolean readInner(TypedXmlPullParser parser, int depth, String tag);
     }
 
     private class DeviceOwnerReadWriter extends FileReadWriter {
@@ -831,11 +826,11 @@
         }
 
         @Override
-        void writeInner(XmlSerializer out) throws IOException {
+        void writeInner(TypedXmlSerializer out) throws IOException {
             if (mDeviceOwner != null) {
                 mDeviceOwner.writeToXml(out, TAG_DEVICE_OWNER);
                 out.startTag(null, TAG_DEVICE_OWNER_CONTEXT);
-                out.attribute(null, ATTR_USERID, String.valueOf(mDeviceOwnerUserId));
+                out.attributeInt(null, ATTR_USERID, mDeviceOwnerUserId);
                 out.endTag(null, TAG_DEVICE_OWNER_CONTEXT);
             }
 
@@ -863,7 +858,7 @@
         }
 
         @Override
-        boolean readInner(XmlPullParser parser, int depth, String tag) {
+        boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
             if (depth > 2) {
                 return true; // Ignore
             }
@@ -873,13 +868,8 @@
                     mDeviceOwnerUserId = UserHandle.USER_SYSTEM; // Set default
                     break;
                 case TAG_DEVICE_OWNER_CONTEXT: {
-                    final String userIdString =
-                            parser.getAttributeValue(null, ATTR_USERID);
-                    try {
-                        mDeviceOwnerUserId = Integer.parseInt(userIdString);
-                    } catch (NumberFormatException e) {
-                        Slog.e(TAG, "Error parsing user-id " + userIdString);
-                    }
+                    mDeviceOwnerUserId = parser.getAttributeInt(null, ATTR_USERID,
+                            mDeviceOwnerUserId);
                     break;
                 }
                 case TAG_DEVICE_INITIALIZER:
@@ -927,7 +917,7 @@
         }
 
         @Override
-        void writeInner(XmlSerializer out) throws IOException {
+        void writeInner(TypedXmlSerializer out) throws IOException {
             final OwnerInfo profileOwner = mProfileOwners.get(mUserId);
             if (profileOwner != null) {
                 profileOwner.writeToXml(out, TAG_PROFILE_OWNER);
@@ -935,7 +925,7 @@
         }
 
         @Override
-        boolean readInner(XmlPullParser parser, int depth, String tag) {
+        boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
             if (depth > 2) {
                 return true; // Ignore
             }
@@ -985,7 +975,7 @@
             this.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
         }
 
-        public void writeToXml(XmlSerializer out, String tag) throws IOException {
+        public void writeToXml(TypedXmlSerializer out, String tag) throws IOException {
             out.startTag(null, tag);
             out.attribute(null, ATTR_PACKAGE, packageName);
             if (name != null) {
@@ -994,8 +984,7 @@
             if (admin != null) {
                 out.attribute(null, ATTR_COMPONENT_NAME, admin.flattenToString());
             }
-            out.attribute(null, ATTR_USER_RESTRICTIONS_MIGRATED,
-                    String.valueOf(userRestrictionsMigrated));
+            out.attributeBoolean(null, ATTR_USER_RESTRICTIONS_MIGRATED, userRestrictionsMigrated);
             if (remoteBugreportUri != null) {
                 out.attribute(null, ATTR_REMOTE_BUGREPORT_URI, remoteBugreportUri);
             }
@@ -1003,13 +992,13 @@
                 out.attribute(null, ATTR_REMOTE_BUGREPORT_HASH, remoteBugreportHash);
             }
             if (isOrganizationOwnedDevice) {
-                out.attribute(null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE,
-                        String.valueOf(isOrganizationOwnedDevice));
+                out.attributeBoolean(null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE,
+                        isOrganizationOwnedDevice);
             }
             out.endTag(null, tag);
         }
 
-        public static OwnerInfo readFromXml(XmlPullParser parser) {
+        public static OwnerInfo readFromXml(TypedXmlPullParser parser) {
             final String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
             final String name = parser.getAttributeValue(null, ATTR_NAME);
             final String componentName =
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/TransferOwnershipMetadataManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/TransferOwnershipMetadataManager.java
index 58ece07..289ed36 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/TransferOwnershipMetadataManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/TransferOwnershipMetadataManager.java
@@ -29,18 +29,15 @@
 import android.util.Xml;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.Preconditions;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.nio.charset.StandardCharsets;
 import java.util.Objects;
 
 /**
@@ -106,7 +103,7 @@
         return false;
     }
 
-    private void insertSimpleTag(XmlSerializer serializer, String tagName, String value)
+    private void insertSimpleTag(TypedXmlSerializer serializer, String tagName, String value)
             throws IOException {
         serializer.startTag(null, tagName);
         serializer.text(value);
@@ -132,7 +129,7 @@
         return null;
     }
 
-    private Metadata parseMetadataFile(XmlPullParser parser)
+    private Metadata parseMetadataFile(TypedXmlPullParser parser)
             throws XmlPullParserException, IOException {
         int type;
         final int outerDepth = parser.getDepth();
diff --git a/services/incremental/OWNERS b/services/incremental/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/services/incremental/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/services/people/OWNERS b/services/people/OWNERS
new file mode 100644
index 0000000..7ac9b73
--- /dev/null
+++ b/services/people/OWNERS
@@ -0,0 +1,2 @@
+danningc@google.com
+juliacr@google.com
diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java
index 3e06194..b5e595a 100644
--- a/services/people/java/com/android/server/people/data/DataManager.java
+++ b/services/people/java/com/android/server/people/data/DataManager.java
@@ -554,7 +554,7 @@
             @Nullable List<String> shortcutIds) {
         @ShortcutQuery.QueryFlags int queryFlags = ShortcutQuery.FLAG_MATCH_DYNAMIC
                 | ShortcutQuery.FLAG_MATCH_PINNED | ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER
-                | ShortcutQuery.FLAG_MATCH_CACHED;
+                | ShortcutQuery.FLAG_MATCH_CACHED | ShortcutQuery.FLAG_GET_PERSONS_DATA;
         return mShortcutServiceInternal.getShortcuts(
                 UserHandle.USER_SYSTEM, mContext.getPackageName(),
                 /*changedSince=*/ 0, packageName, shortcutIds, /*locusIds=*/ null,
diff --git a/services/print/OWNERS b/services/print/OWNERS
new file mode 100644
index 0000000..2c7b881
--- /dev/null
+++ b/services/print/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/print/OWNERS
diff --git a/services/restrictions/OWNERS b/services/restrictions/OWNERS
new file mode 100644
index 0000000..95e614c
--- /dev/null
+++ b/services/restrictions/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/restrictions/OWNERS
diff --git a/services/robotests/backup/OWNERS b/services/robotests/backup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/services/robotests/backup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/services/robotests/src/com/android/server/backup/OWNERS b/services/robotests/src/com/android/server/backup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/services/robotests/src/com/android/server/pm/OWNERS b/services/robotests/src/com/android/server/pm/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/services/robotests/src/com/android/server/pm/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/services/startop/OWNERS b/services/startop/OWNERS
new file mode 100644
index 0000000..bd3d829
--- /dev/null
+++ b/services/startop/OWNERS
@@ -0,0 +1 @@
+include /startop/OWNERS
diff --git a/services/tests/PackageManager/OWNERS b/services/tests/PackageManager/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/services/tests/PackageManager/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/services/tests/PackageManagerComponentOverrideTests/OWNERS b/services/tests/PackageManagerComponentOverrideTests/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/services/tests/PackageManagerComponentOverrideTests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 8fc5c08..03083c1 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -15,7 +15,7 @@
 android_test {
     name: "FrameworksMockingServicesTests",
 
-    srcs: ["src/**/*.java"],
+    srcs: ["src/**/*.java", "src/**/*.kt"],
 
     static_libs: [
         "services.core",
@@ -29,6 +29,10 @@
         "mockito-target-extended-minus-junit4",
         "platform-test-annotations",
         "truth-prebuilt",
+        "hamcrest-library",
+        "servicestests-utils-mockito-extended",
+        "mockingservicestests-utils-mockito",
+        "servicestests-core-utils",
         "testables",
         // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows
         "testng",
@@ -54,3 +58,17 @@
         enabled: false,
     },
 }
+
+java_library {
+    name: "mockingservicestests-utils-mockito",
+    srcs: [
+        "utils-mockito/**/*.kt",
+    ],
+    static_libs: [
+        "junit",
+        "mockito-target-extended-minus-junit4",
+    ],
+    libs: [
+        "android.test.runner",
+    ],
+}
\ No newline at end of file
diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml
index 182fe9a..fbde1d2 100644
--- a/services/tests/mockingservicestests/AndroidManifest.xml
+++ b/services/tests/mockingservicestests/AndroidManifest.xml
@@ -27,6 +27,9 @@
     <uses-permission android:name="android.permission.MANAGE_APPOPS"/>
     <uses-permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS"/>
 
+    <!-- needed by MasterClearReceiverTest to display a system dialog -->
+    <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
+
     <application android:testOnly="true"
                  android:debuggable="true">
         <uses-library android:name="android.test.runner" />
diff --git a/services/tests/mockingservicestests/assets/AppOpsUpgradeTest/OWNERS b/services/tests/mockingservicestests/assets/AppOpsUpgradeTest/OWNERS
new file mode 100644
index 0000000..999ea0e
--- /dev/null
+++ b/services/tests/mockingservicestests/assets/AppOpsUpgradeTest/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/permission/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/MasterClearReceiverTest.java b/services/tests/mockingservicestests/src/com/android/server/MasterClearReceiverTest.java
new file mode 100644
index 0000000..f01120e
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/MasterClearReceiverTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2020 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 com.android.server;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.never;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.os.Looper;
+import android.os.RecoverySystem;
+import android.os.storage.StorageManager;
+import android.platform.test.annotations.Presubmit;
+import android.util.Log;
+import android.view.WindowManager;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Run it as {@code FrameworksMockingServicesTests:MasterClearReceiverTest}.
+ */
+@Presubmit
+public final class MasterClearReceiverTest {
+
+    private static final String TAG = MasterClearReceiverTest.class.getSimpleName();
+
+    private MockitoSession mSession;
+
+    // Cannot @Mock context because MasterClearReceiver shows an AlertDialog, which relies
+    // on resources - we'd need to mock them as well.
+    private final Context mContext = new ContextWrapper(
+            InstrumentationRegistry.getInstrumentation().getTargetContext()) {
+
+        @Override
+        public Object getSystemService(String name) {
+            Log.v(TAG, "getSystemService(): " + name);
+            return name.equals(Context.STORAGE_SERVICE) ? mSm : super.getSystemService(name);
+        }
+    };
+
+    private final MasterClearReceiver mReceiver = new MasterClearReceiver();
+
+    // Used to make sure that wipeAdoptableDisks() is called before rebootWipeUserData()
+    private boolean mWipeExternalDataCalled;
+
+    // Uset to block test until rebootWipeUserData() is called, as it might be asynchronous called
+    // in a different thread
+    private final CountDownLatch mRebootWipeUserDataLatch = new CountDownLatch(1);
+
+    @Mock
+    private StorageManager mSm;
+
+    @Mock
+    private WindowManager mWm;
+
+    @Before
+    public void startSession() {
+        mSession = mockitoSession()
+                .initMocks(this)
+                .mockStatic(RecoverySystem.class)
+                .strictness(Strictness.LENIENT)
+                .startMocking();
+    }
+
+    @After
+    public void finishSession() {
+        if (mSession == null) {
+            Log.w(TAG, "finishSession(): no session");
+            return;
+        }
+        mSession.finishMocking();
+    }
+
+    @Test
+    public void testNoExtras() throws Exception {
+        expectNoWipeExternalData();
+        expectRebootWipeUserData();
+
+        Intent intent = new Intent(Intent.ACTION_FACTORY_RESET);
+        mReceiver.onReceive(mContext, intent);
+
+        verifyRebootWipeUserData();
+        verifyNoWipeExternalData();
+    }
+
+    @Test
+    public void testWipeExternalDirectory() throws Exception {
+        expectWipeExternalData();
+        expectRebootWipeUserData();
+
+        Intent intent = new Intent(Intent.ACTION_FACTORY_RESET);
+        intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, true);
+        mReceiver.onReceive(mContext, intent);
+
+        verifyRebootWipeUserData();
+        verifyWipeExternalData();
+    }
+
+    @Test
+    public void testAllExtras() throws Exception {
+        expectWipeExternalData();
+        expectRebootWipeUserData();
+
+        Intent intent = new Intent(Intent.ACTION_FACTORY_RESET);
+        intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, true);
+        intent.putExtra("shutdown", true);
+        intent.putExtra(Intent.EXTRA_REASON, "Self destruct");
+        intent.putExtra(Intent.EXTRA_FORCE_FACTORY_RESET, true);
+        intent.putExtra(Intent.EXTRA_WIPE_ESIMS, true);
+        mReceiver.onReceive(mContext, intent);
+
+        verifyRebootWipeUserData(/* shutdown= */ true, /* reason= */ "Self destruct",
+                /* force= */ true, /* wipeEuicc= */ true);
+        verifyWipeExternalData();
+    }
+
+
+    private void expectNoWipeExternalData() {
+        // This is a trick to simplify how the order of methods are called: as wipeAdoptableDisks()
+        // should be called before rebootWipeUserData(), expectRebootWipeUserData() throws an
+        // exception if it's not called, so this method "emulates" a call when it's not neeeded.
+        //
+        // A more robust solution would be using internal counters for expected and actual mocked
+        // calls, so the expectXXX() methods would increment expected counter and the Answer
+        // implementations would increment the actual counter and check if they match, but that
+        // would be an overkill (and make the test logic more complicated).
+        mWipeExternalDataCalled = true;
+    }
+
+    private void expectRebootWipeUserData() {
+        doAnswer((inv) -> {
+            Log.i(TAG, inv.toString());
+            if (!mWipeExternalDataCalled) {
+                String error = "rebootWipeUserData() called before wipeAdoptableDisks()";
+                Log.e(TAG, error);
+                throw new IllegalStateException(error);
+            }
+            mRebootWipeUserDataLatch.countDown();
+            return null;
+        }).when(() -> RecoverySystem
+                .rebootWipeUserData(any(), anyBoolean(), any(), anyBoolean(), anyBoolean()));
+    }
+
+    private void expectWipeExternalData() {
+        Looper.prepare(); // needed by Dialog
+
+        doAnswer((inv) -> {
+            Log.i(TAG, inv.toString());
+            mWipeExternalDataCalled = true;
+            return null;
+        }).when(mSm).wipeAdoptableDisks();
+    }
+
+    private void verifyRebootWipeUserData() throws Exception  {
+        verifyRebootWipeUserData(/* shutdown= */ false, /* reason= */ null, /* force= */ false,
+                /* wipeEuicc= */ false);
+
+    }
+
+    private void verifyRebootWipeUserData(boolean shutdown, String reason, boolean force,
+            boolean wipeEuicc) throws Exception {
+        boolean called = mRebootWipeUserDataLatch.await(5, TimeUnit.SECONDS);
+        assertWithMessage("rebootWipeUserData not called in 5s").that(called).isTrue();
+
+        verify(()-> RecoverySystem.rebootWipeUserData(same(mContext), eq(shutdown), eq(reason),
+                eq(force), eq(wipeEuicc)));
+    }
+
+    private void verifyWipeExternalData() {
+        verify(mSm).wipeAdoptableDisks();
+    }
+
+    private void verifyNoWipeExternalData() {
+        verify(mSm, never()).wipeAdoptableDisks();
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/OWNERS b/services/tests/mockingservicestests/src/com/android/server/OWNERS
new file mode 100644
index 0000000..e779e21
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/OWNERS
@@ -0,0 +1 @@
+per-file *Alarm* = file:/apex/jobscheduler/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/OWNERS b/services/tests/mockingservicestests/src/com/android/server/alarm/OWNERS
new file mode 100644
index 0000000..6f207fb1
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/OWNERS
@@ -0,0 +1 @@
+include /apex/jobscheduler/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
new file mode 100644
index 0000000..72c0a9e
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/am/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/OWNERS b/services/tests/mockingservicestests/src/com/android/server/appop/OWNERS
new file mode 100644
index 0000000..999ea0e
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/permission/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/blob/OWNERS b/services/tests/mockingservicestests/src/com/android/server/blob/OWNERS
new file mode 100644
index 0000000..65bb6b8
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/blob/OWNERS
@@ -0,0 +1 @@
+include /apex/blobstore/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/OWNERS b/services/tests/mockingservicestests/src/com/android/server/display/OWNERS
new file mode 100644
index 0000000..6ce1ee4
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/display/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/display/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/OWNERS b/services/tests/mockingservicestests/src/com/android/server/job/OWNERS
new file mode 100644
index 0000000..6f207fb1
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/job/OWNERS
@@ -0,0 +1 @@
+include /apex/jobscheduler/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 7f86faa..78bcc13 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -145,7 +145,7 @@
 
         final ConnectivityController controller = new ConnectivityController(mService);
         when(mService.getMaxJobExecutionTimeMs(any()))
-                .thenReturn(JobServiceContext.EXECUTING_TIMESLICE_MILLIS);
+                .thenReturn(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS);
 
         // Slow network is too slow
         assertFalse(controller.isSatisfied(createJobStatus(job), net,
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 8795d77..4f3564d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -35,6 +35,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -42,6 +43,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
@@ -76,6 +78,7 @@
 
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.util.ArrayUtils;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.JobSchedulerService.Constants;
@@ -269,8 +272,9 @@
                 verify(foregroundUids, timeout(2 * SECOND_IN_MILLIS).times(1)).delete(eq(uid));
                 assertFalse(foregroundUids.get(uid));
             }
-        } catch (RemoteException e) {
-            fail("registerUidObserver threw exception: " + e.getMessage());
+            waitForQuietBackground();
+        } catch (Exception e) {
+            fail("exception encountered: " + e.getMessage());
         }
     }
 
@@ -323,6 +327,14 @@
         return createJobStatus(testTag, SOURCE_PACKAGE, CALLING_UID, jobInfo);
     }
 
+    private JobStatus createHpjJobStatus(String testTag, int jobId) {
+        JobInfo jobInfo = new JobInfo.Builder(jobId,
+                new ComponentName(mContext, "TestQuotaHpjJobService"))
+                .setForeground(true)
+                .build();
+        return createJobStatus(testTag, SOURCE_PACKAGE, CALLING_UID, jobInfo);
+    }
+
     private JobStatus createJobStatus(String testTag, String packageName, int callingUid,
             JobInfo jobInfo) {
         JobStatus js = JobStatus.createFromJobInfo(
@@ -356,26 +368,49 @@
         }
     }
 
+    private void waitForQuietBackground() throws Exception {
+        for (int i = 0; i < 5; ++i) {
+            if (!mQuotaController.isActiveBackgroundProcessing()) {
+                break;
+            }
+            Thread.sleep(500);
+        }
+    }
+
     @Test
     public void testSaveTimingSession() {
         assertNull(mQuotaController.getTimingSessions(0, "com.android.test"));
 
-        List<TimingSession> expected = new ArrayList<>();
+        List<TimingSession> expectedRegular = new ArrayList<>();
+        List<TimingSession> expectedHpj = new ArrayList<>();
         TimingSession one = new TimingSession(1, 10, 1);
         TimingSession two = new TimingSession(11, 20, 2);
         TimingSession thr = new TimingSession(21, 30, 3);
+        TimingSession fou = new TimingSession(31, 40, 4);
 
-        mQuotaController.saveTimingSession(0, "com.android.test", one);
-        expected.add(one);
-        assertEquals(expected, mQuotaController.getTimingSessions(0, "com.android.test"));
+        mQuotaController.saveTimingSession(0, "com.android.test", one, false);
+        expectedRegular.add(one);
+        assertEquals(expectedRegular, mQuotaController.getTimingSessions(0, "com.android.test"));
+        assertTrue(
+                ArrayUtils.isEmpty(mQuotaController.getHpjTimingSessions(0, "com.android.test")));
 
-        mQuotaController.saveTimingSession(0, "com.android.test", two);
-        expected.add(two);
-        assertEquals(expected, mQuotaController.getTimingSessions(0, "com.android.test"));
+        mQuotaController.saveTimingSession(0, "com.android.test", two, false);
+        expectedRegular.add(two);
+        assertEquals(expectedRegular, mQuotaController.getTimingSessions(0, "com.android.test"));
+        assertTrue(
+                ArrayUtils.isEmpty(mQuotaController.getHpjTimingSessions(0, "com.android.test")));
 
-        mQuotaController.saveTimingSession(0, "com.android.test", thr);
-        expected.add(thr);
-        assertEquals(expected, mQuotaController.getTimingSessions(0, "com.android.test"));
+        mQuotaController.saveTimingSession(0, "com.android.test", thr, true);
+        expectedHpj.add(thr);
+        assertEquals(expectedRegular, mQuotaController.getTimingSessions(0, "com.android.test"));
+        assertEquals(expectedHpj, mQuotaController.getHpjTimingSessions(0, "com.android.test"));
+
+        mQuotaController.saveTimingSession(0, "com.android.test", fou, false);
+        mQuotaController.saveTimingSession(0, "com.android.test", fou, true);
+        expectedRegular.add(fou);
+        expectedHpj.add(fou);
+        assertEquals(expectedRegular, mQuotaController.getTimingSessions(0, "com.android.test"));
+        assertEquals(expectedHpj, mQuotaController.getHpjTimingSessions(0, "com.android.test"));
     }
 
     @Test
@@ -393,35 +428,48 @@
         // Way past the 24 hour boundary.
         TimingSession fiv = createTimingSession(
                 now - (25 * HOUR_IN_MILLIS), 5 * MINUTE_IN_MILLIS, 4);
-        List<TimingSession> expected = new ArrayList<>();
+        List<TimingSession> expectedRegular = new ArrayList<>();
+        List<TimingSession> expectedHpj = new ArrayList<>();
         // Added in correct (chronological) order.
-        expected.add(fou);
-        expected.add(thr);
-        expected.add(two);
-        expected.add(one);
-        mQuotaController.saveTimingSession(0, "com.android.test", fiv);
-        mQuotaController.saveTimingSession(0, "com.android.test", fou);
-        mQuotaController.saveTimingSession(0, "com.android.test", thr);
-        mQuotaController.saveTimingSession(0, "com.android.test", two);
-        mQuotaController.saveTimingSession(0, "com.android.test", one);
+        expectedRegular.add(fou);
+        expectedRegular.add(thr);
+        expectedRegular.add(two);
+        expectedRegular.add(one);
+        expectedHpj.add(fiv); // HPJ list should be unaffected
+        expectedHpj.add(fou);
+        expectedHpj.add(one);
+        mQuotaController.saveTimingSession(0, "com.android.test", fiv, false);
+        mQuotaController.saveTimingSession(0, "com.android.test", fou, false);
+        mQuotaController.saveTimingSession(0, "com.android.test", thr, false);
+        mQuotaController.saveTimingSession(0, "com.android.test", two, false);
+        mQuotaController.saveTimingSession(0, "com.android.test", one, false);
+        mQuotaController.saveTimingSession(0, "com.android.test", fiv, true);
+        mQuotaController.saveTimingSession(0, "com.android.test", fou, true);
+        mQuotaController.saveTimingSession(0, "com.android.test", one, true);
 
         synchronized (mQuotaController.mLock) {
             mQuotaController.deleteObsoleteSessionsLocked();
         }
 
-        assertEquals(expected, mQuotaController.getTimingSessions(0, "com.android.test"));
+        assertEquals(expectedRegular, mQuotaController.getTimingSessions(0, "com.android.test"));
+        assertEquals(expectedHpj, mQuotaController.getHpjTimingSessions(0, "com.android.test"));
     }
 
     @Test
     public void testOnAppRemovedLocked() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test.remove",
-                createTimingSession(now - (6 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (6 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test.remove",
                 createTimingSession(
-                        now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 6 * MINUTE_IN_MILLIS, 5));
+                        now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 6 * MINUTE_IN_MILLIS, 5),
+                false);
         mQuotaController.saveTimingSession(0, "com.android.test.remove",
-                createTimingSession(now - (HOUR_IN_MILLIS), MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - (HOUR_IN_MILLIS), MINUTE_IN_MILLIS, 1), false);
+        mQuotaController.saveTimingSession(0, "com.android.test.remove",
+                createTimingSession(now - (30 * MINUTE_IN_MILLIS), MINUTE_IN_MILLIS, 1), true);
+        mQuotaController.saveTimingSession(0, "com.android.test.remove",
+                createTimingSession(now - (15 * MINUTE_IN_MILLIS), MINUTE_IN_MILLIS, 1), true);
         // Test that another app isn't affected.
         TimingSession one = createTimingSession(
                 now - 10 * MINUTE_IN_MILLIS, 9 * MINUTE_IN_MILLIS, 3);
@@ -431,8 +479,14 @@
         // Added in correct (chronological) order.
         expected.add(two);
         expected.add(one);
-        mQuotaController.saveTimingSession(0, "com.android.test.stay", two);
-        mQuotaController.saveTimingSession(0, "com.android.test.stay", one);
+        mQuotaController.saveTimingSession(0, "com.android.test.stay", two, false);
+        mQuotaController.saveTimingSession(0, "com.android.test.stay", one, false);
+        mQuotaController.saveTimingSession(0, "com.android.test.stay", one, true);
+
+        assertNotNull(mQuotaController.getTimingSessions(0, "com.android.test.remove"));
+        assertNotNull(mQuotaController.getHpjTimingSessions(0, "com.android.test.remove"));
+        assertNotNull(mQuotaController.getTimingSessions(0, "com.android.test.stay"));
+        assertNotNull(mQuotaController.getHpjTimingSessions(0, "com.android.test.stay"));
 
         ExecutionStats expectedStats = new ExecutionStats();
         expectedStats.expirationTimeElapsed = now + 24 * HOUR_IN_MILLIS;
@@ -445,6 +499,7 @@
             mQuotaController.onAppRemovedLocked("com.android.test.remove", uid);
         }
         assertNull(mQuotaController.getTimingSessions(0, "com.android.test.remove"));
+        assertNull(mQuotaController.getHpjTimingSessions(0, "com.android.test.remove"));
         assertEquals(expected, mQuotaController.getTimingSessions(0, "com.android.test.stay"));
         synchronized (mQuotaController.mLock) {
             assertEquals(expectedStats,
@@ -462,23 +517,36 @@
     public void testOnUserRemovedLocked() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (6 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (6 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
                 createTimingSession(
-                        now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 6 * MINUTE_IN_MILLIS, 5));
+                        now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 6 * MINUTE_IN_MILLIS, 5),
+                false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (HOUR_IN_MILLIS), MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - (HOUR_IN_MILLIS), MINUTE_IN_MILLIS, 1), false);
+        mQuotaController.saveTimingSession(0, "com.android.test",
+                createTimingSession(now - (30 * MINUTE_IN_MILLIS), MINUTE_IN_MILLIS, 1), true);
+        mQuotaController.saveTimingSession(0, "com.android.test",
+                createTimingSession(now - (15 * MINUTE_IN_MILLIS), MINUTE_IN_MILLIS, 1), true);
         // Test that another user isn't affected.
         TimingSession one = createTimingSession(
                 now - 10 * MINUTE_IN_MILLIS, 9 * MINUTE_IN_MILLIS, 3);
         TimingSession two = createTimingSession(
                 now - (70 * MINUTE_IN_MILLIS), 9 * MINUTE_IN_MILLIS, 1);
-        List<TimingSession> expected = new ArrayList<>();
+        List<TimingSession> expectedRegular = new ArrayList<>();
+        List<TimingSession> expectedHpj = new ArrayList<>();
         // Added in correct (chronological) order.
-        expected.add(two);
-        expected.add(one);
-        mQuotaController.saveTimingSession(10, "com.android.test", two);
-        mQuotaController.saveTimingSession(10, "com.android.test", one);
+        expectedRegular.add(two);
+        expectedRegular.add(one);
+        expectedHpj.add(one);
+        mQuotaController.saveTimingSession(10, "com.android.test", two, false);
+        mQuotaController.saveTimingSession(10, "com.android.test", one, false);
+        mQuotaController.saveTimingSession(10, "com.android.test", one, true);
+
+        assertNotNull(mQuotaController.getTimingSessions(0, "com.android.test"));
+        assertNotNull(mQuotaController.getHpjTimingSessions(0, "com.android.test"));
+        assertNotNull(mQuotaController.getTimingSessions(10, "com.android.test"));
+        assertNotNull(mQuotaController.getHpjTimingSessions(10, "com.android.test"));
 
         ExecutionStats expectedStats = new ExecutionStats();
         expectedStats.expirationTimeElapsed = now + 24 * HOUR_IN_MILLIS;
@@ -489,7 +557,11 @@
         synchronized (mQuotaController.mLock) {
             mQuotaController.onUserRemovedLocked(0);
             assertNull(mQuotaController.getTimingSessions(0, "com.android.test"));
-            assertEquals(expected, mQuotaController.getTimingSessions(10, "com.android.test"));
+            assertNull(mQuotaController.getHpjTimingSessions(0, "com.android.test"));
+            assertEquals(expectedRegular,
+                    mQuotaController.getTimingSessions(10, "com.android.test"));
+            assertEquals(expectedHpj,
+                    mQuotaController.getHpjTimingSessions(10, "com.android.test"));
             assertEquals(expectedStats,
                     mQuotaController.getExecutionStatsLocked(0, "com.android.test", RARE_INDEX));
             assertNotEquals(expectedStats,
@@ -502,17 +574,19 @@
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         // Added in chronological order.
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (6 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (6 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
                 createTimingSession(
-                        now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 6 * MINUTE_IN_MILLIS, 5));
+                        now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 6 * MINUTE_IN_MILLIS, 5),
+                false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (HOUR_IN_MILLIS), MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - (HOUR_IN_MILLIS), MINUTE_IN_MILLIS, 1), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
                 createTimingSession(
-                        now - (HOUR_IN_MILLIS - 10 * MINUTE_IN_MILLIS), MINUTE_IN_MILLIS, 1));
+                        now - (HOUR_IN_MILLIS - 10 * MINUTE_IN_MILLIS), MINUTE_IN_MILLIS, 1),
+                false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 5 * MINUTE_IN_MILLIS, 4 * MINUTE_IN_MILLIS, 3));
+                createTimingSession(now - 5 * MINUTE_IN_MILLIS, 4 * MINUTE_IN_MILLIS, 3), false);
 
         // Test an app that hasn't had any activity.
         ExecutionStats expectedStats = new ExecutionStats();
@@ -703,7 +777,6 @@
 
     @Test
     public void testUpdateExecutionStatsLocked_WithTimer() {
-        final long now = sElapsedRealtimeClock.millis();
         setProcessState(ActivityManager.PROCESS_STATE_SERVICE);
 
         ExecutionStats expectedStats = new ExecutionStats();
@@ -741,7 +814,7 @@
         // Add old session. Make sure values are combined correctly.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(sElapsedRealtimeClock.millis() - (6 * HOUR_IN_MILLIS),
-                        10 * MINUTE_IN_MILLIS, 5));
+                        10 * MINUTE_IN_MILLIS, 5), false);
         expectedStats.sessionCountInWindow = 1;
 
         expectedStats.expirationTimeElapsed = sElapsedRealtimeClock.millis() + 18 * HOUR_IN_MILLIS;
@@ -794,13 +867,13 @@
     public void testGetExecutionStatsLocked_Values() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (23 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (23 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (7 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (7 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (2 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (2 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (6 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (6 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
 
         ExecutionStats expectedStats = new ExecutionStats();
 
@@ -882,7 +955,7 @@
         advanceElapsedClock(3 * MINUTE_IN_MILLIS);
 
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 2));
+                createTimingSession(MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 2), false);
 
         ExecutionStats expectedStats = new ExecutionStats();
 
@@ -942,24 +1015,24 @@
             mQuotaController.saveTimingSession(0, "com.android.test",
                     createTimingSession(
                             JobSchedulerService.sElapsedRealtimeClock.millis(),
-                            5 * MINUTE_IN_MILLIS, 5));
+                            5 * MINUTE_IN_MILLIS, 5), false);
             advanceElapsedClock(5 * MINUTE_IN_MILLIS);
             advanceElapsedClock(5 * MINUTE_IN_MILLIS);
             for (int j = 0; j < 5; ++j) {
                 mQuotaController.saveTimingSession(0, "com.android.test",
                         createTimingSession(
                                 JobSchedulerService.sElapsedRealtimeClock.millis(),
-                                MINUTE_IN_MILLIS, 2));
+                                MINUTE_IN_MILLIS, 2), false);
                 advanceElapsedClock(MINUTE_IN_MILLIS);
                 advanceElapsedClock(54 * SECOND_IN_MILLIS);
                 mQuotaController.saveTimingSession(0, "com.android.test",
                         createTimingSession(
-                                JobSchedulerService.sElapsedRealtimeClock.millis(), 500, 1));
+                                JobSchedulerService.sElapsedRealtimeClock.millis(), 500, 1), false);
                 advanceElapsedClock(500);
                 advanceElapsedClock(400);
                 mQuotaController.saveTimingSession(0, "com.android.test",
                         createTimingSession(
-                                JobSchedulerService.sElapsedRealtimeClock.millis(), 100, 1));
+                                JobSchedulerService.sElapsedRealtimeClock.millis(), 100, 1), false);
                 advanceElapsedClock(100);
                 advanceElapsedClock(5 * SECOND_IN_MILLIS);
             }
@@ -1095,13 +1168,13 @@
 
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (23 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (23 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (7 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (7 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (2 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (2 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (6 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (6 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
         final ExecutionStats originalStatsActive;
         final ExecutionStats originalStatsWorking;
         final ExecutionStats originalStatsFrequent;
@@ -1195,20 +1268,20 @@
     public void testGetMaxJobExecutionTimeLocked() {
         mQuotaController.saveTimingSession(0, SOURCE_PACKAGE,
                 createTimingSession(sElapsedRealtimeClock.millis() - (6 * MINUTE_IN_MILLIS),
-                        3 * MINUTE_IN_MILLIS, 5));
+                        3 * MINUTE_IN_MILLIS, 5), false);
         JobStatus job = createJobStatus("testGetMaxJobExecutionTimeLocked", 0);
         job.setStandbyBucket(RARE_INDEX);
 
         setCharging();
         synchronized (mQuotaController.mLock) {
-            assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS,
+            assertEquals(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS,
                     mQuotaController.getMaxJobExecutionTimeMsLocked((job)));
         }
 
         setDischarging();
         setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
         synchronized (mQuotaController.mLock) {
-            assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS,
+            assertEquals(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS,
                     mQuotaController.getMaxJobExecutionTimeMsLocked((job)));
         }
 
@@ -1220,7 +1293,7 @@
         }
         setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
         synchronized (mQuotaController.mLock) {
-            assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS,
+            assertEquals(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS,
                     mQuotaController.getMaxJobExecutionTimeMsLocked((job)));
             mQuotaController.maybeStopTrackingJobLocked(job, null, false);
         }
@@ -1242,17 +1315,17 @@
         // Close to RARE boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - (24 * HOUR_IN_MILLIS - 30 * SECOND_IN_MILLIS),
-                        30 * SECOND_IN_MILLIS, 5));
+                        30 * SECOND_IN_MILLIS, 5), false);
         // Far away from FREQUENT boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (7 * HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (7 * HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
         // Overlap WORKING_SET boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS),
-                        3 * MINUTE_IN_MILLIS, 5));
+                        3 * MINUTE_IN_MILLIS, 5), false);
         // Close to ACTIVE boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (9 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (9 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
 
         setStandbyBucket(RARE_INDEX);
         synchronized (mQuotaController.mLock) {
@@ -1306,7 +1379,8 @@
         // Overlap boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
-                        now - (24 * HOUR_IN_MILLIS + 8 * MINUTE_IN_MILLIS), 4 * HOUR_IN_MILLIS, 5));
+                        now - (24 * HOUR_IN_MILLIS + 8 * MINUTE_IN_MILLIS), 4 * HOUR_IN_MILLIS, 5),
+                false);
 
         setStandbyBucket(WORKING_INDEX);
         synchronized (mQuotaController.mLock) {
@@ -1323,7 +1397,7 @@
         // Close to boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - (24 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS),
-                        4 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS, 5));
+                        4 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS, 5), false);
 
         setStandbyBucket(WORKING_INDEX);
         synchronized (mQuotaController.mLock) {
@@ -1339,7 +1413,8 @@
         // Far from boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
-                        now - (20 * HOUR_IN_MILLIS), 4 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS, 5));
+                        now - (20 * HOUR_IN_MILLIS), 4 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS, 5),
+                false);
 
         setStandbyBucket(WORKING_INDEX);
         synchronized (mQuotaController.mLock) {
@@ -1366,10 +1441,11 @@
                 createTimingSession(
                         now - (24 * HOUR_IN_MILLIS + 11 * MINUTE_IN_MILLIS),
                         4 * HOUR_IN_MILLIS,
-                        5));
+                        5), false);
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
-                        now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                        now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5),
+                false);
 
         synchronized (mQuotaController.mLock) {
             // Both max and bucket time have 8 minutes left.
@@ -1387,15 +1463,17 @@
         // Overlap boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
-                        now - (24 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 2 * MINUTE_IN_MILLIS, 5));
+                        now - (24 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 2 * MINUTE_IN_MILLIS, 5),
+                false);
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
                         now - (20 * HOUR_IN_MILLIS),
                         3 * HOUR_IN_MILLIS + 48 * MINUTE_IN_MILLIS,
-                        5));
+                        5), false);
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
-                        now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                        now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5),
+                false);
 
         synchronized (mQuotaController.mLock) {
             // Both max and bucket time have 8 minutes left.
@@ -1430,9 +1508,9 @@
         setDischarging();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.incrementJobCountLocked(0, "com.android.test", 5);
             assertTrue(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX));
@@ -1445,9 +1523,10 @@
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         final int jobCount = mQcConstants.MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW;
         mQuotaController.saveTimingSession(0, "com.android.test.spam",
-                createTimingSession(now - (HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 25));
+                createTimingSession(now - (HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 25), false);
         mQuotaController.saveTimingSession(0, "com.android.test.spam",
-                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, jobCount));
+                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, jobCount),
+                false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.incrementJobCountLocked(0, "com.android.test.spam", jobCount);
             assertFalse(mQuotaController.isWithinQuotaLocked(
@@ -1455,9 +1534,10 @@
         }
 
         mQuotaController.saveTimingSession(0, "com.android.test.frequent",
-                createTimingSession(now - (2 * HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 2000));
+                createTimingSession(now - (2 * HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 2000),
+                false);
         mQuotaController.saveTimingSession(0, "com.android.test.frequent",
-                createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 500));
+                createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 500), false);
         synchronized (mQuotaController.mLock) {
             assertFalse(mQuotaController.isWithinQuotaLocked(
                     0, "com.android.test.frequent", FREQUENT_INDEX));
@@ -1469,11 +1549,11 @@
         setDischarging();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (30 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (30 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 4 * MINUTE_IN_MILLIS, 5));
+                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 4 * MINUTE_IN_MILLIS, 5), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.incrementJobCountLocked(0, "com.android.test", 5);
             assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX));
@@ -1486,9 +1566,10 @@
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         final int jobCount = mQcConstants.MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW;
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 25));
+                createTimingSession(now - (HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 25), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, jobCount));
+                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, jobCount),
+                false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.incrementJobCountLocked(0, "com.android.test", jobCount);
             assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX));
@@ -1639,7 +1720,7 @@
         for (int i = 0; i < 7; ++i) {
             mQuotaController.saveTimingSession(0, "com.android.test",
                     createTimingSession(now - ((10 - i) * MINUTE_IN_MILLIS), 30 * SECOND_IN_MILLIS,
-                            2));
+                            2), false);
 
             synchronized (mQuotaController.mLock) {
                 mQuotaController.incrementJobCountLocked(0, "com.android.test", 2);
@@ -1673,7 +1754,7 @@
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         final long end = now - (6 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                new TimingSession(now - 6 * HOUR_IN_MILLIS, end, 1));
+                new TimingSession(now - 6 * HOUR_IN_MILLIS, end, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleCleanupAlarmLocked();
         }
@@ -1682,9 +1763,9 @@
 
         // Test with new (more recent) timing sessions saved. AlarmManger shouldn't be called again.
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 3 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - 3 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - HOUR_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - HOUR_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleCleanupAlarmLocked();
         }
@@ -1715,11 +1796,11 @@
         final long expectedAlarmTime =
                 (now - 18 * HOUR_IN_MILLIS) + 24 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - 18 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1));
+                createTimingSession(now - 18 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1), false);
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - 12 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1));
+                createTimingSession(now - 12 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1), false);
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - 7 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1));
+                createTimingSession(now - 7 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(
                     SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket);
@@ -1727,7 +1808,7 @@
         verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
 
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - 2 * HOUR_IN_MILLIS, 55 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - 2 * HOUR_IN_MILLIS, 55 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(
                     SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket);
@@ -1772,7 +1853,7 @@
         // Test with timing sessions out of window.
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 10 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - 10 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1784,7 +1865,7 @@
         final long expectedAlarmTime =
                 end - MINUTE_IN_MILLIS + 2 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.saveTimingSession(0, "com.android.test",
-                new TimingSession(now - 2 * HOUR_IN_MILLIS, end, 1));
+                new TimingSession(now - 2 * HOUR_IN_MILLIS, end, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1792,9 +1873,9 @@
 
         // Add some more sessions, but still in quota.
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (50 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - (50 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1802,7 +1883,7 @@
 
         // Test when out of quota.
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 30 * MINUTE_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - 30 * MINUTE_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1836,7 +1917,7 @@
         // Test with timing sessions out of window.
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 10 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - 10 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1846,7 +1927,7 @@
         final long start = now - (6 * HOUR_IN_MILLIS);
         final long expectedAlarmTime = start + 8 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1854,9 +1935,9 @@
 
         // Add some more sessions, but still in quota.
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 3 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - 3 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - HOUR_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - HOUR_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1864,7 +1945,7 @@
 
         // Test when out of quota.
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1901,7 +1982,7 @@
         // Test with timing sessions out of window.
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 25 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - 25 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1915,7 +1996,7 @@
                 start + MINUTE_IN_MILLIS + 24 * HOUR_IN_MILLIS
                         + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1923,9 +2004,9 @@
 
         // Add some more sessions, but still in quota.
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 3 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - 3 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, 1), false);
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - HOUR_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - HOUR_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1933,7 +2014,7 @@
 
         // Test when out of quota.
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - HOUR_IN_MILLIS, 2 * MINUTE_IN_MILLIS, 1));
+                createTimingSession(now - HOUR_IN_MILLIS, 2 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
@@ -1960,17 +2041,17 @@
 
         // Affects rare bucket
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 12 * HOUR_IN_MILLIS, 9 * MINUTE_IN_MILLIS, 3));
+                createTimingSession(now - 12 * HOUR_IN_MILLIS, 9 * MINUTE_IN_MILLIS, 3), false);
         // Affects frequent and rare buckets
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 4 * HOUR_IN_MILLIS, 4 * MINUTE_IN_MILLIS, 3));
+                createTimingSession(now - 4 * HOUR_IN_MILLIS, 4 * MINUTE_IN_MILLIS, 3), false);
         // Affects working, frequent, and rare buckets
         final long outOfQuotaTime = now - HOUR_IN_MILLIS;
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(outOfQuotaTime, 7 * MINUTE_IN_MILLIS, 10));
+                createTimingSession(outOfQuotaTime, 7 * MINUTE_IN_MILLIS, 10), false);
         // Affects all buckets
         mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - 5 * MINUTE_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 3));
+                createTimingSession(now - 5 * MINUTE_IN_MILLIS, 3 * MINUTE_IN_MILLIS, 3), false);
 
         InOrder inOrder = inOrder(mAlarmManager);
 
@@ -2143,9 +2224,9 @@
         // the quota.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - (2 * HOUR_IN_MILLIS + 3 * MINUTE_IN_MILLIS),
-                        3 * MINUTE_IN_MILLIS + contributionMs, 3));
+                        3 * MINUTE_IN_MILLIS + contributionMs, 3), false);
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - HOUR_IN_MILLIS, remainingTimeMs, 2));
+                createTimingSession(now - HOUR_IN_MILLIS, remainingTimeMs, 2), false);
         // Expected alarm time should be when the app will have QUOTA_BUFFER_MS time of quota, which
         // is 2 hours + (QUOTA_BUFFER_MS - contributionMs) after the start of the second session.
         final long expectedAlarmTime = now - HOUR_IN_MILLIS + 2 * HOUR_IN_MILLIS
@@ -2175,9 +2256,9 @@
         // the quota.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - (24 * HOUR_IN_MILLIS + 3 * MINUTE_IN_MILLIS),
-                        3 * MINUTE_IN_MILLIS + contributionMs, 3));
+                        3 * MINUTE_IN_MILLIS + contributionMs, 3), false);
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - 20 * HOUR_IN_MILLIS, remainingTimeMs, 300));
+                createTimingSession(now - 20 * HOUR_IN_MILLIS, remainingTimeMs, 300), false);
         // Expected alarm time should be when the app will have QUOTA_BUFFER_MS time of quota, which
         // is 24 hours + (QUOTA_BUFFER_MS - contributionMs) after the start of the second session.
         final long expectedAlarmTime = now - 20 * HOUR_IN_MILLIS
@@ -2217,6 +2298,16 @@
         setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS,
                 10 * SECOND_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_MIN_QUOTA_CHECK_DELAY_MS, 7 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_ACTIVE_MS, 2 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_WORKING_MS, 90 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_FREQUENT_MS, 1 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RARE_MS, 30 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RESTRICTED_MS, 27 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_WINDOW_SIZE_MS, 12 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS, 10 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_REWARD_TOP_APP_MS, 87 * SECOND_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_REWARD_INTERACTION_MS, 86 * SECOND_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_REWARD_NOTIFICATION_SEEN_MS, 85 * SECOND_IN_MILLIS);
 
         assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
         assertEquals(2 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs());
@@ -2244,6 +2335,16 @@
         assertEquals(10 * SECOND_IN_MILLIS,
                 mQuotaController.getTimingSessionCoalescingDurationMs());
         assertEquals(7 * MINUTE_IN_MILLIS, mQuotaController.getMinQuotaCheckDelayMs());
+        assertEquals(2 * HOUR_IN_MILLIS, mQuotaController.getHpjLimitsMs()[ACTIVE_INDEX]);
+        assertEquals(90 * MINUTE_IN_MILLIS, mQuotaController.getHpjLimitsMs()[WORKING_INDEX]);
+        assertEquals(HOUR_IN_MILLIS, mQuotaController.getHpjLimitsMs()[FREQUENT_INDEX]);
+        assertEquals(30 * MINUTE_IN_MILLIS, mQuotaController.getHpjLimitsMs()[RARE_INDEX]);
+        assertEquals(27 * MINUTE_IN_MILLIS, mQuotaController.getHpjLimitsMs()[RESTRICTED_INDEX]);
+        assertEquals(12 * HOUR_IN_MILLIS, mQuotaController.getHpjLimitWindowSizeMs());
+        assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getHpjTopAppTimeChunkSizeMs());
+        assertEquals(87 * SECOND_IN_MILLIS, mQuotaController.getHpjRewardTopAppMs());
+        assertEquals(86 * SECOND_IN_MILLIS, mQuotaController.getHpjRewardInteractionMs());
+        assertEquals(85 * SECOND_IN_MILLIS, mQuotaController.getHpjRewardNotificationSeenMs());
     }
 
     @Test
@@ -2272,6 +2373,16 @@
         setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW, 0);
         setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, -1);
         setDeviceConfigLong(QcConstants.KEY_MIN_QUOTA_CHECK_DELAY_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_ACTIVE_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_WORKING_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_FREQUENT_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RARE_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RESTRICTED_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_WINDOW_SIZE_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_REWARD_TOP_APP_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_REWARD_INTERACTION_MS, -1);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_REWARD_NOTIFICATION_SEEN_MS, -1);
 
         assertEquals(MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
         assertEquals(0, mQuotaController.getInQuotaBufferMs());
@@ -2296,6 +2407,16 @@
         assertEquals(0, mQuotaController.getBucketMaxSessionCounts()[RESTRICTED_INDEX]);
         assertEquals(0, mQuotaController.getTimingSessionCoalescingDurationMs());
         assertEquals(0, mQuotaController.getMinQuotaCheckDelayMs());
+        assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getHpjLimitsMs()[ACTIVE_INDEX]);
+        assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getHpjLimitsMs()[WORKING_INDEX]);
+        assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getHpjLimitsMs()[FREQUENT_INDEX]);
+        assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getHpjLimitsMs()[RARE_INDEX]);
+        assertEquals(0, mQuotaController.getHpjLimitsMs()[RESTRICTED_INDEX]);
+        assertEquals(HOUR_IN_MILLIS, mQuotaController.getHpjLimitWindowSizeMs());
+        assertEquals(1, mQuotaController.getHpjTopAppTimeChunkSizeMs());
+        assertEquals(10 * SECOND_IN_MILLIS, mQuotaController.getHpjRewardTopAppMs());
+        assertEquals(5 * SECOND_IN_MILLIS, mQuotaController.getHpjRewardInteractionMs());
+        assertEquals(0, mQuotaController.getHpjRewardNotificationSeenMs());
 
         // Invalid configurations.
         // In_QUOTA_BUFFER should never be greater than ALLOWED_TIME_PER_PERIOD
@@ -2318,6 +2439,16 @@
         setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS,
                 25 * HOUR_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_MIN_QUOTA_CHECK_DELAY_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_ACTIVE_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_WORKING_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_FREQUENT_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RARE_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RESTRICTED_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_WINDOW_SIZE_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_TOP_APP_TIME_CHUNK_SIZE_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_REWARD_TOP_APP_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_REWARD_INTERACTION_MS, 25 * HOUR_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_REWARD_NOTIFICATION_SEEN_MS, 25 * HOUR_IN_MILLIS);
 
         assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
         assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs());
@@ -2332,6 +2463,16 @@
         assertEquals(15 * MINUTE_IN_MILLIS,
                 mQuotaController.getTimingSessionCoalescingDurationMs());
         assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getMinQuotaCheckDelayMs());
+        assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getHpjLimitsMs()[ACTIVE_INDEX]);
+        assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getHpjLimitsMs()[WORKING_INDEX]);
+        assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getHpjLimitsMs()[FREQUENT_INDEX]);
+        assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getHpjLimitsMs()[RARE_INDEX]);
+        assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getHpjLimitsMs()[RESTRICTED_INDEX]);
+        assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getHpjLimitWindowSizeMs());
+        assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getHpjTopAppTimeChunkSizeMs());
+        assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getHpjRewardTopAppMs());
+        assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getHpjRewardInteractionMs());
+        assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getHpjRewardNotificationSeenMs());
     }
 
     /** Tests that TimingSessions aren't saved when the device is charging. */
@@ -2937,7 +3078,7 @@
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
                         JobSchedulerService.sElapsedRealtimeClock.millis() - HOUR_IN_MILLIS,
-                        10 * MINUTE_IN_MILLIS - remainingTimeMs, 1));
+                        10 * MINUTE_IN_MILLIS - remainingTimeMs, 1), false);
 
         InOrder inOrder = inOrder(mJobSchedulerService);
 
@@ -3031,7 +3172,7 @@
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
                         JobSchedulerService.sElapsedRealtimeClock.millis() - HOUR_IN_MILLIS,
-                        10 * MINUTE_IN_MILLIS - remainingTimeMs, 1));
+                        10 * MINUTE_IN_MILLIS - remainingTimeMs, 1), false);
 
         // Start the job.
         synchronized (mQuotaController.mLock) {
@@ -3069,10 +3210,10 @@
         // window, so as the package "reaches its quota" it will have more to keep running.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - 2 * HOUR_IN_MILLIS,
-                        10 * SECOND_IN_MILLIS - remainingTimeMs, 1));
+                        10 * SECOND_IN_MILLIS - remainingTimeMs, 1), false);
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - HOUR_IN_MILLIS,
-                        9 * MINUTE_IN_MILLIS + 50 * SECOND_IN_MILLIS, 1));
+                        9 * MINUTE_IN_MILLIS + 50 * SECOND_IN_MILLIS, 1), false);
 
         synchronized (mQuotaController.mLock) {
             assertEquals(remainingTimeMs,
@@ -3098,7 +3239,9 @@
         }
         // Handler is told to check when the quota will be consumed, not when the initial
         // remaining time is over.
-        verify(handler, atLeast(1)).sendMessageDelayed(any(), eq(10 * SECOND_IN_MILLIS));
+        verify(handler, atLeast(1)).sendMessageDelayed(
+                argThat(msg -> msg.what == QuotaController.MSG_REACHED_QUOTA),
+                eq(10 * SECOND_IN_MILLIS));
         verify(handler, never()).sendMessageDelayed(any(), eq(remainingTimeMs));
 
         // After 10 seconds, the job should finally be out of quota.
@@ -3242,4 +3385,1337 @@
         verify(mAlarmManager, times(1))
                 .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
     }
+
+    @Test
+    public void testGetRemainingHpjExecutionTimeLocked_NoHistory() {
+        final long[] limits = mQuotaController.getHpjLimitsMs();
+        for (int i = 0; i < limits.length; ++i) {
+            setStandbyBucket(i);
+            assertEquals("Got wrong remaining HPJ execution time for bucket #" + i,
+                    limits[i],
+                    mQuotaController.getRemainingHpjExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    @Test
+    public void testGetRemainingHpjExecutionTimeLocked_AllSessionsWithinWindow() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - mQcConstants.HPJ_WINDOW_SIZE_MS, MINUTE_IN_MILLIS, 5),
+                true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 40 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 20 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 10 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+
+        final long[] limits = mQuotaController.getHpjLimitsMs();
+        for (int i = 0; i < limits.length; ++i) {
+            setStandbyBucket(i);
+            assertEquals("Got wrong remaining HPJ execution time for bucket #" + i,
+                    i == NEVER_INDEX ? 0 : (limits[i] - 5 * MINUTE_IN_MILLIS),
+                    mQuotaController.getRemainingHpjExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    @Test
+    public void testGetRemainingHpjExecutionTimeLocked_OneSessionStraddlesEdge() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        final long[] limits = mQuotaController.getHpjLimitsMs();
+        for (int i = 0; i < limits.length; ++i) {
+            synchronized (mQuotaController.mLock) {
+                mQuotaController.onUserRemovedLocked(SOURCE_USER_ID);
+            }
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - (mQcConstants.HPJ_WINDOW_SIZE_MS + MINUTE_IN_MILLIS),
+                            2 * MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - 40 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - 30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - 20 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - 10 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+
+            setStandbyBucket(i);
+            assertEquals("Got wrong remaining HPJ execution time for bucket #" + i,
+                    i == NEVER_INDEX ? 0 : (limits[i] - 5 * MINUTE_IN_MILLIS),
+                    mQuotaController.getRemainingHpjExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    @Test
+    public void testGetRemainingHpjExecutionTimeLocked_WithStaleSessions() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+
+        final long[] limits = mQuotaController.getHpjLimitsMs();
+        for (int i = 0; i < limits.length; ++i) {
+            synchronized (mQuotaController.mLock) {
+                mQuotaController.onUserRemovedLocked(SOURCE_USER_ID);
+            }
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(
+                            now - (mQcConstants.HPJ_WINDOW_SIZE_MS + 10 * MINUTE_IN_MILLIS),
+                            2 * MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(
+                            now - (mQcConstants.HPJ_WINDOW_SIZE_MS + 5 * MINUTE_IN_MILLIS),
+                            MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - (mQcConstants.HPJ_WINDOW_SIZE_MS + MINUTE_IN_MILLIS),
+                            2 * MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - 40 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - 30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - 20 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+            mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                    createTimingSession(now - 10 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+
+            setStandbyBucket(i);
+            assertEquals("Got wrong remaining HPJ execution time for bucket #" + i,
+                    i == NEVER_INDEX ? 0 : (limits[i] - 5 * MINUTE_IN_MILLIS),
+                    mQuotaController.getRemainingHpjExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    /**
+     * Tests that getRemainingHpjExecutionTimeLocked returns the correct stats soon after device
+     * startup.
+     */
+    @Test
+    public void testGetRemainingHpjExecutionTimeLocked_BeginningOfTime() {
+        // Set time to 3 minutes after boot.
+        advanceElapsedClock(-JobSchedulerService.sElapsedRealtimeClock.millis());
+        advanceElapsedClock(3 * MINUTE_IN_MILLIS);
+
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 2), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(150 * SECOND_IN_MILLIS, 15 * SECOND_IN_MILLIS, 5), true);
+
+        final long[] limits = mQuotaController.getHpjLimitsMs();
+        for (int i = 0; i < limits.length; ++i) {
+            setStandbyBucket(i);
+            assertEquals("Got wrong remaining HPJ execution time for bucket #" + i,
+                    i == NEVER_INDEX ? 0 : (limits[i] - 75 * SECOND_IN_MILLIS),
+                    mQuotaController.getRemainingHpjExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    @Test
+    public void testGetTimeUntilHpjQuotaConsumedLocked_NoHistory() {
+        final long[] limits = mQuotaController.getHpjLimitsMs();
+        for (int i = 0; i < limits.length; ++i) {
+            setStandbyBucket(i);
+            assertEquals("Got wrong time until HPJ quota consumed for bucket #" + i,
+                    limits[i], mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    @Test
+    public void testGetTimeUntilHpjQuotaConsumedLocked_AllSessionsWithinWindow() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 40 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 20 * MINUTE_IN_MILLIS, 2 * MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 10 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+
+        final long[] limits = mQuotaController.getHpjLimitsMs();
+        for (int i = 0; i < limits.length; ++i) {
+            setStandbyBucket(i);
+            assertEquals("Got wrong time until HPJ quota consumed for bucket #" + i,
+                    i == NEVER_INDEX ? 0 : (limits[i] - 5 * MINUTE_IN_MILLIS),
+                    mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    @Test
+    public void testGetTimeUntilHpjQuotaConsumedLocked_SessionsAtEdgeOfWindow() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - mQcConstants.HPJ_WINDOW_SIZE_MS, MINUTE_IN_MILLIS, 5),
+                true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (mQcConstants.HPJ_WINDOW_SIZE_MS - 2 * MINUTE_IN_MILLIS),
+                        MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (mQcConstants.HPJ_WINDOW_SIZE_MS - 10 * MINUTE_IN_MILLIS),
+                        MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 20 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 10 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_ACTIVE_MS, 30 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_WORKING_MS, 20 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_FREQUENT_MS, 15 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RARE_MS, 10 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RESTRICTED_MS, 5 * MINUTE_IN_MILLIS);
+
+        setStandbyBucket(ACTIVE_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + ACTIVE_INDEX,
+                28 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(WORKING_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + WORKING_INDEX,
+                18 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(FREQUENT_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + FREQUENT_INDEX,
+                13 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(RARE_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + RARE_INDEX,
+                7 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(RESTRICTED_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + RESTRICTED_INDEX,
+                MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    @Test
+    public void testGetTimeUntilHpjQuotaConsumedLocked_OneSessionStraddlesEdge() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (mQcConstants.HPJ_WINDOW_SIZE_MS + MINUTE_IN_MILLIS),
+                        2 * MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 40 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 20 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 10 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5), true);
+
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_ACTIVE_MS, 30 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_WORKING_MS, 20 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_FREQUENT_MS, 15 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RARE_MS, 10 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RESTRICTED_MS, 5 * MINUTE_IN_MILLIS);
+
+        setStandbyBucket(ACTIVE_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + ACTIVE_INDEX,
+                26 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(WORKING_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + WORKING_INDEX,
+                16 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(FREQUENT_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + FREQUENT_INDEX,
+                11 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(RARE_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + RARE_INDEX,
+                6 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(RESTRICTED_INDEX);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + RESTRICTED_INDEX,
+                MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    @Test
+    public void testGetTimeUntilHpjQuotaConsumedLocked_WithStaleSessions() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+
+        List<TimingSession> timingSessions = new ArrayList<>();
+        timingSessions.add(
+                createTimingSession(now - (mQcConstants.HPJ_WINDOW_SIZE_MS + 10 * MINUTE_IN_MILLIS),
+                        2 * MINUTE_IN_MILLIS, 5));
+        timingSessions.add(
+                createTimingSession(now - (mQcConstants.HPJ_WINDOW_SIZE_MS + 5 * MINUTE_IN_MILLIS),
+                        MINUTE_IN_MILLIS, 5));
+        timingSessions.add(
+                createTimingSession(now - (mQcConstants.HPJ_WINDOW_SIZE_MS + MINUTE_IN_MILLIS),
+                        2 * MINUTE_IN_MILLIS, 5));
+        timingSessions.add(
+                createTimingSession(now - 40 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5));
+        timingSessions.add(
+                createTimingSession(now - 30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5));
+        timingSessions.add(
+                createTimingSession(now - 20 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5));
+        timingSessions.add(
+                createTimingSession(now - 10 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 5));
+
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_ACTIVE_MS, 30 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_WORKING_MS, 20 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_FREQUENT_MS, 15 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RARE_MS, 10 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RESTRICTED_MS, 5 * MINUTE_IN_MILLIS);
+
+        runTestGetTimeUntilHpjQuotaConsumedLocked(
+                timingSessions, ACTIVE_INDEX, 26 * MINUTE_IN_MILLIS);
+        runTestGetTimeUntilHpjQuotaConsumedLocked(
+                timingSessions, WORKING_INDEX, 16 * MINUTE_IN_MILLIS);
+        runTestGetTimeUntilHpjQuotaConsumedLocked(
+                timingSessions, FREQUENT_INDEX, 11 * MINUTE_IN_MILLIS);
+        runTestGetTimeUntilHpjQuotaConsumedLocked(timingSessions, RARE_INDEX, 6 * MINUTE_IN_MILLIS);
+        runTestGetTimeUntilHpjQuotaConsumedLocked(
+                timingSessions, RESTRICTED_INDEX, MINUTE_IN_MILLIS);
+    }
+
+    /**
+     * Tests that getTimeUntilHpjQuotaConsumedLocked returns the correct stats soon after device
+     * startup.
+     */
+    @Test
+    public void testGetTimeUntilHpjQuotaConsumedLocked_BeginningOfTime() {
+        // Set time to 3 minutes after boot.
+        advanceElapsedClock(-JobSchedulerService.sElapsedRealtimeClock.millis());
+        advanceElapsedClock(3 * MINUTE_IN_MILLIS);
+
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 2), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(150 * SECOND_IN_MILLIS, 15 * SECOND_IN_MILLIS, 5), true);
+
+        final long[] limits = mQuotaController.getHpjLimitsMs();
+        for (int i = 0; i < limits.length; ++i) {
+            setStandbyBucket(i);
+            assertEquals("Got wrong time until HPJ quota consumed for bucket #" + i,
+                    limits[i], // All existing sessions will phase out
+                    mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    private void runTestGetTimeUntilHpjQuotaConsumedLocked(
+            List<TimingSession> timingSessions, int bucketIndex, long expectedValue) {
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.onUserRemovedLocked(SOURCE_USER_ID);
+        }
+        if (timingSessions != null) {
+            for (TimingSession session : timingSessions) {
+                mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, session, true);
+            }
+        }
+
+        setStandbyBucket(bucketIndex);
+        assertEquals("Got wrong time until HPJ quota consumed for bucket #" + bucketIndex,
+                expectedValue,
+                mQuotaController.getTimeUntilHpjQuotaConsumedLocked(
+                        SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    @Test
+    public void testMaybeScheduleStartAlarmLocked_Hpj() {
+        // saveTimingSession calls maybeScheduleCleanupAlarmLocked which interferes with these tests
+        // because it schedules an alarm too. Prevent it from doing so.
+        spyOn(mQuotaController);
+        doNothing().when(mQuotaController).maybeScheduleCleanupAlarmLocked();
+
+        final int standbyBucket = WORKING_INDEX;
+        setStandbyBucket(standbyBucket);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_WORKING_MS, 20 * MINUTE_IN_MILLIS);
+
+        InOrder inOrder = inOrder(mAlarmManager);
+
+        synchronized (mQuotaController.mLock) {
+            // No sessions saved yet.
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket);
+        }
+        inOrder.verify(mAlarmManager, never())
+                .set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
+
+        // Test with timing sessions out of window.
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 25 * HOUR_IN_MILLIS, 30 * MINUTE_IN_MILLIS, 1), true);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket);
+        }
+        inOrder.verify(mAlarmManager, never())
+                .set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
+
+        // Test with timing sessions in window but still in quota.
+        final long end = now - (22 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS);
+        final long expectedAlarmTime = now + 2 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                new TimingSession(now - 22 * HOUR_IN_MILLIS, end, 1), true);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket);
+        }
+        inOrder.verify(mAlarmManager, never())
+                .set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
+
+        // Add some more sessions, but still in quota.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (50 * MINUTE_IN_MILLIS), 4 * MINUTE_IN_MILLIS, 1), true);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket);
+        }
+        inOrder.verify(mAlarmManager, never())
+                .set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
+
+        // Test when out of quota.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 30 * MINUTE_IN_MILLIS, 6 * MINUTE_IN_MILLIS, 1), true);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket);
+        }
+        inOrder.verify(mAlarmManager, times(1))
+                .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
+
+        // Alarm already scheduled, so make sure it's not scheduled again.
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket);
+        }
+        inOrder.verify(mAlarmManager, never())
+                .set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
+    }
+
+    /** Tests that the start alarm is properly rescheduled if the app's bucket is changed. */
+    @Test
+    public void testMaybeScheduleStartAlarmLocked_Hpj_BucketChange() {
+        // saveTimingSession calls maybeScheduleCleanupAlarmLocked which interferes with these tests
+        // because it schedules an alarm too. Prevent it from doing so.
+        spyOn(mQuotaController);
+        doNothing().when(mQuotaController).maybeScheduleCleanupAlarmLocked();
+
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_ACTIVE_MS, 30 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_WORKING_MS, 20 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_FREQUENT_MS, 15 * MINUTE_IN_MILLIS);
+        setDeviceConfigLong(QcConstants.KEY_HPJ_LIMIT_RARE_MS, 10 * MINUTE_IN_MILLIS);
+
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        // Affects active bucket
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 12 * HOUR_IN_MILLIS, 9 * MINUTE_IN_MILLIS, 3), true);
+        // Affects active and working buckets
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 4 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 3), true);
+        // Affects active, working, and frequent buckets
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 10), true);
+        // Affects all buckets
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 5 * MINUTE_IN_MILLIS, 10 * MINUTE_IN_MILLIS, 3), true);
+
+        InOrder inOrder = inOrder(mAlarmManager);
+
+        // Start in ACTIVE bucket.
+        setStandbyBucket(ACTIVE_INDEX);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, ACTIVE_INDEX);
+        }
+        inOrder.verify(mAlarmManager, never())
+                .set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
+        inOrder.verify(mAlarmManager, never()).cancel(any(AlarmManager.OnAlarmListener.class));
+
+        // And down from there.
+        setStandbyBucket(WORKING_INDEX);
+        final long expectedWorkingAlarmTime =
+                (now - 4 * HOUR_IN_MILLIS) + (24 * HOUR_IN_MILLIS)
+                        + mQcConstants.IN_QUOTA_BUFFER_MS;
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX);
+        }
+        inOrder.verify(mAlarmManager, times(1))
+                .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
+
+        setStandbyBucket(FREQUENT_INDEX);
+        final long expectedFrequentAlarmTime =
+                (now - HOUR_IN_MILLIS) + (24 * HOUR_IN_MILLIS) + mQcConstants.IN_QUOTA_BUFFER_MS;
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, FREQUENT_INDEX);
+        }
+        inOrder.verify(mAlarmManager, times(1))
+                .set(anyInt(), eq(expectedFrequentAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
+
+        setStandbyBucket(RARE_INDEX);
+        final long expectedRareAlarmTime =
+                (now - 5 * MINUTE_IN_MILLIS) + (24 * HOUR_IN_MILLIS)
+                        + mQcConstants.IN_QUOTA_BUFFER_MS;
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX);
+        }
+        inOrder.verify(mAlarmManager, times(1))
+                .set(anyInt(), eq(expectedRareAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
+
+        // And back up again.
+        setStandbyBucket(FREQUENT_INDEX);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, FREQUENT_INDEX);
+        }
+        inOrder.verify(mAlarmManager, times(1))
+                .set(anyInt(), eq(expectedFrequentAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
+
+        setStandbyBucket(WORKING_INDEX);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX);
+        }
+        inOrder.verify(mAlarmManager, times(1))
+                .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
+
+        setStandbyBucket(ACTIVE_INDEX);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, ACTIVE_INDEX);
+        }
+        inOrder.verify(mAlarmManager, never())
+                .set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
+        inOrder.verify(mAlarmManager, times(1)).cancel(any(AlarmManager.OnAlarmListener.class));
+    }
+
+    /**
+     * Tests that the start alarm is properly rescheduled if the earliest session that contributes
+     * to the app being out of quota contributes less than the quota buffer time.
+     */
+    @Test
+    public void testMaybeScheduleStartAlarmLocked_Hpj_SmallRollingQuota() {
+        // saveTimingSession calls maybeScheduleCleanupAlarmLocked which interferes with these tests
+        // because it schedules an alarm too. Prevent it from doing so.
+        spyOn(mQuotaController);
+        doNothing().when(mQuotaController).maybeScheduleCleanupAlarmLocked();
+
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        setStandbyBucket(WORKING_INDEX);
+        final long contributionMs = mQcConstants.IN_QUOTA_BUFFER_MS / 2;
+        final long remainingTimeMs = mQcConstants.HPJ_LIMIT_WORKING_MS - contributionMs;
+
+        // Session straddles edge of bucket window. Only the contribution should be counted towards
+        // the quota.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (24 * HOUR_IN_MILLIS + 3 * MINUTE_IN_MILLIS),
+                        3 * MINUTE_IN_MILLIS + contributionMs, 3), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - 23 * HOUR_IN_MILLIS, remainingTimeMs, 2), true);
+        // Expected alarm time should be when the app will have QUOTA_BUFFER_MS time of quota, which
+        // is 24 hours + (QUOTA_BUFFER_MS - contributionMs) after the start of the second session.
+        final long expectedAlarmTime =
+                now + HOUR_IN_MILLIS + (mQcConstants.IN_QUOTA_BUFFER_MS - contributionMs);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeScheduleStartAlarmLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX);
+        }
+        verify(mAlarmManager, times(1))
+                .set(anyInt(), eq(expectedAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
+    }
+
+    /** Tests that TimingSessions aren't saved when the device is charging. */
+    @Test
+    public void testHpjTimerTracking_Charging() {
+        setCharging();
+
+        JobStatus jobStatus = createHpjJobStatus("testHpjTimerTracking_Charging", 1);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
+        }
+
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus);
+        }
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false);
+        }
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /** Tests that TimingSessions are saved properly when the device is discharging. */
+    @Test
+    public void testHpjTimerTracking_Discharging() {
+        setDischarging();
+        setProcessState(ActivityManager.PROCESS_STATE_BACKUP);
+
+        JobStatus jobStatus = createHpjJobStatus("testHpjTimerTracking_Discharging", 1);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
+        }
+
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        List<TimingSession> expected = new ArrayList<>();
+
+        long start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus);
+        }
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false);
+        }
+        expected.add(createTimingSession(start, 5 * SECOND_IN_MILLIS, 1));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        // Test overlapping jobs.
+        JobStatus jobStatus2 = createHpjJobStatus("testHpjTimerTracking_Discharging", 2);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null);
+        }
+
+        JobStatus jobStatus3 = createHpjJobStatus("testHpjTimerTracking_Discharging", 3);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus3, null);
+        }
+
+        advanceElapsedClock(SECOND_IN_MILLIS);
+
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
+            mQuotaController.prepareForExecutionLocked(jobStatus);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus2);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus3);
+        }
+        advanceElapsedClock(20 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus3, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false);
+        }
+        expected.add(createTimingSession(start, MINUTE_IN_MILLIS, 3));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /**
+     * Tests that TimingSessions are saved properly when the device alternates between
+     * charging and discharging.
+     */
+    @Test
+    public void testHpjTimerTracking_ChargingAndDischarging() {
+        setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+        JobStatus jobStatus = createHpjJobStatus("testHpjTimerTracking_ChargingAndDischarging", 1);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
+        }
+        JobStatus jobStatus2 = createHpjJobStatus("testHpjTimerTracking_ChargingAndDischarging", 2);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null);
+        }
+        JobStatus jobStatus3 = createHpjJobStatus("testHpjTimerTracking_ChargingAndDischarging", 3);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus3, null);
+        }
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+        List<TimingSession> expected = new ArrayList<>();
+
+        // A job starting while charging. Only the portion that runs during the discharging period
+        // should be counted.
+        setCharging();
+
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        setDischarging();
+        long start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus, jobStatus, true);
+        }
+        expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        advanceElapsedClock(SECOND_IN_MILLIS);
+
+        // One job starts while discharging, spans a charging session, and ends after the charging
+        // session. Only the portions during the discharging periods should be counted. This should
+        // result in two TimingSessions. A second job starts while discharging and ends within the
+        // charging session. Only the portion during the first discharging portion should be
+        // counted. A third job starts and ends within the charging session. The third job
+        // shouldn't be included in either job count.
+        setDischarging();
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
+            mQuotaController.prepareForExecutionLocked(jobStatus);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus2);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        setCharging();
+        expected.add(createTimingSession(start, 20 * SECOND_IN_MILLIS, 2));
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus3);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus3, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        setDischarging();
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        advanceElapsedClock(20 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false);
+        }
+        expected.add(createTimingSession(start, 20 * SECOND_IN_MILLIS, 1));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        // A job starting while discharging and ending while charging. Only the portion that runs
+        // during the discharging period should be counted.
+        setDischarging();
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null);
+            mQuotaController.prepareForExecutionLocked(jobStatus2);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        setCharging();
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false);
+        }
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /** Tests that TimingSessions are saved properly when all the jobs are background jobs. */
+    @Test
+    public void testHpjTimerTracking_AllBackground() {
+        setDischarging();
+        setProcessState(ActivityManager.PROCESS_STATE_RECEIVER);
+
+        JobStatus jobStatus = createHpjJobStatus("testHpjTimerTracking_AllBackground", 1);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
+        }
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        List<TimingSession> expected = new ArrayList<>();
+
+        // Test single job.
+        long start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus);
+        }
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false);
+        }
+        expected.add(createTimingSession(start, 5 * SECOND_IN_MILLIS, 1));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        // Test overlapping jobs.
+        JobStatus jobStatus2 = createHpjJobStatus("testHpjTimerTracking_AllBackground", 2);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus2, null);
+        }
+
+        JobStatus jobStatus3 = createHpjJobStatus("testHpjTimerTracking_AllBackground", 3);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus3, null);
+        }
+
+        advanceElapsedClock(SECOND_IN_MILLIS);
+
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
+            mQuotaController.prepareForExecutionLocked(jobStatus);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus2);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus3);
+        }
+        advanceElapsedClock(20 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus3, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus2, null, false);
+        }
+        expected.add(createTimingSession(start, MINUTE_IN_MILLIS, 3));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /** Tests that Timers don't count foreground jobs. */
+    @Test
+    public void testHpjTimerTracking_AllForeground() {
+        setDischarging();
+
+        JobStatus jobStatus = createHpjJobStatus("testHpjTimerTracking_AllForeground", 1);
+        setProcessState(ActivityManager.PROCESS_STATE_TOP);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
+        }
+
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobStatus);
+        }
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        // Change to a state that should still be considered foreground.
+        setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobStatus, null, false);
+        }
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /**
+     * Tests that Timers properly track sessions when switching between foreground and background
+     * states.
+     */
+    @Test
+    public void testHpjTimerTracking_ForegroundAndBackground() {
+        setDischarging();
+
+        JobStatus jobBg1 = createHpjJobStatus("testHpjTimerTracking_ForegroundAndBackground", 1);
+        JobStatus jobBg2 = createHpjJobStatus("testHpjTimerTracking_ForegroundAndBackground", 2);
+        JobStatus jobFg3 = createHpjJobStatus("testHpjTimerTracking_ForegroundAndBackground", 3);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobBg1, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobBg2, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobFg3, null);
+        }
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+        List<TimingSession> expected = new ArrayList<>();
+
+        // UID starts out inactive.
+        setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+        long start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobBg1);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true);
+        }
+        expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        advanceElapsedClock(SECOND_IN_MILLIS);
+
+        // Bg job starts while inactive, spans an entire active session, and ends after the
+        // active session.
+        // App switching to foreground state then fg job starts.
+        // App remains in foreground state after coming to foreground, so there should only be one
+        // session.
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobBg2, null);
+            mQuotaController.prepareForExecutionLocked(jobBg2);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobFg3);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobFg3, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false);
+        }
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        advanceElapsedClock(SECOND_IN_MILLIS);
+
+        // Bg job 1 starts, then fg job starts. Bg job 1 job ends. Shortly after, uid goes
+        // "inactive" and then bg job 2 starts. Then fg job ends.
+        // This should result in two TimingSessions:
+        //  * The first should have a count of 1
+        //  * The second should have a count of 2 since it will include both jobs
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobBg1, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobBg2, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobFg3, null);
+        }
+        setProcessState(ActivityManager.PROCESS_STATE_LAST_ACTIVITY);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobBg1);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobFg3);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS); // UID "inactive" now
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobBg2);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobFg3, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false);
+        }
+        expected.add(createTimingSession(start, 20 * SECOND_IN_MILLIS, 2));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /**
+     * Tests that Timers properly track overlapping top and background jobs.
+     */
+    @Test
+    public void testHpjTimerTracking_TopAndNonTop() {
+        setDischarging();
+
+        JobStatus jobBg1 = createHpjJobStatus("testHpjTimerTracking_TopAndNonTop", 1);
+        JobStatus jobBg2 = createHpjJobStatus("testHpjTimerTracking_TopAndNonTop", 2);
+        JobStatus jobFg1 = createHpjJobStatus("testHpjTimerTracking_TopAndNonTop", 3);
+        JobStatus jobTop = createHpjJobStatus("testHpjTimerTracking_TopAndNonTop", 4);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobBg1, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobBg2, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobFg1, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobTop, null);
+        }
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+        List<TimingSession> expected = new ArrayList<>();
+
+        // UID starts out inactive.
+        setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+        long start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobBg1);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true);
+        }
+        expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        advanceElapsedClock(SECOND_IN_MILLIS);
+
+        // Bg job starts while inactive, spans an entire active session, and ends after the
+        // active session.
+        // App switching to top state then fg job starts.
+        // App remains in top state after coming to top, so there should only be one
+        // session.
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobBg2, null);
+            mQuotaController.prepareForExecutionLocked(jobBg2);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        setProcessState(ActivityManager.PROCESS_STATE_TOP);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobTop);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobTop, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false);
+        }
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        advanceElapsedClock(SECOND_IN_MILLIS);
+
+        // Bg job 1 starts, then top job starts. Bg job 1 job ends. Then app goes to
+        // foreground_service and a new job starts. Shortly after, uid goes
+        // "inactive" and then bg job 2 starts. Then top job ends, followed by bg and fg jobs.
+        // This should result in two TimingSessions:
+        //  * The first should have a count of 1
+        //  * The second should have a count of 2, which accounts for the bg2 and fg, but not top
+        //    jobs.
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobBg1, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobBg2, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobTop, null);
+        }
+        setProcessState(ActivityManager.PROCESS_STATE_LAST_ACTIVITY);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobBg1);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        expected.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        setProcessState(ActivityManager.PROCESS_STATE_TOP);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobTop);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobBg1, jobBg1, true);
+        }
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobFg1);
+        }
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        setProcessState(ActivityManager.PROCESS_STATE_TOP);
+        advanceElapsedClock(10 * SECOND_IN_MILLIS); // UID "inactive" now
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobBg2);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobTop, null, false);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobBg2, null, false);
+            mQuotaController.maybeStopTrackingJobLocked(jobFg1, null, false);
+        }
+        expected.add(createTimingSession(start, 20 * SECOND_IN_MILLIS, 2));
+        assertEquals(expected,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /**
+     * Tests that HPJs aren't stopped when an app runs out of quota.
+     */
+    @Test
+    public void testHpjTracking_OutOfQuota_ForegroundAndBackground() {
+        setDischarging();
+
+        JobStatus jobBg =
+                createHpjJobStatus("testHpjTracking_OutOfQuota_ForegroundAndBackground", 1);
+        JobStatus jobTop =
+                createHpjJobStatus("testHpjTracking_OutOfQuota_ForegroundAndBackground", 2);
+        JobStatus jobUnstarted =
+                createHpjJobStatus("testHpjTracking_OutOfQuota_ForegroundAndBackground", 3);
+        trackJobs(jobBg, jobTop, jobUnstarted);
+        setStandbyBucket(WORKING_INDEX, jobTop, jobBg, jobUnstarted);
+        // Now the package only has 20 seconds to run.
+        final long remainingTimeMs = 20 * SECOND_IN_MILLIS;
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(
+                        JobSchedulerService.sElapsedRealtimeClock.millis() - HOUR_IN_MILLIS,
+                        mQcConstants.HPJ_LIMIT_WORKING_MS - remainingTimeMs, 1), true);
+
+        InOrder inOrder = inOrder(mJobSchedulerService);
+
+        // UID starts out inactive.
+        setProcessState(ActivityManager.PROCESS_STATE_SERVICE);
+        // Start the job.
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobBg);
+        }
+        advanceElapsedClock(remainingTimeMs / 2);
+        // New job starts after UID is in the foreground. Since the app is now in the foreground, it
+        // should continue to have remainingTimeMs / 2 time remaining.
+        setProcessState(ActivityManager.PROCESS_STATE_TOP);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobTop);
+        }
+        advanceElapsedClock(remainingTimeMs);
+
+        // Wait for some extra time to allow for job processing.
+        inOrder.verify(mJobSchedulerService,
+                timeout(remainingTimeMs + 2 * SECOND_IN_MILLIS).times(0))
+                .onControllerStateChanged();
+        synchronized (mQuotaController.mLock) {
+            assertEquals(remainingTimeMs / 2,
+                    mQuotaController.getRemainingHpjExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+        // Go to a background state.
+        setProcessState(ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+        advanceElapsedClock(remainingTimeMs / 2 + 1);
+        inOrder.verify(mJobSchedulerService,
+                timeout(remainingTimeMs / 2 + 2 * SECOND_IN_MILLIS).times(1))
+                .onControllerStateChanged();
+        // Top and bg HPJs should still be allowed to run since they started before the app ran
+        // out of quota.
+        assertTrue(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertTrue(jobTop.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertFalse(jobUnstarted.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        synchronized (mQuotaController.mLock) {
+            assertTrue(
+                    0 >= mQuotaController
+                            .getRemainingHpjExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+
+        // New jobs to run.
+        JobStatus jobBg2 =
+                createHpjJobStatus("testHpjTracking_OutOfQuota_ForegroundAndBackground", 4);
+        JobStatus jobTop2 =
+                createHpjJobStatus("testHpjTracking_OutOfQuota_ForegroundAndBackground", 5);
+        JobStatus jobFg =
+                createHpjJobStatus("testHpjTracking_OutOfQuota_ForegroundAndBackground", 6);
+        setStandbyBucket(WORKING_INDEX, jobBg2, jobTop2, jobFg);
+
+        advanceElapsedClock(20 * SECOND_IN_MILLIS);
+        setProcessState(ActivityManager.PROCESS_STATE_TOP);
+        // Confirm QC recognizes that jobUnstarted has changed from out-of-quota to in-quota.
+        inOrder.verify(mJobSchedulerService, timeout(SECOND_IN_MILLIS).times(1))
+                .onControllerStateChanged();
+        trackJobs(jobTop2, jobFg);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobTop2);
+        }
+        assertTrue(jobTop2.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertTrue(jobFg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertTrue(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertTrue(jobUnstarted.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+
+        // App still in foreground so everything should be in quota.
+        advanceElapsedClock(20 * SECOND_IN_MILLIS);
+        setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+        assertTrue(jobTop2.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertTrue(jobFg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertTrue(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertTrue(jobUnstarted.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+
+        advanceElapsedClock(20 * SECOND_IN_MILLIS);
+        setProcessState(ActivityManager.PROCESS_STATE_SERVICE);
+        inOrder.verify(mJobSchedulerService, timeout(SECOND_IN_MILLIS).times(1))
+                .onControllerStateChanged();
+        // App is now in background and out of quota. Fg should now change to out of quota since it
+        // wasn't started. Top should remain in quota since it started when the app was in TOP.
+        assertTrue(jobTop2.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertFalse(jobFg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertTrue(jobBg.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        trackJobs(jobBg2);
+        assertFalse(jobBg2.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        assertFalse(jobUnstarted.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        synchronized (mQuotaController.mLock) {
+            assertTrue(
+                    0 >= mQuotaController
+                            .getRemainingHpjExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    /**
+     * Tests that Timers properly track overlapping top and background jobs.
+     */
+    @Test
+    public void testHpjTimerTrackingSeparateFromRegularTracking() {
+        setDischarging();
+        setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+        JobStatus jobReg1 = createJobStatus("testHpjTimerTrackingSeparateFromRegularTracking", 1);
+        JobStatus jobHpj1 =
+                createHpjJobStatus("testHpjTimerTrackingSeparateFromRegularTracking", 2);
+        JobStatus jobReg2 = createJobStatus("testHpjTimerTrackingSeparateFromRegularTracking", 3);
+        JobStatus jobHpj2 =
+                createHpjJobStatus("testHpjTimerTrackingSeparateFromRegularTracking", 4);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobReg1, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobHpj1, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobReg2, null);
+            mQuotaController.maybeStartTrackingJobLocked(jobHpj2, null);
+        }
+        assertNull(mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+        List<TimingSession> expectedRegular = new ArrayList<>();
+        List<TimingSession> expectedHpj = new ArrayList<>();
+
+        // First, regular job runs by itself.
+        long start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobReg1);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobReg1, jobReg1, true);
+        }
+        expectedRegular.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        assertEquals(expectedRegular,
+                mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertNull(mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        advanceElapsedClock(SECOND_IN_MILLIS);
+
+        // Next, HPJ runs by itself.
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobHpj1);
+        }
+        advanceElapsedClock(10 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobHpj1, null, false);
+        }
+        expectedHpj.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        assertEquals(expectedRegular,
+                mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertEquals(expectedHpj,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        advanceElapsedClock(SECOND_IN_MILLIS);
+
+        // Finally, a regular job and HPJ happen to overlap runs.
+        start = JobSchedulerService.sElapsedRealtimeClock.millis();
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobHpj2);
+        }
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobReg2);
+        }
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobHpj2, null, false);
+        }
+        expectedHpj.add(createTimingSession(start, 10 * SECOND_IN_MILLIS, 1));
+        advanceElapsedClock(5 * SECOND_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobReg2, null, false);
+        }
+        expectedRegular.add(
+                createTimingSession(start + 5 * SECOND_IN_MILLIS, 10 * SECOND_IN_MILLIS, 1));
+        assertEquals(expectedRegular,
+                mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertEquals(expectedHpj,
+                mQuotaController.getHpjTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /**
+     * Tests that a job is properly handled when it's at the edge of its quota and the old quota is
+     * being phased out.
+     */
+    @Test
+    public void testHpjTracking_RollingQuota() {
+        JobStatus jobStatus = createHpjJobStatus("testHpjTracking_RollingQuota", 1);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
+        }
+        setStandbyBucket(WORKING_INDEX, jobStatus);
+        setProcessState(ActivityManager.PROCESS_STATE_SERVICE);
+        Handler handler = mQuotaController.getHandler();
+        spyOn(handler);
+
+        long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        final long remainingTimeMs = SECOND_IN_MILLIS;
+        // The package only has one second to run, but this session is at the edge of the rolling
+        // window, so as the package "reaches its quota" it will have more to keep running.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - mQcConstants.HPJ_WINDOW_SIZE_MS,
+                        10 * SECOND_IN_MILLIS - remainingTimeMs, 1), true);
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - HOUR_IN_MILLIS,
+                        mQcConstants.HPJ_LIMIT_WORKING_MS - 10 * SECOND_IN_MILLIS, 1), true);
+
+        synchronized (mQuotaController.mLock) {
+            assertEquals(remainingTimeMs,
+                    mQuotaController.getRemainingHpjExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+
+            // Start the job.
+            mQuotaController.prepareForExecutionLocked(jobStatus);
+        }
+        advanceElapsedClock(remainingTimeMs);
+
+        // Wait for some extra time to allow for job processing.
+        verify(mJobSchedulerService,
+                timeout(remainingTimeMs + 2 * SECOND_IN_MILLIS).times(0))
+                .onControllerStateChanged();
+        assertTrue(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_HPJ_QUOTA));
+        // The job used up the remaining quota, but in that time, the same amount of time in the
+        // old TimingSession also fell out of the quota window, so it should still have the same
+        // amount of remaining time left its quota.
+        synchronized (mQuotaController.mLock) {
+            assertEquals(remainingTimeMs,
+                    mQuotaController.getRemainingHpjExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+        // Handler is told to check when the quota will be consumed, not when the initial
+        // remaining time is over.
+        verify(handler, atLeast(1)).sendMessageDelayed(
+                argThat(msg -> msg.what == QuotaController.MSG_REACHED_HPJ_QUOTA),
+                eq(10 * SECOND_IN_MILLIS));
+        verify(handler, never()).sendMessageDelayed(any(), eq(remainingTimeMs));
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
index e331507..63b36fc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
@@ -60,6 +60,7 @@
 import android.content.Context;
 import android.location.ILocationCallback;
 import android.location.ILocationListener;
+import android.location.LastLocationRequest;
 import android.location.Location;
 import android.location.LocationManagerInternal;
 import android.location.LocationManagerInternal.ProviderEnabledListener;
@@ -260,55 +261,77 @@
 
     @Test
     public void testGetLastLocation_Fine() {
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isNull();
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isNull();
 
         Location loc = createLocation(NAME, mRandom);
         mProvider.setProviderLocation(loc);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isEqualTo(loc);
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isEqualTo(loc);
     }
 
     @Test
     public void testGetLastLocation_Coarse() {
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isNull();
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isNull();
 
         Location loc = createLocation(NAME, mRandom);
         mProvider.setProviderLocation(loc);
-        Location coarse = mManager.getLastLocation(IDENTITY, PERMISSION_COARSE, false);
+        Location coarse = mManager.getLastLocation(new LastLocationRequest.Builder().build(),
+                IDENTITY, PERMISSION_COARSE);
         assertThat(coarse).isNotEqualTo(loc);
         assertThat(coarse).isNearby(loc, 5000);
     }
 
     @Test
     public void testGetLastLocation_Bypass() {
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isNull();
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, true)).isNull();
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isNull();
+        assertThat(mManager.getLastLocation(
+                new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
+                IDENTITY, PERMISSION_FINE)).isNull();
 
         Location loc = createLocation(NAME, mRandom);
         mProvider.setProviderLocation(loc);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isEqualTo(loc);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, true)).isEqualTo(
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isEqualTo(loc);
+        assertThat(mManager.getLastLocation(
+                new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
+                IDENTITY, PERMISSION_FINE)).isEqualTo(
                 loc);
 
         mProvider.setProviderAllowed(false);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isNull();
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, true)).isEqualTo(
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isNull();
+        assertThat(mManager.getLastLocation(
+                new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
+                IDENTITY, PERMISSION_FINE)).isEqualTo(
                 loc);
 
         loc = createLocation(NAME, mRandom);
         mProvider.setProviderLocation(loc);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isNull();
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, true)).isEqualTo(
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isNull();
+        assertThat(mManager.getLastLocation(
+                new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
+                IDENTITY, PERMISSION_FINE)).isEqualTo(
                 loc);
 
         mProvider.setProviderAllowed(true);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isNull();
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, true)).isEqualTo(
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isNull();
+        assertThat(mManager.getLastLocation(
+                new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
+                IDENTITY, PERMISSION_FINE)).isEqualTo(
                 loc);
 
         loc = createLocation(NAME, mRandom);
         mProvider.setProviderLocation(loc);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isEqualTo(loc);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, true)).isEqualTo(
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isEqualTo(loc);
+        assertThat(mManager.getLastLocation(
+                new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
+                IDENTITY, PERMISSION_FINE)).isEqualTo(
                 loc);
     }
 
@@ -320,10 +343,12 @@
 
         Location loc = createLocation(NAME, mRandom);
         mockProvider.setProviderLocation(loc);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isEqualTo(loc);
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isEqualTo(loc);
 
         mManager.setMockProvider(null);
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isNull();
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isNull();
     }
 
     @Test
@@ -331,12 +356,14 @@
         Location loc1 = createLocation(NAME, mRandom);
         mManager.injectLastLocation(loc1, CURRENT_USER);
 
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isEqualTo(loc1);
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isEqualTo(loc1);
 
         Location loc2 = createLocation(NAME, mRandom);
         mManager.injectLastLocation(loc2, CURRENT_USER);
 
-        assertThat(mManager.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isEqualTo(loc1);
+        assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isEqualTo(loc1);
     }
 
     @Test
@@ -355,7 +382,8 @@
         Location loc = createLocation(NAME, mRandom);
         mProvider.setProviderLocation(loc);
 
-        assertThat(mPassive.getLastLocation(IDENTITY, PERMISSION_FINE, false)).isEqualTo(loc);
+        assertThat(mPassive.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
+                PERMISSION_FINE)).isEqualTo(loc);
     }
 
     @Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
new file mode 100644
index 0000000..edae08a3
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -0,0 +1,662 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.pm
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
+import android.content.pm.FallbackCategoryProvider
+import android.content.pm.FeatureInfo
+import android.content.pm.PackageParser.SigningDetails
+import android.content.pm.ResolveInfo
+import android.content.pm.ServiceInfo
+import android.content.pm.Signature
+import android.content.pm.UserInfo
+import android.content.pm.parsing.ParsingPackage
+import android.content.pm.parsing.ParsingPackageUtils
+import android.content.res.Resources
+import android.hardware.display.DisplayManager
+import android.os.Build
+import android.os.Environment
+import android.os.SystemProperties
+import android.os.UserHandle
+import android.os.UserManager
+import android.os.incremental.IncrementalManager
+import android.permission.IPermissionManager
+import android.util.ArrayMap
+import android.util.DisplayMetrics
+import android.util.EventLog
+import android.view.Display
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.dx.mockito.inline.extended.ExtendedMockito.any
+import com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean
+import com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt
+import com.android.dx.mockito.inline.extended.ExtendedMockito.anyString
+import com.android.dx.mockito.inline.extended.ExtendedMockito.argThat
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
+import com.android.dx.mockito.inline.extended.ExtendedMockito.eq
+import com.android.dx.mockito.inline.extended.ExtendedMockito.spy
+import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder
+import com.android.internal.R
+import com.android.server.LocalServices
+import com.android.server.LockGuard
+import com.android.server.SystemConfig
+import com.android.server.SystemServerInitThreadPool
+import com.android.server.compat.PlatformCompat
+import com.android.server.extendedtestutils.wheneverStatic
+import com.android.server.pm.dex.DexManager
+import com.android.server.pm.parsing.PackageParser2
+import com.android.server.pm.parsing.pkg.AndroidPackage
+import com.android.server.pm.parsing.pkg.PackageImpl
+import com.android.server.pm.parsing.pkg.ParsedPackage
+import com.android.server.pm.permission.PermissionManagerServiceInternal
+import com.android.server.testutils.mock
+import com.android.server.testutils.nullable
+import com.android.server.testutils.whenever
+import org.junit.Assert
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+import org.mockito.AdditionalMatchers.or
+import org.mockito.invocation.InvocationOnMock
+import org.mockito.quality.Strictness
+import java.io.File
+import java.io.IOException
+import java.nio.file.Files
+import java.security.PublicKey
+import java.security.cert.CertificateException
+import java.util.Arrays
+import java.util.Random
+import java.util.concurrent.FutureTask
+
+/**
+ * A utility for mocking behavior of the system and dependencies when testing PackageManagerService
+ *
+ * Create one of these and call [stageNominalSystemState] as a basis for additional behavior in most
+ * tests.
+ */
+class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
+    private val random = Random()
+    val mocks = Mocks()
+    val packageCacheDirectory: File =
+            Files.createTempDirectory("packageCache").toFile()
+    val rootDirectory: File =
+            Files.createTempDirectory("root").toFile()
+    val dataAppDirectory: File =
+            File(Files.createTempDirectory("data").toFile(), "app")
+    val frameworkSignature: SigningDetails = SigningDetails(arrayOf(generateSpySignature()), 3)
+    val systemPartitions: List<PackageManagerService.ScanPartition> =
+            redirectScanPartitions(PackageManagerService.SYSTEM_PARTITIONS)
+    val session: StaticMockitoSession
+
+    /** Tracks temporary files created by this class during the running of a test.  */
+    private val createdFiles = ArrayList<File>()
+
+    /** Settings that are expected to be added as part of the test  */
+    private val mPendingPackageAdds: MutableList<Pair<String, PackageSetting>> = ArrayList()
+
+    /** Settings simulated to be stored on disk  */
+    private val mPreExistingSettings = ArrayMap<String, PackageSetting>()
+
+    /** The active map simulating the in memory storage of Settings  */
+    private val mSettingsMap = ArrayMap<String, PackageSetting>()
+
+    init {
+        val apply = ExtendedMockito.mockitoSession()
+                .strictness(Strictness.LENIENT)
+                .mockStatic(SystemProperties::class.java)
+                .mockStatic(SystemConfig::class.java)
+                .mockStatic(SELinuxMMAC::class.java)
+                .mockStatic(FallbackCategoryProvider::class.java)
+                .mockStatic(PackageManagerServiceUtils::class.java)
+                .mockStatic(Environment::class.java)
+                .mockStatic(SystemServerInitThreadPool::class.java)
+                .mockStatic(ParsingPackageUtils::class.java)
+                .mockStatic(LockGuard::class.java)
+                .mockStatic(EventLog::class.java)
+                .mockStatic(LocalServices::class.java)
+                .apply(withSession)
+        session = apply.startMocking()
+        whenever(mocks.settings.insertPackageSettingLPw(
+                any(PackageSetting::class.java), any(AndroidPackage::class.java))) {
+            val name: String = (getArgument<Any>(0) as PackageSetting).name
+            val pendingAdd =
+                    mPendingPackageAdds.firstOrNull { it.first == name } ?: return@whenever null
+            mPendingPackageAdds.remove(pendingAdd)
+            mSettingsMap[name] = pendingAdd.second
+            null
+        }
+        whenever(mocks.settings.addPackageLPw(nullable(), nullable(), nullable(), nullable(),
+                nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), nullable(),
+                nullable(), nullable(), nullable())) {
+            val name: String = getArgument(0)
+            val pendingAdd = mPendingPackageAdds.firstOrNull { it.first == name }
+                    ?: return@whenever null
+            mPendingPackageAdds.remove(pendingAdd)
+            mSettingsMap[name] = pendingAdd.second
+            pendingAdd.second
+        }
+        whenever(mocks.settings.packagesLocked).thenReturn(mSettingsMap)
+        whenever(mocks.settings.getPackageLPr(anyString())) { mSettingsMap[getArgument<Any>(0)] }
+        whenever(mocks.settings.readLPw(nullable())) {
+            mSettingsMap.putAll(mPreExistingSettings)
+            !mPreExistingSettings.isEmpty()
+        }
+    }
+
+    /** Collection of mocks used for PackageManagerService tests. */
+
+    class Mocks {
+        val lock = Any()
+        val installLock = Any()
+        val injector: PackageManagerService.Injector = mock()
+        val systemWrapper: PackageManagerService.SystemWrapper = mock()
+        val context: Context = mock()
+        val userManagerService: UserManagerService = mock()
+        val componentResolver: ComponentResolver = mock()
+        val permissionManagerInternal: PermissionManagerServiceInternal = mock()
+        val incrementalManager: IncrementalManager = mock()
+        val platformCompat: PlatformCompat = mock()
+        val settings: Settings = mock()
+        val resources: Resources = mock()
+        val systemConfig: SystemConfig = mock()
+        val apexManager: ApexManager = mock()
+        val userManagerInternal: UserManagerInternal = mock()
+        val packageParser: PackageParser2 = mock()
+        val keySetManagerService: KeySetManagerService = mock()
+        val packageAbiHelper: PackageAbiHelper = mock()
+        val appsFilter: AppsFilter = mock()
+        val dexManager: DexManager = mock()
+        val installer: Installer = mock()
+        val displayMetrics: DisplayMetrics = mock()
+        val permissionManager: IPermissionManager = mock()
+    }
+
+    companion object {
+        private const val DEVICE_PROVISIONING_PACKAGE_NAME =
+                "com.example.android.device.provisioning"
+        private val DEFAULT_AVAILABLE_FEATURES_MAP = ArrayMap<String, FeatureInfo>()
+        private val DEFAULT_ACTIVE_APEX_INFO_LIST = emptyList<ApexManager.ActiveApexInfo>()
+        private val DEFAULT_SHARED_LIBRARIES_LIST =
+                ArrayMap<String, SystemConfig.SharedLibraryEntry>()
+        private val DEFAULT_USERS = Arrays.asList(
+                UserInfo(UserHandle.USER_SYSTEM, "primary", "",
+                        UserInfo.FLAG_PRIMARY or UserInfo.FLAG_SYSTEM or UserInfo.FLAG_FULL,
+                        UserManager.USER_TYPE_FULL_SYSTEM))
+        public val DEFAULT_VERSION_INFO = Settings.VersionInfo()
+
+        init {
+            DEFAULT_VERSION_INFO.fingerprint = "abcdef"
+            DEFAULT_VERSION_INFO.sdkVersion = Build.VERSION_CODES.R
+            DEFAULT_VERSION_INFO.databaseVersion = Settings.CURRENT_DATABASE_VERSION
+        }
+    }
+
+    /**
+     * Clean up any potentially dangling state. This should be run at the end of every test to
+     * account for changes to static memory, such as [LocalServices]
+     */
+    fun cleanup() {
+        createdFiles.forEach(File::delete)
+        createdFiles.clear()
+        mSettingsMap.clear()
+        mPendingPackageAdds.clear()
+        mPreExistingSettings.clear()
+        session.finishMocking()
+    }
+
+    /**
+     * Run this method to ensure that all expected actions were executed, such as pending
+     * [Settings] adds.
+     */
+    fun validateFinalState() {
+        if (mPendingPackageAdds.isNotEmpty()) {
+            Assert.fail(
+                    "Not all expected settings were added: ${mPendingPackageAdds.map { it.first }}")
+        }
+    }
+
+    /**
+     * This method stages enough of system startup to execute the PackageManagerService constructor
+     * successfullly.
+     */
+    @Throws(Exception::class)
+    fun stageNominalSystemState() {
+        whenever(mocks.injector.context).thenReturn(mocks.context)
+        whenever(mocks.injector.lock).thenReturn(mocks.lock)
+        whenever(mocks.injector.installLock).thenReturn(mocks.installLock)
+        whenever(mocks.injector.systemWrapper).thenReturn(mocks.systemWrapper)
+        whenever(mocks.injector.userManagerService).thenReturn(mocks.userManagerService)
+        whenever(mocks.injector.componentResolver).thenReturn(mocks.componentResolver)
+        whenever(mocks.injector.permissionManagerServiceInternal) {
+            mocks.permissionManagerInternal
+        }
+        whenever(mocks.injector.permissionManagerService).thenReturn(mocks.permissionManager)
+        whenever(mocks.injector.incrementalManager).thenReturn(mocks.incrementalManager)
+        whenever(mocks.injector.compatibility).thenReturn(mocks.platformCompat)
+        whenever(mocks.injector.settings).thenReturn(mocks.settings)
+        whenever(mocks.injector.dexManager).thenReturn(mocks.dexManager)
+        whenever(mocks.injector.systemConfig).thenReturn(mocks.systemConfig)
+        whenever(mocks.injector.apexManager).thenReturn(mocks.apexManager)
+        whenever(mocks.injector.scanningCachingPackageParser).thenReturn(mocks.packageParser)
+        whenever(mocks.injector.scanningPackageParser).thenReturn(mocks.packageParser)
+        whenever(mocks.injector.systemPartitions).thenReturn(systemPartitions)
+        whenever(mocks.injector.appsFilter).thenReturn(mocks.appsFilter)
+        whenever(mocks.injector.abiHelper).thenReturn(mocks.packageAbiHelper)
+        whenever(mocks.injector.userManagerInternal).thenReturn(mocks.userManagerInternal)
+        whenever(mocks.injector.installer).thenReturn(mocks.installer)
+        whenever(mocks.injector.displayMetrics).thenReturn(mocks.displayMetrics)
+        wheneverStatic { SystemConfig.getInstance() }.thenReturn(mocks.systemConfig)
+        whenever(mocks.systemConfig.availableFeatures).thenReturn(DEFAULT_AVAILABLE_FEATURES_MAP)
+        whenever(mocks.systemConfig.sharedLibraries).thenReturn(DEFAULT_SHARED_LIBRARIES_LIST)
+        wheneverStatic { SystemProperties.getBoolean("fw.free_cache_v2", true) }.thenReturn(true)
+        wheneverStatic { Environment.getPackageCacheDirectory() }.thenReturn(packageCacheDirectory)
+        wheneverStatic { SystemProperties.digestOf("ro.build.fingerprint") }.thenReturn("cacheName")
+        wheneverStatic { Environment.getRootDirectory() }.thenReturn(rootDirectory)
+        wheneverStatic { SystemServerInitThreadPool.submit(any(Runnable::class.java), anyString())}
+                .thenAnswer { FutureTask<Any?>(it.getArgument(0), null) }
+
+        wheneverStatic { Environment.getDataDirectory() }.thenReturn(dataAppDirectory.parentFile)
+        wheneverStatic { Environment.getDataSystemDirectory() }
+                .thenReturn(File(dataAppDirectory.parentFile, "system"))
+        whenever(mocks.context.resources).thenReturn(mocks.resources)
+        whenever(mocks.resources.getString(R.string.config_deviceProvisioningPackage)) {
+            DEVICE_PROVISIONING_PACKAGE_NAME
+        }
+        whenever(mocks.apexManager.activeApexInfos).thenReturn(DEFAULT_ACTIVE_APEX_INFO_LIST)
+        whenever(mocks.settings.packagesLocked).thenReturn(mSettingsMap)
+        whenever(mocks.settings.internalVersion).thenReturn(DEFAULT_VERSION_INFO)
+        whenever(mocks.settings.keySetManagerService).thenReturn(mocks.keySetManagerService)
+        whenever(mocks.settings.keySetManagerService).thenReturn(mocks.keySetManagerService)
+        whenever(mocks.packageAbiHelper.derivePackageAbi(
+                any(AndroidPackage::class.java), anyBoolean(), nullable(), any(File::class.java))) {
+            android.util.Pair(PackageAbiHelper.Abis("", ""),
+                    PackageAbiHelper.NativeLibraryPaths("", false, "", ""))
+        }
+        whenever(mocks.userManagerInternal.getUsers(true, false, false)).thenReturn(DEFAULT_USERS)
+        whenever(mocks.userManagerService.userIds).thenReturn(intArrayOf(0))
+        whenever(mocks.userManagerService.exists(0)).thenReturn(true)
+        whenever(mocks.packageAbiHelper.deriveNativeLibraryPaths(
+                any(AndroidPackage::class.java), anyBoolean(), any(File::class.java))) {
+            PackageAbiHelper.NativeLibraryPaths("", false, "", "")
+        }
+        // everything visible by default
+        whenever(mocks.appsFilter.shouldFilterApplication(
+                anyInt(), nullable(), nullable(), anyInt())) { false }
+
+        val displayManager: DisplayManager = mock()
+        whenever(mocks.context.getSystemService(DisplayManager::class.java))
+                .thenReturn(displayManager)
+        val display: Display = mock()
+        whenever(displayManager.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(display)
+
+        stageFrameworkScan()
+        stageInstallerScan()
+        stageServicesExtensionScan()
+        stageSystemSharedLibraryScan()
+        stagePermissionsControllerScan()
+        stageInstantAppResolverScan()
+    }
+
+    /**
+     * This method will stage the parsing and scanning of a package as well as add it to the
+     * [PackageSetting]s read from disk.
+     */
+    @Throws(Exception::class)
+    fun stageScanExistingPackage(
+        packageName: String,
+        versionCode: Long,
+        parent: File?,
+        withPackage: (PackageImpl) -> PackageImpl = { it },
+        withSetting:
+        (PackageSettingBuilder) -> PackageSettingBuilder = { it },
+        withExistingSetting:
+        (PackageSettingBuilder) -> PackageSettingBuilder = { it }
+    ) {
+        val existingSettingBuilderRef = arrayOfNulls<PackageSettingBuilder>(1)
+        stageScanNewPackage(packageName, versionCode, parent, withPackage,
+                withSetting = { settingBuilder ->
+                    withSetting(settingBuilder)
+                    existingSettingBuilderRef[0] = settingBuilder
+                    settingBuilder
+                })
+        existingSettingBuilderRef[0]?.setPackage(null)
+        val packageSetting = existingSettingBuilderRef[0]?.let { withExistingSetting(it) }!!.build()
+        addPreExistingSetting(packageName, packageSetting)
+    }
+
+    /**
+     * This method will stage a [PackageSetting] read from disk, but does not stage any scanning
+     * or parsing of the package.
+     */
+    fun addPreExistingSetting(packageName: String, packageSetting: PackageSetting) {
+        mPreExistingSettings[packageName] = packageSetting
+    }
+
+    /**
+     * This method will stage the parsing and scanning of a package but will not add it to the set
+     * of [PackageSetting]s read from disk.
+     */
+    @Throws(Exception::class)
+    fun stageScanNewPackage(
+        packageName: String,
+        versionCode: Long,
+        parent: File?,
+        withPackage: (PackageImpl) -> PackageImpl = { it },
+        withSetting: (PackageSettingBuilder) -> PackageSettingBuilder = { it }
+    ) {
+        val pair = createBasicAndroidPackage(parent, packageName, versionCode)
+        val apkPath = pair.first
+        val pkg = withPackage(pair.second)
+        stageParse(apkPath, pkg)
+        val parentFile = apkPath.parentFile
+        val settingBuilder = withSetting(createBasicSettingBuilder(parentFile, pkg))
+        stageSettingInsert(packageName, settingBuilder.build())
+    }
+
+    /**
+     * Creates a simple package that should reasonably parse for scan operations. This can be used
+     * as a basis for more complicated packages.
+     */
+    fun createBasicAndroidPackage(
+        parent: File?,
+        packageName: String,
+        versionCode: Long,
+        signingDetails: SigningDetails =
+                createRandomSigningDetails()
+    ): Pair<File, PackageImpl> {
+        val apkPath = File(File(parent, packageName), "base.apk")
+        val pkg = PackageImpl.forTesting(packageName, apkPath.parentFile.path) as PackageImpl
+        pkg.signingDetails = signingDetails
+        wheneverStatic { ParsingPackageUtils.getSigningDetails(eq(pkg), anyBoolean()) }
+                .thenReturn(signingDetails)
+        pkg.versionCode = versionCode.toInt()
+        pkg.versionCodeMajor = (versionCode shr 32).toInt()
+        pkg.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT
+        return Pair(apkPath, pkg)
+    }
+
+    /**
+     * This method will create a spy of a [SigningDetails] object to be used when simulating the
+     * collection of signatures.
+     */
+    fun createRandomSigningDetails(): SigningDetails {
+        val signingDetails = spy(SigningDetails(arrayOf(generateSpySignature()),
+                SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3))
+        doReturn(true).whenever(signingDetails).checkCapability(
+                anyString(), anyInt())
+        doReturn(true).whenever(signingDetails).checkCapability(
+                any(SigningDetails::class.java), anyInt())
+        return signingDetails
+    }
+
+    /**
+     * This method will create a basic [PackageSettingBuilder] from an [AndroidPackage] with all of
+     * the necessary parameters to be returned by a simple scan. This can be used as a basis for
+     * more complicated settings.
+     */
+    fun createBasicSettingBuilder(parentFile: File, pkg: AndroidPackage): PackageSettingBuilder {
+        return createBasicSettingBuilder(parentFile, pkg.packageName, pkg.longVersionCode,
+                pkg.signingDetails)
+                .setPackage(pkg)
+    }
+
+    /**
+     * This method will create a basic [PackageSettingBuilder] with all of the necessary parameters
+     * to be returned by a simple scan. This can be used as a basis for more complicated settings.
+     */
+    fun createBasicSettingBuilder(
+        parentFile: File,
+        packageName: String,
+        versionCode: Long,
+        signingDetails: SigningDetails
+    ): PackageSettingBuilder {
+        return PackageSettingBuilder()
+                .setCodePath(parentFile.path)
+                .setName(packageName)
+                .setPVersionCode(versionCode)
+                .setSigningDetails(signingDetails)
+    }
+
+    fun createBasicApplicationInfo(pkg: ParsingPackage): ApplicationInfo {
+        val applicationInfo: ApplicationInfo = mock()
+        applicationInfo.packageName = pkg.packageName
+        return applicationInfo
+    }
+
+    fun createBasicActivityInfo(
+        pkg: ParsingPackage,
+        applicationInfo: ApplicationInfo?,
+        className: String?
+    ):
+            ActivityInfo {
+        val activityInfo = ActivityInfo()
+        activityInfo.applicationInfo = applicationInfo
+        activityInfo.packageName = pkg.packageName
+        activityInfo.name = className
+        return activityInfo
+    }
+
+    fun createBasicServiceInfo(
+        pkg: ParsingPackage,
+        applicationInfo: ApplicationInfo?,
+        className: String?
+    ):
+            ServiceInfo {
+        val serviceInfo = ServiceInfo()
+        serviceInfo.applicationInfo = applicationInfo
+        serviceInfo.packageName = pkg.packageName
+        serviceInfo.name = className
+        return serviceInfo
+    }
+
+    /** Finds the appropriate partition, if available, based on a scan flag unique to it.  */
+    fun getPartitionFromFlag(scanFlagMask: Int): PackageManagerService.ScanPartition =
+            systemPartitions.first { (it.scanFlag and scanFlagMask) != 0 }
+
+    @Throws(Exception::class)
+    private fun stageParse(path: File, parseResult: ParsingPackage): ParsedPackage {
+        val basePath = path.parentFile
+        basePath.mkdirs()
+        path.createNewFile()
+        createdFiles.add(path)
+        val parsedPackage = parseResult.hideAsParsed() as ParsedPackage
+        whenever(mocks.packageParser.parsePackage(
+                or(eq(path), eq(basePath)), anyInt(), anyBoolean())) { parsedPackage }
+        return parsedPackage
+    }
+
+    private fun stageSettingInsert(name: String, setting: PackageSetting): PackageSetting {
+        mPendingPackageAdds.add(Pair(name, setting))
+        return setting
+    }
+
+    @Throws(Exception::class)
+    private fun stageFrameworkScan() {
+        val apk = File(File(rootDirectory, "framework"), "framework-res.apk")
+        val frameworkPkg = PackageImpl.forTesting("android",
+                apk.parentFile.path) as PackageImpl
+        wheneverStatic { ParsingPackageUtils.getSigningDetails(frameworkPkg, true) }
+                .thenReturn(frameworkSignature)
+        stageParse(apk, frameworkPkg)
+        stageSettingInsert("android",
+                PackageSettingBuilder().setCodePath(apk.path).setName(
+                        "android").setPackage(frameworkPkg).build())
+    }
+
+    @Throws(Exception::class)
+    private fun stageInstantAppResolverScan() {
+        whenever(mocks.resources.getStringArray(R.array.config_ephemeralResolverPackage)) {
+            arrayOf("com.android.test.ephemeral.resolver")
+        }
+        stageScanNewPackage("com.android.test.ephemeral.resolver",
+                1L, getPartitionFromFlag(PackageManagerService.SCAN_AS_PRODUCT).privAppFolder,
+                withPackage = { pkg: PackageImpl ->
+                    val applicationInfo: ApplicationInfo = createBasicApplicationInfo(pkg)
+                    whenever(applicationInfo.isPrivilegedApp).thenReturn(true)
+                    mockQueryServices(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE,
+                            createBasicServiceInfo(pkg, applicationInfo, "test.EphemeralService"))
+                    mockQueryActivities(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS,
+                            createBasicActivityInfo(pkg, applicationInfo, "test.SettingsActivity"))
+                    pkg
+                },
+                withSetting = { setting: PackageSettingBuilder ->
+                    setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
+                })
+    }
+
+    @Throws(Exception::class)
+    private fun stagePermissionsControllerScan() {
+        stageScanNewPackage("com.android.permissions.controller",
+                1L, systemPartitions[0].privAppFolder,
+                withPackage = { pkg: PackageImpl ->
+                    val applicationInfo: ApplicationInfo = createBasicApplicationInfo(pkg)
+                    whenever(applicationInfo.isPrivilegedApp).thenReturn(true)
+                    mockQueryActivities(Intent.ACTION_MANAGE_PERMISSIONS,
+                            createBasicActivityInfo(
+                                    pkg, applicationInfo, "test.PermissionActivity"))
+                    pkg
+                },
+                withSetting = { setting: PackageSettingBuilder ->
+                    setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
+                })
+    }
+
+    @Throws(Exception::class)
+    private fun stageSystemSharedLibraryScan() {
+        stageScanNewPackage("android.ext.shared",
+                1L, systemPartitions[0].appFolder,
+                withPackage = { it.addLibraryName("android.ext.shared") as PackageImpl },
+                withSetting = { setting: PackageSettingBuilder ->
+                    setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
+                }
+        )
+    }
+
+    @Throws(Exception::class)
+    private fun stageServicesExtensionScan() {
+        whenever(mocks.context.getString(R.string.config_servicesExtensionPackage)) {
+            "com.android.test.services.extension"
+        }
+        stageScanNewPackage("com.android.test.services.extension",
+                1L, getPartitionFromFlag(PackageManagerService.SCAN_AS_SYSTEM_EXT).privAppFolder,
+                withSetting = { setting: PackageSettingBuilder ->
+                    setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
+                })
+    }
+
+    @Throws(Exception::class)
+    private fun stageInstallerScan() {
+        stageScanNewPackage(
+                "com.android.test.installer",
+                1L, getPartitionFromFlag(PackageManagerService.SCAN_AS_PRODUCT).privAppFolder,
+                withPackage = { pkg: PackageImpl ->
+                    val applicationInfo: ApplicationInfo = createBasicApplicationInfo(pkg)
+                    whenever(applicationInfo.isPrivilegedApp).thenReturn(true)
+                    val installerActivity: ActivityInfo = createBasicActivityInfo(
+                            pkg, applicationInfo, "test.InstallerActivity")
+                    mockQueryActivities(Intent.ACTION_INSTALL_PACKAGE, installerActivity)
+                    mockQueryActivities(Intent.ACTION_UNINSTALL_PACKAGE, installerActivity)
+                    mockQueryActivities(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE,
+                            installerActivity)
+                    pkg
+                },
+                withSetting = { setting: PackageSettingBuilder ->
+                    setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
+                }
+        )
+    }
+
+    private fun mockQueryActivities(action: String, vararg activities: ActivityInfo) {
+        whenever(mocks.componentResolver.queryActivities(
+                argThat { intent: Intent? -> intent != null && (action == intent.action) },
+                nullable(), anyInt(), anyInt())) {
+            ArrayList(activities.asList().map { info: ActivityInfo? ->
+                ResolveInfo().apply { activityInfo = info }
+            })
+        }
+    }
+
+    private fun mockQueryServices(action: String, vararg services: ServiceInfo) {
+        whenever(mocks.componentResolver.queryServices(
+                argThat { intent: Intent? -> intent != null && (action == intent.action) },
+                nullable(), anyInt(), anyInt())) {
+            ArrayList(services.asList().map { info ->
+                ResolveInfo().apply { serviceInfo = info }
+            })
+        }
+    }
+
+    fun generateSpySignature(): Signature {
+        val bytes = ByteArray(32)
+        random.nextBytes(bytes)
+        val signature = spy(Signature(bytes))
+        try {
+            val mockPublicKey: PublicKey = mock()
+            doReturn(mockPublicKey).whenever(signature).getPublicKey()
+        } catch (e: CertificateException) {
+            throw RuntimeException(e)
+        }
+        return signature
+    }
+
+    /** Override get*Folder methods to point to temporary local directories  */
+
+    @Throws(IOException::class)
+    private fun redirectScanPartitions(partitions: List<PackageManagerService.ScanPartition>):
+            List<PackageManagerService.ScanPartition> {
+        val spiedPartitions: MutableList<PackageManagerService.ScanPartition> =
+                ArrayList(partitions.size)
+        for (partition: PackageManagerService.ScanPartition in partitions) {
+            val spy = spy(partition)
+            val newRoot = Files.createTempDirectory(partition.folder.name).toFile()
+            whenever(spy.overlayFolder).thenReturn(File(newRoot, "overlay"))
+            whenever(spy.appFolder).thenReturn(File(newRoot, "app"))
+            whenever(spy.privAppFolder).thenReturn(File(newRoot, "priv-app"))
+            whenever(spy.folder).thenReturn(newRoot)
+            spiedPartitions.add(spy)
+        }
+        return spiedPartitions
+    }
+}
+
+/**
+ * Sets up a basic [MockSystem] for use in a test method. This will create a MockSystem before the
+ * test method and any [org.junit.Before] annotated methods. It can then be used to access the
+ * MockSystem via the [system] method or the mocks directly via [mocks].
+ */
+class MockSystemRule : TestRule {
+    var mockSystem: MockSystem? = null
+    override fun apply(base: Statement?, description: Description?) = object : Statement() {
+        @Throws(Throwable::class)
+        override fun evaluate() {
+            mockSystem = MockSystem()
+            try {
+                base!!.evaluate()
+            } finally {
+                mockSystem?.cleanup()
+                mockSystem = null
+            }
+        }
+    }
+
+    /** Fetch the [MockSystem] instance prepared for this test */
+    fun system(): MockSystem = mockSystem!!
+    /** Fetch the [MockSystem.Mocks] prepared for this test */
+    fun mocks(): MockSystem.Mocks = mockSystem!!.mocks
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceBootTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceBootTest.kt
new file mode 100644
index 0000000..bd44c36
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceBootTest.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.pm
+
+import android.content.pm.ApplicationInfo.FLAG_SYSTEM
+import android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
+import android.content.pm.PackageManager
+import android.content.pm.PackageParser
+import android.os.Build
+import android.os.Process
+import android.util.Log
+import com.android.server.pm.parsing.pkg.AndroidPackage
+import com.android.server.testutils.whenever
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.equalTo
+import org.hamcrest.Matchers.notNullValue
+import org.hamcrest.collection.IsMapContaining.hasKey
+import org.hamcrest.core.IsNot.not
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.argThat
+import org.mockito.Mockito
+import org.mockito.Mockito.verify
+import java.io.File
+
+@RunWith(JUnit4::class)
+class PackageManagerServiceBootTest {
+
+    @Rule
+    @JvmField
+    val rule = MockSystemRule()
+
+    @Before
+    @Throws(Exception::class)
+    fun setup() {
+        Log.i("system.out", "setup", Exception())
+        rule.system().stageNominalSystemState()
+    }
+
+    private fun createPackageManagerService(): PackageManagerService {
+        return PackageManagerService(rule.mocks().injector,
+                false /*coreOnly*/,
+                false /*factoryTest*/,
+                MockSystem.DEFAULT_VERSION_INFO.fingerprint,
+                false /*isEngBuild*/,
+                false /*isUserDebugBuild*/,
+                Build.VERSION_CODES.CUR_DEVELOPMENT,
+                Build.VERSION.INCREMENTAL)
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun simpleConstruction() {
+        val pm = createPackageManagerService()
+        verify(rule.mocks().injector).bootstrap(pm)
+        verify(rule.mocks().settings).addSharedUserLPw("android.uid.system",
+                Process.SYSTEM_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
+        verify(rule.mocks().settings).addSharedUserLPw("android.uid.phone",
+                Process.PHONE_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
+        verify(rule.mocks().settings).addSharedUserLPw("android.uid.log",
+                Process.LOG_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
+        verify(rule.mocks().settings).addSharedUserLPw("android.uid.nfc",
+                Process.NFC_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
+        verify(rule.mocks().settings).addSharedUserLPw("android.uid.bluetooth",
+                Process.BLUETOOTH_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
+        verify(rule.mocks().settings).addSharedUserLPw("android.uid.shell",
+                Process.SHELL_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
+        verify(rule.mocks().settings).addSharedUserLPw("android.uid.se",
+                Process.SE_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
+        verify(rule.mocks().settings).addSharedUserLPw("android.uid.networkstack",
+                Process.NETWORK_STACK_UID, FLAG_SYSTEM, PRIVATE_FLAG_PRIVILEGED)
+        rule.system().validateFinalState()
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun existingDataPackage_remains() {
+        rule.system().stageScanExistingPackage("a.data.package", 1L, rule.system().dataAppDirectory)
+        val pm = createPackageManagerService()
+        rule.system().validateFinalState()
+        assertThat(pm.mPackages, hasKey("a.data.package"))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun unexpectedDataPackage_isRemoved() {
+        rule.system().stageScanNewPackage(
+                "a.data.package", 1L, rule.system().dataAppDirectory)
+        val pm = createPackageManagerService()
+        verify(rule.mocks().settings, Mockito.never()).insertPackageSettingLPw(
+                argThat { setting: PackageSetting -> setting.name == "a.data.package" },
+                argThat { pkg: AndroidPackage -> pkg.packageName == "a.data.package" })
+        assertThat(pm.mPackages, not(hasKey("a.data.package")))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun expectedPackageMissing_doesNotReplace() {
+        // setup existing package
+        rule.system().stageScanExistingPackage("a.data.package", 1L,
+                rule.system().dataAppDirectory)
+        // simulate parsing failure for any path containing the package name.
+        whenever(rule.mocks().packageParser.parsePackage(
+                argThat { path: File -> path.path.contains("a.data.package") },
+                anyInt(),
+                anyBoolean()))
+                .thenThrow(PackageParser.PackageParserException(
+                        PackageManager.INSTALL_FAILED_INVALID_APK, "Oh no!"))
+        val pm = createPackageManagerService()
+        verify(rule.mocks().settings, Mockito.never()).insertPackageSettingLPw(
+                argThat { setting: PackageSetting -> setting.name == "a.data.package" },
+                argThat { pkg: AndroidPackage -> pkg.packageName == "a.data.package" })
+        assertThat(pm.mPackages, not(hasKey("a.data.package")))
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun expectingBetter_updateStillBetter() {
+        // Debug.waitForDebugger()
+        val systemAppPackageName = "com.android.test.updated.system.app"
+        val systemAppSigningDetails = rule.system().createRandomSigningDetails()
+        val systemVersionParent = rule.system()
+                .getPartitionFromFlag(PackageManagerService.SCAN_AS_PRODUCT).privAppFolder
+
+        // system app v1 is disabled
+        whenever(rule.mocks().settings.isDisabledSystemPackageLPr(systemAppPackageName)) {
+            true
+        }
+        whenever(rule.mocks().settings.getDisabledSystemPkgLPr(systemAppPackageName)) {
+            rule.system().createBasicSettingBuilder(
+                    File(systemVersionParent, systemAppPackageName),
+                    systemAppPackageName, 1, systemAppSigningDetails).build()
+        }
+
+        // system app v3 is on data/app
+        rule.system().stageScanExistingPackage(
+                systemAppPackageName,
+                3,
+                rule.system().dataAppDirectory,
+                withPackage = { it.apply { signingDetails = systemAppSigningDetails } },
+                withExistingSetting = { it.setPkgFlags(FLAG_SYSTEM) })
+
+        // system app v2 is scanned from system
+        rule.system().stageScanNewPackage(systemAppPackageName, 2, systemVersionParent,
+                withPackage = { it.apply { signingDetails = systemAppSigningDetails } },
+                withSetting = { it.setPkgFlags(FLAG_SYSTEM) })
+
+        val pm = createPackageManagerService()
+
+        assertThat("system package should exist after boot",
+                pm.mPackages[systemAppPackageName], notNullValue())
+        assertThat("system package should remain at version on data/app",
+                pm.mPackages[systemAppPackageName]!!.longVersionCode, equalTo(3))
+    }
+}
\ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/OWNERS b/services/tests/mockingservicestests/src/com/android/server/power/OWNERS
new file mode 100644
index 0000000..d68066b
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/power/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/power/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/usage/OWNERS b/services/tests/mockingservicestests/src/com/android/server/usage/OWNERS
new file mode 100644
index 0000000..d3227de
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/usage/OWNERS
@@ -0,0 +1 @@
+include /services/usage/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/utils/quota/MultiRateLimiterTest.java b/services/tests/mockingservicestests/src/com/android/server/utils/quota/MultiRateLimiterTest.java
new file mode 100644
index 0000000..df533f3
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/utils/quota/MultiRateLimiterTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.utils.quota;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.testing.TestableContext;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.time.Duration;
+
+@SmallTest
+public class MultiRateLimiterTest {
+
+    private static final int USER_ID = 1;
+    private static final String PACKAGE_NAME_1 = "com.android.package.one";
+    private static final String PACKAGE_NAME_2 = "com.android.package.two";
+    private static final String TAG = "tag";
+
+    @Rule
+    public final TestableContext mContext =
+            new TestableContext(InstrumentationRegistry.getContext(), null);
+
+    private final InjectorForTest mInjector = new InjectorForTest();
+
+    private static class InjectorForTest extends QuotaTracker.Injector {
+        Duration mElapsedTime = Duration.ZERO;
+
+        @Override
+        public long getElapsedRealtime() {
+            return mElapsedTime.toMillis();
+        }
+
+        @Override
+        public boolean isAlarmManagerReady() {
+            return true;
+        }
+    }
+
+    @Test
+    public void testSingleRateLimit_belowLimit_isWithinQuota() {
+        MultiRateLimiter multiRateLimiter =  new MultiRateLimiter.Builder(mContext, mInjector)
+                .addRateLimit(3, Duration.ofSeconds(20))
+                .build();
+
+        // Three quick events are within quota.
+        mInjector.mElapsedTime = Duration.ZERO;
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(50);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(100);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+    }
+
+    @Test
+    public void testSingleRateLimit_aboveLimit_isNotWithinQuota() {
+        MultiRateLimiter multiRateLimiter =  new MultiRateLimiter.Builder(mContext, mInjector)
+                .addRateLimit(3, Duration.ofSeconds(20))
+                .build();
+
+        mInjector.mElapsedTime = Duration.ZERO;
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(50);
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(100);
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(150);
+        // We hit the limit, 4th event in under 20 seconds is not within quota.
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isFalse();
+    }
+
+    @Test
+    public void testSingleRateLimit_afterGoingAboveQuotaAndWaitingWindow_isBackWithinQuota() {
+        MultiRateLimiter multiRateLimiter =  new MultiRateLimiter.Builder(mContext, mInjector)
+                .addRateLimit(3, Duration.ofSeconds(20))
+                .build();
+
+        mInjector.mElapsedTime = Duration.ZERO;
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(50);
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(100);
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(150);
+        // We hit the limit, 4th event in under 20 seconds is not within quota.
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isFalse();
+
+        mInjector.mElapsedTime = Duration.ofSeconds(21);
+        // 20 seconds have passed, we're again within quota.
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+    }
+
+    @Test
+    public void createMultipleRateLimits_testTheyLimitsAsExpected() {
+        MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector)
+                .addRateLimit(3, Duration.ofSeconds(20)) // 1st limit
+                .addRateLimit(4, Duration.ofSeconds(40)) // 2nd limit
+                .addRateLimit(5, Duration.ofSeconds(60)) // 3rd limit
+                .build();
+
+        // Testing the 1st limit
+        mInjector.mElapsedTime = Duration.ZERO;
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(50);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(100);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(150);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isFalse();
+
+        mInjector.mElapsedTime = Duration.ofSeconds(21);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        // Testing the 2nd limit
+        mInjector.mElapsedTime = Duration.ofSeconds(35);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isFalse();
+
+        mInjector.mElapsedTime = Duration.ofSeconds(42);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        // Testing the 3rd limit.
+        mInjector.mElapsedTime = Duration.ofSeconds(43);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isFalse();
+
+        mInjector.mElapsedTime = Duration.ofSeconds(62);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+    }
+
+    @Test
+    public void createSingleRateLimit_testItLimitsOnlyGivenUptc() {
+        MultiRateLimiter multiRateLimiter =  new MultiRateLimiter.Builder(mContext, mInjector)
+                .addRateLimit(3, Duration.ofSeconds(20))
+                .build();
+
+        mInjector.mElapsedTime = Duration.ZERO;
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_2, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(50);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_2, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(100);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_2, TAG)).isTrue();
+        multiRateLimiter.noteEvent(USER_ID, PACKAGE_NAME_1, TAG);
+
+        mInjector.mElapsedTime = Duration.ofMillis(150);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isFalse();
+        // Different userId - packageName - tag combination is still allowed.
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_2, TAG)).isTrue();
+
+        mInjector.mElapsedTime = Duration.ofSeconds(21);
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_1, TAG)).isTrue();
+        assertThat(multiRateLimiter.isWithinQuota(USER_ID, PACKAGE_NAME_2, TAG)).isTrue();
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/OWNERS b/services/tests/mockingservicestests/src/com/android/server/wallpaper/OWNERS
new file mode 100644
index 0000000..8ff0f74
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/wallpaper/OWNERS
diff --git a/services/tests/mockingservicestests/utils-mockito/com/android/server/extendedtestutils/ExtendedMockitoUtils.kt b/services/tests/mockingservicestests/utils-mockito/com/android/server/extendedtestutils/ExtendedMockitoUtils.kt
new file mode 100644
index 0000000..72ae77e
--- /dev/null
+++ b/services/tests/mockingservicestests/utils-mockito/com/android/server/extendedtestutils/ExtendedMockitoUtils.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.extendedtestutils
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.dx.mockito.inline.extended.MockedMethod
+import com.android.dx.mockito.inline.extended.StaticCapableStubber
+import org.mockito.stubbing.Answer
+
+fun <T> StaticCapableStubber.wheneverStatic(methodCall: MockedMethod<T>) {
+    this.`when`(methodCall)
+}
+
+fun <T> wheneverStatic(mockedMethod: MockedMethod<T>) = object : CustomStaticStubber<T> {
+    override fun thenAnswer(answer: Answer<T>) {
+        ExtendedMockito.doAnswer(answer).wheneverStatic(mockedMethod)
+    }
+
+    override fun thenReturn(value: T) {
+        ExtendedMockito.doReturn(value).wheneverStatic(mockedMethod)
+    }
+}
+
+interface CustomStaticStubber<T> {
+    fun thenAnswer(answer: Answer<T>)
+    fun thenReturn(value: T)
+}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 343b156..6daa381 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -33,6 +33,7 @@
         "androidx.test.ext.truth",
         "androidx.test.runner",
         "androidx.test.rules",
+        "platform-compat-test-rules",
         "mockito-target-minus-junit4",
         "platform-test-annotations",
         "ShortcutManagerTestUtils",
@@ -111,6 +112,16 @@
 }
 
 java_library {
+    name: "servicestests-core-utils",
+    srcs: [
+        "src/com/android/server/pm/PackageSettingBuilder.java",
+    ],
+    static_libs: [
+        "services.core",
+    ],
+}
+
+java_library {
     name: "servicestests-utils",
     srcs: [
         "utils/**/*.java",
diff --git a/services/tests/servicestests/apks/OWNERS b/services/tests/servicestests/apks/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/services/tests/servicestests/apks/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/services/tests/servicestests/assets/NetworkPolicy/OWNERS b/services/tests/servicestests/assets/NetworkPolicy/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/services/tests/servicestests/assets/NetworkPolicy/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/OWNERS b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/services/tests/servicestests/assets/NetworkPolicyManagerServiceTest/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java
deleted file mode 100644
index 33ea1d6..0000000
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementInternalTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 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 com.android.server;
-
-import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
-import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
-import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
-import static android.net.INetd.FIREWALL_RULE_ALLOW;
-import static android.net.INetd.FIREWALL_RULE_DENY;
-import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
-import static android.util.DebugUtils.valueToString;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.net.NetworkPolicyManager;
-import android.util.ArrayMap;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.function.BiFunction;
-
-/**
- * Test class for {@link NetworkManagementInternal}.
- *
- * To run the tests, use
- *
- * runtest -c com.android.server.NetworkManagementInternalTest frameworks-services
- *
- * or the following steps:
- *
- * Build: m FrameworksServicesTests
- * Install: adb install -r \
- *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
- * Run: adb shell am instrument -e class com.android.server.NetworkManagementInternalTest -w \
- *     com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NetworkManagementInternalTest {
-    private static final int TEST_UID = 111;
-
-    private NetworkManagementService.Injector mInjector;
-    private NetworkManagementInternal mNmi;
-
-    @Before
-    public void setUp() {
-        final NetworkManagementService service = new NetworkManagementService();
-        mInjector = service.getInjector();
-        mNmi = service.new LocalService();
-    }
-
-    @Test
-    public void testIsNetworkRestrictedForUid() {
-        // No firewall chains enabled
-        assertFalse(mNmi.isNetworkRestrictedForUid(TEST_UID));
-
-        // Restrict usage of mobile data in background
-        mInjector.setUidOnMeteredNetworkList(true, TEST_UID, true);
-        assertTrue("Should be true since mobile data usage is restricted",
-                mNmi.isNetworkRestrictedForUid(TEST_UID));
-        mInjector.reset();
-
-        // Data saver is on and uid is not allowlisted
-        mInjector.setDataSaverMode(true);
-        mInjector.setUidOnMeteredNetworkList(false, TEST_UID, false);
-        assertTrue("Should be true since data saver is on and the uid is not whitelisted",
-                mNmi.isNetworkRestrictedForUid(TEST_UID));
-        mInjector.reset();
-
-        // Data saver is on and uid is allowlisted
-        mInjector.setDataSaverMode(true);
-        mInjector.setUidOnMeteredNetworkList(false, TEST_UID, true);
-        assertFalse("Should be false since data saver is on and the uid is whitelisted",
-                mNmi.isNetworkRestrictedForUid(TEST_UID));
-        mInjector.reset();
-
-        final ArrayMap<Integer, ArrayMap<Integer, Boolean>> expected = new ArrayMap<>();
-        // Dozable chain
-        final ArrayMap<Integer, Boolean> isRestrictedForDozable = new ArrayMap<>();
-        isRestrictedForDozable.put(FIREWALL_RULE_DEFAULT, true);
-        isRestrictedForDozable.put(FIREWALL_RULE_ALLOW, false);
-        isRestrictedForDozable.put(FIREWALL_RULE_DENY, true);
-        expected.put(FIREWALL_CHAIN_DOZABLE, isRestrictedForDozable);
-        // Powersaver chain
-        final ArrayMap<Integer, Boolean> isRestrictedForPowerSave = new ArrayMap<>();
-        isRestrictedForPowerSave.put(FIREWALL_RULE_DEFAULT, true);
-        isRestrictedForPowerSave.put(FIREWALL_RULE_ALLOW, false);
-        isRestrictedForPowerSave.put(FIREWALL_RULE_DENY, true);
-        expected.put(FIREWALL_CHAIN_POWERSAVE, isRestrictedForPowerSave);
-        // Standby chain
-        final ArrayMap<Integer, Boolean> isRestrictedForStandby = new ArrayMap<>();
-        isRestrictedForStandby.put(FIREWALL_RULE_DEFAULT, false);
-        isRestrictedForStandby.put(FIREWALL_RULE_ALLOW, false);
-        isRestrictedForStandby.put(FIREWALL_RULE_DENY, true);
-        expected.put(FIREWALL_CHAIN_STANDBY, isRestrictedForStandby);
-
-        final int[] chains = {
-                FIREWALL_CHAIN_STANDBY,
-                FIREWALL_CHAIN_POWERSAVE,
-                FIREWALL_CHAIN_DOZABLE
-        };
-        final int[] states = {
-                FIREWALL_RULE_ALLOW,
-                FIREWALL_RULE_DENY,
-                FIREWALL_RULE_DEFAULT
-        };
-        BiFunction<Integer, Integer, String> errorMsg = (chain, state) -> {
-            return String.format("Unexpected value for chain: %s and state: %s",
-                    valueToString(NetworkPolicyManager.class, "FIREWALL_CHAIN_", chain),
-                    valueToString(NetworkPolicyManager.class, "FIREWALL_RULE_", state));
-        };
-        for (int chain : chains) {
-            final ArrayMap<Integer, Boolean> expectedValues = expected.get(chain);
-            mInjector.setFirewallChainState(chain, true);
-            for (int state : states) {
-                mInjector.setFirewallRule(chain, TEST_UID, state);
-                assertEquals(errorMsg.apply(chain, state),
-                        expectedValues.get(state), mNmi.isNetworkRestrictedForUid(TEST_UID));
-            }
-            mInjector.reset();
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index e609adc..ce3751a 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -72,7 +72,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.devicepolicy.MockUtils;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.permission.LegacyPermissionManagerInternal;
 
 import com.google.android.collect.Lists;
 
@@ -133,10 +133,10 @@
     @Mock private UnaryOperator<List<ScoredNetwork>> mScanResultsFilter;
     @Mock private WifiInfo mWifiInfo;
     @Mock private NetworkScoreService.ScoringServiceConnection mServiceConnection;
-    @Mock private PermissionManagerServiceInternal mPermissionManagerInternal;
+    @Mock private LegacyPermissionManagerInternal mPermissionManagerInternal;
     @Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
-    @Captor private
-    ArgumentCaptor<PermissionManagerServiceInternal.PackagesProvider> mPackagesProviderCaptor;
+    @Captor private ArgumentCaptor<LegacyPermissionManagerInternal.PackagesProvider>
+            mPackagesProviderCaptor;
 
     private ContentResolver mContentResolver;
     private NetworkScoreService mNetworkScoreService;
@@ -165,7 +165,7 @@
         mHandlerThread = new HandlerThread("NetworkScoreServiceTest");
         mHandlerThread.start();
         LocalServices.addService(
-                PermissionManagerServiceInternal.class, mPermissionManagerInternal);
+                LegacyPermissionManagerInternal.class, mPermissionManagerInternal);
         mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager,
                 networkScorerAppData -> mServiceConnection, mHandlerThread.getLooper());
         WifiConfiguration configuration = new WifiConfiguration();
@@ -191,7 +191,7 @@
     @After
     public void tearDown() throws Exception {
         mHandlerThread.quitSafely();
-        LocalServices.removeServiceForTest(PermissionManagerServiceInternal.class);
+        LocalServices.removeServiceForTest(LegacyPermissionManagerInternal.class);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/OWNERS b/services/tests/servicestests/src/com/android/server/OWNERS
new file mode 100644
index 0000000..6153db3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/OWNERS
@@ -0,0 +1,6 @@
+per-file *Alarm* = file:/apex/jobscheduler/OWNERS
+per-file *AppOps* = file:/core/java/android/permission/OWNERS
+per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS
+per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS
+per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
+per-file *Vibrator* = file:/services/core/java/com/android/server/vibrator/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 3f3d5e5..839bc93 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -35,6 +35,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
 import android.graphics.drawable.Icon;
 import android.os.IBinder;
 import android.os.UserHandle;
@@ -94,6 +95,8 @@
     @Mock private IAccessibilityServiceClient mMockServiceClient;
     @Mock private WindowMagnificationManager mMockWindowMagnificationMgr;
     @Mock private MagnificationController mMockMagnificationController;
+    @Mock private Resources mMockResources;
+
     private AccessibilityUserState mUserState;
 
     private MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
@@ -121,6 +124,9 @@
             mMockA11yDisplayListener,
             mMockMagnificationController);
 
+        mMockResources = mock(Resources.class);
+        when(mMockContext.getResources()).thenReturn(mMockResources);
+
         final AccessibilityUserState userState = new AccessibilityUserState(
                 mA11yms.getCurrentUserIdLocked(), mMockContext, mA11yms);
         mA11yms.mUserStates.put(mA11yms.getCurrentUserIdLocked(), userState);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
index fbfb045..81ca92c 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
@@ -42,11 +42,16 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Color;
 import android.provider.Settings;
 import android.test.mock.MockContentResolver;
 import android.testing.DexmakerShareClassLoaderRule;
 import android.util.ArraySet;
 
+import androidx.test.InstrumentationRegistry;
+
+import com.android.internal.R;
 import com.android.internal.util.test.FakeSettingsProvider;
 
 import org.junit.After;
@@ -90,8 +95,13 @@
 
     private AccessibilityUserState mUserState;
 
+    private int mFocusStrokeWidthDefaultValue;
+    private int mFocusColorDefaultValue;
+
     @Before
     public void setUp() {
+        final Resources resources = InstrumentationRegistry.getContext().getResources();
+
         MockitoAnnotations.initMocks(this);
         FakeSettingsProvider.clearSettingsProvider();
         mMockResolver = new MockContentResolver();
@@ -99,6 +109,11 @@
         when(mMockContext.getContentResolver()).thenReturn(mMockResolver);
         when(mMockServiceInfo.getComponentName()).thenReturn(COMPONENT_NAME);
         when(mMockConnection.getServiceInfo()).thenReturn(mMockServiceInfo);
+        when(mMockContext.getResources()).thenReturn(resources);
+
+        mFocusStrokeWidthDefaultValue =
+                resources.getDimensionPixelSize(R.dimen.accessibility_focus_highlight_stroke_width);
+        mFocusColorDefaultValue = resources.getColor(R.color.accessibility_focus_highlight_color);
 
         mUserState = new AccessibilityUserState(USER_ID, mMockContext, mMockListener);
     }
@@ -129,6 +144,7 @@
         mUserState.setUserNonInteractiveUiTimeoutLocked(30);
         mUserState.setUserInteractiveUiTimeoutLocked(30);
         mUserState.setMagnificationModeLocked(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        mUserState.setFocusAppearanceLocked(20, Color.BLUE);
 
         mUserState.onSwitchToAnotherUserLocked();
 
@@ -150,6 +166,8 @@
         assertEquals(0, mUserState.getUserInteractiveUiTimeoutLocked());
         assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
                 mUserState.getMagnificationModeLocked());
+        assertEquals(mFocusStrokeWidthDefaultValue, mUserState.getFocusStrokeWidthLocked());
+        assertEquals(mFocusColorDefaultValue, mUserState.getFocusColorLocked());
     }
 
     @Test
@@ -350,6 +368,21 @@
                 mUserState.getMagnificationModeLocked());
     }
 
+    @Test
+    public void setFocusAppearanceData_returnExpectedFocusAppearanceData() {
+        final int focusStrokeWidthValue = 100;
+        final int focusColorValue = Color.BLUE;
+
+        assertEquals(mFocusStrokeWidthDefaultValue, mUserState.getFocusStrokeWidthLocked());
+        assertEquals(mFocusColorDefaultValue, mUserState.getFocusColorLocked());
+
+        mUserState.setFocusAppearanceLocked(focusStrokeWidthValue, focusColorValue);
+
+        assertEquals(focusStrokeWidthValue, mUserState.getFocusStrokeWidthLocked());
+        assertEquals(focusColorValue, mUserState.getFocusColorLocked());
+
+    }
+
     private int getSecureIntForUser(String key, int userId) {
         return Settings.Secure.getIntForUser(mMockResolver, key, -1, userId);
     }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/OWNERS b/services/tests/servicestests/src/com/android/server/accessibility/OWNERS
new file mode 100644
index 0000000..b74281e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/accessibility/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/accounts/OWNERS b/services/tests/servicestests/src/com/android/server/accounts/OWNERS
new file mode 100644
index 0000000..df1b4f4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accounts/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/accounts/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/adb/OWNERS b/services/tests/servicestests/src/com/android/server/adb/OWNERS
new file mode 100644
index 0000000..b97f795
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/adb/OWNERS
@@ -0,0 +1 @@
+include platform/packages/modules/adb:/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/am/OWNERS b/services/tests/servicestests/src/com/android/server/am/OWNERS
new file mode 100644
index 0000000..72c0a9e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/am/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/appop/OWNERS b/services/tests/servicestests/src/com/android/server/appop/OWNERS
new file mode 100644
index 0000000..999ea0e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/appop/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/permission/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/OWNERS b/services/tests/servicestests/src/com/android/server/appsearch/OWNERS
new file mode 100644
index 0000000..ebe9e4e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/appsearch/OWNERS
@@ -0,0 +1 @@
+include /apex/appsearch/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
index b929061..f38def8 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
@@ -37,6 +37,7 @@
 import com.android.server.appsearch.proto.StringIndexingConfig;
 import com.android.server.appsearch.proto.TermMatchType;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
 import org.junit.Before;
@@ -46,9 +47,7 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 public class AppSearchImplTest {
     @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
@@ -66,14 +65,15 @@
                                         + VisibilityStore.SCHEMA_TYPE)
                         .addProperty(
                                 new AppSearchSchema.PropertyConfig.Builder(
-                                                VisibilityStore.PLATFORM_HIDDEN_PROPERTY)
+                                                VisibilityStore.NOT_PLATFORM_SURFACEABLE_PROPERTY)
                                         .setDataType(
                                                 AppSearchSchema.PropertyConfig.DATA_TYPE_STRING)
                                         .setCardinality(
                                                 AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
                                         .build())
                         .build();
-        mVisibilitySchemaProto = SchemaToProtoConverter.convert(visibilityAppSearchSchema);
+        mVisibilitySchemaProto =
+                SchemaToProtoConverter.toSchemaTypeConfigProto(visibilityAppSearchSchema);
     }
 
     /**
@@ -340,9 +340,13 @@
     @Test
     public void testOptimize() throws Exception {
         // Insert schema
-        Set<AppSearchSchema> schemas =
-                Collections.singleton(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema("database", schemas, /*forceOverride=*/ false);
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+        mAppSearchImpl.setSchema(
+                "database",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ false);
 
         // Insert enough documents.
         for (int i = 0;
@@ -351,7 +355,7 @@
                                 + AppSearchImpl.CHECK_OPTIMIZE_INTERVAL;
                 i++) {
             GenericDocument document =
-                    new GenericDocument.Builder("uri" + i, "type")
+                    new GenericDocument.Builder<>("uri" + i, "type")
                             .setNamespace("namespace")
                             .build();
             mAppSearchImpl.putDocument("database", document);
@@ -392,13 +396,17 @@
         SearchSpecProto.Builder searchSpecProto = SearchSpecProto.newBuilder().setQuery("");
 
         // Insert schema
-        Set<AppSearchSchema> schemas =
-                Collections.singleton(new AppSearchSchema.Builder("type").build());
-        mAppSearchImpl.setSchema("database", schemas, /*forceOverride=*/ false);
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+        mAppSearchImpl.setSchema(
+                "database",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ false);
 
         // Insert document
         GenericDocument document =
-                new GenericDocument.Builder("uri", "type").setNamespace("namespace").build();
+                new GenericDocument.Builder<>("uri", "type").setNamespace("namespace").build();
         mAppSearchImpl.putDocument("database", document);
 
         // Rewrite SearchSpec
@@ -413,20 +421,28 @@
         SearchSpecProto.Builder searchSpecProto = SearchSpecProto.newBuilder().setQuery("");
 
         // Insert schema
-        Set<AppSearchSchema> schemas =
-                Set.of(
+        List<AppSearchSchema> schemas =
+                ImmutableList.of(
                         new AppSearchSchema.Builder("typeA").build(),
                         new AppSearchSchema.Builder("typeB").build());
-        mAppSearchImpl.setSchema("database1", schemas, /*forceOverride=*/ false);
-        mAppSearchImpl.setSchema("database2", schemas, /*forceOverride=*/ false);
+        mAppSearchImpl.setSchema(
+                "database1",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ false);
+        mAppSearchImpl.setSchema(
+                "database2",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ false);
 
         // Insert documents
         GenericDocument document1 =
-                new GenericDocument.Builder("uri", "typeA").setNamespace("namespace").build();
+                new GenericDocument.Builder<>("uri", "typeA").setNamespace("namespace").build();
         mAppSearchImpl.putDocument("database1", document1);
 
         GenericDocument document2 =
-                new GenericDocument.Builder("uri", "typeB").setNamespace("namespace").build();
+                new GenericDocument.Builder<>("uri", "typeB").setNamespace("namespace").build();
         mAppSearchImpl.putDocument("database2", document2);
 
         // Rewrite SearchSpec
@@ -477,10 +493,14 @@
 
     @Test
     public void testSetSchema() throws Exception {
-        Set<AppSearchSchema> schemas =
-                Collections.singleton(new AppSearchSchema.Builder("Email").build());
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
         // Set schema Email to AppSearch database1
-        mAppSearchImpl.setSchema("database1", schemas, /*forceOverride=*/ false);
+        mAppSearchImpl.setSchema(
+                "database1",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ false);
 
         // Create expected schemaType proto.
         SchemaProto expectedProto =
@@ -500,35 +520,47 @@
     public void testSetSchema_existingSchemaRetainsVisibilitySetting() throws Exception {
         mAppSearchImpl.setSchema(
                 "database",
-                Collections.singleton(new AppSearchSchema.Builder("schema1").build()),
+                Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
+                /*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
                 /*forceOverride=*/ false);
-        mAppSearchImpl.setVisibility("database", Set.of("schema1"));
 
         // "schema1" is platform hidden now
-        assertThat(mAppSearchImpl.getVisibilityStoreLocked().getPlatformHiddenSchemas("database"))
+        assertThat(
+                        mAppSearchImpl
+                                .getVisibilityStoreLocked()
+                                .getSchemasNotPlatformSurfaceable("database"))
                 .containsExactly("database/schema1");
 
         // Add a new schema, and include the already-existing "schema1"
         mAppSearchImpl.setSchema(
                 "database",
-                Set.of(
+                ImmutableList.of(
                         new AppSearchSchema.Builder("schema1").build(),
                         new AppSearchSchema.Builder("schema2").build()),
+                /*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
                 /*forceOverride=*/ false);
 
         // Check that "schema1" is still platform hidden, but "schema2" is the default platform
         // visible.
-        assertThat(mAppSearchImpl.getVisibilityStoreLocked().getPlatformHiddenSchemas("database"))
+        assertThat(
+                        mAppSearchImpl
+                                .getVisibilityStoreLocked()
+                                .getSchemasNotPlatformSurfaceable("database"))
                 .containsExactly("database/schema1");
     }
 
     @Test
     public void testRemoveSchema() throws Exception {
-        Set<AppSearchSchema> schemas = new HashSet<>();
-        schemas.add(new AppSearchSchema.Builder("Email").build());
-        schemas.add(new AppSearchSchema.Builder("Document").build());
+        List<AppSearchSchema> schemas =
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Email").build(),
+                        new AppSearchSchema.Builder("Document").build());
         // Set schema Email and Document to AppSearch database1
-        mAppSearchImpl.setSchema("database1", schemas, /*forceOverride=*/ false);
+        mAppSearchImpl.setSchema(
+                "database1",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ false);
 
         // Create expected schemaType proto.
         SchemaProto expectedProto =
@@ -547,20 +579,27 @@
         assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
                 .containsExactlyElementsIn(expectedTypes);
 
-        final Set<AppSearchSchema> finalSchemas =
-                Collections.singleton(new AppSearchSchema.Builder("Email").build());
+        final List<AppSearchSchema> finalSchemas =
+                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
         // Check the incompatible error has been thrown.
         AppSearchException e =
                 expectThrows(
                         AppSearchException.class,
                         () ->
                                 mAppSearchImpl.setSchema(
-                                        "database1", finalSchemas, /*forceOverride=*/ false));
+                                        "database1",
+                                        finalSchemas,
+                                        /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                                        /*forceOverride=*/ false));
         assertThat(e).hasMessageThat().contains("Schema is incompatible");
         assertThat(e).hasMessageThat().contains("Deleted types: [database1/Document]");
 
         // ForceOverride to delete.
-        mAppSearchImpl.setSchema("database1", finalSchemas, /*forceOverride=*/ true);
+        mAppSearchImpl.setSchema(
+                "database1",
+                finalSchemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ true);
 
         // Check Document schema is removed.
         expectedProto =
@@ -579,13 +618,22 @@
     @Test
     public void testRemoveSchema_differentDataBase() throws Exception {
         // Create schemas
-        Set<AppSearchSchema> schemas = new HashSet<>();
-        schemas.add(new AppSearchSchema.Builder("Email").build());
-        schemas.add(new AppSearchSchema.Builder("Document").build());
+        List<AppSearchSchema> schemas =
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Email").build(),
+                        new AppSearchSchema.Builder("Document").build());
 
         // Set schema Email and Document to AppSearch database1 and 2
-        mAppSearchImpl.setSchema("database1", schemas, /*forceOverride=*/ false);
-        mAppSearchImpl.setSchema("database2", schemas, /*forceOverride=*/ false);
+        mAppSearchImpl.setSchema(
+                "database1",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ false);
+        mAppSearchImpl.setSchema(
+                "database2",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ false);
 
         // Create expected schemaType proto.
         SchemaProto expectedProto =
@@ -610,8 +658,12 @@
                 .containsExactlyElementsIn(expectedTypes);
 
         // Save only Email to database1 this time.
-        schemas = Collections.singleton(new AppSearchSchema.Builder("Email").build());
-        mAppSearchImpl.setSchema("database1", schemas, /*forceOverride=*/ true);
+        schemas = Collections.singletonList(new AppSearchSchema.Builder("Email").build());
+        mAppSearchImpl.setSchema(
+                "database1",
+                schemas,
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ true);
 
         // Create expected schemaType list, database 1 should only contain Email but database 2
         // remains in same.
@@ -638,76 +690,82 @@
     public void testRemoveSchema_removedFromVisibilityStore() throws Exception {
         mAppSearchImpl.setSchema(
                 "database",
-                Collections.singleton(new AppSearchSchema.Builder("schema1").build()),
+                Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
+                /*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
                 /*forceOverride=*/ false);
-        mAppSearchImpl.setVisibility("database", Set.of("schema1"));
 
         // "schema1" is platform hidden now
-        assertThat(mAppSearchImpl.getVisibilityStoreLocked().getPlatformHiddenSchemas("database"))
+        assertThat(
+                        mAppSearchImpl
+                                .getVisibilityStoreLocked()
+                                .getSchemasNotPlatformSurfaceable("database"))
                 .containsExactly("database/schema1");
 
         // Remove "schema1" by force overriding
-        mAppSearchImpl.setSchema("database", Collections.emptySet(), /*forceOverride=*/ true);
+        mAppSearchImpl.setSchema(
+                "database",
+                Collections.emptyList(),
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
+                /*forceOverride=*/ true);
 
         // Check that "schema1" is no longer considered platform hidden
-        assertThat(mAppSearchImpl.getVisibilityStoreLocked().getPlatformHiddenSchemas("database"))
+        assertThat(
+                        mAppSearchImpl
+                                .getVisibilityStoreLocked()
+                                .getSchemasNotPlatformSurfaceable("database"))
                 .isEmpty();
 
         // Add "schema1" back, it gets default visibility settings which means it's not platform
         // hidden.
         mAppSearchImpl.setSchema(
                 "database",
-                Collections.singleton(new AppSearchSchema.Builder("schema1").build()),
+                Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*forceOverride=*/ false);
-        assertThat(mAppSearchImpl.getVisibilityStoreLocked().getPlatformHiddenSchemas("database"))
+        assertThat(
+                        mAppSearchImpl
+                                .getVisibilityStoreLocked()
+                                .getSchemasNotPlatformSurfaceable("database"))
                 .isEmpty();
     }
 
     @Test
-    public void testSetVisibility_defaultPlatformVisible() throws Exception {
+    public void testSetSchema_defaultPlatformVisible() throws Exception {
         mAppSearchImpl.setSchema(
                 "database",
-                Collections.singleton(new AppSearchSchema.Builder("Schema").build()),
+                Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*forceOverride=*/ false);
-        assertThat(mAppSearchImpl.getVisibilityStoreLocked().getPlatformHiddenSchemas("database"))
+        assertThat(
+                        mAppSearchImpl
+                                .getVisibilityStoreLocked()
+                                .getSchemasNotPlatformSurfaceable("database"))
                 .isEmpty();
     }
 
     @Test
-    public void testSetVisibility_platformHidden() throws Exception {
+    public void testSetSchema_platformHidden() throws Exception {
         mAppSearchImpl.setSchema(
                 "database",
-                Collections.singleton(new AppSearchSchema.Builder("Schema").build()),
+                Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
+                /*schemasNotPlatformSurfaceable=*/ Collections.singletonList("Schema"),
                 /*forceOverride=*/ false);
-        mAppSearchImpl.setVisibility("database", Set.of("Schema"));
-        assertThat(mAppSearchImpl.getVisibilityStoreLocked().getPlatformHiddenSchemas("database"))
+        assertThat(
+                        mAppSearchImpl
+                                .getVisibilityStoreLocked()
+                                .getSchemasNotPlatformSurfaceable("database"))
                 .containsExactly("database/Schema");
     }
 
     @Test
-    public void testSetVisibility_unknownSchema() throws Exception {
-        mAppSearchImpl.setSchema(
-                "database",
-                Collections.singleton(new AppSearchSchema.Builder("Schema").build()),
-                /*forceOverride=*/ false);
-
-        // We'll throw an exception if a client tries to set visibility on a schema we don't know
-        // about.
-        AppSearchException e =
-                expectThrows(
-                        AppSearchException.class,
-                        () -> mAppSearchImpl.setVisibility("database", Set.of("UnknownSchema")));
-        assertThat(e).hasMessageThat().contains("Unknown schema(s)");
-    }
-
-    @Test
     public void testHasSchemaType() throws Exception {
         // Nothing exists yet
         assertThat(mAppSearchImpl.hasSchemaTypeLocked("database", "Schema")).isFalse();
 
         mAppSearchImpl.setSchema(
                 "database",
-                Collections.singleton(new AppSearchSchema.Builder("Schema").build()),
+                Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*forceOverride=*/ false);
         assertThat(mAppSearchImpl.hasSchemaTypeLocked("database", "Schema")).isTrue();
 
@@ -723,7 +781,8 @@
         // Has database1
         mAppSearchImpl.setSchema(
                 "database1",
-                Collections.singleton(new AppSearchSchema.Builder("schema").build()),
+                Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*forceOverride=*/ false);
         assertThat(mAppSearchImpl.getDatabasesLocked())
                 .containsExactly(VisibilityStore.DATABASE_NAME, "database1");
@@ -731,7 +790,8 @@
         // Has both databases
         mAppSearchImpl.setSchema(
                 "database2",
-                Collections.singleton(new AppSearchSchema.Builder("schema").build()),
+                Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
+                /*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
                 /*forceOverride=*/ false);
         assertThat(mAppSearchImpl.getDatabasesLocked())
                 .containsExactly(VisibilityStore.DATABASE_NAME, "database1", "database2");
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/VisibilityStoreTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/VisibilityStoreTest.java
index dfe2de6..a1f575a 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/VisibilityStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/VisibilityStoreTest.java
@@ -41,34 +41,19 @@
     @Test
     public void testSetVisibility() throws Exception {
         mVisibilityStore.setVisibility(
-                "database", /*platformHiddenSchemas=*/ Set.of("schema1", "schema2"));
-        assertThat(mVisibilityStore.getPlatformHiddenSchemas("database"))
+                "database", /*schemasNotPlatformSurfaceable=*/ Set.of("schema1", "schema2"));
+        assertThat(mVisibilityStore.getSchemasNotPlatformSurfaceable("database"))
                 .containsExactly("schema1", "schema2");
 
         // New .setVisibility() call completely overrides previous visibility settings. So
         // "schema1" isn't preserved.
         mVisibilityStore.setVisibility(
-                "database", /*platformHiddenSchemas=*/ Set.of("schema1", "schema3"));
-        assertThat(mVisibilityStore.getPlatformHiddenSchemas("database"))
+                "database", /*schemasNotPlatformSurfaceable=*/ Set.of("schema1", "schema3"));
+        assertThat(mVisibilityStore.getSchemasNotPlatformSurfaceable("database"))
                 .containsExactly("schema1", "schema3");
 
         mVisibilityStore.setVisibility(
-                "database", /*platformHiddenSchemas=*/ Collections.emptySet());
-        assertThat(mVisibilityStore.getPlatformHiddenSchemas("database")).isEmpty();
-    }
-
-    @Test
-    public void testRemoveSchemas() throws Exception {
-        mVisibilityStore.setVisibility(
-                "database", /*platformHiddenSchemas=*/ Set.of("schema1", "schema2"));
-
-        // Removed just schema1
-        mVisibilityStore.updateSchemas("database", /*schemasToRemove=*/ Set.of("schema1"));
-        assertThat(mVisibilityStore.getPlatformHiddenSchemas("database"))
-                .containsExactly("schema2");
-
-        // Removed everything now
-        mVisibilityStore.updateSchemas("database", /*schemasToRemove=*/ Set.of("schema2"));
-        assertThat(mVisibilityStore.getPlatformHiddenSchemas("database")).isEmpty();
+                "database", /*schemasNotPlatformSurfaceable=*/ Collections.emptySet());
+        assertThat(mVisibilityStore.getSchemasNotPlatformSurfaceable("database")).isEmpty();
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
index 98392a7..194be37 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
@@ -94,20 +94,24 @@
                 PropertyProto.newBuilder()
                         .setName("documentKey1")
                         .addDocumentValues(
-                                GenericDocumentToProtoConverter.convert(DOCUMENT_PROPERTIES_1)));
+                                GenericDocumentToProtoConverter.toDocumentProto(
+                                        DOCUMENT_PROPERTIES_1)));
         propertyProtoMap.put(
                 "documentKey2",
                 PropertyProto.newBuilder()
                         .setName("documentKey2")
                         .addDocumentValues(
-                                GenericDocumentToProtoConverter.convert(DOCUMENT_PROPERTIES_2)));
+                                GenericDocumentToProtoConverter.toDocumentProto(
+                                        DOCUMENT_PROPERTIES_2)));
         List<String> sortedKey = new ArrayList<>(propertyProtoMap.keySet());
         Collections.sort(sortedKey);
         for (String key : sortedKey) {
             documentProtoBuilder.addProperties(propertyProtoMap.get(key));
         }
         DocumentProto documentProto = documentProtoBuilder.build();
-        assertThat(GenericDocumentToProtoConverter.convert(document)).isEqualTo(documentProto);
-        assertThat(document).isEqualTo(GenericDocumentToProtoConverter.convert(documentProto));
+        assertThat(GenericDocumentToProtoConverter.toDocumentProto(document))
+                .isEqualTo(documentProto);
+        assertThat(document)
+                .isEqualTo(GenericDocumentToProtoConverter.toGenericDocument(documentProto));
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
index dedfca4..88edcb8 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
@@ -89,7 +89,10 @@
                                                                 TermMatchType.Code.PREFIX)))
                         .build();
 
-        assertThat(SchemaToProtoConverter.convert(emailSchema)).isEqualTo(expectedEmailProto);
+        assertThat(SchemaToProtoConverter.toSchemaTypeConfigProto(emailSchema))
+                .isEqualTo(expectedEmailProto);
+        assertThat(SchemaToProtoConverter.toAppSearchSchema(expectedEmailProto))
+                .isEqualTo(emailSchema);
     }
 
     @Test
@@ -151,7 +154,9 @@
                                                                 TermMatchType.Code.UNKNOWN)))
                         .build();
 
-        assertThat(SchemaToProtoConverter.convert(musicRecordingSchema))
+        assertThat(SchemaToProtoConverter.toSchemaTypeConfigProto(musicRecordingSchema))
                 .isEqualTo(expectedMusicRecordingProto);
+        assertThat(SchemaToProtoConverter.toAppSearchSchema(expectedMusicRecordingProto))
+                .isEqualTo(musicRecordingSchema);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
index 518f532..7c68c6b 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
@@ -83,7 +83,7 @@
 
         // Making ResultReader and getting Snippet values.
         SearchResultPage searchResultPage =
-                SearchResultToProtoConverter.convertToSearchResultPage(searchResultProto);
+                SearchResultToProtoConverter.toSearchResultPage(searchResultProto);
         for (SearchResult result : searchResultPage.getResults()) {
             SearchResult.MatchInfo match = result.getMatches().get(0);
             assertThat(match.getPropertyPath()).isEqualTo(propertyKeyString);
@@ -131,7 +131,7 @@
                 SearchResultProto.newBuilder().addResults(resultProto).build();
 
         SearchResultPage searchResultPage =
-                SearchResultToProtoConverter.convertToSearchResultPage(searchResultProto);
+                SearchResultToProtoConverter.toSearchResultPage(searchResultProto);
         for (SearchResult result : searchResultPage.getResults()) {
             assertThat(result.getMatches()).isEmpty();
         }
@@ -196,7 +196,7 @@
 
         // Making ResultReader and getting Snippet values.
         SearchResultPage searchResultPage =
-                SearchResultToProtoConverter.convertToSearchResultPage(searchResultProto);
+                SearchResultToProtoConverter.toSearchResultPage(searchResultProto);
         for (SearchResult result : searchResultPage.getResults()) {
 
             SearchResult.MatchInfo match1 = result.getMatches().get(0);
diff --git a/services/tests/servicestests/src/com/android/server/attention/OWNERS b/services/tests/servicestests/src/com/android/server/attention/OWNERS
new file mode 100644
index 0000000..51fc9bd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/attention/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/attention/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/backup/OWNERS b/services/tests/servicestests/src/com/android/server/backup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java
index 444155d..738527e 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java
@@ -18,14 +18,17 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.app.backup.BackupManager.OperationType;
+import android.compat.testing.PlatformCompatChangeRule;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.Property;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageParser;
 import android.content.pm.Signature;
@@ -38,9 +41,15 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.backup.UserBackupManagerService;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -50,17 +59,19 @@
 @RunWith(AndroidJUnit4.class)
 public class BackupEligibilityRulesTest {
     private static final String CUSTOM_BACKUP_AGENT_NAME = "custom.backup.agent";
-    private static final String TEST_PACKAGE_NAME = "test_package";
+    private static final String TEST_PACKAGE_NAME = "com.android.frameworks.servicestests";
 
     private static final Signature SIGNATURE_1 = generateSignature((byte) 1);
     private static final Signature SIGNATURE_2 = generateSignature((byte) 2);
     private static final Signature SIGNATURE_3 = generateSignature((byte) 3);
     private static final Signature SIGNATURE_4 = generateSignature((byte) 4);
 
+    @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
     @Mock private PackageManagerInternal mMockPackageManagerInternal;
     @Mock private PackageManager mPackageManager;
-    private BackupEligibilityRules mBackupEligibilityRules;
 
+    private BackupEligibilityRules mBackupEligibilityRules;
     private int mUserId;
 
     @Before
@@ -225,7 +236,6 @@
             throws Exception {
         ApplicationInfo applicationInfo = getApplicationInfo(Process.SYSTEM_UID,
                 /* flags */ 0, CUSTOM_BACKUP_AGENT_NAME);
-
         BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
                 OperationType.MIGRATION);
         boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo);
@@ -234,6 +244,82 @@
     }
 
     @Test
+    @EnableCompatChanges({BackupEligibilityRules.RESTRICT_ADB_BACKUP})
+    public void appIsEligibleForBackup_adbBackupNotAllowed_returnsFalseForAdbBackup()
+            throws Exception {
+        ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID,
+                /* flags */ ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, CUSTOM_BACKUP_AGENT_NAME);
+        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
+                OperationType.ADB_BACKUP);
+        when(mPackageManager.getProperty(eq(PackageManager.PROPERTY_ALLOW_ADB_BACKUP),
+                eq(TEST_PACKAGE_NAME))).thenReturn(getAdbBackupProperty(
+                        /* allowAdbBackup */ false));
+
+        boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    @EnableCompatChanges({BackupEligibilityRules.RESTRICT_ADB_BACKUP})
+    public void appIsEligibleForBackup_adbBackupAllowed_returnsTrueForAdbBackup()
+            throws Exception {
+        ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID,
+                /* flags */ ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, CUSTOM_BACKUP_AGENT_NAME);
+        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
+                OperationType.ADB_BACKUP);
+        when(mPackageManager.getProperty(eq(PackageManager.PROPERTY_ALLOW_ADB_BACKUP),
+                eq(TEST_PACKAGE_NAME))).thenReturn(getAdbBackupProperty(
+                /* allowAdbBackup */ true));
+
+        boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    @EnableCompatChanges({BackupEligibilityRules.RESTRICT_ADB_BACKUP})
+    public void appIsEligibleForBackup_debuggableNonPrivilegedApp_returnsTrueForAdbBackup()
+            throws Exception {
+        ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID,
+                /* flags */ ApplicationInfo.FLAG_DEBUGGABLE, CUSTOM_BACKUP_AGENT_NAME);
+        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
+                OperationType.ADB_BACKUP);
+
+        boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    @DisableCompatChanges({BackupEligibilityRules.RESTRICT_ADB_BACKUP})
+    public void appIsEligibleForBackup_allowBackupTrueBeforeS_returnsTrueForAdbBackup()
+            throws Exception {
+        ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID,
+                ApplicationInfo.FLAG_ALLOW_BACKUP, CUSTOM_BACKUP_AGENT_NAME);
+        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
+                OperationType.ADB_BACKUP);
+
+        boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    @DisableCompatChanges({BackupEligibilityRules.RESTRICT_ADB_BACKUP})
+    public void appIsEligibleForBackup_allowBackupFalseBeforeS_returnsFalseForAdbBackup()
+            throws Exception {
+        ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID,
+                /* flags */ 0, CUSTOM_BACKUP_AGENT_NAME);
+        BackupEligibilityRules eligibilityRules = getBackupEligibilityRules(
+                OperationType.ADB_BACKUP);
+
+        boolean isEligible = eligibilityRules.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
     public void appIsDisabled_stateDefaultManifestEnabled_returnsFalse() throws Exception {
         ApplicationInfo applicationInfo = new ApplicationInfo();
         applicationInfo.flags = 0;
@@ -789,10 +875,15 @@
     private static ApplicationInfo getApplicationInfo(int appUid, int flags,
             String backupAgentName) {
         ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.flags = 0;
+        applicationInfo.flags = flags;
         applicationInfo.packageName = TEST_PACKAGE_NAME;
         applicationInfo.uid = appUid;
         applicationInfo.backupAgentName = backupAgentName;
         return applicationInfo;
     }
+
+    private static Property getAdbBackupProperty(boolean allowAdbBackup) {
+        return new Property(PackageManager.PROPERTY_ALLOW_ADB_BACKUP, allowAdbBackup,
+                TEST_PACKAGE_NAME, /* className */ "");
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/compat/OWNERS b/services/tests/servicestests/src/com/android/server/compat/OWNERS
new file mode 100644
index 0000000..f8c3520
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/compat/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/compat/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OWNERS b/services/tests/servicestests/src/com/android/server/devicepolicy/OWNERS
new file mode 100644
index 0000000..e95633a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/admin/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/OWNERS b/services/tests/servicestests/src/com/android/server/devicestate/OWNERS
new file mode 100644
index 0000000..d9b0e2e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicestate/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/devicestate/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/display/OWNERS b/services/tests/servicestests/src/com/android/server/display/OWNERS
new file mode 100644
index 0000000..6ce1ee4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/display/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
index 6debc89..f2254a9 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
@@ -98,17 +98,17 @@
             }
 
             @Override
-            PowerManager getPowerManager() {
+            protected PowerManager getPowerManager() {
                 return powerManager;
             }
 
             @Override
-            void writeStringSystemProperty(String key, String value) {
+            protected void writeStringSystemProperty(String key, String value) {
                 // do nothing
             }
 
             @Override
-            HdmiCecConfig getHdmiCecConfig() {
+            protected HdmiCecConfig getHdmiCecConfig() {
                 return hdmiCecConfig;
             }
         };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
index a19336e..6e4d994 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
@@ -90,7 +90,7 @@
                     }
 
                     @Override
-                    PowerManager getPowerManager() {
+                    protected PowerManager getPowerManager() {
                         return powerManager;
                     }
 
@@ -110,7 +110,7 @@
                     }
 
                     @Override
-                    HdmiCecConfig getHdmiCecConfig() {
+                    protected HdmiCecConfig getHdmiCecConfig() {
                         return hdmiCecConfig;
                     }
                 };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index cd69775..bbe1156 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -86,7 +86,7 @@
                     }
 
                     @Override
-                    PowerManager getPowerManager() {
+                    protected PowerManager getPowerManager() {
                         return powerManager;
                     }
 
@@ -111,7 +111,7 @@
                     }
 
                     @Override
-                    HdmiCecConfig getHdmiCecConfig() {
+                    protected HdmiCecConfig getHdmiCecConfig() {
                         return hdmiCecConfig;
                     }
                 };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
new file mode 100644
index 0000000..af119c8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecAtomLoggingTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2018 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 com.android.server.hdmi;
+
+import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
+import static com.android.server.hdmi.Constants.ADDR_TV;
+import static com.android.server.hdmi.Constants.PATH_RELATIONSHIP_ANCESTOR;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.hardware.hdmi.HdmiPortInfo;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IThermalService;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.test.TestLooper;
+import android.platform.test.annotations.Presubmit;
+import android.stats.hdmi.nano.HdmiStatsEnums;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import com.android.server.SystemService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+/**
+ * Tests for the {@link HdmiCecAtomWriter} class and its usage by the HDMI-CEC framework.
+ */
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class HdmiCecAtomLoggingTest {
+    private HdmiCecAtomWriter mHdmiCecAtomWriterSpy;
+    private HdmiControlService mHdmiControlServiceSpy;
+    private HdmiCecController mHdmiCecController;
+    private HdmiCecLocalDevicePlayback mHdmiCecLocalDevicePlayback;
+    private HdmiMhlControllerStub mHdmiMhlControllerStub;
+    private FakeNativeWrapper mNativeWrapper;
+    private HdmiCecNetwork mHdmiCecNetwork;
+    private Looper mLooper;
+    private TestLooper mTestLooper = new TestLooper();
+    private int mPhysicalAddress = 0x1110;
+    private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
+    private HdmiPortInfo[] mHdmiPortInfo;
+
+    @Mock private IPowerManager mIPowerManagerMock;
+    @Mock private IThermalService mIThermalServiceMock;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+
+        mHdmiCecAtomWriterSpy = spy(new HdmiCecAtomWriter());
+
+        mLooper = mTestLooper.getLooper();
+
+        Context mContextSpy = spy(new ContextWrapper(
+                InstrumentationRegistry.getInstrumentation().getTargetContext()));
+
+        PowerManager powerManager = new PowerManager(
+                mContextSpy, mIPowerManagerMock, mIThermalServiceMock, new Handler(mLooper));
+        doReturn(powerManager).when(mContextSpy).getSystemService(Context.POWER_SERVICE);
+        doReturn(true).when(mIPowerManagerMock).isInteractive();
+
+        mHdmiControlServiceSpy = spy(new HdmiControlService(mContextSpy));
+        doNothing().when(mHdmiControlServiceSpy)
+                .writeStringSystemProperty(anyString(), anyString());
+        doReturn(mHdmiCecAtomWriterSpy).when(mHdmiControlServiceSpy).getAtomWriter();
+
+        HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
+        doReturn(hdmiCecConfig).when(mHdmiControlServiceSpy).getHdmiCecConfig();
+
+        mHdmiControlServiceSpy.setIoLooper(mLooper);
+        mHdmiControlServiceSpy.setMessageValidator(
+                new HdmiCecMessageValidator(mHdmiControlServiceSpy));
+        mHdmiControlServiceSpy.setCecMessageBuffer(
+                new CecMessageBuffer(mHdmiControlServiceSpy));
+
+        mNativeWrapper = new FakeNativeWrapper();
+        mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
+
+        mHdmiCecController = HdmiCecController.createWithNativeWrapper(
+                mHdmiControlServiceSpy, mNativeWrapper, mHdmiCecAtomWriterSpy);
+        mHdmiControlServiceSpy.setCecController(mHdmiCecController);
+
+        mHdmiMhlControllerStub = HdmiMhlControllerStub.create(mHdmiControlServiceSpy);
+        mHdmiControlServiceSpy.setHdmiMhlController(
+                mHdmiMhlControllerStub);
+
+        mHdmiCecNetwork = new HdmiCecNetwork(mHdmiControlServiceSpy,
+                mHdmiCecController, mHdmiMhlControllerStub);
+        mHdmiControlServiceSpy.setHdmiCecNetwork(mHdmiCecNetwork);
+
+        HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[1];
+        hdmiPortInfos[0] =
+                new HdmiPortInfo(1, HdmiPortInfo.PORT_OUTPUT, 0x0000, true, false, false);
+        mNativeWrapper.setPortInfo(hdmiPortInfos);
+        mNativeWrapper.setPortConnectionStatus(1, true);
+
+        mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlServiceSpy);
+        mHdmiCecLocalDevicePlayback.init();
+        mLocalDevices.add(mHdmiCecLocalDevicePlayback);
+
+        mHdmiControlServiceSpy.initService();
+        mHdmiControlServiceSpy.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mHdmiControlServiceSpy.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+
+        mTestLooper.dispatchAll();
+    }
+
+    @Test
+    public void testActiveSourceChanged_calledOnSetActiveSource() {
+        mHdmiControlServiceSpy.setActiveSource(1, 0x1111, "caller");
+        verify(mHdmiCecAtomWriterSpy, times(1))
+                .activeSourceChanged(1, 0x1111, PATH_RELATIONSHIP_ANCESTOR);
+    }
+
+    @Test
+    public void testMessageReported_calledOnOutgoingMessage() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+                mPhysicalAddress);
+
+        mHdmiCecController.sendCommand(message);
+
+        verify(mHdmiCecAtomWriterSpy, times(1)).messageReported(
+                message,
+                HdmiStatsEnums.OUTGOING,
+                SendMessageResult.SUCCESS);
+    }
+
+    @Test
+    public void testMessageReported_calledOnIncomingMessage() {
+        HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
+
+        mNativeWrapper.onCecMessage(message);
+        mTestLooper.dispatchAll();
+
+        verify(mHdmiCecAtomWriterSpy, times(1)).messageReported(
+                message,
+                HdmiStatsEnums.INCOMING);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
index d10e075..777713e 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
@@ -99,7 +99,7 @@
                 + "</cec-settings>", null);
         assertThat(hdmiCecConfig.getAllSettings())
                 .containsExactly(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
-                                 HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
+                                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE);
     }
 
     @Test
@@ -147,7 +147,7 @@
                 + "</cec-settings>", null);
         assertThat(hdmiCecConfig.getUserSettings())
                 .containsExactly(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
-                                 HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP);
+                                 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE);
     }
 
     @Test
@@ -230,7 +230,7 @@
                 + "  </setting>"
                 + "</cec-settings>", null);
         assertTrue(hdmiCecConfig.isStringValueType(
-                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP));
+                    HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE));
     }
 
     @Test
@@ -330,10 +330,10 @@
                 + "  </setting>"
                 + "</cec-settings>", null);
         assertThat(hdmiCecConfig.getAllowedStringValues(
-                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP))
-                .containsExactly(HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV,
-                                 HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST,
-                                 HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE);
+                    HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE))
+                .containsExactly(HdmiControlManager.POWER_CONTROL_MODE_TV,
+                                 HdmiControlManager.POWER_CONTROL_MODE_BROADCAST,
+                                 HdmiControlManager.POWER_CONTROL_MODE_NONE);
     }
 
     @Test
@@ -374,7 +374,7 @@
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
                 () -> hdmiCecConfig.getAllowedIntValues(
-                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP));
+                    HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE));
     }
 
     @Test
@@ -479,8 +479,8 @@
                 + "  </setting>"
                 + "</cec-settings>", null);
         assertThat(hdmiCecConfig.getDefaultStringValue(
-                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP))
-                .isEqualTo(HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
+                    HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE))
+                .isEqualTo(HdmiControlManager.POWER_CONTROL_MODE_TV);
     }
 
     @Test
@@ -521,7 +521,7 @@
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
                 () -> hdmiCecConfig.getDefaultIntValue(
-                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP));
+                    HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE));
     }
 
     @Test
@@ -610,8 +610,8 @@
     public void getStringValue_GlobalSetting_BasicSanity() {
         when(mStorageAdapter.retrieveGlobalSetting(
                   Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
-                  HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV))
-            .thenReturn(HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+                  HdmiControlManager.POWER_CONTROL_MODE_TV))
+            .thenReturn(HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
         HdmiCecConfig hdmiCecConfig = HdmiCecConfig.createFromStrings(
                 mContext, mStorageAdapter,
                 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
@@ -628,8 +628,8 @@
                 + "  </setting>"
                 + "</cec-settings>", null);
         assertThat(hdmiCecConfig.getStringValue(
-                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP))
-                .isEqualTo(HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+                    HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE))
+                .isEqualTo(HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
     }
 
     @Test
@@ -696,7 +696,7 @@
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
                 () -> hdmiCecConfig.getIntValue(
-                    HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP));
+                    HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE));
     }
 
     @Test
@@ -812,8 +812,8 @@
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
                 () -> hdmiCecConfig.setStringValue(
-                        HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                        HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST));
+                        HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                        HdmiControlManager.POWER_CONTROL_MODE_BROADCAST));
     }
 
     @Test
@@ -835,7 +835,7 @@
                 + "</cec-settings>", null);
         assertThrows(IllegalArgumentException.class,
                 () -> hdmiCecConfig.setStringValue(
-                        HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
+                        HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
                         "bar"));
     }
 
@@ -856,11 +856,11 @@
                 + "    <default-value string-value=\"to_tv\" />"
                 + "  </setting>"
                 + "</cec-settings>", null);
-        hdmiCecConfig.setStringValue(HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                               HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+        hdmiCecConfig.setStringValue(HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                               HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
         verify(mStorageAdapter).storeGlobalSetting(
                   Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
-                  HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+                  HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 3fd3ce3..6bb68da 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -170,7 +170,7 @@
                 }
 
                 @Override
-                void writeStringSystemProperty(String key, String value) {
+                protected void writeStringSystemProperty(String key, String value) {
                     // do nothing
                 }
 
@@ -185,12 +185,12 @@
                 }
 
                 @Override
-                PowerManager getPowerManager() {
+                protected PowerManager getPowerManager() {
                     return powerManager;
                 }
 
                 @Override
-                HdmiCecConfig getHdmiCecConfig() {
+                protected HdmiCecConfig getHdmiCecConfig() {
                     return hdmiCecConfig;
                 }
             };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index dfeed13..f7d52b6 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -18,7 +18,6 @@
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
 import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
 import static com.android.server.hdmi.Constants.ADDR_INVALID;
-import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
 import static com.android.server.hdmi.Constants.ADDR_TV;
 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
 
@@ -114,7 +113,7 @@
                     }
 
                     @Override
-                    void writeStringSystemProperty(String key, String value) {
+                    protected void writeStringSystemProperty(String key, String value) {
                         // do nothing
                     }
 
@@ -124,12 +123,12 @@
                     }
 
                     @Override
-                    PowerManager getPowerManager() {
+                    protected PowerManager getPowerManager() {
                         return powerManager;
                     }
 
                     @Override
-                    HdmiCecConfig getHdmiCecConfig() {
+                    protected HdmiCecConfig getHdmiCecConfig() {
                         return hdmiCecConfig;
                     }
                 };
@@ -557,8 +556,8 @@
     @Test
     public void handleOnStandby_ScreenOff_NotActiveSource_ToTv() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_TV);
         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
                 "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
@@ -577,8 +576,8 @@
     @Test
     public void handleOnStandby_ScreenOff_NotActiveSource_Broadcast() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
                 "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
@@ -597,8 +596,8 @@
     @Test
     public void handleOnStandby_ScreenOff_NotActiveSource_None() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_NONE);
         mHdmiCecLocalDevicePlayback.setActiveSource(ADDR_TV, 0x0000,
                 "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
@@ -617,8 +616,8 @@
     @Test
     public void handleOnStandby_ScreenOff_ActiveSource_ToTv() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_TV);
         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
@@ -637,8 +636,8 @@
     @Test
     public void handleOnStandby_ScreenOff_ActiveSource_Broadcast() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
@@ -657,8 +656,8 @@
     @Test
     public void handleOnStandby_ScreenOff_ActiveSource_None() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_NONE);
         mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
                 mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
         mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
@@ -828,12 +827,12 @@
                 HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
                 HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
         mStandby = false;
         // 1. DUT is <AS>.
-        HdmiCecMessage message1 = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
-                                         mPlaybackPhysicalAddress);
+        HdmiCecMessage message1 = HdmiCecMessageBuilder.buildActiveSource(
+                mHdmiCecLocalDevicePlayback.mAddress, mPlaybackPhysicalAddress);
         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message1)).isTrue();
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isTrue();
         assertThat(mStandby).isFalse();
@@ -1141,8 +1140,8 @@
     @Test
     public void oneTouchPlay_SendStandbyOnSleepToTv() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_TV);
         mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
             @Override
             public void onComplete(int result) {
@@ -1164,8 +1163,8 @@
     @Test
     public void oneTouchPlay_SendStandbyOnSleepBroadcast() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
         mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
             @Override
             public void onComplete(int result) {
@@ -1187,8 +1186,8 @@
     @Test
     public void oneTouchPlay_SendStandbyOnSleepNone() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_NONE);
         mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
             @Override
             public void onComplete(int result) {
@@ -1266,8 +1265,8 @@
     @Test
     public void toggleAndFollowTvPower_ToTv_TvStatusOn() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_TV);
         mStandby = false;
         mHdmiControlService.toggleAndFollowTvPower();
         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
@@ -1284,8 +1283,8 @@
     @Test
     public void toggleAndFollowTvPower_Broadcast_TvStatusOn() {
         mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
-                HdmiControlManager.CEC_SETTING_NAME_SEND_STANDBY_ON_SLEEP,
-                HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_BROADCAST);
         mStandby = false;
         mHdmiControlService.toggleAndFollowTvPower();
         HdmiCecMessage tvPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(ADDR_TV,
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 12414d9..d24b376 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -88,17 +88,17 @@
                     }
 
                     @Override
-                    void writeStringSystemProperty(String key, String value) {
+                    protected void writeStringSystemProperty(String key, String value) {
                         // do nothing
                     }
 
                     @Override
-                    PowerManager getPowerManager() {
+                    protected PowerManager getPowerManager() {
                         return powerManager;
                     }
 
                     @Override
-                    HdmiCecConfig getHdmiCecConfig() {
+                    protected HdmiCecConfig getHdmiCecConfig() {
                         return hdmiCecConfig;
                     }
                 };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
index a05cbb4..6285f58 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
@@ -56,6 +56,30 @@
     }
 
     @Test
+    public void isValid_unregisteredSource() {
+        // Message invokes a broadcast response
+        //   <Get Menu Language>
+        assertMessageValidity("F4:91").isEqualTo(OK);
+        //   <Request Active Source>
+        assertMessageValidity("FF:85").isEqualTo(OK);
+
+        // Message by CEC Switch
+        //   <Routing Change>
+        assertMessageValidity("FF:80:00:00:10:00").isEqualTo(OK);
+
+        //   <Routing Information>
+        assertMessageValidity("FF:81:10:00").isEqualTo(OK);
+
+        // Standby
+        assertMessageValidity("F4:36").isEqualTo(OK);
+        assertMessageValidity("FF:36").isEqualTo(OK);
+
+        // <Report Physical Address> / <Active Source>
+        assertMessageValidity("FF:84:10:00:04").isEqualTo(OK);
+        assertMessageValidity("FF:82:10:00").isEqualTo(OK);
+    }
+
+    @Test
     public void isValid_giveDevicePowerStatus() {
         assertMessageValidity("04:8F").isEqualTo(OK);
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
index 3cc7c6b..670d512 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
@@ -95,7 +95,7 @@
             }
 
             @Override
-            void writeStringSystemProperty(String key, String value) {
+            protected void writeStringSystemProperty(String key, String value) {
                 // do nothing
             }
 
@@ -110,7 +110,7 @@
             }
 
             @Override
-            HdmiCecConfig getHdmiCecConfig() {
+            protected HdmiCecConfig getHdmiCecConfig() {
                 return hdmiCecConfig;
             }
         };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 819bd019..2513807 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -151,7 +151,7 @@
             }
 
             @Override
-            HdmiCecConfig getHdmiCecConfig() {
+            protected HdmiCecConfig getHdmiCecConfig() {
                 return hdmiCecConfig;
             }
         };
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/OWNERS b/services/tests/servicestests/src/com/android/server/hdmi/OWNERS
new file mode 100644
index 0000000..c3c47ed
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/hardware/hdmi/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
index 0a225a0..f80b573 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
@@ -162,7 +162,7 @@
                     }
 
                     @Override
-                    HdmiCecConfig getHdmiCecConfig() {
+                    protected HdmiCecConfig getHdmiCecConfig() {
                         return hdmiCecConfig;
                     }
                 };
diff --git a/services/tests/servicestests/src/com/android/server/input/OWNERS b/services/tests/servicestests/src/com/android/server/input/OWNERS
new file mode 100644
index 0000000..d701f23
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/input/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/hardware/input/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/OWNERS b/services/tests/servicestests/src/com/android/server/inputmethod/OWNERS
new file mode 100644
index 0000000..5deb2ce
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/inputmethod/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/integrity/OWNERS b/services/tests/servicestests/src/com/android/server/integrity/OWNERS
new file mode 100644
index 0000000..653d1c9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/integrity/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/job/OWNERS b/services/tests/servicestests/src/com/android/server/job/OWNERS
new file mode 100644
index 0000000..6f207fb1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/job/OWNERS
@@ -0,0 +1 @@
+include /apex/jobscheduler/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/lights/OWNERS b/services/tests/servicestests/src/com/android/server/lights/OWNERS
new file mode 100644
index 0000000..cb46a80
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/lights/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/lights/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
index 2205694..25dbc6b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
@@ -16,6 +16,9 @@
 
 package com.android.server.locksettings;
 
+import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
+import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
+import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
@@ -277,6 +280,94 @@
         verify(mLockPatternUtils, never()).setLockCredential(any(), any(), anyInt());
     }
 
+    @Test
+    public void testSetPin_nonCompliantWithComplexity() throws Exception {
+        when(mLockPatternUtils.isSecure(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)).thenReturn(
+                PASSWORD_QUALITY_NUMERIC);
+        when(mLockPatternUtils.checkCredential(
+                LockscreenCredential.createPin("1234"), mUserId, null)).thenReturn(true);
+        when(mLockPatternUtils.getRequestedPasswordMetrics(mUserId))
+                .thenReturn(metricsForAdminQuality(PASSWORD_QUALITY_UNSPECIFIED));
+        when(mLockPatternUtils.getRequestedPasswordComplexity(mUserId))
+                .thenReturn(PASSWORD_COMPLEXITY_MEDIUM);
+
+        assertEquals(-1, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pin", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+
+        verify(mLockPatternUtils, never()).setLockCredential(any(), any(), anyInt());
+    }
+
+    @Test
+    public void testSetPin_compliantWithComplexity() throws Exception {
+        when(mLockPatternUtils.isSecure(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)).thenReturn(
+                PASSWORD_QUALITY_NUMERIC);
+        when(mLockPatternUtils.checkCredential(
+                LockscreenCredential.createPin("1234"), mUserId, null)).thenReturn(true);
+        when(mLockPatternUtils.getRequestedPasswordMetrics(mUserId))
+                .thenReturn(metricsForAdminQuality(PASSWORD_QUALITY_UNSPECIFIED));
+        when(mLockPatternUtils.getRequestedPasswordComplexity(mUserId))
+                .thenReturn(PASSWORD_COMPLEXITY_MEDIUM);
+
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pin", "--old", "1234", "4231" },
+                mShellCallback, mResultReceiver));
+
+        verify(mLockPatternUtils).setLockCredential(
+                LockscreenCredential.createPin("4231"),
+                LockscreenCredential.createPin("1234"),
+                mUserId);
+    }
+
+    @Test
+    public void testSetPattern_nonCompliantWithComplexity() throws Exception {
+        when(mLockPatternUtils.isSecure(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.checkCredential(
+                LockscreenCredential.createPattern(stringToPattern("1234")),
+                mUserId, null)).thenReturn(true);
+        when(mLockPatternUtils.getRequestedPasswordMetrics(mUserId))
+                .thenReturn(metricsForAdminQuality(PASSWORD_QUALITY_UNSPECIFIED));
+        when(mLockPatternUtils.getRequestedPasswordComplexity(mUserId))
+                .thenReturn(PASSWORD_COMPLEXITY_HIGH);
+
+        assertEquals(-1, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pattern", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+
+        verify(mLockPatternUtils, never()).setLockCredential(any(), any(), anyInt());
+    }
+
+    @Test
+    public void testSetPattern_compliantWithComplexity() throws Exception {
+        when(mLockPatternUtils.isSecure(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.checkCredential(
+                LockscreenCredential.createPattern(stringToPattern("1234")),
+                mUserId, null)).thenReturn(true);
+        when(mLockPatternUtils.getRequestedPasswordMetrics(mUserId))
+                .thenReturn(metricsForAdminQuality(PASSWORD_QUALITY_UNSPECIFIED));
+        when(mLockPatternUtils.getRequestedPasswordComplexity(mUserId))
+                .thenReturn(PASSWORD_COMPLEXITY_LOW);
+
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pattern", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+
+        verify(mLockPatternUtils).setLockCredential(
+                LockscreenCredential.createPattern(stringToPattern("4321")),
+                LockscreenCredential.createPattern(stringToPattern("1234")),
+                mUserId);
+    }
+
     private List<LockPatternView.Cell> stringToPattern(String str) {
         return LockPatternUtils.byteArrayToPattern(str.getBytes());
     }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/OWNERS b/services/tests/servicestests/src/com/android/server/locksettings/OWNERS
new file mode 100644
index 0000000..0a8dc8c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/locksettings/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/net/OWNERS b/services/tests/servicestests/src/com/android/server/net/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/net/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/om/OWNERS b/services/tests/servicestests/src/com/android/server/om/OWNERS
new file mode 100644
index 0000000..afb98d4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/om/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/content/om/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/people/OWNERS b/services/tests/servicestests/src/com/android/server/people/OWNERS
new file mode 100644
index 0000000..3198a5e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/people/OWNERS
@@ -0,0 +1 @@
+include /services/people/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
index f823bb9..2471210 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
@@ -22,6 +22,8 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -58,6 +60,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.LauncherApps.ShortcutChangeCallback;
+import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ShortcutInfo;
@@ -136,6 +139,7 @@
 
     @Captor private ArgumentCaptor<ShortcutChangeCallback> mShortcutChangeCallbackCaptor;
     @Captor private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
+    @Captor private ArgumentCaptor<Integer> mQueryFlagsCaptor;
 
     private ScheduledExecutorService mExecutorService;
     private NotificationChannel mNotificationChannel;
@@ -854,6 +858,8 @@
         List<ConversationChannel> result = mDataManager.getRecentConversations(USER_ID_PRIMARY);
         assertEquals(1, result.size());
         assertEquals(shortcut.getId(), result.get(0).getShortcutInfo().getId());
+        assertEquals(1, result.get(0).getShortcutInfo().getPersons().length);
+        assertEquals(CONTACT_URI, result.get(0).getShortcutInfo().getPersons()[0].getUri());
         assertEquals(mParentNotificationChannel.getId(),
                 result.get(0).getParentNotificationChannel().getId());
         assertEquals(mStatusBarNotification.getPostTime(), result.get(0).getLastEventTimestamp());
@@ -861,6 +867,28 @@
     }
 
     @Test
+    public void testGetRecentConversationsGetsPersonsData() {
+        mDataManager.onUserUnlocked(USER_ID_PRIMARY);
+
+        ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
+                buildPerson());
+        shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
+        mDataManager.addOrUpdateConversationInfo(shortcut);
+
+        NotificationListenerService listenerService =
+                mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
+        listenerService.onNotificationPosted(mStatusBarNotification);
+
+        List<ConversationChannel> result = mDataManager.getRecentConversations(USER_ID_PRIMARY);
+
+        verify(mShortcutServiceInternal).getShortcuts(
+                anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(),
+                mQueryFlagsCaptor.capture(), anyInt(), anyInt(), anyInt());
+        Integer queryFlags = mQueryFlagsCaptor.getValue();
+        assertThat(hasFlag(queryFlags, ShortcutQuery.FLAG_GET_PERSONS_DATA)).isTrue();
+    }
+
+    @Test
     public void testPruneOldRecentConversations() {
         mDataManager.onUserUnlocked(USER_ID_PRIMARY);
 
@@ -1068,6 +1096,13 @@
         return new UserInfo(userId, "", 0);
     }
 
+    /**
+     * Returns {@code true} iff {@link ShortcutQuery}'s {@code queryFlags} has {@code flag} set.
+     */
+    private static boolean hasFlag(int queryFlags, int flag) {
+        return (queryFlags & flag) != 0;
+    }
+
     private class TestContactsQueryHelper extends ContactsQueryHelper {
 
         private Uri mContactUri;
diff --git a/services/tests/servicestests/src/com/android/server/pm/OWNERS b/services/tests/servicestests/src/com/android/server/pm/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
index f8e92ad..84551c5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
@@ -22,6 +22,7 @@
 import android.util.SparseArray;
 
 import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.parsing.pkg.PackageImpl;
 
 import java.io.File;
 import java.util.Map;
@@ -38,14 +39,14 @@
     private int mPkgFlags;
     private int mPrivateFlags;
     private int mSharedUserId;
+    private String mVolumeUuid;
+    private int mAppId;
+    private SparseArray<PackageUserState> mUserStates = new SparseArray<>();
+    private AndroidPackage mPkg;
+    private InstallSource mInstallSource;
     private String[] mUsesStaticLibraries;
     private long[] mUsesStaticLibrariesVersions;
     private Map<String, ArraySet<String>> mMimeGroups;
-    private String mVolumeUuid;
-    private SparseArray<PackageUserState> mUserStates = new SparseArray<>();
-    private AndroidPackage mPkg;
-    private int mAppId;
-    private InstallSource mInstallSource;
     private PackageParser.SigningDetails mSigningDetails;
 
     public PackageSettingBuilder setPackage(AndroidPackage pkg) {
@@ -143,6 +144,14 @@
         return this;
     }
 
+    public PackageSettingBuilder setInstallState(int userId, boolean installed) {
+        if (mUserStates.indexOfKey(userId) < 0) {
+            mUserStates.put(userId, new PackageUserState());
+        }
+        mUserStates.get(userId).installed = installed;
+        return this;
+    }
+
     public PackageSettingBuilder setInstallSource(InstallSource installSource) {
         mInstallSource = installSource;
         return this;
@@ -173,6 +182,5 @@
             packageSetting.setUserState(mUserStates.keyAt(i), mUserStates.valueAt(i));
         }
         return packageSetting;
-
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
index fcbb5ed..d8c3979 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
@@ -101,7 +101,8 @@
     @Before
     public void setupDefaultAbiBehavior() throws Exception {
         when(mMockPackageAbiHelper.derivePackageAbi(
-                any(AndroidPackage.class), anyBoolean(), nullable(String.class)))
+                any(AndroidPackage.class), anyBoolean(), nullable(String.class),
+                any(File.class)))
                 .thenReturn(new Pair<>(
                         new PackageAbiHelper.Abis("derivedPrimary", "derivedSecondary"),
                         new PackageAbiHelper.NativeLibraryPaths(
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
index 3ce7a7d..eaf62cb 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java
@@ -227,8 +227,8 @@
         File dm = createDexMetadataFile("install_split_base.apk");
         try (FileInputStream is = new FileInputStream(base)) {
             ApkLite baseApk = PackageParser.parseApkLite(is.getFD(), base.getAbsolutePath(), 0);
-            PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
-                    null, null);
+            PackageLite pkgLite = new PackageLite(null, baseApk.codePath, baseApk, null, null, null,
+                    null, null, null);
             Assert.assertEquals(dm.length(), DexMetadataHelper.getPackageDexMetadataSize(pkgLite));
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java
index 92942bb..e816cbe 100644
--- a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java
@@ -23,6 +23,7 @@
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -170,16 +171,16 @@
 
     @Test
     public void create_sensor() throws Exception {
-        Sensor sensor = newSensor("sensor", Sensor.TYPE_HINGE_ANGLE);
-        when(mSensorManager.getSensorList(eq(sensor.getType()))).thenReturn(List.of(sensor));
+        Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE);
+        when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of(sensor));
 
         String configString = "<device-state-config>\n"
                 + "    <device-state>\n"
                 + "        <identifier>1</identifier>\n"
                 + "        <conditions>\n"
                 + "            <sensor>\n"
+                + "                <type>" + sensor.getStringType() + "</type>\n"
                 + "                <name>" + sensor.getName() + "</name>\n"
-                + "                <type>" + sensor.getType() + "</type>\n"
                 + "                <value>\n"
                 + "                    <max>90</max>\n"
                 + "                </value>\n"
@@ -190,8 +191,8 @@
                 + "        <identifier>2</identifier>\n"
                 + "        <conditions>\n"
                 + "            <sensor>\n"
+                + "                <type>" + sensor.getStringType() + "</type>\n"
                 + "                <name>" + sensor.getName() + "</name>\n"
-                + "                <type>" + sensor.getType() + "</type>\n"
                 + "                <value>\n"
                 + "                    <min-inclusive>90</min-inclusive>\n"
                 + "                    <max>180</max>\n"
@@ -203,8 +204,8 @@
                 + "        <identifier>3</identifier>\n"
                 + "        <conditions>\n"
                 + "            <sensor>\n"
+                + "                <type>" + sensor.getStringType() + "</type>\n"
                 + "                <name>" + sensor.getName() + "</name>\n"
-                + "                <type>" + sensor.getType() + "</type>\n"
                 + "                <value>\n"
                 + "                    <min-inclusive>180</min-inclusive>\n"
                 + "                </value>\n"
@@ -262,13 +263,13 @@
         assertEquals(1, mIntegerCaptor.getValue().intValue());
     }
 
-    private static Sensor newSensor(String name, int type) throws Exception {
+    private static Sensor newSensor(String name, String type) throws Exception {
         Constructor<Sensor> constructor = Sensor.class.getDeclaredConstructor();
         constructor.setAccessible(true);
 
         Sensor sensor = constructor.newInstance();
         FieldSetter.setField(sensor, Sensor.class.getDeclaredField("mName"), name);
-        FieldSetter.setField(sensor, Sensor.class.getDeclaredField("mType"), type);
+        FieldSetter.setField(sensor, Sensor.class.getDeclaredField("mStringType"), type);
         return sensor;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/policy/OWNERS b/services/tests/servicestests/src/com/android/server/policy/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/policy/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/power/OWNERS b/services/tests/servicestests/src/com/android/server/power/OWNERS
new file mode 100644
index 0000000..d68066b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/power/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/power/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
index fb6b29e..9bd488d3 100644
--- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
@@ -25,6 +25,7 @@
 import android.os.PowerManager;
 import android.os.PowerManager.ServiceType;
 import android.os.PowerSaveState;
+import android.provider.DeviceConfig;
 import android.provider.Settings.Global;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -47,19 +48,19 @@
     private static final int GPS_MODE = 0; // LOCATION_MODE_NO_CHANGE
     private static final int DEFAULT_GPS_MODE =
             PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF;
-    private static final String BATTERY_SAVER_CONSTANTS = "vibration_disabled=true,"
+    private static final String BATTERY_SAVER_CONSTANTS = "disable_vibration=true,"
             + "advertise_is_enabled=true,"
-            + "animation_disabled=false,"
-            + "soundtrigger_disabled=true,"
-            + "firewall_disabled=false,"
-            + "datasaver_disabled=false,"
-            + "adjust_brightness_disabled=true,"
+            + "disable_animation=false,"
+            + "disable_soundtrigger=true,"
+            + "enable_firewall=true,"
+            + "enable_datasaver=true,"
+            + "enable_brightness_adjustment=false,"
             + "adjust_brightness_factor=0.7,"
-            + "fullbackup_deferred=true,"
-            + "keyvaluebackup_deferred=false,"
-            + "gps_mode=0," // LOCATION_MODE_NO_CHANGE
+            + "defer_full_backup=true,"
+            + "defer_keyvalue_backup=false,"
+            + "location_mode=0," // LOCATION_MODE_NO_CHANGE
             + "enable_night_mode=false,"
-            + "quick_doze_enabled=true";
+            + "enable_quick_doze=true";
     private static final String BATTERY_SAVER_INCORRECT_CONSTANTS = "vi*,!=,,true";
 
     private class BatterySaverPolicyForTest extends BatterySaverPolicy {
@@ -336,13 +337,15 @@
         }
 
         mBatterySaverPolicy.setAdaptivePolicyLocked(
-                Policy.fromSettings(BATTERY_SAVER_CONSTANTS, ""));
+                Policy.fromSettings(BATTERY_SAVER_CONSTANTS, "",
+                        new DeviceConfig.Properties.Builder(
+                                DeviceConfig.NAMESPACE_BATTERY_SAVER).build(), null));
         verifyBatterySaverConstantsUpdated();
     }
 
     public void testAutomotiveProjectionChanges_Full() {
         mBatterySaverPolicy.updateConstantsLocked(
-                "gps_mode=" + PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF
+                "location_mode=" + PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF
                         + ",enable_night_mode=true", "");
         mBatterySaverPolicy.setPolicyLevel(POLICY_LEVEL_FULL);
         assertThat(mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION).locationMode)
@@ -369,8 +372,10 @@
     public void testAutomotiveProjectionChanges_Adaptive() {
         mBatterySaverPolicy.setAdaptivePolicyLocked(
                 Policy.fromSettings(
-                        "gps_mode=" + PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF
-                                + ",enable_night_mode=true", ""));
+                        "location_mode=" + PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF
+                                + ",enable_night_mode=true", "",
+                        new DeviceConfig.Properties.Builder(
+                                DeviceConfig.NAMESPACE_BATTERY_SAVER).build(), null));
         mBatterySaverPolicy.setPolicyLevel(POLICY_LEVEL_ADAPTIVE);
         assertThat(mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.LOCATION).locationMode)
                 .isEqualTo(PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF);
@@ -392,4 +397,188 @@
         assertTrue(mBatterySaverPolicy.getBatterySaverPolicy(
                 ServiceType.NIGHT_MODE).batterySaverEnabled);
     }
+
+    public void testUserSettingsOverrideDeviceConfig() {
+        Policy policy = Policy.fromSettings(
+                BatterySaverPolicy.KEY_ADJUST_BRIGHTNESS_FACTOR + "=.1"
+                        + "," + BatterySaverPolicy.KEY_ADVERTISE_IS_ENABLED + "=true"
+                        + "," + BatterySaverPolicy.KEY_DEFER_FULL_BACKUP + "=true"
+                        + "," + BatterySaverPolicy.KEY_DEFER_KEYVALUE_BACKUP + "=true"
+                        + "," + BatterySaverPolicy.KEY_DISABLE_ANIMATION + "=true"
+                        + "," + BatterySaverPolicy.KEY_DISABLE_AOD + "=true"
+                        + "," + BatterySaverPolicy.KEY_DISABLE_LAUNCH_BOOST + "=true"
+                        + "," + BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS + "=true"
+                        + "," + BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER + "=true"
+                        + "," + BatterySaverPolicy.KEY_DISABLE_VIBRATION + "=true"
+                        + "," + BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT + "=true"
+                        + "," + BatterySaverPolicy.KEY_ENABLE_DATASAVER + "=true"
+                        + "," + BatterySaverPolicy.KEY_ENABLE_FIREWALL + "=true"
+                        + "," + BatterySaverPolicy.KEY_ENABLE_NIGHT_MODE + "=true"
+                        + "," + BatterySaverPolicy.KEY_ENABLE_QUICK_DOZE + "=true"
+                        + "," + BatterySaverPolicy.KEY_FORCE_ALL_APPS_STANDBY + "=true"
+                        + "," + BatterySaverPolicy.KEY_FORCE_BACKGROUND_CHECK + "=true"
+                        + "," + BatterySaverPolicy.KEY_LOCATION_MODE
+                        + "=" + PowerManager.LOCATION_MODE_FOREGROUND_ONLY,
+                "",
+                new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_BATTERY_SAVER)
+                        .setFloat(BatterySaverPolicy.KEY_ADJUST_BRIGHTNESS_FACTOR, .5f)
+                        .setBoolean(BatterySaverPolicy.KEY_ADVERTISE_IS_ENABLED, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DEFER_FULL_BACKUP, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DEFER_KEYVALUE_BACKUP, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_ANIMATION, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_AOD, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_LAUNCH_BOOST, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_VIBRATION, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_DATASAVER, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_FIREWALL, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_NIGHT_MODE, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_QUICK_DOZE, false)
+                        .setBoolean(BatterySaverPolicy.KEY_FORCE_ALL_APPS_STANDBY, false)
+                        .setBoolean(BatterySaverPolicy.KEY_FORCE_BACKGROUND_CHECK, false)
+                        .setInt(BatterySaverPolicy.KEY_LOCATION_MODE,
+                                PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF)
+                        .build(),
+                null);
+        assertEquals(.1f, policy.adjustBrightnessFactor);
+        assertTrue(policy.advertiseIsEnabled);
+        assertTrue(policy.deferFullBackup);
+        assertTrue(policy.deferKeyValueBackup);
+        assertTrue(policy.disableAnimation);
+        assertTrue(policy.disableAod);
+        assertTrue(policy.disableLaunchBoost);
+        assertTrue(policy.disableOptionalSensors);
+        assertTrue(policy.disableSoundTrigger);
+        assertTrue(policy.disableVibration);
+        assertTrue(policy.enableAdjustBrightness);
+        assertTrue(policy.enableDataSaver);
+        assertTrue(policy.enableFirewall);
+        assertTrue(policy.enableNightMode);
+        assertTrue(policy.enableQuickDoze);
+        assertTrue(policy.forceAllAppsStandby);
+        assertTrue(policy.forceBackgroundCheck);
+        assertEquals(PowerManager.LOCATION_MODE_FOREGROUND_ONLY, policy.locationMode);
+    }
+
+    public void testDeviceConfigOverridesDefaults() {
+        Policy policy = Policy.fromSettings(
+                "", "",
+                new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_BATTERY_SAVER)
+                        .setFloat(BatterySaverPolicy.KEY_ADJUST_BRIGHTNESS_FACTOR, .5f)
+                        .setBoolean(BatterySaverPolicy.KEY_ADVERTISE_IS_ENABLED, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DEFER_FULL_BACKUP, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DEFER_KEYVALUE_BACKUP, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_ANIMATION, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_AOD, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_LAUNCH_BOOST, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_VIBRATION, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_DATASAVER, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_FIREWALL, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_NIGHT_MODE, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_QUICK_DOZE, false)
+                        .setBoolean(BatterySaverPolicy.KEY_FORCE_ALL_APPS_STANDBY, false)
+                        .setBoolean(BatterySaverPolicy.KEY_FORCE_BACKGROUND_CHECK, false)
+                        .setInt(BatterySaverPolicy.KEY_LOCATION_MODE,
+                                PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF)
+                        .build(),
+                null);
+        assertEquals(.5f, policy.adjustBrightnessFactor);
+        assertFalse(policy.advertiseIsEnabled);
+        assertFalse(policy.deferFullBackup);
+        assertFalse(policy.deferKeyValueBackup);
+        assertFalse(policy.disableAnimation);
+        assertFalse(policy.disableAod);
+        assertFalse(policy.disableLaunchBoost);
+        assertFalse(policy.disableOptionalSensors);
+        assertFalse(policy.disableSoundTrigger);
+        assertFalse(policy.disableVibration);
+        assertFalse(policy.enableAdjustBrightness);
+        assertFalse(policy.enableDataSaver);
+        assertFalse(policy.enableFirewall);
+        assertFalse(policy.enableNightMode);
+        assertFalse(policy.enableQuickDoze);
+        assertFalse(policy.forceAllAppsStandby);
+        assertFalse(policy.forceBackgroundCheck);
+        assertEquals(PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF,
+                policy.locationMode);
+    }
+
+    public void testDeviceConfig_AdaptiveValues() {
+        final String adaptiveSuffix = "_adaptive";
+        Policy policy = Policy.fromSettings(
+                "", "",
+                new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_BATTERY_SAVER)
+                        .setFloat(BatterySaverPolicy.KEY_ADJUST_BRIGHTNESS_FACTOR, .5f)
+                        .setBoolean(BatterySaverPolicy.KEY_ADVERTISE_IS_ENABLED, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DEFER_FULL_BACKUP, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DEFER_KEYVALUE_BACKUP, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_ANIMATION, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_AOD, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_LAUNCH_BOOST, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER, false)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_VIBRATION, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_DATASAVER, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_FIREWALL, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_NIGHT_MODE, false)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_QUICK_DOZE, false)
+                        .setBoolean(BatterySaverPolicy.KEY_FORCE_ALL_APPS_STANDBY, false)
+                        .setBoolean(BatterySaverPolicy.KEY_FORCE_BACKGROUND_CHECK, false)
+                        .setInt(BatterySaverPolicy.KEY_LOCATION_MODE,
+                                PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF)
+                        .setFloat(BatterySaverPolicy.KEY_ADJUST_BRIGHTNESS_FACTOR + adaptiveSuffix,
+                                .9f)
+                        .setBoolean(BatterySaverPolicy.KEY_ADVERTISE_IS_ENABLED + adaptiveSuffix,
+                                true)
+                        .setBoolean(BatterySaverPolicy.KEY_DEFER_FULL_BACKUP + adaptiveSuffix, true)
+                        .setBoolean(BatterySaverPolicy.KEY_DEFER_KEYVALUE_BACKUP + adaptiveSuffix,
+                                true)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_ANIMATION + adaptiveSuffix, true)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_AOD + adaptiveSuffix, true)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_LAUNCH_BOOST + adaptiveSuffix,
+                                true)
+                        .setBoolean(
+                                BatterySaverPolicy.KEY_DISABLE_OPTIONAL_SENSORS + adaptiveSuffix,
+                                true)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_SOUNDTRIGGER + adaptiveSuffix,
+                                true)
+                        .setBoolean(BatterySaverPolicy.KEY_DISABLE_VIBRATION + adaptiveSuffix, true)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_BRIGHTNESS_ADJUSTMENT
+                                        + adaptiveSuffix, true)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_DATASAVER + adaptiveSuffix, true)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_FIREWALL + adaptiveSuffix, true)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_NIGHT_MODE + adaptiveSuffix, true)
+                        .setBoolean(BatterySaverPolicy.KEY_ENABLE_QUICK_DOZE + adaptiveSuffix, true)
+                        .setBoolean(BatterySaverPolicy.KEY_FORCE_ALL_APPS_STANDBY + adaptiveSuffix,
+                                true)
+                        .setBoolean(BatterySaverPolicy.KEY_FORCE_BACKGROUND_CHECK + adaptiveSuffix,
+                                true)
+                        .setInt(BatterySaverPolicy.KEY_LOCATION_MODE + adaptiveSuffix,
+                                PowerManager.LOCATION_MODE_FOREGROUND_ONLY)
+                        .build(), adaptiveSuffix);
+        assertEquals(.9f, policy.adjustBrightnessFactor);
+        assertTrue(policy.advertiseIsEnabled);
+        assertTrue(policy.deferFullBackup);
+        assertTrue(policy.deferKeyValueBackup);
+        assertTrue(policy.disableAnimation);
+        assertTrue(policy.disableAod);
+        assertTrue(policy.disableLaunchBoost);
+        assertTrue(policy.disableOptionalSensors);
+        assertTrue(policy.disableSoundTrigger);
+        assertTrue(policy.disableVibration);
+        assertTrue(policy.enableAdjustBrightness);
+        assertTrue(policy.enableDataSaver);
+        assertTrue(policy.enableFirewall);
+        assertTrue(policy.enableNightMode);
+        assertTrue(policy.enableQuickDoze);
+        assertTrue(policy.forceAllAppsStandby);
+        assertTrue(policy.forceBackgroundCheck);
+        assertEquals(PowerManager.LOCATION_MODE_FOREGROUND_ONLY, policy.locationMode);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/powerstats/OWNERS b/services/tests/servicestests/src/com/android/server/powerstats/OWNERS
new file mode 100644
index 0000000..d68066b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/powerstats/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/power/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/rollback/OWNERS b/services/tests/servicestests/src/com/android/server/rollback/OWNERS
new file mode 100644
index 0000000..d04a706
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/rollback/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/rollback/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS
new file mode 100644
index 0000000..816bc6b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/media/soundtrigger/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/stats/OWNERS b/services/tests/servicestests/src/com/android/server/stats/OWNERS
new file mode 100644
index 0000000..ee865b1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/stats/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/stats/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/storage/OWNERS b/services/tests/servicestests/src/com/android/server/storage/OWNERS
new file mode 100644
index 0000000..6f9dbea
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/storage/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/os/storage/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/textclassifier/OWNERS b/services/tests/servicestests/src/com/android/server/textclassifier/OWNERS
new file mode 100644
index 0000000..46b3cb8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/textclassifier/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/textclassifier/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/OWNERS b/services/tests/servicestests/src/com/android/server/timedetector/OWNERS
new file mode 100644
index 0000000..09447a9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timedetector/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/timezone/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/timezone/OWNERS b/services/tests/servicestests/src/com/android/server/timezone/OWNERS
new file mode 100644
index 0000000..09447a9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezone/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/timezone/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/OWNERS b/services/tests/servicestests/src/com/android/server/timezonedetector/OWNERS
new file mode 100644
index 0000000..09447a9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/timezone/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/tv/OWNERS b/services/tests/servicestests/src/com/android/server/tv/OWNERS
new file mode 100644
index 0000000..305027c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/tv/OWNERS
@@ -0,0 +1 @@
+include /media/java/android/media/tv/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/tv/TvInputServiceManagerTest.java b/services/tests/servicestests/src/com/android/server/tv/TvInputServiceManagerTest.java
new file mode 100644
index 0000000..229e27b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/tv/TvInputServiceManagerTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.tv;
+
+import static android.media.tv.TvInputManager.VIDEO_UNAVAILABLE_REASON_BUFFERING;
+import static android.media.tv.TvInputManager.VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN;
+import static android.media.tv.TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING;
+import static android.media.tv.TvInputManager.VIDEO_UNAVAILABLE_REASON_UNKNOWN;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+/**
+ * Tests for {@link TvInputManagerService}.
+ */
+@Presubmit
+@RunWith(JUnit4.class)
+public class TvInputServiceManagerTest {
+
+    @Test
+    public void getVideoUnavailableReasonForStatsd_tuning() {
+        assertThat(TvInputManagerService.getVideoUnavailableReasonForStatsd(
+                VIDEO_UNAVAILABLE_REASON_TUNING
+        )).isEqualTo(
+                FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_TUNING);
+    }
+
+    @Test
+    public void getVideoUnavailableReasonForStatsd_unknown() {
+        assertThat(TvInputManagerService.getVideoUnavailableReasonForStatsd(
+                VIDEO_UNAVAILABLE_REASON_UNKNOWN
+        )).isEqualTo(
+                FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN);
+    }
+
+
+    @Test
+    public void getVideoUnavailableReasonForStatsd_casBuffering() {
+        assertThat(TvInputManagerService.getVideoUnavailableReasonForStatsd(
+                VIDEO_UNAVAILABLE_REASON_BUFFERING
+        )).isEqualTo(
+                FrameworkStatsLog
+                        .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_BUFFERING);
+    }
+
+    @Test
+    public void getVideoUnavailableReasonForStatsd_casUnknown() {
+        assertThat(TvInputManagerService.getVideoUnavailableReasonForStatsd(
+                VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN
+        )).isEqualTo(
+                FrameworkStatsLog
+                        .TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN);
+    }
+
+    @Test
+    public void getVideoUnavailableReasonForStatsd_negative() {
+        assertThat(TvInputManagerService.getVideoUnavailableReasonForStatsd(
+                -1
+        )).isEqualTo(
+                FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN);
+    }
+
+    @Test
+    public void getVideoUnavailableReasonForStatsd_oneBelow() {
+        assertThat(TvInputManagerService.getVideoUnavailableReasonForStatsd(
+                VIDEO_UNAVAILABLE_REASON_UNKNOWN - 1
+        )).isEqualTo(
+                FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN);
+    }
+
+    @Test
+    public void getVideoUnavailableReasonForStatsd_oneAbove() {
+        assertThat(TvInputManagerService.getVideoUnavailableReasonForStatsd(
+                VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN + 1
+        )).isEqualTo(
+                FrameworkStatsLog.TIF_TUNE_STATE_CHANGED__STATE__VIDEO_UNAVAILABLE_REASON_UNKNOWN);
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/uri/OWNERS b/services/tests/servicestests/src/com/android/server/uri/OWNERS
new file mode 100644
index 0000000..ca5d5f98
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/uri/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/uri/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/usage/OWNERS b/services/tests/servicestests/src/com/android/server/usage/OWNERS
new file mode 100644
index 0000000..d3227de
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/usage/OWNERS
@@ -0,0 +1 @@
+include /services/usage/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/OWNERS b/services/tests/servicestests/src/com/android/server/vibrator/OWNERS
new file mode 100644
index 0000000..cc63ceb
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/vibrator/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/vibrator/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/wallpaper/OWNERS b/services/tests/servicestests/src/com/android/server/wallpaper/OWNERS
new file mode 100644
index 0000000..8ff0f74
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wallpaper/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/wallpaper/OWNERS
diff --git a/services/tests/servicestests/test-apps/JobTestApp/OWNERS b/services/tests/servicestests/test-apps/JobTestApp/OWNERS
new file mode 100644
index 0000000..6f207fb1
--- /dev/null
+++ b/services/tests/servicestests/test-apps/JobTestApp/OWNERS
@@ -0,0 +1 @@
+include /apex/jobscheduler/OWNERS
diff --git a/services/tests/servicestests/test-apps/PackageParserApp/OWNERS b/services/tests/servicestests/test-apps/PackageParserApp/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/services/tests/servicestests/test-apps/PackageParserApp/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/services/tests/servicestests/test-apps/PackageParsingTestManifests/OWNERS b/services/tests/servicestests/test-apps/PackageParsingTestManifests/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/services/tests/servicestests/test-apps/PackageParsingTestManifests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt b/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt
index 59cbd1c..4c82818 100644
--- a/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt
+++ b/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt
@@ -17,6 +17,7 @@
 package com.android.server.testutils
 
 import org.mockito.Answers
+import org.mockito.ArgumentMatchers
 import org.mockito.Mockito
 import org.mockito.invocation.InvocationOnMock
 import org.mockito.stubbing.Answer
@@ -53,7 +54,7 @@
 
 fun <T> spy(value: T, block: T.() -> Unit = {}) = Mockito.spy(value).apply(block)
 
-fun <Type> Stubber.whenever(mock: Type) = Mockito.`when`(mock)
+fun <Type> Stubber.whenever(mock: Type) = this.`when`(mock)
 fun <Type : Any?> whenever(mock: Type) = Mockito.`when`(mock)
 
 @Suppress("UNCHECKED_CAST")
@@ -81,3 +82,5 @@
 
 inline fun <reified T> mockThrowOnUnmocked(block: T.() -> Unit = {}) =
         spyThrowOnUnmocked<T>(null, block)
+
+inline fun <reified T : Any> nullable() = ArgumentMatchers.nullable(T::class.java)
\ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/OWNERS b/services/tests/uiservicestests/src/com/android/server/OWNERS
new file mode 100644
index 0000000..05944c0
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/OWNERS
@@ -0,0 +1 @@
+per-file UiModeManagerServiceTest.java = file:/packages/SystemUI/OWNERS
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 00f706b..e510b4f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -153,7 +153,8 @@
                 AccessibilityEvent.TYPES_ALL_MASK);
         when(mAccessibilityService.addClient(any(), anyInt())).thenReturn(serviceReturnValue);
         AccessibilityManager accessibilityManager =
-                new AccessibilityManager(Handler.getMain(), mAccessibilityService, 0);
+                new AccessibilityManager(getContext(), Handler.getMain(), mAccessibilityService,
+                        0, true);
         verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt());
         assertTrue(accessibilityManager.isEnabled());
 
@@ -1191,7 +1192,7 @@
         NotificationRecord r = getLightsNotification();
         mService.buzzBeepBlinkLocked(r);
         verifyNeverLights();
-        assertFalse(r.isInterruptive());
+        assertTrue(r.isInterruptive());
         assertEquals(-1, r.getLastAudiblyAlertedMs());
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 4a4d9bc..ec28baf 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -249,13 +249,13 @@
                         backupPrimary.get(approvalLevel).get(userId),
                         Build.VERSION_CODES.N_MR1, userId);
             }
-            verifyExpectedApprovedEntries(service, true);
 
             for (int userId : backupSecondary.get(approvalLevel).keySet()) {
                 service.onSettingRestored(service.getConfig().secondarySettingName,
                         backupSecondary.get(approvalLevel).get(userId),
                         Build.VERSION_CODES.N_MR1, userId);
             }
+            // both sets of approved entries should be allowed
             verifyExpectedApprovedEntries(service);
             verifyExpectedApprovedEntries(service, backupPrimary.get(approvalLevel));
             verifyExpectedApprovedEntries(service, backupSecondary.get(approvalLevel));
@@ -638,8 +638,8 @@
     @Test
     public void testWriteXml_writesSetting() throws Exception {
         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
-            ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
-                    mIpm, approvalLevel);
+            ManagedServices service = new TestManagedServicesSettings(getContext(), mLock,
+                    mUserProfiles, mIpm, approvalLevel);
             loadXml(service);
 
             TypedXmlSerializer serializer = Xml.newFastSerializer();
@@ -662,6 +662,36 @@
     }
 
     @Test
+    public void testWriteXml_doesNotWriteSetting() throws Exception {
+        for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
+            ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
+                    mIpm, approvalLevel);
+
+            for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
+                Settings.Secure.putStringForUser(
+                        getContext().getContentResolver(),
+                        service.getConfig().secureSettingName, null, userId);
+            }
+            loadXml(service);
+
+            TypedXmlSerializer serializer = Xml.newFastSerializer();
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
+            serializer.startDocument(null, true);
+            service.writeXml(serializer, false, UserHandle.USER_ALL);
+            serializer.endDocument();
+            serializer.flush();
+
+            for (int userId : mUserProfiles.getCurrentProfileIds().toArray()) {
+                String actual = Settings.Secure.getStringForUser(
+                        getContext().getContentResolver(),
+                        service.getConfig().secureSettingName, userId);
+                assertTrue(TextUtils.isEmpty(actual));
+            }
+        }
+    }
+
+    @Test
     public void testWriteXml_writesUserSet() throws Exception {
         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
@@ -1415,11 +1445,11 @@
         xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
                         + ManagedServices.ATT_USER_ID + "=\"99\" "
                         + ManagedServices.ATT_IS_PRIMARY + "=\"true\" "
-                        + ManagedServices.ATT_APPROVED_LIST + "=\"99\" />\n");
+                        + ManagedServices.ATT_APPROVED_LIST + "=\"990\" />\n");
         xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
                 + ManagedServices.ATT_USER_ID + "=\"98\" "
                 + ManagedServices.ATT_IS_PRIMARY + "=\"false\" "
-                + ManagedServices.ATT_APPROVED_LIST + "=\"98\" />\n");
+                + ManagedServices.ATT_APPROVED_LIST + "=\"981\" />\n");
         xml.append("</" + xmlTag + ">");
 
         return xml.toString();
@@ -1483,7 +1513,7 @@
 
     private void assertContentsInAnyOrder(Collection<?> expected, Collection<?> actual) {
         assertNotNull(actual);
-        assertEquals(expected.size(), actual.size());
+        assertEquals(expected + " : " + actual, expected.size(), actual.size());
 
         for (Object o : expected) {
             assertTrue("Actual missing " + o, actual.contains(o));
@@ -1665,4 +1695,17 @@
             return null;
         }
     }
+
+    class TestManagedServicesSettings extends TestManagedServices {
+
+        public TestManagedServicesSettings(Context context, Object mutex, UserProfiles userProfiles,
+                IPackageManager pm, int approvedServiceType) {
+            super(context, mutex, userProfiles, pm, approvedServiceType);
+        }
+
+        @Override
+        public boolean shouldReflectToSettings() {
+            return true;
+        }
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAdjustmentExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAdjustmentExtractorTest.java
index e658d17..824c05e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAdjustmentExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAdjustmentExtractorTest.java
@@ -126,6 +126,7 @@
         return new Notification.Action.Builder(
                 Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
                 "action",
-                PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0)).build();
+                PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"),
+                    PendingIntent.FLAG_MUTABLE_UNAUDITED)).build();
     }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java
index 00d93de..a9a3b2b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationIntrusivenessExtractorTest.java
@@ -58,8 +58,11 @@
         NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
         final Notification.Builder builder = new Notification.Builder(getContext())
                 .setContentTitle("foo")
+                // TODO(b/174258141) Please replace FLAG_MUTABLE_UNAUDITED below
+                // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
                 .setFullScreenIntent(PendingIntent.getActivity(
-                        getContext(), 0, new Intent(""), 0), true)
+                        getContext(), 0, new Intent(""), PendingIntent.FLAG_MUTABLE_UNAUDITED),
+                        true)
                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
 
         Notification n = builder.build();
@@ -76,8 +79,11 @@
         NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
         final Notification.Builder builder = new Notification.Builder(getContext())
                 .setContentTitle("foo")
+                // TODO(b/174258141) Please replace FLAG_MUTABLE_UNAUDITED below
+                // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
                 .setFullScreenIntent(PendingIntent.getActivity(
-                        getContext(), 0, new Intent(""), 0), true)
+                        getContext(), 0, new Intent(""), PendingIntent.FLAG_MUTABLE_UNAUDITED),
+                        true)
                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
 
         Notification n = builder.build();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index fdc089e..c634706 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -102,7 +102,7 @@
             String key = mKeys[i];
             Ranking ranking = new Ranking();
             service.getCurrentRanking().getRanking(key, ranking);
-            assertEquals(getVisibilityOverride(i), ranking.getVisibilityOverride());
+            assertEquals(getVisibilityOverride(i), ranking.getLockscreenVisibilityOverride());
             assertEquals(getOverrideGroupKey(key), ranking.getOverrideGroupKey());
             assertEquals(!isIntercepted(i), ranking.matchesInterruptionFilter());
             assertEquals(getSuppressedVisualEffects(i), ranking.getSuppressedVisualEffects());
@@ -173,7 +173,7 @@
                 tweak.getKey(),
                 tweak.getRank(),
                 !tweak.matchesInterruptionFilter(), // note the inversion here!
-                tweak.getVisibilityOverride(),
+                tweak.getLockscreenVisibilityOverride(),
                 tweak.getSuppressedVisualEffects(),
                 tweak.getImportance(),
                 tweak.getImportanceExplanation(),
@@ -357,11 +357,13 @@
     private ArrayList<Notification.Action> getSmartActions(String key, int index) {
         ArrayList<Notification.Action> actions = new ArrayList<>();
         for (int i = 0; i < index; i++) {
+            // TODO(b/174935955) Please replace FLAG_MUTABLE_UNAUDITED below
+            // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
             PendingIntent intent = PendingIntent.getBroadcast(
                     getContext(),
                     index /*requestCode*/,
                     new Intent("ACTION_" + key),
-                    0 /*flags*/);
+                    PendingIntent.FLAG_MUTABLE_UNAUDITED /*flags*/);
             actions.add(new Notification.Action.Builder(null /*icon*/, key, intent).build());
         }
         return actions;
@@ -424,7 +426,7 @@
         assertEquals(comment, a.getKey(), b.getKey());
         assertEquals(comment, a.getRank(), b.getRank());
         assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter());
-        assertEquals(comment, a.getVisibilityOverride(), b.getVisibilityOverride());
+        assertEquals(comment, a.getLockscreenVisibilityOverride(), b.getLockscreenVisibilityOverride());
         assertEquals(comment, a.getSuppressedVisualEffects(), b.getSuppressedVisualEffects());
         assertEquals(comment, a.getImportance(), b.getImportance());
         assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation());
@@ -440,7 +442,8 @@
         assertEquals(comment, a.getSmartReplies(), b.getSmartReplies());
         assertEquals(comment, a.canBubble(), b.canBubble());
         assertEquals(comment, a.isConversation(), b.isConversation());
-        assertEquals(comment, a.getConversationShortcutInfo().getId(), b.getConversationShortcutInfo().getId());
+        assertEquals(comment, a.getConversationShortcutInfo().getId(),
+                b.getConversationShortcutInfo().getId());
         assertActionsEqual(a.getSmartActions(), b.getSmartActions());
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 5cf529a..849477c 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -183,6 +183,7 @@
 import com.android.server.notification.NotificationManagerService.NotificationListeners;
 import com.android.server.statusbar.StatusBarManagerInternal;
 import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.utils.quota.MultiRateLimiter;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -295,6 +296,8 @@
     NotificationHistoryManager mHistoryManager;
     @Mock
     StatsManager mStatsManager;
+    @Mock
+    MultiRateLimiter mToastRateLimiter;
     BroadcastReceiver mPackageIntentReceiver;
     NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
     private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
@@ -486,7 +489,7 @@
                 mGroupHelper, mAm, mAtm, mAppUsageStats,
                 mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal,
                 mAppOpsManager, mUm, mHistoryManager, mStatsManager,
-                mock(TelephonyManager.class), mAmi);
+                mock(TelephonyManager.class), mAmi, mToastRateLimiter);
         mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
 
         mService.setAudioManager(mAudioManager);
@@ -566,7 +569,7 @@
 
         try {
             mService.onDestroy();
-        } catch (IllegalStateException e) {
+        } catch (IllegalStateException | IllegalArgumentException e) {
             // can throw if a broadcast receiver was never registered
         }
 
@@ -787,7 +790,10 @@
                 .setName("bubblebot")
                 .build();
         RemoteInput remoteInput = new RemoteInput.Builder("reply_key").setLabel("reply").build();
-        PendingIntent inputIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        // TODO(b/174965245) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+        PendingIntent inputIntent = PendingIntent.getActivity(mContext, 0, new Intent(),
+                PendingIntent.FLAG_MUTABLE_UNAUDITED);
         Icon icon = Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon);
         Notification.Action replyAction = new Notification.Action.Builder(icon, "Reply",
                 inputIntent).addRemoteInput(remoteInput)
@@ -4888,6 +4894,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -4910,6 +4917,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -4928,6 +4936,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -4950,10 +4959,32 @@
     }
 
     @Test
+    public void testToastRateLimiterCanPreventsShowCallForCustomToast() throws Exception {
+        final String testPackage = "testPackageName";
+        assertEquals(0, mService.mToastQueue.size());
+        mService.isSystemUid = false;
+        setToastRateIsWithinQuota(false); // rate limit reached
+
+        // package is not suspended
+        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+                .thenReturn(false);
+
+        setAppInForegroundForToasts(mUid, true);
+
+        Binder token = new Binder();
+        ITransientNotification callback = mock(ITransientNotification.class);
+        INotificationManager nmService = (INotificationManager) mService.mService;
+
+        nmService.enqueueToast(testPackage, token, callback, 2000, 0);
+        verify(callback, times(0)).show(any());
+    }
+
+    @Test
     public void testAllowForegroundTextToasts() throws Exception {
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -4972,6 +5003,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -4990,6 +5022,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5013,11 +5046,31 @@
     }
 
     @Test
+    public void testToastRateLimiterCanPreventsShowCallForTextToast() throws Exception {
+        final String testPackage = "testPackageName";
+        assertEquals(0, mService.mToastQueue.size());
+        mService.isSystemUid = false;
+        setToastRateIsWithinQuota(false); // rate limit reached
+
+        // package is not suspended
+        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+                .thenReturn(false);
+
+        Binder token = new Binder();
+        INotificationManager nmService = (INotificationManager) mService.mService;
+
+        nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null);
+        verify(mStatusBar, times(0))
+                .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any());
+    }
+
+    @Test
     public void backgroundSystemCustomToast_callsSetProcessImportantAsForegroundForToast() throws
             Exception {
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = true;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5042,6 +5095,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5062,6 +5116,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5081,6 +5136,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5097,6 +5153,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5117,6 +5174,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5139,6 +5197,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = true;
+        setToastRateIsWithinQuota(true);
 
         // package is suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5161,6 +5220,7 @@
         final String testPackage = "testPackageName";
         assertEquals(0, mService.mToastQueue.size());
         mService.isSystemUid = false;
+        setToastRateIsWithinQuota(true);
 
         // package is not suspended
         when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
@@ -5188,6 +5248,14 @@
         when(mAtm.hasResumedActivity(uid)).thenReturn(inForeground);
     }
 
+    private void setToastRateIsWithinQuota(boolean isWithinQuota) {
+        when(mToastRateLimiter.isWithinQuota(
+                anyInt(),
+                anyString(),
+                eq(NotificationManagerService.TOAST_QUOTA_TAG)))
+                .thenReturn(isWithinQuota);
+    }
+
     @Test
     public void testOnPanelRevealedAndHidden() {
         int items = 5;
@@ -7301,7 +7369,10 @@
         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         ArrayList<Notification.Action> extraAction = new ArrayList<>();
         RemoteInput remoteInput = new RemoteInput.Builder("reply_key").setLabel("reply").build();
-        PendingIntent inputIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        // TODO(b/174965245) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+        PendingIntent inputIntent = PendingIntent.getActivity(mContext, 0, new Intent(),
+                PendingIntent.FLAG_MUTABLE_UNAUDITED);
         Icon icon = Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon);
         Notification.Action replyAction = new Notification.Action.Builder(icon, "Reply",
                 inputIntent).addRemoteInput(remoteInput)
@@ -7331,7 +7402,10 @@
         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         ArrayList<Notification.Action> extraAction = new ArrayList<>();
         RemoteInput remoteInput = new RemoteInput.Builder("reply_key").setLabel("reply").build();
-        PendingIntent inputIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        // TODO(b/174965245) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+        PendingIntent inputIntent = PendingIntent.getActivity(mContext, 0, new Intent(),
+                PendingIntent.FLAG_MUTABLE_UNAUDITED);
         Icon icon = Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon);
         Notification.Action replyAction = new Notification.Action.Builder(icon, "Reply",
                 inputIntent).addRemoteInput(remoteInput)
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/OWNERS b/services/tests/uiservicestests/src/com/android/server/notification/OWNERS
new file mode 100644
index 0000000..396fd12
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/notification/OWNERS
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 98c4a2d..4d2a478 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -97,6 +97,7 @@
 import android.testing.TestableContentResolver;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.IntArray;
 import android.util.Pair;
 import android.util.StatsEvent;
 import android.util.TypedXmlPullParser;
@@ -3320,7 +3321,8 @@
         channel2.setImportantConversation(true);
         mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
 
-        List<ConversationChannelWrapper> convos = mHelper.getConversations(false);
+        List<ConversationChannelWrapper> convos =
+                mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
 
         assertEquals(3, convos.size());
         assertTrue(conversationWrapperContainsChannel(convos, channel));
@@ -3329,6 +3331,44 @@
     }
 
     @Test
+    public void testGetConversations_multiUser() {
+        String convoId = "convo";
+        NotificationChannel messages =
+                new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+
+        NotificationChannel messagesUser10 =
+                new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(
+                PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesUser10, true, false);
+
+        NotificationChannel messagesFromB =
+                new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
+        messagesFromB.setConversationId(messages.getId(), "different convo");
+        mHelper.createNotificationChannel(PKG_O, UID_O, messagesFromB, true, false);
+
+        NotificationChannel messagesFromBUser10 =
+                new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
+        messagesFromBUser10.setConversationId(messagesUser10.getId(), "different convo");
+        mHelper.createNotificationChannel(
+                PKG_O, UID_O + UserHandle.PER_USER_RANGE, messagesFromBUser10, true, false);
+
+
+        List<ConversationChannelWrapper> convos =
+                mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
+
+        assertEquals(1, convos.size());
+        assertTrue(conversationWrapperContainsChannel(convos, messagesFromB));
+
+        convos =
+                mHelper.getConversations(IntArray.wrap(new int[] {0, UserHandle.getUserId(UID_O + UserHandle.PER_USER_RANGE)}), false);
+
+        assertEquals(2, convos.size());
+        assertTrue(conversationWrapperContainsChannel(convos, messagesFromB));
+        assertTrue(conversationWrapperContainsChannel(convos, messagesFromBUser10));
+    }
+
+    @Test
     public void testGetConversations_notDemoted() {
         String convoId = "convo";
         NotificationChannel messages =
@@ -3358,7 +3398,8 @@
         channel2.setImportantConversation(true);
         mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
 
-        List<ConversationChannelWrapper> convos = mHelper.getConversations(false);
+        List<ConversationChannelWrapper> convos =
+                mHelper.getConversations(IntArray.wrap(new int[] {0}), false);
 
         assertEquals(2, convos.size());
         assertTrue(conversationWrapperContainsChannel(convos, channel));
@@ -3396,7 +3437,8 @@
         channel2.setConversationId(calls.getId(), convoId);
         mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
 
-        List<ConversationChannelWrapper> convos = mHelper.getConversations(true);
+        List<ConversationChannelWrapper> convos =
+                mHelper.getConversations(IntArray.wrap(new int[] {0}), true);
 
         assertEquals(2, convos.size());
         assertTrue(conversationWrapperContainsChannel(convos, channel));
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
index a80f62a..4ce237e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -67,6 +67,7 @@
 import com.android.server.notification.NotificationManagerService.NotificationAssistants;
 import com.android.server.notification.NotificationManagerService.NotificationListeners;
 import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.utils.quota.MultiRateLimiter;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -156,7 +157,8 @@
                     mock(UriGrantsManagerInternal.class),
                     mock(AppOpsManager.class), mUm, mock(NotificationHistoryManager.class),
                     mock(StatsManager.class), mock(TelephonyManager.class),
-                    mock(ActivityManagerInternal.class));
+                    mock(ActivityManagerInternal.class),
+                    mock(MultiRateLimiter.class));
         } catch (SecurityException e) {
             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
                 throw e;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
index e5ae2d3..f43e5a8 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
@@ -27,8 +27,11 @@
 import static org.mockito.Mockito.when;
 
 import android.app.Notification;
+import android.app.Person;
 import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutQueryWrapper;
 import android.content.pm.ShortcutServiceInternal;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
@@ -44,6 +47,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -60,6 +64,7 @@
     private static final String SHORTCUT_ID = "shortcut";
     private static final String PKG = "pkg";
     private static final String KEY = "key";
+    private static final Person PERSON = mock(Person.class);
 
     @Mock
     LauncherApps mLauncherApps;
@@ -78,6 +83,8 @@
     @Mock
     ShortcutInfo mShortcutInfo;
 
+    @Captor private ArgumentCaptor<ShortcutQuery> mShortcutQueryCaptor;
+
     ShortcutHelper mShortcutHelper;
 
     @Before
@@ -298,6 +305,7 @@
         when(si.getUserId()).thenReturn(UserHandle.USER_SYSTEM);
         when(si.isLongLived()).thenReturn(true);
         when(si.isEnabled()).thenReturn(true);
+        when(si.getPersons()).thenReturn(new Person[]{PERSON});
         ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
         shortcuts.add(si);
         when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
@@ -308,4 +316,23 @@
         assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM))
                 .isSameInstanceAs(si);
     }
+
+    @Test
+    public void testGetValidShortcutInfo_hasGetPersonsDataFlag() {
+
+        ShortcutInfo info = mShortcutHelper.getValidShortcutInfo(
+                "a", "p", UserHandle.SYSTEM);
+        verify(mLauncherApps).getShortcuts(mShortcutQueryCaptor.capture(), any());
+        ShortcutQueryWrapper shortcutQuery =
+                new ShortcutQueryWrapper(mShortcutQueryCaptor.getValue());
+        assertThat(hasFlag(shortcutQuery.getQueryFlags(), ShortcutQuery.FLAG_GET_PERSONS_DATA))
+                .isTrue();
+    }
+
+    /**
+     * Returns {@code true} iff {@link ShortcutQuery}'s {@code queryFlags} has {@code flag} set.
+    */
+    private static boolean hasFlag(int queryFlags, int flag) {
+        return (queryFlags & flag) != 0;
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/VisibilityExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/VisibilityExtractorTest.java
new file mode 100644
index 0000000..3998129
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/VisibilityExtractorTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.notification;
+
+import static android.app.Notification.VISIBILITY_PRIVATE;
+import static android.app.Notification.VISIBILITY_SECRET;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.app.NotificationManager.VISIBILITY_NO_OVERRIDE;
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.app.Notification.Builder;
+import android.app.NotificationChannel;
+import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.media.session.MediaSession;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.UiServiceTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class VisibilityExtractorTest extends UiServiceTestCase {
+
+    @Mock RankingConfig mConfig;
+    @Mock
+    DevicePolicyManager mDpm;
+
+    private String mPkg = "com.android.server.notification";
+    private int mId = 1001;
+    private String mTag = null;
+    private int mUid = 1000;
+    private int mPid = 2000;
+    private int mUser = ActivityManager.getCurrentUser();
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext.addMockSystemService(DevicePolicyManager.class, mDpm);
+    }
+
+    private NotificationRecord getNotificationRecord(int visibility) {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        channel.setLockscreenVisibility(visibility);
+        when(mConfig.getNotificationChannel(mPkg, mUid, "a", false)).thenReturn(channel);
+
+        final Builder builder = new Builder(getContext())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        Notification n = builder.build();
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, mId, mTag, mUid,
+                mPid, n, UserHandle.of(mUser), null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+        return r;
+    }
+
+    //
+    // Tests
+    //
+
+    @Test
+    public void testGlobalAllDpmAllChannelAll() {
+        VisibilityExtractor extractor = new VisibilityExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        when(mConfig.canShowNotificationsOnLockscreen(mUser)).thenReturn(true);
+        when(mConfig.canShowPrivateNotificationsOnLockScreen(mUser)).thenReturn(true);
+
+        when(mDpm.getKeyguardDisabledFeatures(null, mUser)).thenReturn(0);
+
+        NotificationRecord r = getNotificationRecord(VISIBILITY_NO_OVERRIDE);
+
+        extractor.process(r);
+
+        assertEquals(VISIBILITY_NO_OVERRIDE, r.getPackageVisibilityOverride());
+    }
+
+    @Test
+    public void testGlobalNoneDpmAllChannelAll() {
+        VisibilityExtractor extractor = new VisibilityExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        when(mConfig.canShowNotificationsOnLockscreen(mUser)).thenReturn(false);
+        when(mConfig.canShowPrivateNotificationsOnLockScreen(mUser)).thenReturn(true);
+
+        when(mDpm.getKeyguardDisabledFeatures(null, mUser)).thenReturn(0);
+
+        NotificationRecord r = getNotificationRecord(VISIBILITY_NO_OVERRIDE);
+
+        extractor.process(r);
+
+        assertEquals(VISIBILITY_SECRET, r.getPackageVisibilityOverride());
+    }
+
+    @Test
+    public void testGlobalSomeDpmAllChannelAll() {
+        VisibilityExtractor extractor = new VisibilityExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        when(mConfig.canShowNotificationsOnLockscreen(mUser)).thenReturn(true);
+        when(mConfig.canShowPrivateNotificationsOnLockScreen(mUser)).thenReturn(false);
+
+        when(mDpm.getKeyguardDisabledFeatures(null, mUser)).thenReturn(0);
+
+        NotificationRecord r = getNotificationRecord(VISIBILITY_NO_OVERRIDE);
+
+        extractor.process(r);
+
+        assertEquals(VISIBILITY_PRIVATE, r.getPackageVisibilityOverride());
+    }
+
+    @Test
+    public void testGlobalAllDpmNoneChannelAll() {
+        VisibilityExtractor extractor = new VisibilityExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        when(mConfig.canShowNotificationsOnLockscreen(mUser)).thenReturn(true);
+        when(mConfig.canShowPrivateNotificationsOnLockScreen(mUser)).thenReturn(true);
+
+        when(mDpm.getKeyguardDisabledFeatures(null, mUser)).thenReturn(
+                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+
+        NotificationRecord r = getNotificationRecord(VISIBILITY_NO_OVERRIDE);
+
+        extractor.process(r);
+
+        assertEquals(VISIBILITY_SECRET, r.getPackageVisibilityOverride());
+    }
+
+    @Test
+    public void testGlobalAllDpmSomeChannelAll() {
+        VisibilityExtractor extractor = new VisibilityExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        when(mConfig.canShowNotificationsOnLockscreen(mUser)).thenReturn(true);
+        when(mConfig.canShowPrivateNotificationsOnLockScreen(mUser)).thenReturn(true);
+
+        when(mDpm.getKeyguardDisabledFeatures(null, mUser)).thenReturn(
+                KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+
+        NotificationRecord r = getNotificationRecord(VISIBILITY_NO_OVERRIDE);
+
+        extractor.process(r);
+
+        assertEquals(VISIBILITY_PRIVATE, r.getPackageVisibilityOverride());
+    }
+
+    @Test
+    public void testGlobalAllDpmAllChannelNone() {
+        VisibilityExtractor extractor = new VisibilityExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        when(mConfig.canShowNotificationsOnLockscreen(mUser)).thenReturn(true);
+        when(mConfig.canShowPrivateNotificationsOnLockScreen(mUser)).thenReturn(true);
+
+        when(mDpm.getKeyguardDisabledFeatures(null, mUser)).thenReturn(0);
+
+        NotificationRecord r = getNotificationRecord(VISIBILITY_SECRET);
+
+        extractor.process(r);
+
+        assertEquals(VISIBILITY_SECRET, r.getPackageVisibilityOverride());
+    }
+
+    @Test
+    public void testGlobalAllDpmAllChannelSome() {
+        VisibilityExtractor extractor = new VisibilityExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        when(mConfig.canShowNotificationsOnLockscreen(mUser)).thenReturn(true);
+        when(mConfig.canShowPrivateNotificationsOnLockScreen(mUser)).thenReturn(true);
+
+        when(mDpm.getKeyguardDisabledFeatures(null, mUser)).thenReturn(0);
+
+        NotificationRecord r = getNotificationRecord(VISIBILITY_PRIVATE);
+
+        extractor.process(r);
+
+        assertEquals(VISIBILITY_PRIVATE, r.getPackageVisibilityOverride());
+    }
+
+    @Test
+    public void testGlobalAllDpmSomeChannelNone() {
+        VisibilityExtractor extractor = new VisibilityExtractor();
+        extractor.setConfig(mConfig);
+        extractor.initialize(mContext, null);
+
+        when(mConfig.canShowNotificationsOnLockscreen(mUser)).thenReturn(true);
+        when(mConfig.canShowPrivateNotificationsOnLockScreen(mUser)).thenReturn(true);
+
+        when(mDpm.getKeyguardDisabledFeatures(null, mUser)).thenReturn(
+                KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+
+        NotificationRecord r = getNotificationRecord(VISIBILITY_SECRET);
+
+        extractor.process(r);
+
+        assertEquals(VISIBILITY_SECRET, r.getPackageVisibilityOverride());
+    }
+
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/OWNERS b/services/tests/uiservicestests/src/com/android/server/slice/OWNERS
new file mode 100644
index 0000000..3d0859f
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/slice/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/slice/OWNERS
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index a443695..dd0c162 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -75,7 +75,6 @@
         LocalServices.addService(UsageStatsManagerInternal.class,
                 mock(UsageStatsManagerInternal.class));
         mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
-        mContext.getTestablePermissions().setPermission(TEST_URI, PERMISSION_GRANTED);
 
         mContextSpy = spy(mContext);
         mService = spy(new SliceManagerService(mContextSpy, TestableLooper.get(this).getLooper()));
@@ -90,6 +89,7 @@
 
     @Test
     public void testAddPinCreatesPinned() throws RemoteException {
+        grantSlicePermission();
         doReturn("pkg").when(mService).getDefaultHome(anyInt());
 
         mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
@@ -99,6 +99,7 @@
 
     @Test
     public void testRemovePinDestroysPinned() throws RemoteException {
+        grantSlicePermission();
         doReturn("pkg").when(mService).getDefaultHome(anyInt());
 
         mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
@@ -130,11 +131,13 @@
 
     @Test(expected = IllegalStateException.class)
     public void testNoPinThrow() throws Exception {
+        grantSlicePermission();
         mService.getPinnedSpecs(TEST_URI, "pkg");
     }
 
     @Test
     public void testGetPinnedSpecs() throws Exception {
+        grantSlicePermission();
         SliceSpec[] specs = new SliceSpec[] {
             new SliceSpec("Something", 1) };
         mService.pinSlice("pkg", TEST_URI, specs, mToken);
@@ -143,4 +146,10 @@
         assertEquals(specs, mService.getPinnedSpecs(TEST_URI, "pkg"));
     }
 
+    private void grantSlicePermission() {
+        doReturn(PERMISSION_GRANTED).when(mService).checkSlicePermission(
+                eq(TEST_URI), anyString(), anyString(), anyInt(), anyInt(), any());
+        doReturn(PERMISSION_GRANTED).when(mService).checkAccess(
+                anyString(), eq(TEST_URI), anyInt(), anyInt());
+    }
 }
diff --git a/services/tests/wmtests/OWNERS b/services/tests/wmtests/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/services/tests/wmtests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java
new file mode 100644
index 0000000..75479de
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyCombinationTests.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.policy;
+
+import static android.view.KeyEvent.ACTION_DOWN;
+import static android.view.KeyEvent.ACTION_UP;
+import static android.view.KeyEvent.KEYCODE_BACK;
+import static android.view.KeyEvent.KEYCODE_POWER;
+import static android.view.KeyEvent.KEYCODE_VOLUME_DOWN;
+import static android.view.KeyEvent.KEYCODE_VOLUME_UP;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.view.KeyEvent;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test class for {@link KeyCombinationManager}.
+ *
+ * Build/Install/Run:
+ *  atest KeyCombinationTests
+ */
+
+@SmallTest
+public class KeyCombinationTests {
+    private KeyCombinationManager mKeyCombinationManager;
+
+    private boolean mAction1Triggered = false;
+    private boolean mAction2Triggered = false;
+    private boolean mAction3Triggered = false;
+
+    private boolean mPreCondition = true;
+    private static final long SCHEDULE_TIME = 300;
+
+    @Before
+    public void setUp() {
+        mKeyCombinationManager = new KeyCombinationManager();
+        initKeyCombinationRules();
+    }
+
+    private void initKeyCombinationRules() {
+        // Rule 1 : power + volume_down trigger action immediately.
+        mKeyCombinationManager.addRule(
+                new KeyCombinationManager.TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN,
+                        KEYCODE_POWER) {
+                    @Override
+                    void execute() {
+                        mAction1Triggered = true;
+                    }
+
+                    @Override
+                    void cancel() {
+                    }
+                });
+
+        // Rule 2 : volume_up + volume_down with condition.
+        mKeyCombinationManager.addRule(
+                new KeyCombinationManager.TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN,
+                        KEYCODE_VOLUME_UP) {
+                    @Override
+                    boolean preCondition() {
+                        return mPreCondition;
+                    }
+
+                    @Override
+                    void execute() {
+                        mAction2Triggered = true;
+                    }
+
+                    @Override
+                    void cancel() {
+                    }
+                });
+
+        // Rule 3 : power + volume_up schedule and trigger action after timeout.
+        mKeyCombinationManager.addRule(
+                new KeyCombinationManager.TwoKeysCombinationRule(KEYCODE_VOLUME_UP, KEYCODE_POWER) {
+                    final Runnable mAction = new Runnable() {
+                        @Override
+                        public void run() {
+                            mAction3Triggered = true;
+                        }
+                    };
+                    final Handler mHandler = new Handler(Looper.getMainLooper());
+
+                    @Override
+                    void execute() {
+                        mHandler.postDelayed(mAction, SCHEDULE_TIME);
+                    }
+
+                    @Override
+                    void cancel() {
+                        mHandler.removeCallbacks(mAction);
+                    }
+                });
+    }
+
+    private void pressKeys(long firstKeyTime, int firstKeyCode, long secondKeyTime,
+            int secondKeyCode) {
+        pressKeys(firstKeyTime, firstKeyCode, secondKeyTime, secondKeyCode, 0);
+    }
+
+    private void pressKeys(long firstKeyTime, int firstKeyCode, long secondKeyTime,
+            int secondKeyCode, long pressTime) {
+        final KeyEvent firstKeyDown = new KeyEvent(firstKeyTime, firstKeyTime, ACTION_DOWN,
+                firstKeyCode, 0 /* repeat */, 0 /* metaState */);
+        final KeyEvent secondKeyDown = new KeyEvent(secondKeyTime, secondKeyTime, ACTION_DOWN,
+                secondKeyCode, 0 /* repeat */, 0 /* metaState */);
+
+        mKeyCombinationManager.interceptKey(firstKeyDown, true);
+        mKeyCombinationManager.interceptKey(secondKeyDown, true);
+
+        // keep press down.
+        try {
+            Thread.sleep(pressTime);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+        final KeyEvent firstKeyUp = new KeyEvent(firstKeyTime, firstKeyTime, ACTION_UP,
+                firstKeyCode, 0 /* repeat */, 0 /* metaState */);
+        final KeyEvent secondKeyUp = new KeyEvent(secondKeyTime, secondKeyTime, ACTION_UP,
+                secondKeyCode, 0 /* repeat */, 0 /* metaState */);
+
+        mKeyCombinationManager.interceptKey(firstKeyUp, true);
+        mKeyCombinationManager.interceptKey(secondKeyUp, true);
+    }
+
+    @Test
+    public void testTriggerRule() {
+        final long eventTime = SystemClock.uptimeMillis();
+        pressKeys(eventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_DOWN);
+        assertTrue(mAction1Triggered);
+
+        pressKeys(eventTime, KEYCODE_VOLUME_UP, eventTime, KEYCODE_VOLUME_DOWN);
+        assertTrue(mAction2Triggered);
+
+        pressKeys(eventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_UP, SCHEDULE_TIME + 50);
+        assertTrue(mAction3Triggered);
+    }
+
+    /**
+     *  Nothing should happen if there is no definition.
+     */
+    @Test
+    public void testNotTrigger_NoRule() {
+        final long eventTime = SystemClock.uptimeMillis();
+        pressKeys(eventTime, KEYCODE_BACK, eventTime, KEYCODE_VOLUME_DOWN);
+        assertFalse(mAction1Triggered);
+        assertFalse(mAction2Triggered);
+        assertFalse(mAction3Triggered);
+    }
+
+    /**
+     *  Nothing should happen if the interval of press time is too long.
+     */
+    @Test
+    public void testNotTrigger_Interval() {
+        final long eventTime = SystemClock.uptimeMillis();
+        final long earlyEventTime = eventTime - 200; // COMBINE_KEY_DELAY_MILLIS = 150;
+        pressKeys(earlyEventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_DOWN);
+        assertFalse(mAction1Triggered);
+    }
+
+    /**
+     *  Nothing should happen if the condition is false.
+     */
+    @Test
+    public void testNotTrigger_Condition() {
+        final long eventTime = SystemClock.uptimeMillis();
+        // we won't trigger action 2 because the condition is false.
+        mPreCondition = false;
+        pressKeys(eventTime, KEYCODE_VOLUME_UP, eventTime, KEYCODE_VOLUME_DOWN);
+        assertFalse(mAction2Triggered);
+    }
+
+    /**
+     *  Nothing should happen if the keys released too early.
+     */
+    @Test
+    public void testNotTrigger_EarlyRelease() {
+        final long eventTime = SystemClock.uptimeMillis();
+        pressKeys(eventTime, KEYCODE_POWER, eventTime, KEYCODE_VOLUME_UP);
+        assertFalse(mAction3Triggered);
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 3d31824..080f04ef 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -80,13 +80,13 @@
     public void testActivityFinish() {
         final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
         final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
-        assertTrue("Activity must be finished", mAtm.finishActivity(activity.appToken,
-                0 /* resultCode */, null /* resultData */,
+        assertTrue("Activity must be finished", mAtm.mActivityClientController.finishActivity(
+                activity.appToken, 0 /* resultCode */, null /* resultData */,
                 Activity.DONT_FINISH_TASK_WITH_ACTIVITY));
         assertTrue(activity.finishing);
 
         assertTrue("Duplicate activity finish request must also return 'true'",
-                mAtm.finishActivity(activity.appToken, 0 /* resultCode */,
+                mAtm.mActivityClientController.finishActivity(activity.appToken, 0 /* resultCode */,
                         null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY));
     }
 
@@ -225,7 +225,7 @@
         //to simulate NPE
         doReturn(null).when(record).getParent();
 
-        mAtm.enterPictureInPictureMode(token, params);
+        mAtm.mActivityClientController.enterPictureInPictureMode(token, params);
         //if record's null parent is not handled gracefully, test will fail with NPE
 
         mockSession.finishMocking();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java
index bc91c70..f536cd0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaGroupTest.java
@@ -61,7 +61,7 @@
         mTaskDisplayArea = new TaskDisplayArea(
                 mDisplayContent, mWm, "TDA1", FEATURE_VENDOR_FIRST + 1);
         mDisplayAreaGroup.addChild(mTaskDisplayArea, POSITION_TOP);
-        mDisplayContent.setLastFocusedTaskDisplayArea(mTaskDisplayArea);
+        mDisplayContent.onLastFocusedTaskDisplayAreaChanged(mTaskDisplayArea);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
index 266ce5b..e47913f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
@@ -32,6 +32,7 @@
 import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED;
 import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
 import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
+import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_LAST;
 import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
 
 import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
@@ -46,6 +47,7 @@
 import static java.util.stream.Collectors.toList;
 
 import android.content.res.Resources;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
@@ -114,11 +116,13 @@
         final Feature bar;
         DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy =
                 new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
-                        .addFeature(foo = new Feature.Builder(mPolicy, "Foo", 0)
+                        .addFeature(foo = new Feature.Builder(mPolicy, "Foo",
+                                FEATURE_VENDOR_FIRST)
                                 .upTo(TYPE_STATUS_BAR)
                                 .and(TYPE_NAVIGATION_BAR)
                                 .build())
-                        .addFeature(bar = new Feature.Builder(mPolicy, "Bar", 1)
+                        .addFeature(bar = new Feature.Builder(mPolicy, "Bar",
+                                FEATURE_VENDOR_FIRST + 1)
                                 .all()
                                 .except(TYPE_STATUS_BAR)
                                 .build())
@@ -240,12 +244,14 @@
         final Feature other;
         DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy =
                 new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
-                        .addFeature(dimmable = new Feature.Builder(mPolicy, "Dimmable", 0)
+                        .addFeature(dimmable = new Feature.Builder(mPolicy, "Dimmable",
+                                FEATURE_VENDOR_FIRST)
                                 .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
                                 .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
                                 .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new)
                                 .build())
-                        .addFeature(other = new Feature.Builder(mPolicy, "Other", 1)
+                        .addFeature(other = new Feature.Builder(mPolicy, "Other",
+                                FEATURE_VENDOR_FIRST + 1)
                                 .all()
                                 .build())
                         .setImeContainer(mImeContainer)
@@ -313,9 +319,7 @@
         builder2.addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(
                 mGroupRoot1)
                 .setImeContainer(mImeContainer)
-                .setTaskDisplayAreas(Lists.newArrayList(
-                        new TaskDisplayArea(mDisplayContent, mWms, "testTda",
-                                FEATURE_VENDOR_FIRST + 1))));
+                .setTaskDisplayAreas(Lists.newArrayList(mTda1)));
 
         assertThrows(IllegalStateException.class, () -> builder2.build(mWms));
 
@@ -340,14 +344,147 @@
                 .setTaskDisplayAreas(mTaskDisplayAreaList));
         builder4.addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(
                 mGroupRoot2)
-                .setTaskDisplayAreas(Lists.newArrayList(
-                        new TaskDisplayArea(mDisplayContent, mWms, "testTda",
-                                FEATURE_VENDOR_FIRST + 1))));
+                .setTaskDisplayAreas(Lists.newArrayList(mTda1)));
 
         builder4.build(mWms);
     }
 
     @Test
+    public void testBuilder_rootHasUniqueId() {
+        // Root must have different id from all roots.
+        final DisplayAreaPolicyBuilder builder1 = new DisplayAreaPolicyBuilder();
+        builder1.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(mTaskDisplayAreaList));
+        final RootDisplayArea groupRoot1 = new SurfacelessDisplayAreaRoot(mWms, "group1",
+                mRoot.mFeatureId);
+        builder1.addDisplayAreaGroupHierarchy(
+                new DisplayAreaPolicyBuilder.HierarchyBuilder(groupRoot1)
+                        .setTaskDisplayAreas(Lists.newArrayList(mTda1)));
+
+        assertThrows(IllegalStateException.class, () -> builder1.build(mWms));
+
+        // Root must have different id from all TDAs.
+        final DisplayAreaPolicyBuilder builder2 = new DisplayAreaPolicyBuilder();
+        builder2.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(Lists.newArrayList(
+                        mDefaultTaskDisplayArea,
+                        new TaskDisplayArea(mDisplayContent, mWms, "testTda",
+                                mRoot.mFeatureId))));
+
+        assertThrows(IllegalStateException.class, () -> builder2.build(mWms));
+
+        // Root must have different id from all features.
+        final DisplayAreaPolicyBuilder builder3 = new DisplayAreaPolicyBuilder();
+        builder3.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(mTaskDisplayAreaList)
+                .addFeature(new Feature.Builder(mPolicy, "testFeature", mRoot.mFeatureId)
+                        .all()
+                        .build()));
+
+        assertThrows(IllegalStateException.class, () -> builder3.build(mWms));
+    }
+
+    @Test
+    public void testBuilder_taskDisplayAreaHasUniqueId() {
+        // TDA must have different id from all TDAs.
+        final DisplayAreaPolicyBuilder builder = new DisplayAreaPolicyBuilder();
+        final List<TaskDisplayArea> tdaList = Lists.newArrayList(
+                mDefaultTaskDisplayArea,
+                mTda1,
+                new TaskDisplayArea(mDisplayContent, mWms, "tda2", mTda1.mFeatureId));
+        builder.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(tdaList));
+
+        assertThrows(IllegalStateException.class, () -> builder.build(mWms));
+
+        // TDA must have different id from all features.
+        final DisplayAreaPolicyBuilder builder2 = new DisplayAreaPolicyBuilder();
+        builder2.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(Lists.newArrayList(
+                        mDefaultTaskDisplayArea,
+                        mTda1))
+                .addFeature(new Feature.Builder(mPolicy, "testFeature", mTda1.mFeatureId)
+                        .all()
+                        .build()));
+
+        assertThrows(IllegalStateException.class, () -> builder2.build(mWms));
+    }
+
+    @Test
+    public void testBuilder_featureHasUniqueId() {
+        // Feature must have different id from features below the same root.
+        final DisplayAreaPolicyBuilder builder = new DisplayAreaPolicyBuilder();
+        builder.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(mTaskDisplayAreaList)
+                .addFeature(new Feature.Builder(mPolicy, "feature1", FEATURE_VENDOR_FIRST + 10)
+                        .all()
+                        .build())
+                .addFeature(new Feature.Builder(mPolicy, "feature2", FEATURE_VENDOR_FIRST + 10)
+                        .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
+                        .build()));
+
+        assertThrows(IllegalStateException.class, () -> builder.build(mWms));
+
+        // Features below different root can have the same id.
+        final DisplayAreaPolicyBuilder builder2 = new DisplayAreaPolicyBuilder();
+        builder2.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(mTaskDisplayAreaList)
+                .addFeature(new Feature.Builder(mPolicy, "feature1", FEATURE_VENDOR_FIRST + 10)
+                        .all()
+                        .build()));
+        builder2.addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(
+                mGroupRoot1)
+                .setTaskDisplayAreas(Lists.newArrayList(mTda1))
+                .addFeature(new Feature.Builder(mPolicy, "feature2", FEATURE_VENDOR_FIRST + 10)
+                        .all()
+                        .build()));
+
+        builder2.build(mWms);
+    }
+
+    @Test
+    public void testBuilder_idsNotGreaterThanFeatureVendorLast() {
+        // Root id should not be greater than FEATURE_VENDOR_LAST.
+        final DisplayAreaPolicyBuilder builder1 = new DisplayAreaPolicyBuilder();
+        final RootDisplayArea root = new SurfacelessDisplayAreaRoot(mWms, "testRoot",
+                FEATURE_VENDOR_LAST + 1);
+        builder1.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(mTaskDisplayAreaList));
+
+        assertThrows(IllegalStateException.class, () -> builder1.build(mWms));
+
+        // TDA id should not be greater than FEATURE_VENDOR_LAST.
+        final DisplayAreaPolicyBuilder builder2 = new DisplayAreaPolicyBuilder();
+        builder2.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(Lists.newArrayList(
+                        mDefaultTaskDisplayArea,
+                        new TaskDisplayArea(mDisplayContent, mWms, "testTda",
+                                FEATURE_VENDOR_LAST + 1))));
+
+        assertThrows(IllegalStateException.class, () -> builder2.build(mWms));
+
+        // Feature id should not be greater than FEATURE_VENDOR_LAST.
+        final DisplayAreaPolicyBuilder builder3 = new DisplayAreaPolicyBuilder();
+        builder3.setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
+                .setImeContainer(mImeContainer)
+                .setTaskDisplayAreas(mTaskDisplayAreaList)
+                .addFeature(new Feature.Builder(mPolicy, "testFeature", FEATURE_VENDOR_LAST + 1)
+                        .all()
+                        .build()));
+
+        assertThrows(IllegalStateException.class, () -> builder3.build(mWms));
+    }
+
+    @Test
     public void testBuilder_displayAreaGroup_attachDisplayAreas() {
         final DisplayAreaPolicyBuilder.Result policy = new DisplayAreaPolicyBuilder()
                 .setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
@@ -449,8 +586,8 @@
                         .setTaskDisplayAreas(mTaskDisplayAreaList))
                 .addDisplayAreaGroupHierarchy(hierarchy1)
                 .addDisplayAreaGroupHierarchy(hierarchy2)
-                .setSelectRootForWindowFunc((token, options) -> {
-                    if (token.windowType == TYPE_STATUS_BAR) {
+                .setSelectRootForWindowFunc((type, options) -> {
+                    if (type == TYPE_STATUS_BAR) {
                         return mGroupRoot1;
                     }
                     return mGroupRoot2;
@@ -604,10 +741,9 @@
     }
 
     private WindowToken tokenOfType(int type) {
-        WindowToken m = mock(WindowToken.class);
-        when(m.getWindowLayerFromType()).thenReturn(
-                mPolicy.getWindowLayerFromTypeLw(type, false /* canAddInternalSystemWindow */));
-        return m;
+        WindowToken token = new WindowToken(mWms, new Binder(), type, false /* persistOnEmpty */,
+                mDisplayContent, false /* ownerCanManageAppTokens */);
+        return token;
     }
 
     private static void assertMatchLayerOrder(List<DisplayArea<?>> actualOrder,
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
index 025c5a6..6f5a874 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
@@ -458,8 +458,7 @@
 
     @Test
     public void testSetIgnoreOrientationRequest_notCallSuperOnDescendantOrientationChanged() {
-        final TaskDisplayArea tda =
-                mDisplayContent.getDefaultTaskDisplayArea();
+        final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
         final Task stack =
                 new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
         final ActivityRecord activity = stack.getTopNonFinishingActivity();
@@ -478,6 +477,27 @@
         verify(mDisplayContent).onDescendantOrientationChanged(any());
     }
 
+    @Test
+    public void testSetIgnoreOrientationRequest_updateOrientationRequestingTaskDisplayArea() {
+        final TaskDisplayArea tda = mDisplayContent.getDefaultTaskDisplayArea();
+        final Task stack =
+                new TaskBuilder(mSupervisor).setOnTop(!ON_TOP).setCreateActivity(true).build();
+        final ActivityRecord activity = stack.getTopNonFinishingActivity();
+
+        mDisplayContent.setFocusedApp(activity);
+        assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isEqualTo(tda);
+
+        // TDA is no longer handling orientation request, clear the last focused TDA.
+        tda.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isNull();
+
+        // TDA now handles orientation request, update last focused TDA based on the focused app.
+        tda.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+
+        assertThat(mDisplayContent.getOrientationRequestingTaskDisplayArea()).isEqualTo(tda);
+    }
+
     private static class TestDisplayArea<T extends WindowContainer> extends DisplayArea<T> {
         private TestDisplayArea(WindowManagerService wms, Rect bounds) {
             super(wms, ANY, "half display area");
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
new file mode 100644
index 0000000..eebc207
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.wm;
+
+import static android.content.ActivityInfoProto.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.view.Surface.ROTATION_90;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
+import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
+import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
+import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.SizeCompatTests.prepareUnresizable;
+import static com.android.server.wm.SizeCompatTests.rotateDisplay;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.view.Display;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for the Dual DisplayAreaGroup device behavior.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:DualDisplayAreaGroupPolicyTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase {
+    private static final int FEATURE_FIRST_ROOT = FEATURE_VENDOR_FIRST;
+    private static final int FEATURE_FIRST_TASK_CONTAINER = FEATURE_DEFAULT_TASK_CONTAINER;
+    private static final int FEATURE_SECOND_ROOT = FEATURE_VENDOR_FIRST + 1;
+    private static final int FEATURE_SECOND_TASK_CONTAINER = FEATURE_VENDOR_FIRST + 2;
+
+    private DualDisplayContent mDisplay;
+    private DisplayAreaGroup mFirstRoot;
+    private DisplayAreaGroup mSecondRoot;
+    private TaskDisplayArea mFirstTda;
+    private TaskDisplayArea mSecondTda;
+    private Task mFirstTask;
+    private Task mSecondTask;
+    private ActivityRecord mFirstActivity;
+    private ActivityRecord mSecondActivity;
+
+    @Before
+    public void setUp() {
+        // Let the Display to be created with the DualDisplay policy.
+        final DisplayAreaPolicy.Provider policyProvider = new DualDisplayTestPolicyProvider();
+        doReturn(policyProvider).when(mWm).getDisplayAreaPolicyProvider();
+
+        // Display: 1920x1200 (landscape). First and second display are both 860x1200 (portrait).
+        mDisplay = (DualDisplayContent) new DualDisplayContent.Builder(mAtm, 1920, 1200).build();
+        mFirstRoot = mDisplay.mFirstRoot;
+        mSecondRoot = mDisplay.mSecondRoot;
+        mFirstTda = mDisplay.getTaskDisplayArea(FEATURE_FIRST_TASK_CONTAINER);
+        mSecondTda = mDisplay.getTaskDisplayArea(FEATURE_SECOND_TASK_CONTAINER);
+        mFirstTask = new TaskBuilder(mSupervisor)
+                .setTaskDisplayArea(mFirstTda)
+                .setCreateActivity(true)
+                .build()
+                .getBottomMostTask();
+        mSecondTask = new TaskBuilder(mSupervisor)
+                .setTaskDisplayArea(mSecondTda)
+                .setCreateActivity(true)
+                .build()
+                .getBottomMostTask();
+        mFirstActivity = mFirstTask.getTopNonFinishingActivity();
+        mSecondActivity = mSecondTask.getTopNonFinishingActivity();
+
+        spyOn(mDisplay);
+        spyOn(mFirstRoot);
+        spyOn(mSecondRoot);
+    }
+
+    @Test
+    public void testNotIgnoreOrientationRequest_differentOrientationFromDisplay_reversesRequest() {
+        mFirstRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+        mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+        prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+        assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_PORTRAIT);
+        assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE);
+
+        prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_PORTRAIT);
+
+        assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE);
+        assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT);
+    }
+
+    @Test
+    public void testNotIgnoreOrientationRequest_onlyRespectsFocusedTaskDisplayArea() {
+        mFirstRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+        mSecondRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+        mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+        // Second TDA is not focused, so Display won't get the request
+        prepareUnresizable(mSecondActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+        assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSPECIFIED);
+
+        // First TDA is focused, so Display gets the request
+        prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+        assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_PORTRAIT);
+    }
+
+    @Test
+    public void testIgnoreOrientationRequest_displayDoesNotReceiveOrientationChange() {
+        mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+        prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+        verify(mFirstRoot).onDescendantOrientationChanged(any());
+        verify(mDisplay, never()).onDescendantOrientationChanged(any());
+    }
+
+    @Test
+    public void testLaunchPortraitApp_fillsDisplayAreaGroup() {
+        mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+        prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_PORTRAIT);
+        final Rect dagBounds = new Rect(mFirstRoot.getBounds());
+        final Rect taskBounds = new Rect(mFirstTask.getBounds());
+        final Rect activityBounds = new Rect(mFirstActivity.getBounds());
+
+        // DAG is portrait (860x1200), so Task and Activity fill DAG.
+        assertThat(mFirstTask.isTaskLetterboxed()).isFalse();
+        assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+        assertThat(taskBounds).isEqualTo(dagBounds);
+        assertThat(activityBounds).isEqualTo(taskBounds);
+    }
+
+    @Test
+    public void testLaunchPortraitApp_sizeCompatAfterRotation() {
+        mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+        prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_PORTRAIT);
+        final Rect dagBounds = new Rect(mFirstRoot.getBounds());
+        final Rect activityBounds = new Rect(mFirstActivity.getBounds());
+
+        rotateDisplay(mDisplay, ROTATION_90);
+        final Rect newDagBounds = new Rect(mFirstRoot.getBounds());
+        final Rect newTaskBounds = new Rect(mFirstTask.getBounds());
+        final Rect activitySizeCompatBounds = new Rect(mFirstActivity.getBounds());
+        final Rect activityConfigBounds =
+                new Rect(mFirstActivity.getConfiguration().windowConfiguration.getBounds());
+
+        // DAG is landscape (1200x860), Task fills parent
+        assertThat(mFirstTask.isTaskLetterboxed()).isFalse();
+        assertThat(mFirstActivity.inSizeCompatMode()).isTrue();
+        assertThat(newDagBounds.width()).isEqualTo(dagBounds.height());
+        assertThat(newDagBounds.height()).isEqualTo(dagBounds.width());
+        assertThat(newTaskBounds).isEqualTo(newDagBounds);
+
+        // Activity config bounds is unchanged, size compat bounds is (860x[860x860/1200=616])
+        assertThat(mFirstActivity.getSizeCompatScale()).isLessThan(1f);
+        assertThat(activityConfigBounds.width()).isEqualTo(activityBounds.width());
+        assertThat(activityConfigBounds.height()).isEqualTo(activityBounds.height());
+        assertThat(activitySizeCompatBounds.height()).isEqualTo(newTaskBounds.height());
+        assertThat(activitySizeCompatBounds.width()).isEqualTo(
+                newTaskBounds.height() * newTaskBounds.height() / newTaskBounds.width());
+    }
+
+    @Test
+    public void testLaunchLandscapeApp_taskIsLetterboxInDisplayAreaGroup() {
+        mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+        prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+        final Rect dagBounds = new Rect(mFirstRoot.getBounds());
+        final Rect taskBounds = new Rect(mFirstTask.getBounds());
+        final Rect activityBounds = new Rect(mFirstActivity.getBounds());
+
+        // DAG is portrait (860x1200), so Task is letterbox (860x[860x860/1200=616])
+        assertThat(mFirstTask.isTaskLetterboxed()).isTrue();
+        assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
+        assertThat(taskBounds.width()).isEqualTo(dagBounds.width());
+        assertThat(taskBounds.height())
+                .isEqualTo(dagBounds.width() * dagBounds.width() / dagBounds.height());
+        assertThat(activityBounds).isEqualTo(taskBounds);
+    }
+
+    @Test
+    public void testLaunchLandscapeApp_taskLetterboxBecomesActivityLetterboxAfterRotation() {
+        mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
+
+        prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_LANDSCAPE);
+        final Rect dagBounds = new Rect(mFirstRoot.getBounds());
+        final Rect activityBounds = new Rect(mFirstActivity.getBounds());
+
+        rotateDisplay(mDisplay, ROTATION_90);
+        final Rect newDagBounds = new Rect(mFirstRoot.getBounds());
+        final Rect newTaskBounds = new Rect(mFirstTask.getBounds());
+        final Rect newActivityBounds = new Rect(mFirstActivity.getBounds());
+
+        // DAG is landscape (1200x860), Task fills parent
+        // Task letterbox size
+        assertThat(mFirstTask.isTaskLetterboxed()).isFalse();
+        assertThat(mFirstActivity.inSizeCompatMode()).isTrue();
+        assertThat(newDagBounds.width()).isEqualTo(dagBounds.height());
+        assertThat(newDagBounds.height()).isEqualTo(dagBounds.width());
+        assertThat(newTaskBounds).isEqualTo(newDagBounds);
+
+        // Because we don't scale up, there is no size compat bounds and app bounds is the same as
+        // the previous bounds.
+        assertThat(mFirstActivity.hasSizeCompatBounds()).isFalse();
+        assertThat(newActivityBounds.width()).isEqualTo(activityBounds.width());
+        assertThat(newActivityBounds.height()).isEqualTo(activityBounds.height());
+    }
+
+    /** Display with two {@link DisplayAreaGroup}. Each of them take half of the screen. */
+    private static class DualDisplayContent extends TestDisplayContent {
+        final DisplayAreaGroup mFirstRoot;
+        final DisplayAreaGroup mSecondRoot;
+        final Rect mLastDisplayBounds;
+
+        /** Please use the {@link Builder} to create. */
+        DualDisplayContent(RootWindowContainer rootWindowContainer,
+                Display display) {
+            super(rootWindowContainer, display);
+
+            mFirstRoot = getGroupRoot(FEATURE_FIRST_ROOT);
+            mSecondRoot = getGroupRoot(FEATURE_SECOND_ROOT);
+            mLastDisplayBounds = new Rect(getBounds());
+            updateDisplayAreaGroupBounds();
+        }
+
+        DisplayAreaGroup getGroupRoot(int rootFeatureId) {
+            DisplayArea da = getDisplayArea(rootFeatureId);
+            assertThat(da).isInstanceOf(DisplayAreaGroup.class);
+            return (DisplayAreaGroup) da;
+        }
+
+        TaskDisplayArea getTaskDisplayArea(int tdaFeatureId) {
+            DisplayArea da = getDisplayArea(tdaFeatureId);
+            assertThat(da).isInstanceOf(TaskDisplayArea.class);
+            return (TaskDisplayArea) da;
+        }
+
+        DisplayArea getDisplayArea(int featureId) {
+            final DisplayArea displayArea =
+                    getItemFromDisplayAreas(da -> da.mFeatureId == featureId ? da : null);
+            assertThat(displayArea).isNotNull();
+            return displayArea;
+        }
+
+        @Override
+        public void onConfigurationChanged(Configuration newParentConfig) {
+            super.onConfigurationChanged(newParentConfig);
+
+            final Rect curBounds = getBounds();
+            if (mLastDisplayBounds != null && !mLastDisplayBounds.equals(curBounds)) {
+                mLastDisplayBounds.set(curBounds);
+                updateDisplayAreaGroupBounds();
+            }
+        }
+
+        /** Updates first and second {@link DisplayAreaGroup} to take half of the screen. */
+        private void updateDisplayAreaGroupBounds() {
+            if (mFirstRoot == null || mSecondRoot == null) {
+                return;
+            }
+
+            final Rect bounds = mLastDisplayBounds;
+            Rect groupBounds1, groupBounds2;
+            if (bounds.width() >= bounds.height()) {
+                groupBounds1 = new Rect(bounds.left, bounds.top,
+                        (bounds.right + bounds.left) / 2, bounds.bottom);
+
+                groupBounds2 = new Rect((bounds.right + bounds.left) / 2, bounds.top,
+                        bounds.right, bounds.bottom);
+            } else {
+                groupBounds1 = new Rect(bounds.left, bounds.top,
+                        bounds.right, (bounds.top + bounds.bottom) / 2);
+
+                groupBounds2 = new Rect(bounds.left,
+                        (bounds.top + bounds.bottom) / 2, bounds.right, bounds.bottom);
+            }
+            mFirstRoot.setBounds(groupBounds1);
+            mSecondRoot.setBounds(groupBounds2);
+        }
+
+        static class Builder extends TestDisplayContent.Builder {
+
+            Builder(ActivityTaskManagerService service, int width, int height) {
+                super(service, width, height);
+            }
+
+            @Override
+            TestDisplayContent createInternal(Display display) {
+                return new DualDisplayContent(mService.mRootWindowContainer, display);
+            }
+        }
+    }
+
+    /** Policy to create a dual {@link DisplayAreaGroup} policy in test. */
+    private static class DualDisplayTestPolicyProvider implements DisplayAreaPolicy.Provider {
+
+        @Override
+        public DisplayAreaPolicy instantiate(WindowManagerService wmService, DisplayContent content,
+                RootDisplayArea root, DisplayArea.Tokens imeContainer) {
+            // Root
+            // Include FEATURE_WINDOWED_MAGNIFICATION because it will be used as the screen rotation
+            // layer
+            DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy =
+                    new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
+                            .setImeContainer(imeContainer)
+                            .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(
+                                    wmService.mPolicy,
+                                    "WindowedMagnification", FEATURE_WINDOWED_MAGNIFICATION)
+                                    .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
+                                    .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)
+                                    .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new)
+                                    .build());
+
+            // First
+            final RootDisplayArea firstRoot = new DisplayAreaGroup(wmService, "FirstRoot",
+                    FEATURE_FIRST_ROOT);
+            final TaskDisplayArea firstTaskDisplayArea = new TaskDisplayArea(content, wmService,
+                    "FirstTaskDisplayArea", FEATURE_FIRST_TASK_CONTAINER);
+            final List<TaskDisplayArea> firstTdaList = new ArrayList<>();
+            firstTdaList.add(firstTaskDisplayArea);
+            DisplayAreaPolicyBuilder.HierarchyBuilder firstHierarchy =
+                    new DisplayAreaPolicyBuilder.HierarchyBuilder(firstRoot)
+                            .setTaskDisplayAreas(firstTdaList);
+
+            // Second
+            final RootDisplayArea secondRoot = new DisplayAreaGroup(wmService, "SecondRoot",
+                    FEATURE_SECOND_ROOT);
+            final TaskDisplayArea secondTaskDisplayArea = new TaskDisplayArea(content, wmService,
+                    "SecondTaskDisplayArea", FEATURE_SECOND_TASK_CONTAINER);
+            final List<TaskDisplayArea> secondTdaList = new ArrayList<>();
+            secondTdaList.add(secondTaskDisplayArea);
+            DisplayAreaPolicyBuilder.HierarchyBuilder secondHierarchy =
+                    new DisplayAreaPolicyBuilder.HierarchyBuilder(secondRoot)
+                            .setTaskDisplayAreas(secondTdaList);
+
+            return new DisplayAreaPolicyBuilder()
+                    .setRootHierarchy(rootHierarchy)
+                    .addDisplayAreaGroupHierarchy(firstHierarchy)
+                    .addDisplayAreaGroupHierarchy(secondHierarchy)
+                    .build(wmService);
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
index 91cfd4e..59d195b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
@@ -18,7 +18,9 @@
 
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.graphics.PixelFormat;
@@ -64,4 +66,22 @@
         mImeProvider.scheduleShowImePostLayout(target);
         assertTrue(mImeProvider.isImeTargetFromDisplayContentAndImeSame());
     }
+
+    @Test
+    public void testIsImeShowing() {
+        WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        makeWindowVisibleAndDrawn(ime);
+        mImeProvider.setWindow(ime, null, null);
+
+        WindowState target = createWindow(null, TYPE_APPLICATION, "app");
+        mDisplayContent.mInputMethodTarget = target;
+        mDisplayContent.mInputMethodControlTarget = target;
+
+        mImeProvider.scheduleShowImePostLayout(target);
+        assertFalse(mImeProvider.isImeShowing());
+        mImeProvider.checkShowImePostLayout();
+        assertTrue(mImeProvider.isImeShowing());
+        mImeProvider.setImeShowing(false);
+        assertFalse(mImeProvider.isImeShowing());
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 5c39bd0..6dd23ba 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -423,6 +423,7 @@
 
         final WindowState homeWindow = createWindow(null, TYPE_BASE_APPLICATION, homeActivity,
                 "homeWindow");
+        makeWindowVisible(homeWindow);
         homeActivity.addWindow(homeWindow);
         homeWindow.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index da00198..dd6e490 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -92,7 +92,7 @@
         mActivity.mVisibleRequested = true;
         mActivity.setSavedState(null /* savedState */);
         mActivity.setState(Task.ActivityState.RESUMED, "testRestart");
-        prepareUnresizable(1.5f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+        prepareUnresizable(mActivity, 1.5f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
 
         final Rect originalOverrideBounds = new Rect(mActivity.getBounds());
         resizeDisplay(mTask.mDisplayContent, 600, 1200);
@@ -115,7 +115,7 @@
         // Put app window into freeform and then make it a compat app.
         final Rect bounds = new Rect(100, 100, 400, 600);
         mTask.setBounds(bounds);
-        prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
         assertEquals(bounds, mActivity.getBounds());
 
         // The activity should be able to accept negative x position [-150, 100 - 150, 600].
@@ -145,7 +145,7 @@
         final Rect displayBounds = mActivity.mDisplayContent.getWindowConfiguration().getBounds();
         final float aspectRatio = 1.2f;
         mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = aspectRatio;
-        prepareUnresizable(-1f, SCREEN_ORIENTATION_UNSPECIFIED);
+        prepareUnresizable(mActivity, -1f, SCREEN_ORIENTATION_UNSPECIFIED);
         final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
 
         // The parent configuration doesn't change since the first resolved configuration, so the
@@ -205,7 +205,7 @@
     @Test
     public void testFixedScreenBoundsWhenDisplaySizeChanged() {
         setUpDisplaySizeWithApp(1000, 2500);
-        prepareUnresizable(-1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, -1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
         assertFitted();
 
         final Rect origBounds = new Rect(mActivity.getBounds());
@@ -262,7 +262,7 @@
         setUpDisplaySizeWithApp(displayWidth, 1000);
 
         final float maxAspect = 1.5f;
-        prepareUnresizable(maxAspect, SCREEN_ORIENTATION_LANDSCAPE);
+        prepareUnresizable(mActivity, maxAspect, SCREEN_ORIENTATION_LANDSCAPE);
         assertFitted();
 
         final Rect bounds = mActivity.getBounds();
@@ -286,7 +286,7 @@
     public void testAspectRatioMatchParentBoundsAndImeAttachable() {
         setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2000)
                 .setSystemDecorations(true).build());
-        prepareUnresizable(2f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+        prepareUnresizable(mActivity, 2f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
         assertFitted();
 
         rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
@@ -307,7 +307,7 @@
     @Test
     public void testMoveToDifferentOrientDisplay() {
         setUpDisplaySizeWithApp(1000, 2500);
-        prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
         assertFitted();
 
         final Rect configBounds = mActivity.getWindowConfiguration().getBounds();
@@ -352,7 +352,7 @@
         setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2500)
                 .setNotch(notchHeight).build());
         // Bounds=[0, 0 - 1000, 1460], AppBounds=[0, 60 - 1000, 1460].
-        prepareUnresizable(1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, 1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
 
         final Rect currentBounds = mActivity.getWindowConfiguration().getBounds();
         final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
@@ -381,7 +381,7 @@
         setUpDisplaySizeWithApp(1000, 2500);
 
         final float maxAspect = 1.4f;
-        prepareUnresizable(maxAspect, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, maxAspect, SCREEN_ORIENTATION_PORTRAIT);
         // The display aspect ratio 2.5 > 1.4 (max of activity), so the size is fitted.
         assertFitted();
 
@@ -415,7 +415,7 @@
         Configuration c = new Configuration(mTask.getRequestedOverrideConfiguration());
         c.screenLayout = fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR;
         mTask.onRequestedOverrideConfigurationChanged(c);
-        prepareUnresizable(1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
+        prepareUnresizable(mActivity, 1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
 
         // The initial configuration should inherit from parent.
         assertEquals(fixedScreenLayout | Configuration.SCREENLAYOUT_LAYOUTDIR_LTR,
@@ -433,7 +433,7 @@
     @Test
     public void testResetNonVisibleActivity() {
         setUpDisplaySizeWithApp(1000, 2500);
-        prepareUnresizable(1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
+        prepareUnresizable(mActivity, 1.5f, SCREEN_ORIENTATION_UNSPECIFIED);
         final DisplayContent display = mTask.mDisplayContent;
         // Resize the display so the activity is in size compatibility mode.
         resizeDisplay(display, 900, 1800);
@@ -472,7 +472,7 @@
         setUpDisplaySizeWithApp(1000, 2000);
         ActivityRecord activity = mActivity;
         activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatMode");
-        prepareUnresizable(-1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
         assertFitted();
 
         final ArrayList<IBinder> compatTokens = new ArrayList<>();
@@ -545,7 +545,7 @@
         mActivity.mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_OPEN);
         mActivity.mDisplayContent.mOpeningApps.add(mActivity);
         final float maxAspect = 1.8f;
-        prepareUnresizable(maxAspect, SCREEN_ORIENTATION_LANDSCAPE);
+        prepareUnresizable(mActivity, maxAspect, SCREEN_ORIENTATION_LANDSCAPE);
 
         assertFitted();
         assertTrue(mActivity.isFixedRotationTransforming());
@@ -576,7 +576,7 @@
         assertFalse(statusBarController.isTransparentAllowed(w));
 
         // Make the activity fill the display.
-        prepareUnresizable(10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
+        prepareUnresizable(mActivity, 10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
         w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
         // Refresh the letterbox.
         mActivity.mRootWindowContainer.performSurfacePlacement();
@@ -593,11 +593,11 @@
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         // Portrait fixed app without max aspect.
-        prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
 
-        final Rect displayBounds = mActivity.mDisplayContent.getBounds();
-        final Rect taskBounds = mTask.getBounds();
-        final Rect activityBounds = mActivity.getBounds();
+        final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+        final Rect taskBounds = new Rect(mTask.getBounds());
+        final Rect activityBounds = new Rect(mActivity.getBounds());
 
         // Display shouldn't be rotated.
         assertEquals(SCREEN_ORIENTATION_UNSPECIFIED,
@@ -622,15 +622,15 @@
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         // Portrait fixed app without max aspect.
-        prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
 
-        final Rect activityBounds = mActivity.getBounds();
+        final Rect activityBounds = new Rect(mActivity.getBounds());
 
         // Rotate display to portrait.
         rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
 
-        final Rect displayBounds = mActivity.mDisplayContent.getBounds();
-        final Rect newActivityBounds = mActivity.getBounds();
+        final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+        final Rect newActivityBounds = new Rect(mActivity.getBounds());
         assertTrue(displayBounds.width() < displayBounds.height());
 
         // App should be in size compat.
@@ -647,10 +647,10 @@
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         // Portrait fixed app without max aspect.
-        prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
 
-        Rect displayBounds = mActivity.mDisplayContent.getBounds();
-        Rect activityBounds = mActivity.getBounds();
+        Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+        Rect activityBounds = new Rect(mActivity.getBounds());
 
         // App should launch in fullscreen.
         assertFalse(mTask.isTaskLetterboxed());
@@ -660,8 +660,8 @@
         // Rotate display to landscape.
         rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
 
-        displayBounds = mActivity.mDisplayContent.getBounds();
-        activityBounds = mActivity.getBounds();
+        displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+        activityBounds = new Rect(mActivity.getBounds());
         assertTrue(displayBounds.width() > displayBounds.height());
 
         // App should be in size compat.
@@ -682,7 +682,7 @@
         display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         // Portrait fixed app without max aspect.
-        prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
 
         assertTrue(mTask.isTaskLetterboxed());
         assertFalse(mActivity.inSizeCompatMode());
@@ -701,9 +701,9 @@
         verify(mTask).onDescendantOrientationChanged(same(newActivity));
         verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
 
-        final Rect displayBounds = display.getBounds();
-        final Rect taskBounds = mTask.getBounds();
-        final Rect newActivityBounds = newActivity.getBounds();
+        final Rect displayBounds = new Rect(display.getBounds());
+        final Rect taskBounds = new Rect(mTask.getBounds());
+        final Rect newActivityBounds = new Rect(newActivity.getBounds());
 
         // Task and app bounds should be 700x1400 with the ratio as the display.
         assertTrue(mTask.isTaskLetterboxed());
@@ -722,7 +722,7 @@
         display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         // Portrait fixed app without max aspect.
-        prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
 
         assertTrue(mTask.isTaskLetterboxed());
         assertFalse(mActivity.inSizeCompatMode());
@@ -742,9 +742,9 @@
         verify(mTask).onDescendantOrientationChanged(same(newActivity));
         verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
 
-        final Rect displayBounds = display.getBounds();
-        final Rect taskBounds = mTask.getBounds();
-        final Rect newActivityBounds = newActivity.getBounds();
+        final Rect displayBounds = new Rect(display.getBounds());
+        final Rect taskBounds = new Rect(mTask.getBounds());
+        final Rect newActivityBounds = new Rect(newActivity.getBounds());
 
         // Task bounds should be (1400 / 1.3 = 1076)x1400 with the app requested ratio.
         assertTrue(mTask.isTaskLetterboxed());
@@ -765,7 +765,7 @@
         display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         // Portrait fixed app.
-        prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
+        prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
         clearInvocations(mActivity);
 
         assertTrue(mTask.isTaskLetterboxed());
@@ -829,26 +829,31 @@
                 displayContent.getConfiguration().uiMode);
     }
 
+    static void prepareUnresizable(ActivityRecord activity, int screenOrientation) {
+        prepareUnresizable(activity, -1 /* maxAspect */, screenOrientation);
+    }
+
     /**
-     * Setup {@link #mActivity} as a size-compat-mode-able activity with fixed aspect and/or
+     * Setups {@link #mActivity} as a size-compat-mode-able activity with fixed aspect and/or
      * orientation.
      */
-    private void prepareUnresizable(float maxAspect, int screenOrientation) {
-        mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
-        mActivity.mVisibleRequested = true;
+    static void prepareUnresizable(ActivityRecord activity, float maxAspect,
+            int screenOrientation) {
+        activity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
+        activity.mVisibleRequested = true;
         if (maxAspect >= 0) {
-            mActivity.info.maxAspectRatio = maxAspect;
+            activity.info.maxAspectRatio = maxAspect;
         }
         if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
-            mActivity.info.screenOrientation = screenOrientation;
-            mActivity.setRequestedOrientation(screenOrientation);
+            activity.info.screenOrientation = screenOrientation;
+            activity.setRequestedOrientation(screenOrientation);
         }
         // Make sure to use the provided configuration to construct the size compat fields.
-        mActivity.clearSizeCompatMode();
-        mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
+        activity.clearSizeCompatMode();
+        activity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */);
         // Make sure the display configuration reflects the change of activity.
-        if (mActivity.mDisplayContent.updateOrientation()) {
-            mActivity.mDisplayContent.sendNewConfiguration();
+        if (activity.mDisplayContent.updateOrientation()) {
+            activity.mDisplayContent.sendNewConfiguration();
         }
     }
 
@@ -869,7 +874,7 @@
         assertFalse(mActivity.hasSizeCompatBounds());
     }
 
-    private static Configuration rotateDisplay(DisplayContent display, int rotation) {
+    static Configuration rotateDisplay(DisplayContent display, int rotation) {
         final Configuration c = new Configuration();
         display.getDisplayRotation().setRotation(rotation);
         display.computeScreenConfiguration(c);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 83e3d22..e1bc90a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -325,7 +325,7 @@
         final TaskDisplayArea taskDisplayArea = display.getDefaultTaskDisplayArea();
 
         // Set the default focused TDA.
-        display.setLastFocusedTaskDisplayArea(taskDisplayArea);
+        display.onLastFocusedTaskDisplayAreaChanged(taskDisplayArea);
         spyOn(taskDisplayArea);
         final Task homeStack = taskDisplayArea.getRootTask(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index d80f816..1c93e0f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -262,20 +262,50 @@
         // Activity on TDA1 is focused
         mDisplayContent.setFocusedApp(firstActivity);
 
-        assertThat(firstTaskDisplayArea.isLastFocused()).isTrue();
-        assertThat(secondTaskDisplayArea.isLastFocused()).isFalse();
+        assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isTrue();
+        assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
 
         // No focused app, TDA1 is still recorded as last focused.
         mDisplayContent.setFocusedApp(null);
 
-        assertThat(firstTaskDisplayArea.isLastFocused()).isTrue();
-        assertThat(secondTaskDisplayArea.isLastFocused()).isFalse();
+        assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isTrue();
+        assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
 
         // Activity on TDA2 is focused
         mDisplayContent.setFocusedApp(secondActivity);
 
-        assertThat(firstTaskDisplayArea.isLastFocused()).isFalse();
-        assertThat(secondTaskDisplayArea.isLastFocused()).isTrue();
+        assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse();
+        assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isTrue();
+    }
+
+    @Test
+    public void testIsLastFocused_onlyCountIfTaskDisplayAreaHandlesOrientationRequest() {
+        final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+                mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
+                FEATURE_VENDOR_FIRST);
+        final Task firstStack = firstTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final Task secondStack = secondTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(firstStack).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+                .setTask(secondStack).build();
+        firstTaskDisplayArea.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        secondTaskDisplayArea.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */);
+
+        // Activity on TDA1 is focused, but TDA1 doesn't respect orientation request
+        mDisplayContent.setFocusedApp(firstActivity);
+
+        assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse();
+        assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isFalse();
+
+        // Activity on TDA2 is focused, and TDA2 respects orientation request
+        mDisplayContent.setFocusedApp(secondActivity);
+
+        assertThat(firstTaskDisplayArea.canSpecifyOrientation()).isFalse();
+        assertThat(secondTaskDisplayArea.canSpecifyOrientation()).isTrue();
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index e95efe7..ae85ceb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -37,7 +37,8 @@
 
 class TestDisplayContent extends DisplayContent {
 
-    private TestDisplayContent(RootWindowContainer rootWindowContainer, Display display) {
+    /** Please use the {@link Builder} to create, visible for use in test builder overrides only. */
+    TestDisplayContent(RootWindowContainer rootWindowContainer, Display display) {
         super(display, rootWindowContainer);
         // Normally this comes from display-properties as exposed by WM. Without that, just
         // hard-code to FULLSCREEN for tests.
@@ -72,7 +73,7 @@
         private boolean mCanRotate = true;
         private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
         private int mPosition = POSITION_BOTTOM;
-        private final ActivityTaskManagerService mService;
+        protected final ActivityTaskManagerService mService;
         private boolean mSystemDecorations = false;
 
         Builder(ActivityTaskManagerService service, int width, int height) {
@@ -125,14 +126,16 @@
             mInfo.logicalDensityDpi = dpi;
             return this;
         }
+        TestDisplayContent createInternal(Display display) {
+            return new TestDisplayContent(mService.mRootWindowContainer, display);
+        }
         TestDisplayContent build() {
             SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
 
             final int displayId = SystemServicesTestRule.sNextDisplayId++;
             final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
                     mInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
-            final TestDisplayContent newDisplay =
-                    new TestDisplayContent(mService.mRootWindowContainer, display);
+            final TestDisplayContent newDisplay = createInternal(display);
             // disable the normal system decorations
             final DisplayPolicy displayPolicy = newDisplay.getDisplayPolicy();
             spyOn(displayPolicy);
@@ -158,7 +161,7 @@
             mService.mRootWindowContainer.addChild(newDisplay, mPosition);
 
             // Set the default focused TDA.
-            newDisplay.setLastFocusedTaskDisplayArea(newDisplay.getDefaultTaskDisplayArea());
+            newDisplay.onLastFocusedTaskDisplayAreaChanged(newDisplay.getDefaultTaskDisplayArea());
 
             return newDisplay;
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index c4bcfdb..b0b8afd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -948,6 +948,36 @@
         assertFalse(act.isAnimating(PARENTS));
     }
 
+    @Test
+    public void testRegisterWindowContainerListener() {
+        final WindowContainer container = new WindowContainer(mWm);
+        container.mDisplayContent = mDisplayContent;
+        final TestWindowContainerListener listener = new TestWindowContainerListener();
+        Configuration config = container.getConfiguration();
+        Rect bounds = new Rect(0, 0, 10, 10);
+        config.windowConfiguration.setBounds(bounds);
+        config.densityDpi = 100;
+        container.onRequestedOverrideConfigurationChanged(config);
+        container.registerWindowContainerListener(listener);
+
+        assertEquals(mDisplayContent, listener.mDisplayContent);
+        assertEquals(bounds, listener.mConfiguration.windowConfiguration.getBounds());
+        assertEquals(100, listener.mConfiguration.densityDpi);
+
+        container.onDisplayChanged(mDefaultDisplay);
+        assertEquals(listener.mDisplayContent, mDefaultDisplay);
+
+        config = new Configuration();
+        bounds = new Rect(0, 0, 20, 20);
+        config.windowConfiguration.setBounds(bounds);
+        config.densityDpi = 200;
+
+        container.onRequestedOverrideConfigurationChanged(config);
+
+        assertEquals(bounds, listener.mConfiguration.windowConfiguration.getBounds());
+        assertEquals(200, listener.mConfiguration.densityDpi);
+    }
+
     /* Used so we can gain access to some protected members of the {@link WindowContainer} class */
     private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
         private final int mLayer;
@@ -1131,4 +1161,19 @@
             mSession.kill();
         }
     }
+
+    private static class TestWindowContainerListener implements WindowContainerListener {
+        private Configuration mConfiguration = new Configuration();
+        private DisplayContent mDisplayContent;
+
+        @Override
+        public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
+            mConfiguration.setTo(overrideConfiguration);
+        }
+
+        @Override
+        public void onDisplayChanged(DisplayContent dc) {
+            mDisplayContent = dc;
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
new file mode 100644
index 0000000..67067ee
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2020 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 com.android.server.wm;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.IWindowToken;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Build/Install/Run:
+ *  atest WmTests:WindowContextListenerControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class WindowContextListenerControllerTests extends WindowTestsBase {
+    private WindowContextListenerController mController;
+
+    private static final int TEST_UID = 12345;
+    private static final int ANOTHER_UID = 1000;
+
+    private final IBinder mClientToken = new Binder();
+    private WindowContainer mContainer;
+
+    @Before
+    public void setUp() {
+        mController = new WindowContextListenerController();
+        mContainer = createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent);
+    }
+
+    @Test
+    public void testRegisterWindowContextListener() {
+        mController.registerWindowContainerListener(mClientToken, mContainer, -1);
+
+        assertEquals(1, mController.mListeners.size());
+
+        final IBinder clientToken = new Binder();
+        mController.registerWindowContainerListener(clientToken, mContainer, -1);
+
+        assertEquals(2, mController.mListeners.size());
+
+        final WindowContainer container = createTestWindowToken(TYPE_APPLICATION_OVERLAY,
+                mDefaultDisplay);
+        mController.registerWindowContainerListener(mClientToken, container, -1);
+
+        // The number of listeners doesn't increase since the listener just gets updated.
+        assertEquals(2, mController.mListeners.size());
+
+        WindowContextListenerController.WindowContextListenerImpl listener =
+                mController.mListeners.get(mClientToken);
+        assertEquals(container, listener.getWindowContainer());
+    }
+
+    @Test
+    public void testRegisterWindowContextListenerClientConfigPropagation() {
+        final TestWindowTokenClient clientToken = new TestWindowTokenClient();
+
+        final Configuration config1 = mContainer.getConfiguration();
+        final Rect bounds1 = new Rect(0, 0, 10, 10);
+        config1.windowConfiguration.setBounds(bounds1);
+        config1.densityDpi = 100;
+        mContainer.onRequestedOverrideConfigurationChanged(config1);
+
+        mController.registerWindowContainerListener(clientToken, mContainer, -1);
+
+        assertEquals(bounds1, clientToken.mConfiguration.windowConfiguration.getBounds());
+        assertEquals(config1.densityDpi, clientToken.mConfiguration.densityDpi);
+        assertEquals(mDisplayContent.mDisplayId, clientToken.mDisplayId);
+
+        // Update the WindowContainer.
+        final WindowContainer container = createTestWindowToken(TYPE_APPLICATION_OVERLAY,
+                mDefaultDisplay);
+        final Configuration config2 = container.getConfiguration();
+        final Rect bounds2 = new Rect(0, 0, 20, 20);
+        config2.windowConfiguration.setBounds(bounds2);
+        config2.densityDpi = 200;
+        container.onRequestedOverrideConfigurationChanged(config2);
+
+        mController.registerWindowContainerListener(clientToken, container, -1);
+
+        assertEquals(bounds2, clientToken.mConfiguration.windowConfiguration.getBounds());
+        assertEquals(config2.densityDpi, clientToken.mConfiguration.densityDpi);
+        assertEquals(DEFAULT_DISPLAY, clientToken.mDisplayId);
+
+        // Update the configuration of WindowContainer.
+        container.onRequestedOverrideConfigurationChanged(config1);
+
+        assertEquals(bounds1, clientToken.mConfiguration.windowConfiguration.getBounds());
+        assertEquals(config1.densityDpi, clientToken.mConfiguration.densityDpi);
+
+        // Update the display of WindowContainer.
+        container.onDisplayChanged(mDisplayContent);
+
+        assertEquals(mDisplayContent.mDisplayId, clientToken.mDisplayId);
+    }
+
+    @Test
+    public void testCanCallerRemoveListener_NullListener_ReturnFalse() {
+        assertFalse(mController.assertCallerCanRemoveListener(mClientToken,
+                true /* callerCanManagerAppTokens */, TEST_UID));
+    }
+
+    @Test
+    public void testCanCallerRemoveListener_CanManageAppTokens_ReturnTrue() {
+        mController.registerWindowContainerListener(mClientToken, mContainer, TEST_UID);
+
+        assertTrue(mController.assertCallerCanRemoveListener(mClientToken,
+                true /* callerCanManagerAppTokens */, ANOTHER_UID));
+    }
+
+    @Test
+    public void testCanCallerRemoveListener_SameUid_ReturnTrue() {
+        mController.registerWindowContainerListener(mClientToken, mContainer, TEST_UID);
+
+        assertTrue(mController.assertCallerCanRemoveListener(mClientToken,
+                false /* callerCanManagerAppTokens */, TEST_UID));
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testCanCallerRemoveListener_DifferentUid_ThrowException() {
+        mController.registerWindowContainerListener(mClientToken, mContainer, TEST_UID);
+
+        mController.assertCallerCanRemoveListener(mClientToken,
+                false /* callerCanManagerAppTokens */, ANOTHER_UID);
+    }
+
+    private class TestWindowTokenClient extends IWindowToken.Stub {
+        private Configuration mConfiguration;
+        private int mDisplayId;
+        private boolean mRemoved;
+
+        @Override
+        public void onConfigurationChanged(Configuration configuration, int displayId) {
+            mConfiguration = configuration;
+            mDisplayId = displayId;
+        }
+
+        @Override
+        public void onWindowTokenRemoved() {
+            mRemoved = true;
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index dba157e..f123bc1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -824,7 +824,8 @@
 
         final PictureInPictureParams p = new PictureInPictureParams.Builder()
                 .setAspectRatio(new Rational(1, 2)).build();
-        assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p));
+        assertTrue(mWm.mAtmService.mActivityClientController.enterPictureInPictureMode(
+                record.token, p));
         waitUntilHandlersIdle();
         assertNotNull(o.mInfo);
         assertNotNull(o.mInfo.pictureInPictureParams);
@@ -845,14 +846,15 @@
         final ActivityRecord record = makePipableActivity();
         final PictureInPictureParams p = new PictureInPictureParams.Builder()
                 .setAspectRatio(new Rational(1, 2)).build();
-        assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p));
+        assertTrue(mWm.mAtmService.mActivityClientController.enterPictureInPictureMode(
+                record.token, p));
         waitUntilHandlersIdle();
         assertNotNull(o.mInfo);
         assertNotNull(o.mInfo.pictureInPictureParams);
 
         final PictureInPictureParams p2 = new PictureInPictureParams.Builder()
                 .setAspectRatio(new Rational(3, 4)).build();
-        mWm.mAtmService.setPictureInPictureParams(record.token, p2);
+        mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2);
         waitUntilHandlersIdle();
         assertNotNull(o.mChangedInfo);
         assertNotNull(o.mChangedInfo.pictureInPictureParams);
@@ -920,7 +922,7 @@
         assertTrue(stack2.isOrganized());
 
         // Verify a back pressed does not call the organizer
-        mWm.mAtmService.onBackPressedOnTaskRoot(activity.token);
+        mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token);
         verify(organizer, never()).onBackPressedOnTaskRoot(any());
 
         // Enable intercepting back
@@ -928,7 +930,7 @@
                 stack.mRemoteToken.toWindowContainerToken(), true);
 
         // Verify now that the back press does call the organizer
-        mWm.mAtmService.onBackPressedOnTaskRoot(activity.token);
+        mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token);
         verify(organizer, times(1)).onBackPressedOnTaskRoot(any());
 
         // Disable intercepting back
@@ -936,7 +938,7 @@
                 stack.mRemoteToken.toWindowContainerToken(), false);
 
         // Verify now that the back press no longer calls the organizer
-        mWm.mAtmService.onBackPressedOnTaskRoot(activity.token);
+        mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token);
         verify(organizer, times(1)).onBackPressedOnTaskRoot(any());
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 227eba2..a57de09 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -19,9 +19,10 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -480,33 +481,49 @@
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
         final SurfaceControl.Transaction t = spy(StubTransaction.class);
 
-        app.mHasSurface = true;
+        makeWindowVisible(app);
         app.mSurfaceControl = mock(SurfaceControl.class);
-        try {
-            app.getFrame().set(10, 20, 60, 80);
-            app.updateSurfacePosition(t);
+        final Rect frame = app.getFrame();
+        frame.set(10, 20, 60, 80);
+        app.updateSurfacePosition(t);
+        assertTrue(app.mLastSurfacePosition.equals(frame.left, frame.top));
+        app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true /* requested */);
+        assertTrue(app.mSeamlesslyRotated);
 
-            app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true);
+        // Verify we un-rotate the window state surface.
+        final Matrix matrix = new Matrix();
+        // Un-rotate 90 deg.
+        matrix.setRotate(270);
+        // Translate it back to origin.
+        matrix.postTranslate(0, mDisplayInfo.logicalWidth);
+        verify(t).setMatrix(eq(app.mSurfaceControl), eq(matrix), any(float[].class));
 
-            assertTrue(app.mSeamlesslyRotated);
+        // Verify we update the position as well.
+        final float[] curSurfacePos = {app.mLastSurfacePosition.x, app.mLastSurfacePosition.y};
+        matrix.mapPoints(curSurfacePos);
+        verify(t).setPosition(eq(app.mSurfaceControl), eq(curSurfacePos[0]), eq(curSurfacePos[1]));
 
-            // Verify we un-rotate the window state surface.
-            Matrix matrix = new Matrix();
-            // Un-rotate 90 deg
-            matrix.setRotate(270);
-            // Translate it back to origin
-            matrix.postTranslate(0, mDisplayInfo.logicalWidth);
-            verify(t).setMatrix(eq(app.mSurfaceControl), eq(matrix), any(float[].class));
+        app.finishSeamlessRotation(false /* timeout */);
+        assertFalse(app.mSeamlesslyRotated);
+        assertNull(app.mPendingSeamlessRotate);
 
-            // Verify we update the position as well.
-            float[] currentSurfacePos = {app.mLastSurfacePosition.x, app.mLastSurfacePosition.y};
-            matrix.mapPoints(currentSurfacePos);
-            verify(t).setPosition(eq(app.mSurfaceControl), eq(currentSurfacePos[0]),
-                    eq(currentSurfacePos[1]));
-        } finally {
-            app.mSurfaceControl = null;
-            app.mHasSurface = false;
-        }
+        // Simulate the case with deferred layout and animation.
+        app.resetSurfacePositionForAnimationLeash(t);
+        clearInvocations(t);
+        mWm.mWindowPlacerLocked.deferLayout();
+        app.updateSurfacePosition(t);
+        // Because layout is deferred, the position should keep the reset value.
+        assertTrue(app.mLastSurfacePosition.equals(0, 0));
+
+        app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_270, true /* requested */);
+        // The last position must be updated so the surface can be unrotated properly.
+        assertTrue(app.mLastSurfacePosition.equals(frame.left, frame.top));
+        matrix.setRotate(90);
+        matrix.postTranslate(mDisplayInfo.logicalHeight, 0);
+        curSurfacePos[0] = frame.left;
+        curSurfacePos[1] = frame.top;
+        matrix.mapPoints(curSurfacePos);
+        verify(t).setPosition(eq(app.mSurfaceControl), eq(curSurfacePos[0]), eq(curSurfacePos[1]));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 14a62d1..d64b46d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -49,6 +49,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
+import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -354,6 +355,13 @@
         }
     }
 
+    static void makeWindowVisibleAndDrawn(WindowState... windows) {
+        makeWindowVisible(windows);
+        for (WindowState win : windows) {
+            win.mWinAnimator.mDrawState = HAS_DRAWN;
+        }
+    }
+
     /** Creates a {@link TaskDisplayArea} right above the default one. */
     static TaskDisplayArea createTaskDisplayArea(DisplayContent displayContent,
             WindowManagerService service, String name, int displayAreaFeature) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index e0785c1..462df30 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -231,7 +231,7 @@
 
     @Test
     public void testWindowAttachedWithOptions() {
-        BiFunction<WindowToken, Bundle, RootDisplayArea> selectFunc =
+        BiFunction<Integer, Bundle, RootDisplayArea> selectFunc =
                 ((DisplayAreaPolicyBuilder.Result) mDisplayContent.mDisplayAreaPolicy)
                         .mSelectRootForWindowFunc;
         spyOn(selectFunc);
@@ -241,7 +241,7 @@
                 true /* ownerCanManageAppTokens */, INVALID_UID, true /* roundedCornerOverlay */,
                 false /* fromClientToken */, null /* options */);
 
-        verify(selectFunc).apply(token1, null);
+        verify(selectFunc).apply(token1.windowType, null);
 
         final Bundle options = new Bundle();
         final WindowToken token2 = new WindowToken(mDisplayContent.mWmService, mock(IBinder.class),
@@ -249,6 +249,6 @@
                 true /* ownerCanManageAppTokens */, INVALID_UID, true /* roundedCornerOverlay */,
                 false /* fromClientToken */, options /* options */);
 
-        verify(selectFunc).apply(token2, options);
+        verify(selectFunc).apply(token2.windowType, options);
     }
 }
diff --git a/services/voiceinteraction/OWNERS b/services/voiceinteraction/OWNERS
new file mode 100644
index 0000000..ef1061b
--- /dev/null
+++ b/services/voiceinteraction/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/voice/OWNERS
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 06c23de..b5bb2a8 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -49,7 +49,6 @@
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.media.permission.Identity;
-import android.media.permission.IdentityContext;
 import android.media.permission.PermissionUtil;
 import android.media.permission.SafeCloseable;
 import android.os.Binder;
@@ -92,7 +91,7 @@
 import com.android.server.SystemService;
 import com.android.server.UiThread;
 import com.android.server.pm.UserManagerInternal;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.permission.LegacyPermissionManagerInternal;
 import com.android.server.soundtrigger.SoundTriggerInternal;
 import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.wm.ActivityTaskManagerInternal;
@@ -141,10 +140,10 @@
         mUserManagerInternal = Objects.requireNonNull(
                 LocalServices.getService(UserManagerInternal.class));
 
-        PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
-                PermissionManagerServiceInternal.class);
+        LegacyPermissionManagerInternal permissionManagerInternal = LocalServices.getService(
+                LegacyPermissionManagerInternal.class);
         permissionManagerInternal.setVoiceInteractionPackagesProvider(
-                new PermissionManagerServiceInternal.PackagesProvider() {
+                new LegacyPermissionManagerInternal.PackagesProvider() {
             @Override
             public String[] getPackages(int userId) {
                 mServiceStub.initForUser(userId);
diff --git a/services/wifi/OWNERS b/services/wifi/OWNERS
new file mode 100644
index 0000000..2ae7065
--- /dev/null
+++ b/services/wifi/OWNERS
@@ -0,0 +1 @@
+include /wifi/OWNERS
diff --git a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
index 3104c7e..1a0e526 100644
--- a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
+++ b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
@@ -34,6 +34,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
+import android.provider.DeviceConfig;
 import android.util.ArraySet;
 import android.util.Log;
 
@@ -42,15 +43,20 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.pm.BackgroundDexOptService;
+import com.android.server.pm.PackageManagerService;
 import com.android.server.wm.ActivityMetricsLaunchObserver;
 import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto;
 import com.android.server.wm.ActivityMetricsLaunchObserver.Temperature;
 import com.android.server.wm.ActivityMetricsLaunchObserverRegistry;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.BooleanSupplier;
 import java.util.HashMap;
+import java.util.List;
 
 /**
  * System-server-local proxy into the {@code IIorap} native service.
@@ -65,6 +71,7 @@
     /** $> adb shell 'setprop iorapd.forwarding_service.wtf_crash true' */
     private static boolean WTF_CRASH = SystemProperties.getBoolean(
             "iorapd.forwarding_service.wtf_crash", false);
+    private static final Duration TIMEOUT = Duration.ofSeconds(600L);
 
     // "Unique" job ID from the service name. Also equal to 283673059.
     public static final int JOB_ID_IORAPD = encodeEnglishAlphabetStringIntoInt("iorapd");
@@ -80,6 +87,12 @@
     private volatile IorapdJobService mJobService;  // Write-once (null -> non-null forever).
     private volatile static IorapForwardingService sSelfService;  // Write once (null -> non-null).
 
+
+    /**
+     * Atomics set to true if the JobScheduler requests an abort.
+     */
+    private final AtomicBoolean mAbortIdleCompilation = new AtomicBoolean(false);
+
     /**
      * Initializes the system service.
      * <p>
@@ -154,9 +167,27 @@
 
     @VisibleForTesting
     protected boolean isIorapEnabled() {
+        // These two mendel flags should match those in iorapd native process
+        // system/iorapd/src/common/property.h
+        boolean isTracingEnabled =
+            getMendelFlag("iorap_perfetto_enable", "iorapd.perfetto.enable", false);
+        boolean isReadAheadEnabled =
+            getMendelFlag("iorap_readahead_enable", "iorapd.readahead.enable", false);
         // Same as the property in iorapd.rc -- disabling this will mean the 'iorapd' binder process
         // never comes up, so all binder connections will fail indefinitely.
-        return IS_ENABLED;
+        return IS_ENABLED && (isTracingEnabled || isReadAheadEnabled);
+    }
+
+    private boolean getMendelFlag(String mendelFlag, String sysProperty, boolean defaultValue) {
+        // TODO(yawanng) use DeviceConfig to get mendel property.
+        // DeviceConfig doesn't work and the reason is not clear.
+        // Provider service is already up before IORapForwardService.
+        String mendelProperty = "persist.device_config."
+            + DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT
+            + "."
+            + mendelFlag;
+        return SystemProperties.getBoolean(mendelProperty,
+            SystemProperties.getBoolean(sysProperty, defaultValue));
     }
 
     //</editor-fold>
@@ -239,7 +270,9 @@
         //
         // TODO: it would be good to get nodified of 'adb shell stop iorapd' to avoid
         // printing this warning.
-        Log.w(TAG, "Failed to connect to iorapd, is it down? Delay for " + sleepTime);
+        if (DEBUG) {
+            Log.v(TAG, "Failed to connect to iorapd, is it down? Delay for " + sleepTime);
+        }
 
         // Use a handler instead of Thread#sleep to avoid backing up the binder thread
         // when this is called from the death recipient callback.
@@ -275,7 +308,9 @@
         // Connect to the native binder service.
         mIorapRemote = provideIorapRemote();
         if (mIorapRemote == null) {
-            Log.e(TAG, "connectToRemoteAndConfigure - null iorap remote. check for Log.wtf?");
+            if (DEBUG) {
+                Log.e(TAG, "connectToRemoteAndConfigure - null iorap remote. check for Log.wtf?");
+            }
             return false;
         }
         invokeRemote(mIorapRemote,
@@ -542,32 +577,86 @@
             // Tell iorapd to start a background job.
             Log.d(TAG, "Starting background job: " + params.toString());
 
-            // We wait until that job's sequence ID returns to us with 'Completed',
-            RequestId request;
-            synchronized (mLock) {
-                // TODO: would be cleaner if we got the request from the 'invokeRemote' function.
-                // Better yet, consider a Pair<RequestId, Future<TaskResult>> or similar.
-                request = RequestId.nextValueForSequence();
-                mRunningJobs.put(request, params);
-            }
+            mAbortIdleCompilation.set(false);
+            // PackageManagerService starts before IORap service.
+            PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");
+            List<String> pkgs = pm.getAllPackages();
+            runIdleCompilationAsync(params, pkgs);
+            return true;
+        }
 
-            if (!invokeRemote(mIorapRemote, (IIorap remote) ->
-                    remote.onJobScheduledEvent(request,
-                            JobScheduledEvent.createIdleMaintenance(
-                                    JobScheduledEvent.TYPE_START_JOB,
-                                    params))
-            )) {
-                synchronized (mLock) {
-                    mRunningJobs.remove(request); // Avoid memory leaks.
+        private void runIdleCompilationAsync(final JobParameters params, final List<String> pkgs) {
+            new Thread("IORap_IdleCompilation") {
+                @Override
+                public void run() {
+                    for (int i = 0; i < pkgs.size(); i++) {
+                        String pkg = pkgs.get(i);
+                        if (mAbortIdleCompilation.get()) {
+                            Log.i(TAG, "The idle compilation is aborted");
+                            return;
+                        }
+
+                        // We wait until that job's sequence ID returns to us with 'Completed',
+                        RequestId request;
+                        synchronized (mLock) {
+                            // TODO: would be cleaner if we got the request from the
+                            // 'invokeRemote' function. Better yet, consider
+                            // a Pair<RequestId, Future<TaskResult>> or similar.
+                            request = RequestId.nextValueForSequence();
+                            mRunningJobs.put(request, params);
+                        }
+
+                        Log.i(TAG, String.format("IORap compile package: %s, [%d/%d]",
+                              pkg, i + 1, pkgs.size()));
+                        boolean shouldUpdateVersions = (i == 0);
+                        if (!invokeRemote(mIorapRemote, (IIorap remote) ->
+                                remote.onJobScheduledEvent(request,
+                                        JobScheduledEvent.createIdleMaintenance(
+                                                JobScheduledEvent.TYPE_START_JOB,
+                                                params,
+                                                pkg,
+                                                shouldUpdateVersions)))) {
+                            synchronized (mLock) {
+                                mRunningJobs.remove(request); // Avoid memory leaks.
+                            }
+                        }
+
+                        // Wait until the job is complete and removed from the running jobs.
+                        retryWithTimeout(TIMEOUT, () -> {
+                            synchronized (mLock) {
+                                return !mRunningJobs.containsKey(request);
+                            }
+                        });
+                    }
+
+                    // Finish the job after all packages are compiled.
+                    if (mProxy != null) {
+                        mProxy.jobFinished(params, /*reschedule*/false);
+                    }
+                }
+          }.start();
+        }
+
+        /** Retry until timeout. */
+        private boolean retryWithTimeout(final Duration timeout, BooleanSupplier supplier) {
+            long totalSleepTimeMs = 0L;
+            long sleepIntervalMs = 10L;
+            while (true) {
+                if (supplier.getAsBoolean()) {
+                    return true;
+                }
+                try {
+                    TimeUnit.MILLISECONDS.sleep(sleepIntervalMs);
+                } catch (InterruptedException e) {
+                    Log.e(TAG, e.getMessage());
+                    return false;
                 }
 
-                // Something went wrong on the remote side. Treat the job as being
-                // 'already finished' (i.e. immediately release wake lock).
-                return false;
+                totalSleepTimeMs += sleepIntervalMs;
+                if (totalSleepTimeMs > timeout.toMillis()) {
+                    return false;
+                }
             }
-
-            // True -> keep the wakelock acquired until #jobFinished is called.
-            return true;
         }
 
         // Called by system to prematurely stop the job.
@@ -575,32 +664,7 @@
         public boolean onStopJob(JobParameters params) {
             // As this is unexpected behavior, print a warning.
             Log.w(TAG, "onStopJob(params=" + params.toString() + ")");
-
-            // No longer track this job (avoids a memory leak).
-            boolean wasTracking = false;
-            synchronized (mLock) {
-                for (HashMap.Entry<RequestId, JobParameters> entry : mRunningJobs.entrySet()) {
-                   if (entry.getValue().getJobId() == params.getJobId()) {
-                       mRunningJobs.remove(entry.getKey());
-                       wasTracking = true;
-                   }
-                }
-            }
-
-            // Notify iorapd to stop (abort) the job.
-            if (wasTracking) {
-                invokeRemote(mIorapRemote, (IIorap remote) ->
-                        remote.onJobScheduledEvent(RequestId.nextValueForSequence(),
-                                JobScheduledEvent.createIdleMaintenance(
-                                        JobScheduledEvent.TYPE_STOP_JOB,
-                                        params))
-                );
-            } else {
-                // Even weirder. This could only be considered "correct" if iorapd reported success
-                // concurrently to the JobService requesting an onStopJob.
-                Log.e(TAG, "Untracked onStopJob request");  // see above Log.w for the params.
-            }
-
+            mAbortIdleCompilation.set(true);
 
             // Yes, retry the job at a later time no matter what.
             return true;
@@ -626,18 +690,6 @@
             }
 
             Log.d(TAG, "Finished background job: " + jobParameters.toString());
-
-            // Job is successful and periodic. Do not 'reschedule' according to the back-off
-            // criteria.
-            //
-            // This releases the wakelock that was acquired in #onStartJob.
-
-            IorapdJobServiceProxy proxy = mProxy;
-            if (proxy != null) {
-                proxy.jobFinished(jobParameters, /*reschedule*/false);
-            }
-            // Cannot call 'jobFinished' on 'this' because it was not constructed
-            // from the JobService, so it would get an NPE when calling mEngine.
         }
 
         public void onIorapdDisconnected() {
diff --git a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java b/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java
index 2055b20..b91dd71 100644
--- a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java
+++ b/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java
@@ -55,6 +55,10 @@
     /** @see JobParameters#getJobId() */
     public final int jobId;
 
+    public final String packageName;
+
+    public final boolean shouldUpdateVersions;
+
     /** Device is 'idle' and it's charging (plugged in). */
     public static final int SORT_IDLE_MAINTENANCE = 0;
     private static final int SORT_MAX = 0;
@@ -77,14 +81,22 @@
      * Only the job ID is retained from {@code jobParams}, all other param info is dropped.
      */
     @NonNull
-    public static JobScheduledEvent createIdleMaintenance(@Type int type, JobParameters jobParams) {
-        return new JobScheduledEvent(type, jobParams.getJobId(), SORT_IDLE_MAINTENANCE);
+    public static JobScheduledEvent createIdleMaintenance(
+        @Type int type, JobParameters jobParams, String packageName, boolean shouldUpdateVersions) {
+        return new JobScheduledEvent(
+            type, jobParams.getJobId(), SORT_IDLE_MAINTENANCE, packageName, shouldUpdateVersions);
     }
 
-    private JobScheduledEvent(@Type int type, int jobId, @Sort int sort) {
+    private JobScheduledEvent(@Type int type,
+                              int jobId,
+                              @Sort int sort,
+                              String packageName,
+                              boolean shouldUpdateVersions) {
         this.type = type;
         this.jobId = jobId;
         this.sort = sort;
+        this.packageName = packageName;
+        this.shouldUpdateVersions = shouldUpdateVersions;
 
         checkConstructorArguments();
     }
@@ -108,12 +120,16 @@
     private boolean equals(JobScheduledEvent other) {
         return type == other.type &&
                 jobId == other.jobId &&
-                sort == other.sort;
+                sort == other.sort &&
+                packageName.equals(other.packageName) &&
+                shouldUpdateVersions == other.shouldUpdateVersions;
     }
 
     @Override
     public String toString() {
-        return String.format("{type: %d, jobId: %d, sort: %d}", type, jobId, sort);
+        return String.format(
+            "{type: %d, jobId: %d, sort: %d, packageName: %s, shouldUpdateVersions %b}",
+            type, jobId, sort, packageName, shouldUpdateVersions);
     }
 
     //<editor-fold desc="Binder boilerplate">
@@ -122,6 +138,8 @@
         out.writeInt(type);
         out.writeInt(jobId);
         out.writeInt(sort);
+        out.writeString(packageName);
+        out.writeBoolean(shouldUpdateVersions);
 
         // We do not parcel the entire JobParameters here because there is no C++ equivalent
         // of that class [which the iorapd side of the binder interface requires].
@@ -131,6 +149,8 @@
         this.type = in.readInt();
         this.jobId = in.readInt();
         this.sort = in.readInt();
+        this.packageName = in.readString();
+        this.shouldUpdateVersions = in.readBoolean();
 
         checkConstructorArguments();
     }
diff --git a/telecomm/TEST_MAPPING b/telecomm/TEST_MAPPING
index c9903f9..1963ff3 100644
--- a/telecomm/TEST_MAPPING
+++ b/telecomm/TEST_MAPPING
@@ -23,7 +23,9 @@
           "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
-    },
+    }
+  ],
+  "presubmit-large": [
     {
       "name": "CtsTelecomTestCases",
       "options": [
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 6288bc1..b1ccb53 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -1988,8 +1988,10 @@
             connection.setAudioModeIsVoip(true);
         }
         connection.setTelecomCallId(callId);
+        PhoneAccountHandle phoneAccountHandle = connection.getPhoneAccountHandle() == null
+                            ? request.getAccountHandle() : connection.getPhoneAccountHandle();
         if (connection.getState() != Connection.STATE_DISCONNECTED) {
-            addConnection(request.getAccountHandle(), callId, connection);
+            addConnection(phoneAccountHandle, callId, connection);
         }
 
         Uri address = connection.getAddress();
@@ -2005,7 +2007,7 @@
                 callId,
                 request,
                 new ParcelableConnection(
-                        request.getAccountHandle(),
+                        phoneAccountHandle,
                         connection.getState(),
                         connection.getConnectionCapabilities(),
                         connection.getConnectionProperties(),
diff --git a/telecomm/java/android/telecom/OWNERS b/telecomm/java/android/telecom/OWNERS
new file mode 100644
index 0000000..6656a01
--- /dev/null
+++ b/telecomm/java/android/telecom/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+breadley@google.com
+hallliu@google.com
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 960b0df4..5b03863 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -268,10 +268,69 @@
     /**
      * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a string call
      * subject which will be associated with an outgoing call.  Should only be specified if the
-     * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}.
+     * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}
+     * or {@link PhoneAccount#CAPABILITY_CALL_COMPOSER}.
      */
     public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
 
+    // Values for EXTRA_PRIORITY
+    /**
+     * Indicates the call composer call priority is normal.
+     *
+     * Reference: RCC.20 Section 2.4.4.2
+     */
+    public static final int PRIORITY_NORMAL = 0;
+
+    /**
+     * Indicates the call composer call priority is urgent.
+     *
+     * Reference: RCC.20 Section 2.4.4.2
+     */
+    public static final int PRIORITY_URGENT = 1;
+
+    /**
+     * Extra for the call composer call priority, either {@link #PRIORITY_NORMAL} or
+     * {@link #PRIORITY_URGENT}.
+     *
+     * Reference: RCC.20 Section 2.4.4.2
+     */
+    public static final String EXTRA_PRIORITY = "android.telecom.extra.PRIORITY";
+
+    /**
+     * Extra for the call composer call location, an {@link android.location.Location} parcelable
+     * class to represent the geolocation as a latitude and longitude pair.
+     *
+     * Reference: RCC.20 Section 2.4.3.2
+     */
+    public static final String EXTRA_LOCATION = "android.telecom.extra.LOCATION";
+
+    /**
+     * A boolean extra set on incoming calls to indicate that the call has a picture specified.
+     * Given that image download could take a (short) time, the EXTRA is set immediately upon
+     * adding the call to the Dialer app, this allows the Dialer app to reserve space for an image
+     * if one is expected. The EXTRA may be unset if the image download ends up failing for some
+     * reason.
+     */
+    public static final String EXTRA_HAS_PICTURE = "android.telecom.extra.HAS_PICTURE";
+
+    /**
+     * A URI representing the picture that was downloaded when a call is received.
+     * This is a content URI within the call log provider which can be used to open a file
+     * descriptor. This could be set a short time after a call is added to the Dialer app if the
+     * download is delayed for some reason. The Dialer app will receive a callback via
+     * {@link Call.Callback#onDetailsChanged} when this value has changed.
+     *
+     * Reference: RCC.20 Section 2.4.3.2
+     */
+    public static final String EXTRA_INCOMING_PICTURE = "android.telecom.extra.INCOMING_PICTURE";
+
+    // TODO(hallliu), This UUID is obtained from TelephonyManager#uploadCallComposerPicture.
+    /**
+     * A ParcelUuid used as a token to represent a picture that was uploaded prior to the call
+     * being placed.
+     */
+    public static final String EXTRA_OUTGOING_PICTURE = "android.telecom.extra.OUTGOING_PICTURE";
+
     /**
      * The extra used by a {@link ConnectionService} to provide the handle of the caller that
      * has initiated a new incoming call.
diff --git a/telephony/java/android/service/euicc/OWNERS b/telephony/java/android/service/euicc/OWNERS
new file mode 100644
index 0000000..6aa399d
--- /dev/null
+++ b/telephony/java/android/service/euicc/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+amitmahajan@google.com
diff --git a/telephony/java/android/service/sms/OWNERS b/telephony/java/android/service/sms/OWNERS
new file mode 100644
index 0000000..6aa399d
--- /dev/null
+++ b/telephony/java/android/service/sms/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+amitmahajan@google.com
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index b381cce..189a4b8 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -21,7 +21,6 @@
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.hardware.radio.V1_4.CellInfo.Info;
-import android.hardware.radio.V1_5.CellInfo.CellInfoRatSpecificInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -352,6 +351,13 @@
     }
 
     /** @hide */
+    protected CellInfo(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
+        this.mRegistered = ci.registered;
+        this.mTimeStamp = timeStamp;
+        this.mCellConnectionStatus = ci.connectionStatus;
+    }
+
+    /** @hide */
     public static CellInfo create(android.hardware.radio.V1_0.CellInfo ci) {
         if (ci == null) return null;
         switch(ci.cellInfoType) {
@@ -395,17 +401,49 @@
     public static CellInfo create(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
         if (ci == null) return null;
         switch (ci.ratSpecificInfo.getDiscriminator()) {
-            case CellInfoRatSpecificInfo.hidl_discriminator.gsm:
+            case android.hardware.radio.V1_5.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.gsm:
                 return new CellInfoGsm(ci, timeStamp);
-            case CellInfoRatSpecificInfo.hidl_discriminator.cdma:
+            case android.hardware.radio.V1_5.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.cdma:
                 return new CellInfoCdma(ci, timeStamp);
-            case CellInfoRatSpecificInfo.hidl_discriminator.lte:
+            case android.hardware.radio.V1_5.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.lte:
                 return new CellInfoLte(ci, timeStamp);
-            case CellInfoRatSpecificInfo.hidl_discriminator.wcdma:
+            case android.hardware.radio.V1_5.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.wcdma:
                 return new CellInfoWcdma(ci, timeStamp);
-            case CellInfoRatSpecificInfo.hidl_discriminator.tdscdma:
+            case android.hardware.radio.V1_5.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.tdscdma:
                 return new CellInfoTdscdma(ci, timeStamp);
-            case CellInfoRatSpecificInfo.hidl_discriminator.nr:
+            case android.hardware.radio.V1_5.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.nr:
+                return new CellInfoNr(ci, timeStamp);
+            default: return null;
+        }
+    }
+
+    /** @hide */
+    public static CellInfo create(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
+        if (ci == null) return null;
+        switch (ci.ratSpecificInfo.getDiscriminator()) {
+            case android.hardware.radio.V1_6.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.gsm:
+                return new CellInfoGsm(ci, timeStamp);
+            case android.hardware.radio.V1_6.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.cdma:
+                return new CellInfoCdma(ci, timeStamp);
+            case android.hardware.radio.V1_6.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.lte:
+                return new CellInfoLte(ci, timeStamp);
+            case android.hardware.radio.V1_6.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.wcdma:
+                return new CellInfoWcdma(ci, timeStamp);
+            case android.hardware.radio.V1_6.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.tdscdma:
+                return new CellInfoTdscdma(ci, timeStamp);
+            case android.hardware.radio.V1_6.CellInfo
+                    .CellInfoRatSpecificInfo.hidl_discriminator.nr:
                 return new CellInfoNr(ci, timeStamp);
             default: return null;
         }
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index 3ce99fa..dbb30d2 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -87,6 +87,15 @@
                 new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo);
     }
 
+    /** @hide */
+    public CellInfoCdma(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_2.CellInfoCdma cic = ci.ratSpecificInfo.cdma();
+        mCellIdentityCdma = new CellIdentityCdma(cic.cellIdentityCdma);
+        mCellSignalStrengthCdma =
+                new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo);
+    }
+
     /**
      * @return a {@link CellIdentityCdma} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java
index e296e61..e1d996e 100644
--- a/telephony/java/android/telephony/CellInfoGsm.java
+++ b/telephony/java/android/telephony/CellInfoGsm.java
@@ -82,6 +82,14 @@
         mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm);
     }
 
+    /** @hide */
+    public CellInfoGsm(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_5.CellInfoGsm cig = ci.ratSpecificInfo.gsm();
+        mCellIdentityGsm = new CellIdentityGsm(cig.cellIdentityGsm);
+        mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm);
+    }
+
     /**
      * @return a {@link CellIdentityGsm} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index 6f81234..39b320a 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -91,6 +91,15 @@
         mCellConfig = new CellConfigLte();
     }
 
+    /** @hide */
+    public CellInfoLte(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_6.CellInfoLte cil = ci.ratSpecificInfo.lte();
+        mCellIdentityLte = new CellIdentityLte(cil.cellIdentityLte);
+        mCellSignalStrengthLte = new CellSignalStrengthLte(cil.signalStrengthLte);
+        mCellConfig = new CellConfigLte();
+    }
+
     /**
      * @return a {@link CellIdentityLte} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java
index e01e8f0..12e6a38 100644
--- a/telephony/java/android/telephony/CellInfoNr.java
+++ b/telephony/java/android/telephony/CellInfoNr.java
@@ -68,6 +68,14 @@
         mCellSignalStrength = new CellSignalStrengthNr(cil.signalStrengthNr);
     }
 
+    /** @hide */
+    public CellInfoNr(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_6.CellInfoNr cil = ci.ratSpecificInfo.nr();
+        mCellIdentity = new CellIdentityNr(cil.cellIdentityNr);
+        mCellSignalStrength = new CellSignalStrengthNr(cil.signalStrengthNr);
+    }
+
     /**
      * @return a {@link CellIdentityNr} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java
index 038c49a..994b317 100644
--- a/telephony/java/android/telephony/CellInfoTdscdma.java
+++ b/telephony/java/android/telephony/CellInfoTdscdma.java
@@ -85,6 +85,14 @@
         mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma);
     }
 
+    /** @hide */
+    public CellInfoTdscdma(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_5.CellInfoTdscdma cit = ci.ratSpecificInfo.tdscdma();
+        mCellIdentityTdscdma = new CellIdentityTdscdma(cit.cellIdentityTdscdma);
+        mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma);
+    }
+
     /**
      * @return a {@link CellIdentityTdscdma} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java
index c74955f..62ac0b8 100644
--- a/telephony/java/android/telephony/CellInfoWcdma.java
+++ b/telephony/java/android/telephony/CellInfoWcdma.java
@@ -80,6 +80,14 @@
         mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma);
     }
 
+    /** @hide */
+    public CellInfoWcdma(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_5.CellInfoWcdma ciw = ci.ratSpecificInfo.wcdma();
+        mCellIdentityWcdma = new CellIdentityWcdma(ciw.cellIdentityWcdma);
+        mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma);
+    }
+
     /**
      * @return a {@link CellIdentityWcdma} instance.
      */
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 47a8f72..db7d10a 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -86,6 +86,15 @@
     private int mRsrq;
     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
     private int mRssnr;
+    /**
+     * CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
+     * The definition of CQI in each table is different.
+     *
+     * Reference: 3GPP TS 136.213 section 7.2.3.
+     *
+     * Range [1, 6].
+     */
+    private int mCqiTableIndex;
     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
     private int mCqi;
     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
@@ -120,6 +129,32 @@
      * @param rsrp in dBm [-140,-43], UNKNOWN
      * @param rsrq in dB [-34, 3], UNKNOWN
      * @param rssnr in dB [-20, +30], UNKNOWN
+     * @param cqiTableIndex [1, 6], UNKNOWN
+     * @param cqi [0, 15], UNKNOWN
+     * @param timingAdvance [0, 1282], UNKNOWN
+     *
+     */
+    /** @hide */
+    public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqiTableIndex,
+            int cqi, int timingAdvance) {
+        mRssi = inRangeOrUnavailable(rssi, -113, -51);
+        mSignalStrength = mRssi;
+        mRsrp = inRangeOrUnavailable(rsrp, -140, -43);
+        mRsrq = inRangeOrUnavailable(rsrq, -34, 3);
+        mRssnr = inRangeOrUnavailable(rssnr, -20, 30);
+        mCqiTableIndex = inRangeOrUnavailable(cqiTableIndex, 1, 6);
+        mCqi = inRangeOrUnavailable(cqi, 0, 15);
+        mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282);
+        updateLevel(null, null);
+    }
+
+    /**
+     * Construct a cell signal strength
+     *
+     * @param rssi in dBm [-113,-51], UNKNOWN
+     * @param rsrp in dBm [-140,-43], UNKNOWN
+     * @param rsrq in dB [-34, 3], UNKNOWN
+     * @param rssnr in dB [-20, +30], UNKNOWN
      * @param cqi [0, 15], UNKNOWN
      * @param timingAdvance [0, 1282], UNKNOWN
      *
@@ -127,15 +162,7 @@
     /** @hide */
     public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi,
             int timingAdvance) {
-
-        mRssi = inRangeOrUnavailable(rssi, -113, -51);
-        mSignalStrength = mRssi;
-        mRsrp = inRangeOrUnavailable(rsrp, -140, -43);
-        mRsrq = inRangeOrUnavailable(rsrq, -34, 3);
-        mRssnr = inRangeOrUnavailable(rssnr, -20, 30);
-        mCqi = inRangeOrUnavailable(cqi, 0, 15);
-        mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282);
-        updateLevel(null, null);
+        this(rssi, rsrp, rsrq, rssnr, CellInfo.UNAVAILABLE, cqi, timingAdvance);
     }
 
     /** @hide */
@@ -148,6 +175,16 @@
     }
 
     /** @hide */
+    public CellSignalStrengthLte(android.hardware.radio.V1_6.LteSignalStrength lte) {
+        // Convert from HAL values as part of construction.
+        this(convertRssiAsuToDBm(lte.base.signalStrength),
+                lte.base.rsrp != CellInfo.UNAVAILABLE ? -lte.base.rsrp : lte.base.rsrp,
+                lte.base.rsrq != CellInfo.UNAVAILABLE ? -lte.base.rsrq : lte.base.rsrq,
+                convertRssnrUnitFromTenDbToDB(lte.base.rssnr), lte.cqiTableIndex, lte.base.cqi,
+                lte.base.timingAdvance);
+    }
+
+    /** @hide */
     public CellSignalStrengthLte(CellSignalStrengthLte s) {
         copyFrom(s);
     }
@@ -159,6 +196,7 @@
         mRsrp = s.mRsrp;
         mRsrq = s.mRsrq;
         mRssnr = s.mRssnr;
+        mCqiTableIndex = s.mCqiTableIndex;
         mCqi = s.mCqi;
         mTimingAdvance = s.mTimingAdvance;
         mLevel = s.mLevel;
@@ -179,6 +217,7 @@
         mRsrp = CellInfo.UNAVAILABLE;
         mRsrq = CellInfo.UNAVAILABLE;
         mRssnr = CellInfo.UNAVAILABLE;
+        mCqiTableIndex = CellInfo.UNAVAILABLE;
         mCqi = CellInfo.UNAVAILABLE;
         mTimingAdvance = CellInfo.UNAVAILABLE;
         mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
@@ -402,6 +441,17 @@
     }
 
     /**
+     * Get table index for channel quality indicator
+     *
+     * @return the CQI table index if available or
+     *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
+     */
+    /** @hide */
+    public int getCqiTableIndex() {
+        return mCqiTableIndex;
+    }
+
+    /**
      * Get channel quality indicator
      *
      * @return the CQI if available or
@@ -454,7 +504,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance, mLevel);
+        return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqiTableIndex, mCqi, mTimingAdvance,
+                mLevel);
     }
 
     private static final CellSignalStrengthLte sInvalid = new CellSignalStrengthLte();
@@ -476,6 +527,7 @@
                 && mRsrp == s.mRsrp
                 && mRsrq == s.mRsrq
                 && mRssnr == s.mRssnr
+                && mCqiTableIndex == s.mCqiTableIndex
                 && mCqi == s.mCqi
                 && mTimingAdvance == s.mTimingAdvance
                 && mLevel == s.mLevel;
@@ -491,6 +543,7 @@
                 + " rsrp=" + mRsrp
                 + " rsrq=" + mRsrq
                 + " rssnr=" + mRssnr
+                + " cqiTableIndex=" + mCqiTableIndex
                 + " cqi=" + mCqi
                 + " ta=" + mTimingAdvance
                 + " level=" + mLevel
@@ -508,6 +561,7 @@
         dest.writeInt(mRsrp);
         dest.writeInt(mRsrq);
         dest.writeInt(mRssnr);
+        dest.writeInt(mCqiTableIndex);
         dest.writeInt(mCqi);
         dest.writeInt(mTimingAdvance);
         dest.writeInt(mLevel);
@@ -523,6 +577,7 @@
         mRsrp = in.readInt();
         mRsrq = in.readInt();
         mRssnr = in.readInt();
+        mCqiTableIndex = in.readInt();
         mCqi = in.readInt();
         mTimingAdvance = in.readInt();
         mLevel = in.readInt();
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 766019e..1518190 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.IntRange;
+import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
@@ -27,7 +28,10 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * 5G NR signal strength related information.
@@ -109,6 +113,28 @@
     private int mCsiRsrp;
     private int mCsiRsrq;
     private int mCsiSinr;
+    /**
+     * CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
+     * The definition of CQI in each table is different.
+     *
+     * Reference: 3GPP TS 138.214 section 5.2.2.1.
+     *
+     * Range [1, 3].
+     */
+    private int mCsiCqiTableIndex;
+    /**
+     * CSI channel quality indicators (CQI) for all subbands.
+     *
+     * If the CQI report is for the entire wideband, a single CQI index is provided.
+     * If the CQI report is for all subbands, one CQI index is provided for each subband,
+     * in ascending order of subband index.
+     * If CQI is not available, the CQI report is empty.
+     *
+     * Reference: 3GPP TS 138.214 section 5.2.2.1.
+     *
+     * Range [0, 15] for each CQI.
+     */
+    private List<Integer> mCsiCqiReport;;
     private int mSsRsrp;
     private int mSsRsrq;
     private int mSsSinr;
@@ -138,6 +164,32 @@
      * @param csiRsrp CSI reference signal received power.
      * @param csiRsrq CSI reference signal received quality.
      * @param csiSinr CSI signal-to-noise and interference ratio.
+     * @param csiCqiTableIndex CSI CSI channel quality indicator (CQI) table index.
+     * @param csiCqiReport CSI channel quality indicators (CQI) for all subbands.
+     * @param ssRsrp SS reference signal received power.
+     * @param ssRsrq SS reference signal received quality.
+     * @param ssSinr SS signal-to-noise and interference ratio.
+     * @hide
+     */
+    public CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex,
+            List<Integer> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr) {
+        mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44);
+        mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
+        mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
+        mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3);
+        mCsiCqiReport =  csiCqiReport.stream()
+                .map(cqi -> new Integer(inRangeOrUnavailable(cqi.intValue(), 1, 3)))
+                .collect(Collectors.toList());
+        mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
+        mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
+        mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
+        updateLevel(null, null);
+    }
+
+    /**
+     * @param csiRsrp CSI reference signal received power.
+     * @param csiRsrq CSI reference signal received quality.
+     * @param csiSinr CSI signal-to-noise and interference ratio.
      * @param ssRsrp SS reference signal received power.
      * @param ssRsrq SS reference signal received quality.
      * @param ssSinr SS signal-to-noise and interference ratio.
@@ -145,13 +197,8 @@
      */
     public CellSignalStrengthNr(
             int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) {
-        mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44);
-        mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
-        mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
-        mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
-        mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
-        mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
-        updateLevel(null, null);
+        this(csiRsrp, csiRsrq, csiSinr, CellInfo.UNAVAILABLE, Collections.emptyList(),
+                ssRsrp, ssRsrq, ssSinr);
     }
 
     /**
@@ -164,6 +211,15 @@
     }
 
     /**
+     * @hide
+     * @param ss signal strength from modem.
+     */
+    public CellSignalStrengthNr(android.hardware.radio.V1_6.NrSignalStrength ss) {
+        this(flip(ss.base.csiRsrp), flip(ss.base.csiRsrq), ss.base.csiSinr, ss.csiCqiTableIndex,
+                ss.csiCqiReport, flip(ss.base.ssRsrp), flip(ss.base.ssRsrq), ss.base.ssSinr);
+    }
+
+    /**
      * Flip sign cell strength value when taking in the value from hal
      * @param val cell strength value
      * @return flipped value
@@ -232,6 +288,36 @@
         return mCsiSinr;
     }
 
+    /**
+     * Return CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
+     * The definition of CQI in each table is different.
+     *
+     * Reference: 3GPP TS 138.214 section 5.2.2.1.
+     *
+     * Range [1, 3].
+     */
+    /** @hide */
+    public int getCsiCqiTableIndex() {
+        return mCsiCqiTableIndex;
+    }
+    /**
+     * Return a list of CSI channel quality indicators (CQI) for all subbands.
+     *
+     * If the CQI report is for the entire wideband, a single CQI index is provided.
+     * If the CQI report is for all subbands, one CQI index is provided for each subband,
+     * in ascending order of subband index.
+     * If CQI is not available, the CQI report is empty.
+     *
+     * Reference: 3GPP TS 138.214 section 5.2.2.1.
+     *
+     * Range [0, 15] for each CQI.
+     */
+    /** @hide */
+    @NonNull
+    public List<Integer> getCsiCqiReport() {
+        return mCsiCqiReport;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -243,6 +329,8 @@
         dest.writeInt(mCsiRsrp);
         dest.writeInt(mCsiRsrq);
         dest.writeInt(mCsiSinr);
+        dest.writeInt(mCsiCqiTableIndex);
+        dest.writeList(mCsiCqiReport);
         dest.writeInt(mSsRsrp);
         dest.writeInt(mSsRsrq);
         dest.writeInt(mSsSinr);
@@ -253,6 +341,8 @@
         mCsiRsrp = in.readInt();
         mCsiRsrq = in.readInt();
         mCsiSinr = in.readInt();
+        mCsiCqiTableIndex = in.readInt();
+        mCsiCqiReport = in.readArrayList(Integer.class.getClassLoader());
         mSsRsrp = in.readInt();
         mSsRsrq = in.readInt();
         mSsSinr = in.readInt();
@@ -265,6 +355,8 @@
         mCsiRsrp = CellInfo.UNAVAILABLE;
         mCsiRsrq = CellInfo.UNAVAILABLE;
         mCsiSinr = CellInfo.UNAVAILABLE;
+        mCsiCqiTableIndex = CellInfo.UNAVAILABLE;
+        mCsiCqiReport = Collections.emptyList();
         mSsRsrp = CellInfo.UNAVAILABLE;
         mSsRsrq = CellInfo.UNAVAILABLE;
         mSsSinr = CellInfo.UNAVAILABLE;
@@ -408,6 +500,8 @@
         mCsiRsrp = s.mCsiRsrp;
         mCsiRsrq = s.mCsiRsrq;
         mCsiSinr = s.mCsiSinr;
+        mCsiCqiTableIndex = s.mCsiCqiTableIndex;
+        mCsiCqiReport = s.mCsiCqiReport;
         mSsRsrp = s.mSsRsrp;
         mSsRsrq = s.mSsRsrq;
         mSsSinr = s.mSsSinr;
@@ -423,7 +517,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr, mLevel);
+        return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mCsiCqiTableIndex,
+                mCsiCqiReport, mSsRsrp, mSsRsrq, mSsSinr, mLevel);
     }
 
     private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr();
@@ -439,6 +534,8 @@
         if (obj instanceof CellSignalStrengthNr) {
             CellSignalStrengthNr o = (CellSignalStrengthNr) obj;
             return mCsiRsrp == o.mCsiRsrp && mCsiRsrq == o.mCsiRsrq && mCsiSinr == o.mCsiSinr
+                    && mCsiCqiTableIndex == o.mCsiCqiTableIndex
+                    && mCsiCqiReport.equals(o.mCsiCqiReport)
                     && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr
                     && mLevel == o.mLevel;
         }
@@ -451,7 +548,8 @@
                 .append(TAG + ":{")
                 .append(" csiRsrp = " + mCsiRsrp)
                 .append(" csiRsrq = " + mCsiRsrq)
-                .append(" csiSinr = " + mCsiSinr)
+                .append(" csiCqiTableIndex = " + mCsiCqiTableIndex)
+                .append(" csiCqiReport = " + mCsiCqiReport)
                 .append(" ssRsrp = " + mSsRsrp)
                 .append(" ssRsrq = " + mSsRsrq)
                 .append(" ssSinr = " + mSsSinr)
diff --git a/telephony/java/android/telephony/OWNERS b/telephony/java/android/telephony/OWNERS
new file mode 100644
index 0000000..6aa399d
--- /dev/null
+++ b/telephony/java/android/telephony/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+amitmahajan@google.com
diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java
index b785037..6571858 100644
--- a/telephony/java/android/telephony/PhoneCapability.java
+++ b/telephony/java/android/telephony/PhoneCapability.java
@@ -28,8 +28,6 @@
 /**
  * Define capability of a modem group. That is, the capabilities
  * are shared between those modems defined by list of modem IDs.
- *
- * @hide
  */
 public final class PhoneCapability implements Parcelable {
     // Hardcoded default DSDS capability.
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index 8d49e15..95c69ba 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -29,10 +29,6 @@
 import java.util.Arrays;
 import java.util.Objects;
 
-/**
- * @hide
- */
-@SystemApi
 public final class PhysicalChannelConfig implements Parcelable {
 
     // TODO(b/72993578) consolidate these enums in a central location.
@@ -86,7 +82,7 @@
     private int mFrequencyRange;
 
     /**
-     * The absolute radio frequency channel number, {@link CHANNEL_NUMBER_UNKNOWN} if unknown.
+     * The absolute radio frequency channel number, {@link #CHANNEL_NUMBER_UNKNOWN} if unknown.
      */
     private int mChannelNumber;
 
@@ -97,7 +93,7 @@
     private int[] mContextIds;
 
     /**
-     * The physical cell identifier for this cell - PCI, PSC, {@link PHYSICAL_CELL_ID_UNKNOWN}
+     * The physical cell identifier for this cell - PCI, PSC, {@link #PHYSICAL_CELL_ID_UNKNOWN}
      * if unknown.
      */
     private int mPhysicalCellId;
@@ -153,7 +149,7 @@
 
     /**
      * @return the absolute radio frequency channel number for this physical channel,
-     * {@link CHANNEL_NUMBER_UNKNOWN} if unknown.
+     * {@link #CHANNEL_NUMBER_UNKNOWN} if unknown.
      */
     public int getChannelNumber() {
         return mChannelNumber;
@@ -169,7 +165,7 @@
      * In 5G RAN, this value is physical layer cell identity. The range is [0, 1007].
      * Reference: 3GPP TS 38.211 section 7.4.2.1.
      *
-     * @return the physical cell identifier for this cell, {@link PHYSICAL_CELL_ID_UNKNOWN}
+     * @return the physical cell identifier for this cell, {@link #PHYSICAL_CELL_ID_UNKNOWN}
      * if {@link android.telephony.CellInfo#UNAVAILABLE}.
      */
     @IntRange(from = 0, to = 1007)
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 7bd0bc0..b317c55 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -187,6 +187,21 @@
                 new CellSignalStrengthNr(signalStrength.nr));
     }
 
+    /**
+     * Constructor for Radio HAL V1.6.
+     *
+     * @param signalStrength signal strength reported from modem.
+     * @hide
+     */
+    public SignalStrength(android.hardware.radio.V1_6.SignalStrength signalStrength) {
+        this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo),
+                new CellSignalStrengthGsm(signalStrength.gsm),
+                new CellSignalStrengthWcdma(signalStrength.wcdma),
+                new CellSignalStrengthTdscdma(signalStrength.tdscdma),
+                new CellSignalStrengthLte(signalStrength.lte),
+                new CellSignalStrengthNr(signalStrength.nr));
+    }
+
     private CellSignalStrength getPrimary() {
         // This behavior is intended to replicate the legacy behavior of getLevel() by prioritizing
         // newer faster RATs for default/for display purposes.
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 886ec33..239329c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -124,6 +124,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
@@ -155,6 +156,7 @@
 public class TelephonyManager {
     private static final String TAG = "TelephonyManager";
 
+    private TelephonyRegistryManager mTelephonyRegistryMgr;
     /**
      * To expand the error codes for {@link TelephonyManager#updateAvailableNetworks} and
      * {@link TelephonyManager#setPreferredOpportunisticDataSubscription}.
@@ -5574,12 +5576,22 @@
      * @param events The telephony state(s) of interest to the listener,
      *               as a bitwise-OR combination of {@link PhoneStateListener}
      *               LISTEN_ flags.
-     * @deprecated use {@link #listen(long, PhoneStateListener) instead due to the event number
-     *             limit increased to 64.
+     * @deprecated Use {@link #registerPhoneStateListener(Executor, PhoneStateListener)}.
      */
     @Deprecated
     public void listen(PhoneStateListener listener, int events) {
-        listen(events, listener);
+        boolean notifyNow = getITelephony() != null;
+        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
+        if (mTelephonyRegistryMgr != null) {
+            if (events != PhoneStateListener.LISTEN_NONE) {
+                mTelephonyRegistryMgr.registerPhoneStateListenerWithEvents(mSubId,
+                        getOpPackageName(), getAttributionTag(), listener, events, notifyNow);
+            } else {
+                unregisterPhoneStateListener(listener);
+            }
+        } else {
+            throw new IllegalStateException("telephony service is null.");
+        }
     }
 
     /**
@@ -5615,18 +5627,21 @@
      *               LISTEN_ flags.
      * @param listener The {@link PhoneStateListener} object to register
      *                 (or unregister)
+     * @deprecated Use {@link #registerPhoneStateListener(Executor, PhoneStateListener)}.
      */
+    @Deprecated
     public void listen(long events, @NonNull PhoneStateListener listener) {
-        if (mContext == null) return;
-        boolean notifyNow = (getITelephony() != null);
-        TelephonyRegistryManager telephonyRegistry =
-                (TelephonyRegistryManager)
-                        mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
-        if (telephonyRegistry != null) {
-            telephonyRegistry.listenForSubscriber(mSubId, getOpPackageName(), getAttributionTag(),
-                    listener, events, notifyNow);
+        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
+        if (mTelephonyRegistryMgr != null) {
+            if (events != PhoneStateListener.LISTEN_NONE) {
+                mTelephonyRegistryMgr.registerPhoneStateListenerWithEvents(mSubId,
+                        getOpPackageName(), getAttributionTag(), listener,
+                        Long.valueOf(events).intValue(), getITelephony() != null);
+            } else {
+                unregisterPhoneStateListener(listener);
+            }
         } else {
-            Rlog.w(TAG, "telephony registry not ready.");
+            throw new IllegalStateException("telephony service is null.");
         }
     }
 
@@ -12290,23 +12305,15 @@
     @NonNull
     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
             @EmergencyServiceCategories int categories) {
-        Map<Integer, List<EmergencyNumber>> emergencyNumberList = new HashMap<>();
+        Map<Integer, List<EmergencyNumber>> emergencyNumberListForCategories = new HashMap<>();
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                emergencyNumberList = telephony.getEmergencyNumberList(
-                        mContext.getOpPackageName(), mContext.getAttributionTag());
-                if (emergencyNumberList != null) {
-                    for (Integer subscriptionId : emergencyNumberList.keySet()) {
-                        List<EmergencyNumber> numberList = emergencyNumberList.get(subscriptionId);
-                        for (EmergencyNumber number : numberList) {
-                            if (!number.isInEmergencyServiceCategories(categories)) {
-                                numberList.remove(number);
-                            }
-                        }
-                    }
-                }
-                return emergencyNumberList;
+                Map<Integer, List<EmergencyNumber>> emergencyNumberList =
+                        telephony.getEmergencyNumberList(mContext.getOpPackageName(),
+                                mContext.getAttributionTag());
+                emergencyNumberListForCategories =
+                        filterEmergencyNumbersByCategories(emergencyNumberList, categories);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -12314,7 +12321,34 @@
             Log.e(TAG, "getEmergencyNumberList with Categories RemoteException", ex);
             ex.rethrowAsRuntimeException();
         }
-        return emergencyNumberList;
+        return emergencyNumberListForCategories;
+    }
+
+    /**
+     * Filter emergency numbers with categories.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public Map<Integer, List<EmergencyNumber>> filterEmergencyNumbersByCategories(
+            Map<Integer, List<EmergencyNumber>> emergencyNumberList,
+                    @EmergencyServiceCategories int categories) {
+        Map<Integer, List<EmergencyNumber>> emergencyNumberListForCategories = new HashMap<>();
+        if (emergencyNumberList != null) {
+            for (Integer subscriptionId : emergencyNumberList.keySet()) {
+                List<EmergencyNumber> allNumbersForSub = emergencyNumberList.get(
+                        subscriptionId);
+                List<EmergencyNumber> numbersForCategoriesPerSub = new ArrayList<>();
+                for (EmergencyNumber number : allNumbersForSub) {
+                    if (number.isInEmergencyServiceCategories(categories)) {
+                        numbersForCategoriesPerSub.add(number);
+                    }
+                }
+                emergencyNumberListForCategories.put(
+                        subscriptionId, numbersForCategoriesPerSub);
+            }
+        }
+        return emergencyNumberListForCategories;
     }
 
     /**
@@ -14316,4 +14350,69 @@
         }
         return THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
     }
+    /**
+     * Registers a listener object to receive notification of changes
+     * in specified telephony states.
+     * <p>
+     * To register a listener, pass a {@link PhoneStateListener} which implements
+     * interfaces of events. For example,
+     * FakeServiceStateChangedListener extends {@link PhoneStateListener} implements
+     * {@link PhoneStateListener.ServiceStateChangedListener}.
+     *
+     * At registration, and when a specified telephony state changes, the telephony manager invokes
+     * the appropriate callback method on the listener object and passes the current (updated)
+     * values.
+     * <p>
+     *
+     * If this TelephonyManager object has been created with {@link #createForSubscriptionId},
+     * applies to the given subId. Otherwise, applies to
+     * {@link SubscriptionManager#getDefaultSubscriptionId()}. To listen events for multiple subIds,
+     * pass a separate listener object to each TelephonyManager object created with
+     * {@link #createForSubscriptionId}.
+     *
+     * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
+     * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
+     * {@link SecurityException} will be thrown otherwise.
+     *
+     * This API should be used sparingly -- large numbers of listeners will cause system
+     * instability. If a process has registered too many listeners without unregistering them, it
+     * may encounter an {@link IllegalStateException} when trying to register more listeners.
+     *
+     * @param executor The executor of where the callback will execute.
+     * @param listener The {@link PhoneStateListener} object to register.
+     */
+    public void registerPhoneStateListener(@NonNull @CallbackExecutor Executor executor,
+            @NonNull PhoneStateListener listener) {
+        if (executor == null || listener == null) {
+            throw new IllegalArgumentException("PhoneStateListener and executor must be non-null");
+        }
+        mTelephonyRegistryMgr = (TelephonyRegistryManager)
+                mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+        if (mTelephonyRegistryMgr != null) {
+            mTelephonyRegistryMgr.registerPhoneStateListener(executor, mSubId,
+                    getOpPackageName(), getAttributionTag(), listener, getITelephony() != null);
+        } else {
+            throw new IllegalStateException("telephony service is null.");
+        }
+    }
+
+    /**
+     * Unregister an existing {@link PhoneStateListener}.
+     *
+     * @param listener The {@link PhoneStateListener} object to unregister.
+     */
+    public void unregisterPhoneStateListener(@NonNull PhoneStateListener listener) {
+
+        if (mContext == null) {
+            throw new IllegalStateException("telephony service is null.");
+        }
+
+        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
+        if (mTelephonyRegistryMgr != null) {
+            mTelephonyRegistryMgr.unregisterPhoneStateListener(mSubId, getOpPackageName(),
+                    getAttributionTag(), listener, getITelephony() != null);
+        } else {
+            throw new IllegalStateException("telephony service is null.");
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/cdma/OWNERS b/telephony/java/android/telephony/cdma/OWNERS
new file mode 100644
index 0000000..6aa399d
--- /dev/null
+++ b/telephony/java/android/telephony/cdma/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+amitmahajan@google.com
diff --git a/telephony/java/android/telephony/data/OWNERS b/telephony/java/android/telephony/data/OWNERS
new file mode 100644
index 0000000..932b35c
--- /dev/null
+++ b/telephony/java/android/telephony/data/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+jackyu@google.com
diff --git a/telephony/java/android/telephony/emergency/OWNERS b/telephony/java/android/telephony/emergency/OWNERS
new file mode 100644
index 0000000..fa07dce
--- /dev/null
+++ b/telephony/java/android/telephony/emergency/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+shuoq@google.com
diff --git a/telephony/java/android/telephony/euicc/OWNERS b/telephony/java/android/telephony/euicc/OWNERS
new file mode 100644
index 0000000..9e51a4b
--- /dev/null
+++ b/telephony/java/android/telephony/euicc/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+refuhoo@google.com
+amitmahajan@google.com
diff --git a/telephony/java/android/telephony/gsm/OWNERS b/telephony/java/android/telephony/gsm/OWNERS
new file mode 100644
index 0000000..6aa399d
--- /dev/null
+++ b/telephony/java/android/telephony/gsm/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+amitmahajan@google.com
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 184477a..c140249 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -1322,6 +1322,13 @@
      */
     public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3;
 
+    /**
+     * An extra that may be populated when the {@link #CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+     * been returned.
+     * <p>
+     * Try to connect the call using CS as emergency
+     */
+    public static final int EXTRA_CODE_CALL_RETRY_EMERGENCY = 4;
 
     // For main reason code
     /** @hide */
diff --git a/telephony/java/android/telephony/ims/OWNERS b/telephony/java/android/telephony/ims/OWNERS
new file mode 100644
index 0000000..0854c5d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+breadley@google.com
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
index b47e3c7..10c50be 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl
@@ -22,7 +22,6 @@
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IOptionsResponseCallback;
 import android.telephony.ims.aidl.IPublishResponseCallback;
-import android.telephony.ims.aidl.IRcsFeatureListener;
 import android.telephony.ims.aidl.ISubscribeResponseCallback;
 import android.telephony.ims.feature.CapabilityChangeRequest;
 
@@ -34,7 +33,6 @@
  */
 interface IImsRcsFeature {
     // Not oneway because we need to verify this completes before doing anything else.
-    void setListener(IRcsFeatureListener listener);
     int queryCapabilityStatus();
     // Inherited from ImsFeature
     int getFeatureState();
@@ -50,14 +48,4 @@
     oneway void subscribeForCapabilities(in List<Uri> uris, ISubscribeResponseCallback cb);
     oneway void sendOptionsCapabilityRequest(in Uri contactUri,
             in List<String> myCapabilities, IOptionsResponseCallback cb);
-    // RcsPresenceExchangeImplBase specific api
-    oneway void requestCapabilities(in List<Uri> uris, int operationToken);
-    oneway void updateCapabilities(in RcsContactUceCapability capabilities, int operationToken);
-    // RcsSipOptionsImplBase specific api
-    oneway void sendCapabilityRequest(in Uri contactUri,
-            in RcsContactUceCapability capabilities, int operationToken);
-    oneway void respondToCapabilityRequest(in String contactUri,
-            in RcsContactUceCapability ownCapabilities, int operationToken);
-    oneway void respondToCapabilityRequestWithError(in Uri contactUri, int code, in String reason,
-            int operationToken);
 }
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl b/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl
deleted file mode 100644
index 70cf651..0000000
--- a/telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2018 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.telephony.ims.aidl;
-
-import android.net.Uri;
-import android.telephony.ims.RcsContactUceCapability;
-
-import java.util.List;
-
-/**
- * Listener interface for updates from the RcsFeature back to the framework.
- * {@hide}
- */
-interface IRcsFeatureListener {
-    //RcsCapabilityExchange specific
-    oneway void onCommandUpdate(int commandCode, int operationToken);
-    // RcsPresenceExchangeImplBase Specific
-    oneway void onNetworkResponse(int code, in String reason, int operationToken);
-    oneway void onCapabilityRequestResponsePresence(in List<RcsContactUceCapability> infos,
-    int operationToken);
-    oneway void onNotifyUpdateCapabilities(int publishTriggerType);
-    oneway void onUnpublish();
-    // RcsSipOptionsImplBase specific
-    oneway void onCapabilityRequestResponseOptions(int code, in String reason,
-            in RcsContactUceCapability info, int operationToken);
-    oneway void onRemoteCapabilityRequest(in Uri contactUri, in RcsContactUceCapability remoteInfo,
-            int operationToken);
-}
diff --git a/telephony/java/android/telephony/ims/aidl/OWNERS b/telephony/java/android/telephony/ims/aidl/OWNERS
new file mode 100644
index 0000000..0854c5d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+breadley@google.com
diff --git a/telephony/java/android/telephony/ims/compat/OWNERS b/telephony/java/android/telephony/ims/compat/OWNERS
new file mode 100644
index 0000000..0854c5d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/compat/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+breadley@google.com
diff --git a/telephony/java/android/telephony/ims/compat/feature/OWNERS b/telephony/java/android/telephony/ims/compat/feature/OWNERS
new file mode 100644
index 0000000..0854c5d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/compat/feature/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+breadley@google.com
diff --git a/telephony/java/android/telephony/ims/compat/stub/OWNERS b/telephony/java/android/telephony/ims/compat/stub/OWNERS
new file mode 100644
index 0000000..0854c5d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/compat/stub/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+breadley@google.com
diff --git a/telephony/java/android/telephony/ims/feature/OWNERS b/telephony/java/android/telephony/ims/feature/OWNERS
new file mode 100644
index 0000000..0854c5d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/feature/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+breadley@google.com
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index 5de2ddc..cde7067 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -19,17 +19,16 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.Uri;
 import android.os.RemoteException;
-import android.telephony.ims.RcsContactUceCapability;
 import android.telephony.ims.RcsUceAdapter;
 import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsFeature;
 import android.telephony.ims.aidl.IOptionsResponseCallback;
 import android.telephony.ims.aidl.IPublishResponseCallback;
-import android.telephony.ims.aidl.IRcsFeatureListener;
 import android.telephony.ims.aidl.ISubscribeResponseCallback;
 import android.telephony.ims.aidl.RcsOptionsResponseAidlWrapper;
 import android.telephony.ims.aidl.RcsPublishResponseAidlWrapper;
@@ -74,16 +73,6 @@
             mExecutor = executor;
         }
 
-        /**
-         * @deprecated This method is deprecated. Please call the method
-         * setCapabilityExchangeEventListener instead.
-         */
-        @Override
-        @Deprecated
-        public void setListener(IRcsFeatureListener listener) {
-            Log.w(LOG_TAG, "The method setListener is deprecated");
-        }
-
         @Override
         public int queryCapabilityStatus() throws RemoteException {
             return executeMethodAsyncForResult(
@@ -124,7 +113,7 @@
         // RcsCapabilityExchangeImplBase specific APIs
         @Override
         public void setCapabilityExchangeEventListener(
-                @NonNull ICapabilityExchangeEventListener listener) throws RemoteException {
+                @Nullable ICapabilityExchangeEventListener listener) throws RemoteException {
             executeMethodAsync(() -> mReference.setCapabilityExchangeEventListener(listener),
                     "setCapabilityExchangeEventListener");
         }
@@ -155,34 +144,6 @@
                     "sendOptionsCapabilityRequest");
         }
 
-        // RcsPresenceExchangeImplBase specific APIS
-        @Override
-        public void requestCapabilities(List<Uri> uris, int operationToken) throws RemoteException {
-            throw new RemoteException("Unsupported operation: requestCapabilities");
-        }
-        @Override
-        public void updateCapabilities(RcsContactUceCapability capabilities, int operationToken)
-                throws RemoteException {
-            throw new RemoteException("Unsupported operation: updateCapabilities");
-        }
-        // RcsSipOptionsImplBase specific APIS
-        @Override
-        public void sendCapabilityRequest(Uri contactUri, RcsContactUceCapability capabilities,
-                int operationToken) throws RemoteException {
-            throw new RemoteException("Unsupported operation: sendCapabilityRequest");
-        }
-        @Override
-        public void respondToCapabilityRequest(String contactUri,
-                RcsContactUceCapability ownCapabilities, int operationToken)
-                throws RemoteException {
-            throw new RemoteException("Unsupported operation: respondToCapabilityRequest");
-        }
-        @Override
-        public void respondToCapabilityRequestWithError(Uri contactUri, int code, String reason,
-                int operationToken) throws RemoteException {
-            throw new RemoteException("Unsupported operation: respondToCapabilityRequestWithError");
-        }
-
         // Call the methods with a clean calling identity on the executor and wait indefinitely for
         // the future to return.
         private void executeMethodAsync(Runnable r, String errorLogName)
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index e0290a5..e757d9f 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -126,7 +126,7 @@
          */
         @Override
         public synchronized String getConfigString(int item) throws RemoteException {
-            if (mProvisionedIntValue.containsKey(item)) {
+            if (mProvisionedStringValue.containsKey(item)) {
                 return mProvisionedStringValue.get(item);
             } else {
                 String retVal = getImsConfigImpl().getConfigString(item);
diff --git a/telephony/java/android/telephony/ims/stub/OWNERS b/telephony/java/android/telephony/ims/stub/OWNERS
new file mode 100644
index 0000000..0854c5d
--- /dev/null
+++ b/telephony/java/android/telephony/ims/stub/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+breadley@google.com
diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
deleted file mode 100644
index 0b13efb..0000000
--- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchange.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2018 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.telephony.ims.stub;
-
-import android.annotation.IntDef;
-import android.os.RemoteException;
-import android.telephony.ims.ImsException;
-import android.telephony.ims.aidl.IRcsFeatureListener;
-import android.telephony.ims.feature.ImsFeature;
-import android.telephony.ims.feature.RcsFeature;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Base class for different types of Capability exchange, presence using
- * {@link RcsPresenceExchangeImplBase} and SIP OPTIONS exchange using {@link RcsSipOptionsImplBase}.
- *
- * @hide
- */
-public class RcsCapabilityExchange {
-
-    /**  Service is unknown. */
-    public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0;
-    /** The command completed successfully. */
-    public static final int COMMAND_CODE_SUCCESS = 1;
-    /** The command failed with an unknown error. */
-    public static final int COMMAND_CODE_GENERIC_FAILURE = 2;
-    /**  Invalid parameter(s). */
-    public static final int COMMAND_CODE_INVALID_PARAM = 3;
-    /**  Fetch error. */
-    public static final int COMMAND_CODE_FETCH_ERROR = 4;
-    /**  Request timed out. */
-    public static final int COMMAND_CODE_REQUEST_TIMEOUT = 5;
-    /**  Failure due to insufficient memory available. */
-    public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 6;
-    /**  Network connection is lost. */
-    public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 7;
-    /**  Requested feature/resource is not supported. */
-    public static final int COMMAND_CODE_NOT_SUPPORTED = 8;
-    /**  Contact or resource is not found. */
-    public static final int COMMAND_CODE_NOT_FOUND = 9;
-    /**  Service is not available. */
-    public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 10;
-    /**  No Change in Capabilities */
-    public static final int COMMAND_CODE_NO_CHANGE_IN_CAP = 11;
-
-    /** @hide*/
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "COMMAND_CODE_", value = {
-            COMMAND_CODE_SERVICE_UNKNOWN,
-            COMMAND_CODE_SUCCESS,
-            COMMAND_CODE_GENERIC_FAILURE,
-            COMMAND_CODE_INVALID_PARAM,
-            COMMAND_CODE_FETCH_ERROR,
-            COMMAND_CODE_REQUEST_TIMEOUT,
-            COMMAND_CODE_INSUFFICIENT_MEMORY,
-            COMMAND_CODE_LOST_NETWORK_CONNECTION,
-            COMMAND_CODE_NOT_SUPPORTED,
-            COMMAND_CODE_NOT_FOUND,
-            COMMAND_CODE_SERVICE_UNAVAILABLE,
-            COMMAND_CODE_NO_CHANGE_IN_CAP
-    })
-    public @interface CommandCode {}
-
-
-    private RcsFeature mFeature;
-
-    /** @hide */
-    public final void initialize(RcsFeature feature) {
-        mFeature = feature;
-    }
-
-    /** @hide */
-    protected final IRcsFeatureListener getListener() throws ImsException {
-        throw new ImsException("This method is deprecated.",
-                ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
-    }
-
-    /**
-     * Provides the framework with an update as to whether or not a command completed successfully
-     * locally. This includes capabilities requests and updates from the network. If it does not
-     * complete successfully, then the framework may retry the command again later, depending on the
-     * error. If the command does complete successfully, the framework will then wait for network
-     * updates.
-     *
-     * @param code The result of the pending command. If {@link #COMMAND_CODE_SUCCESS}, further
-     *             updates will be sent for this command using the associated operationToken.
-     * @param operationToken the token associated with the pending command.
-     * @throws ImsException If this {@link RcsCapabilityExchange} instance is not currently
-     * connected to the framework. This can happen if the {@link RcsFeature} is not
-     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
-     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
-     * Telephony stack has crashed.
-     */
-    public final void onCommandUpdate(@CommandCode int code, int operationToken)
-            throws ImsException {
-        try {
-            getListener().onCommandUpdate(code, operationToken);
-        } catch (RemoteException e) {
-            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-    }
-}
diff --git a/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java
deleted file mode 100644
index bb03448..0000000
--- a/telephony/java/android/telephony/ims/stub/RcsPresenceExchangeImplBase.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2018 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.telephony.ims.stub;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.telephony.ims.ImsException;
-import android.telephony.ims.RcsContactUceCapability;
-import android.telephony.ims.feature.ImsFeature;
-import android.telephony.ims.feature.RcsFeature;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/**
- * Base implementation for RCS User Capability Exchange using Presence. Any ImsService implementing
- * this service must implement the stub methods {@link #requestCapabilities(List, int)}  and
- * {@link #updateCapabilities(RcsContactUceCapability, int)}.
- *
- * @hide
- */
-public class RcsPresenceExchangeImplBase extends RcsCapabilityExchange {
-
-    private static final String LOG_TAG = "RcsPresenceExchangeIB";
-
-    /**
-     * The request has resulted in any other 4xx/5xx/6xx that is not covered below. No retry will be
-     * attempted.
-     */
-    public static final int RESPONSE_SUBSCRIBE_GENERIC_FAILURE = -1;
-
-    /**
-     * The request has succeeded with a “200” message from the network.
-     */
-    public static final int RESPONSE_SUCCESS = 0;
-
-    /**
-     * The request has resulted in a “403” (User Not Registered) error from the network. Will retry
-     * capability polling with an exponential backoff.
-     */
-    public static final int RESPONSE_NOT_REGISTERED = 1;
-
-    /**
-     * The request has resulted in a “403” (not authorized (Requestor)) error from the network. No
-     * retry will be attempted.
-     */
-    public static final int RESPONSE_NOT_AUTHORIZED_FOR_PRESENCE = 2;
-
-    /**
-     * The request has resulted in a "403” (Forbidden) or other “403” error from the network and
-     * will be handled the same as “404” Not found. No retry will be attempted.
-     */
-    public static final int RESPONSE_FORBIDDEN = 3;
-
-    /**
-     * The request has resulted in a “404” (Not found) result from the network. No retry will be
-     * attempted.
-     */
-    public static final int RESPONSE_NOT_FOUND = 4;
-
-    /**
-     * The request has resulted in a “408” response. Retry after exponential backoff.
-     */
-    public static final int RESPONSE_SIP_REQUEST_TIMEOUT = 5;
-
-    /**
-     *  The network has responded with a “413” (Too Large) response from the network. Capability
-     *  request contains too many items and must be shrunk before the request will be accepted.
-     */
-    public static final int RESPONSE_SUBSCRIBE_TOO_LARGE = 6;
-
-    /**
-     * The request has resulted in a “423” response. Retry after exponential backoff.
-     */
-    public static final int RESPONSE_SIP_INTERVAL_TOO_SHORT = 7;
-
-    /**
-     * The request has resulted in a “503” response. Retry after exponential backoff.
-     */
-    public static final int RESPONSE_SIP_SERVICE_UNAVAILABLE = 8;
-
-    /** @hide*/
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "RESPONSE_", value = {
-            RESPONSE_SUBSCRIBE_GENERIC_FAILURE,
-            RESPONSE_SUCCESS,
-            RESPONSE_NOT_REGISTERED,
-            RESPONSE_NOT_AUTHORIZED_FOR_PRESENCE,
-            RESPONSE_FORBIDDEN,
-            RESPONSE_NOT_FOUND,
-            RESPONSE_SIP_REQUEST_TIMEOUT,
-            RESPONSE_SUBSCRIBE_TOO_LARGE,
-            RESPONSE_SIP_INTERVAL_TOO_SHORT,
-            RESPONSE_SIP_SERVICE_UNAVAILABLE
-    })
-    public @interface PresenceResponseCode {}
-
-
-    /** A capability update has been requested due to the Entity Tag (ETag) expiring. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 0;
-    /** A capability update has been requested due to moving to LTE with VoPS disabled. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1;
-    /** A capability update has been requested due to moving to LTE with VoPS enabled. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2;
-    /** A capability update has been requested due to moving to eHRPD. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 3;
-    /** A capability update has been requested due to moving to HSPA+. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 4;
-    /** A capability update has been requested due to moving to 3G. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 5;
-    /** A capability update has been requested due to moving to 2G. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 6;
-    /** A capability update has been requested due to moving to WLAN */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 7;
-    /** A capability update has been requested due to moving to IWLAN */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 8;
-    /** A capability update has been requested but the reason is unknown. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_UNKNOWN = 9;
-    /** A capability update has been requested due to moving to 5G NR with VoPS disabled. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10;
-    /** A capability update has been requested due to moving to 5G NR with VoPS enabled. */
-    public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11;
-
-    /** @hide*/
-    @IntDef(value = {
-            CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN,
-            CAPABILITY_UPDATE_TRIGGER_UNKNOWN,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED,
-            CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED
-    }, prefix = "CAPABILITY_UPDATE_TRIGGER_")
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface StackPublishTriggerType {
-    }
-
-    /**
-     * Provide the framework with a subsequent network response update to
-     * {@link #updateCapabilities(RcsContactUceCapability, int)} and
-     * {@link #requestCapabilities(List, int)} operations.
-     *
-     * @param code The SIP response code sent from the network for the operation token specified.
-     * @param reason The optional reason response from the network. If the network provided no
-     *         reason with the code, the string should be empty.
-     * @param operationToken The token associated with the operation this service is providing a
-     *         response for.
-     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
-     * connected to the framework. This can happen if the {@link RcsFeature} is not
-     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
-     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
-     * Telephony stack has crashed.
-     */
-    public final void onNetworkResponse(@PresenceResponseCode int code, @NonNull String reason,
-            int operationToken) throws ImsException {
-        try {
-            getListener().onNetworkResponse(code, reason, operationToken);
-        } catch (RemoteException e) {
-            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-    }
-
-    /**
-     * Provides the framework with the requested contacts’ capabilities requested by the framework
-     * using {@link #requestCapabilities(List, int)}.
-     *
-     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
-     * connected to the framework. This can happen if the {@link RcsFeature} is not
-     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
-     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
-     * Telephony stack has crashed.
-     */
-    public final void onCapabilityRequestResponse(@NonNull List<RcsContactUceCapability> infos,
-            int operationToken) throws ImsException {
-        try {
-            getListener().onCapabilityRequestResponsePresence(infos, operationToken);
-        } catch (RemoteException e) {
-            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-    }
-
-    /**
-     * Trigger the framework to provide a capability update using
-     * {@link #updateCapabilities(RcsContactUceCapability, int)}.
-     * <p>
-     * This is typically used when trying to generate an initial PUBLISH for a new subscription to
-     * the network. The device will cache all presence publications after boot until this method is
-     * called once.
-     * @param publishTriggerType {@link StackPublishTriggerType} The reason for the capability
-     *         update request.
-     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
-     * connected to the framework. This can happen if the {@link RcsFeature} is not
-     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
-     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
-     * Telephony stack has crashed.
-     */
-    public final void onNotifyUpdateCapabilites(@StackPublishTriggerType int publishTriggerType)
-            throws ImsException {
-        try {
-            getListener().onNotifyUpdateCapabilities(publishTriggerType);
-        } catch (RemoteException e) {
-            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-    }
-
-    /**
-     * Notify the framework that the device’s capabilities have been unpublished from the network.
-     *
-     * @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
-     * connected to the framework. This can happen if the {@link RcsFeature} is not
-     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
-     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
-     * Telephony stack has crashed.
-     */
-    public final void onUnpublish() throws ImsException {
-        try {
-            getListener().onUnpublish();
-        } catch (RemoteException e) {
-            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-    }
-
-    /**
-     * The user capabilities of one or multiple contacts have been requested by the framework.
-     * <p>
-     * The implementer must follow up this call with an {@link #onCommandUpdate(int, int)} call to
-     * indicate whether or not this operation succeeded.  If this operation succeeds, network
-     * response updates should be sent to the framework using
-     * {@link #onNetworkResponse(int, String, int)}. When the operation is completed,
-     * {@link #onCapabilityRequestResponse(List, int)} should be called with the presence
-     * information for the contacts specified.
-     * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE
-     *             capabilities for.
-     * @param operationToken The token associated with this operation. Updates to this request using
-     *         {@link #onCommandUpdate(int, int)}, {@link #onNetworkResponse(int, String, int)}, and
-     *         {@link #onCapabilityRequestResponse(List, int)}  must use the same operation token
-     *         in response.
-     */
-    public void requestCapabilities(@NonNull List<Uri> uris, int operationToken) {
-        // Stub - to be implemented by service
-        Log.w(LOG_TAG, "requestCapabilities called with no implementation.");
-        try {
-            getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
-        } catch (RemoteException | ImsException e) {
-            // Do not do anything, this is a stub implementation.
-        }
-    }
-
-    /**
-     * The capabilities of this device have been updated and should be published to the network.
-     * <p>
-     * The implementer must follow up this call with an {@link #onCommandUpdate(int, int)} call to
-     * indicate whether or not this operation succeeded. If this operation succeeds, network
-     * response updates should be sent to the framework using
-     * {@link #onNetworkResponse(int, String, int)}.
-     * @param capabilities The capabilities for this device.
-     * @param operationToken The token associated with this operation. Any subsequent
-     *         {@link #onCommandUpdate(int, int)} or {@link #onNetworkResponse(int, String, int)}
-     *         calls regarding this update must use the same token.
-     */
-    public void updateCapabilities(@NonNull RcsContactUceCapability capabilities,
-            int operationToken) {
-        // Stub - to be implemented by service
-        Log.w(LOG_TAG, "updateCapabilities called with no implementation.");
-        try {
-            getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
-        } catch (RemoteException | ImsException e) {
-            // Do not do anything, this is a stub implementation.
-        }
-    }
-}
diff --git a/telephony/java/android/telephony/ims/stub/RcsSipOptionsImplBase.java b/telephony/java/android/telephony/ims/stub/RcsSipOptionsImplBase.java
deleted file mode 100644
index 2035fac..0000000
--- a/telephony/java/android/telephony/ims/stub/RcsSipOptionsImplBase.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2018 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.telephony.ims.stub;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.telephony.ims.ImsException;
-import android.telephony.ims.RcsContactUceCapability;
-import android.telephony.ims.feature.ImsFeature;
-import android.telephony.ims.feature.RcsFeature;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Base implementation for RCS User Capability Exchange using SIP OPTIONS.
- *
- * @hide
- */
-public class RcsSipOptionsImplBase extends RcsCapabilityExchange {
-
-    private static final String LOG_TAG = "RcsSipOptionsImplBase";
-
-    /**
-     * Indicates a SIP response from the remote user other than 200, 480, 408, 404, or 604.
-     */
-    public static final int RESPONSE_GENERIC_FAILURE = -1;
-
-    /**
-     * Indicates that the remote user responded with a 200 OK response.
-     */
-    public static final int RESPONSE_SUCCESS = 0;
-
-    /**
-     * Indicates that the remote user responded with a 480 TEMPORARY UNAVAILABLE response.
-     */
-    public static final int RESPONSE_TEMPORARILY_UNAVAILABLE = 1;
-
-    /**
-     * Indicates that the remote user responded with a 408 REQUEST TIMEOUT response.
-     */
-    public static final int RESPONSE_REQUEST_TIMEOUT = 2;
-
-    /**
-     * Indicates that the remote user responded with a 404 NOT FOUND response.
-     */
-    public static final int RESPONSE_NOT_FOUND = 3;
-
-    /**
-     * Indicates that the remote user responded with a 604 DOES NOT EXIST ANYWHERE response.
-     */
-    public static final int RESPONSE_DOES_NOT_EXIST_ANYWHERE = 4;
-
-    /**
-     * Indicates that the remote user responded with a 400 BAD REQUEST response.
-     */
-    public static final int RESPONSE_BAD_REQUEST = 5;
-
-    /** @hide*/
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "RESPONSE_", value = {
-            RESPONSE_GENERIC_FAILURE,
-            RESPONSE_SUCCESS,
-            RESPONSE_TEMPORARILY_UNAVAILABLE,
-            RESPONSE_REQUEST_TIMEOUT,
-            RESPONSE_NOT_FOUND,
-            RESPONSE_DOES_NOT_EXIST_ANYWHERE,
-            RESPONSE_BAD_REQUEST
-    })
-    public @interface SipResponseCode {}
-
-    /**
-     * Send the response of a SIP OPTIONS capability exchange to the framework. If {@code code} is
-     * {@link #RESPONSE_SUCCESS}, info must be non-null.
-     * @param code The SIP response code that was sent by the network in response to the request
-     *        sent by {@link #sendCapabilityRequest(Uri, RcsContactUceCapability, int)}.
-     * @param reason The optional SIP response reason sent by the network. If none was sent, this
-     *        should be an empty string.
-     * @param info the contact's UCE capabilities associated with the capability request.
-     * @param operationToken The token associated with the original capability request, set by
-     *        {@link #sendCapabilityRequest(Uri, RcsContactUceCapability, int)}.
-     * @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not currently
-     * connected to the framework. This can happen if the {@link RcsFeature} is not
-     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
-     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
-     * Telephony stack has crashed.
-     */
-    public final void onCapabilityRequestResponse(@SipResponseCode int code, @NonNull String reason,
-            @Nullable RcsContactUceCapability info, int operationToken) throws ImsException {
-        try {
-            getListener().onCapabilityRequestResponseOptions(code, reason, info, operationToken);
-        } catch (RemoteException e) {
-            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-    }
-
-    /**
-     * Inform the framework of a query for this device's UCE capabilities.
-     * <p>
-     * The framework will respond via the
-     * {@link #respondToCapabilityRequest(String, RcsContactUceCapability, int)} or
-     * {@link #respondToCapabilityRequestWithError(Uri, int, String, int)} method.
-     * @param contactUri The URI associated with the remote contact that is requesting capabilities.
-     * @param remoteInfo The remote contact's capability information.
-     * @param operationToken An unique operation token that you have generated that will be returned
-     *         by the framework in
-     *         {@link #respondToCapabilityRequest(String, RcsContactUceCapability, int)}.
-     * @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not currently
-     * connected to the framework. This can happen if the {@link RcsFeature} is not
-     * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
-     * {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
-     * Telephony stack has crashed.
-     */
-    public final void onRemoteCapabilityRequest(@NonNull Uri contactUri,
-            @NonNull RcsContactUceCapability remoteInfo, int operationToken) throws ImsException {
-        try {
-            getListener().onRemoteCapabilityRequest(contactUri, remoteInfo, operationToken);
-        } catch (RemoteException e) {
-            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
-        }
-    }
-
-    /**
-     * Push one's own capabilities to a remote user via the SIP OPTIONS presence exchange mechanism
-     * in order to receive the capabilities of the remote user in response.
-     * <p>
-     * The implementer must call
-     * {@link #onCapabilityRequestResponse(int, String, RcsContactUceCapability, int)} to send the
-     * response of this query back to the framework.
-     * @param contactUri The URI of the remote user that we wish to get the capabilities of.
-     * @param capabilities The capabilities of this device to send to the remote user.
-     * @param operationToken A token generated by the framework that will be passed through
-     * {@link #onCapabilityRequestResponse(int, String, RcsContactUceCapability, int)} when this
-     *         operation has succeeded.
-     */
-    public void sendCapabilityRequest(@NonNull Uri contactUri,
-            @NonNull RcsContactUceCapability capabilities, int operationToken) {
-        // Stub - to be implemented by service
-        Log.w(LOG_TAG, "sendCapabilityRequest called with no implementation.");
-        try {
-            getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
-        } catch (RemoteException | ImsException e) {
-            // Do not do anything, this is a stub implementation.
-        }
-    }
-
-    /**
-     * Respond to a remote capability request from the contact specified with the capabilities of
-     * this device.
-     * <p>
-     * The framework will use the same token and uri as what was passed in to
-     * {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)}.
-     * @param contactUri The URI of the remote contact.
-     * @param ownCapabilities The capabilities of this device.
-     * @param operationToken The token generated by the framework that this service obtained when
-     *         {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)} was called.
-     */
-    public void respondToCapabilityRequest(@NonNull String contactUri,
-            @NonNull RcsContactUceCapability ownCapabilities, int operationToken) {
-        // Stub - to be implemented by service
-        Log.w(LOG_TAG, "respondToCapabilityRequest called with no implementation.");
-        try {
-            getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
-        } catch (RemoteException | ImsException e) {
-            // Do not do anything, this is a stub implementation.
-        }
-    }
-
-    /**
-     * Respond to a remote capability request from the contact specified with the specified error.
-     * <p>
-     * The framework will use the same token and uri as what was passed in to
-     * {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)}.
-     * @param contactUri A URI containing the remote contact.
-     * @param code The SIP response code to respond with.
-     * @param reason A non-null String containing the reason associated with the SIP code.
-     * @param operationToken The token provided by the framework when
-     *         {@link #onRemoteCapabilityRequest(Uri, RcsContactUceCapability, int)} was called.
-     */
-    public void respondToCapabilityRequestWithError(@NonNull Uri contactUri,
-            @SipResponseCode int code, @NonNull String reason, int operationToken) {
-        // Stub - to be implemented by service
-        Log.w(LOG_TAG, "respondToCapabiltyRequestWithError called with no implementation.");
-        try {
-            getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
-        } catch (RemoteException | ImsException e) {
-            // Do not do anything, this is a stub implementation.
-        }
-    }
-}
diff --git a/telephony/java/android/telephony/mbms/OWNERS b/telephony/java/android/telephony/mbms/OWNERS
new file mode 100644
index 0000000..718e0a2
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+hallliu@google.com
diff --git a/telephony/java/android/telephony/mbms/vendor/OWNERS b/telephony/java/android/telephony/mbms/vendor/OWNERS
new file mode 100644
index 0000000..718e0a2
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/vendor/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 20868
+
+rgreenwalt@google.com
+tgunn@google.com
+hallliu@google.com
diff --git a/tests/ActivityManagerPerfTests/OWNERS b/tests/ActivityManagerPerfTests/OWNERS
new file mode 100644
index 0000000..72c0a9e
--- /dev/null
+++ b/tests/ActivityManagerPerfTests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/am/OWNERS
diff --git a/tests/AmSlam/OWNERS b/tests/AmSlam/OWNERS
new file mode 100644
index 0000000..72c0a9e
--- /dev/null
+++ b/tests/AmSlam/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/am/OWNERS
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
index 7d826f7..e05816e 100644
--- a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
+++ b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
@@ -264,9 +264,9 @@
             // Set time to future.
             setTimeFutureDays(deltaDays);
 
-            // Set filter to quicken.
-            compilePackageWithFilter(PACKAGE_NAME, "quicken");
-            Assert.assertEquals("quicken", getCompilerFilter(PACKAGE_NAME));
+            // Set filter to verify.
+            compilePackageWithFilter(PACKAGE_NAME, "verify");
+            Assert.assertEquals("verify", getCompilerFilter(PACKAGE_NAME));
 
             // Fill up storage to trigger low storage threshold.
             fillUpToLowStorage();
@@ -290,9 +290,9 @@
             // Set time to future.
             setTimeFutureDays(deltaDays);
 
-            // Set filter to quicken.
-            compilePackageWithFilter(PACKAGE_NAME, "quicken");
-            Assert.assertEquals("quicken", getCompilerFilter(PACKAGE_NAME));
+            // Set filter to speed-profile.
+            compilePackageWithFilter(PACKAGE_NAME, "speed-profile");
+            Assert.assertEquals("speed-profile", getCompilerFilter(PACKAGE_NAME));
 
             // Fill up storage to trigger low storage threshold.
             fillUpToLowStorage();
diff --git a/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java
new file mode 100644
index 0000000..54d7047
--- /dev/null
+++ b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 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 com.android.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.BatteryStatsManager;
+import android.os.BatteryUsageStats;
+import android.os.UidBatteryConsumer;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class BatteryUsageStatsPerfTest {
+
+    @Rule
+    public final PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    /**
+     * Measures the performance of {@link BatteryStatsManager#getBatteryUsageStats()},
+     * which triggers a battery stats sync on every iteration.
+     */
+    @Test
+    public void testGetBatteryUsageStats() {
+        final Context context = InstrumentationRegistry.getContext();
+        final BatteryStatsManager batteryStatsManager =
+                context.getSystemService(BatteryStatsManager.class);
+
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            BatteryUsageStats batteryUsageStats = batteryStatsManager.getBatteryUsageStats();
+
+            state.pauseTiming();
+
+            List<UidBatteryConsumer> uidBatteryConsumers =
+                    batteryUsageStats.getUidBatteryConsumers();
+            double power = 0;
+            for (int i = 0; i < uidBatteryConsumers.size(); i++) {
+                UidBatteryConsumer uidBatteryConsumer = uidBatteryConsumers.get(i);
+                power += uidBatteryConsumer.getConsumedPower();
+            }
+
+            assertThat(power).isGreaterThan(0.0);
+
+            state.resumeTiming();
+        }
+    }
+}
diff --git a/tests/BlobStoreTestUtils/OWNERS b/tests/BlobStoreTestUtils/OWNERS
new file mode 100644
index 0000000..65bb6b8
--- /dev/null
+++ b/tests/BlobStoreTestUtils/OWNERS
@@ -0,0 +1 @@
+include /apex/blobstore/OWNERS
diff --git a/tests/Camera2Tests/OWNERS b/tests/Camera2Tests/OWNERS
new file mode 100644
index 0000000..f48a95c
--- /dev/null
+++ b/tests/Camera2Tests/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/av:/camera/OWNERS
diff --git a/tests/CanvasCompare/OWNERS b/tests/CanvasCompare/OWNERS
new file mode 100644
index 0000000..c88a9f8
--- /dev/null
+++ b/tests/CanvasCompare/OWNERS
@@ -0,0 +1 @@
+include /libs/hwui/OWNERS
diff --git a/tests/Compatibility/OWNERS b/tests/Compatibility/OWNERS
new file mode 100644
index 0000000..f8c3520
--- /dev/null
+++ b/tests/Compatibility/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/compat/OWNERS
diff --git a/tests/DozeTest/OWNERS b/tests/DozeTest/OWNERS
new file mode 100644
index 0000000..2e96c97
--- /dev/null
+++ b/tests/DozeTest/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/OWNERS
diff --git a/tests/FixVibrateSetting/OWNERS b/tests/FixVibrateSetting/OWNERS
new file mode 100644
index 0000000..cc63ceb
--- /dev/null
+++ b/tests/FixVibrateSetting/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/vibrator/OWNERS
diff --git a/tests/FlickerTests/AndroidManifest.xml b/tests/FlickerTests/AndroidManifest.xml
index 58f56f2..f9f9d58 100644
--- a/tests/FlickerTests/AndroidManifest.xml
+++ b/tests/FlickerTests/AndroidManifest.xml
@@ -21,6 +21,8 @@
     <!-- Read and write traces from external storage -->
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <!-- Allow the test to write directly to /sdcard/ -->
+    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
     <!-- Write secure settings -->
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <!-- Capture screen contents -->
@@ -34,7 +36,8 @@
     <!-- Workaround grant runtime permission exception from b/152733071 -->
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
     <uses-permission android:name="android.permission.READ_LOGS"/>
-    <application>
+    <!-- Allow the test to write directly to /sdcard/ -->
+    <application android:requestLegacyExternalStorage="true">
         <uses-library android:name="android.test.runner"/>
     </application>
 
diff --git a/tests/FlickerTests/AndroidTestPhysicalDevices.xml b/tests/FlickerTests/AndroidTestPhysicalDevices.xml
index 1650438..abd620f 100644
--- a/tests/FlickerTests/AndroidTestPhysicalDevices.xml
+++ b/tests/FlickerTests/AndroidTestPhysicalDevices.xml
@@ -34,7 +34,7 @@
         <option name="hidden-api-checks" value="false" />
     </test>
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
-        <option name="directory-keys" value="/storage/emulated/0/Android/data/com.android.server.wm.flicker/files" />
+        <option name="directory-keys" value="/sdcard/flicker" />
         <option name="collect-on-run-ended-only" value="true" />
         <option name="clean-up" value="true" />
     </metrics_collector>
diff --git a/tests/FlickerTests/AndroidTestVirtualDevices.xml b/tests/FlickerTests/AndroidTestVirtualDevices.xml
index 222212a..9a5413a 100644
--- a/tests/FlickerTests/AndroidTestVirtualDevices.xml
+++ b/tests/FlickerTests/AndroidTestVirtualDevices.xml
@@ -34,7 +34,7 @@
         <option name="hidden-api-checks" value="false" />
     </test>
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
-        <option name="directory-keys" value="/storage/emulated/0/Android/data/com.android.server.wm.flicker/files" />
+        <option name="directory-keys" value="/sdcard/flicker" />
         <option name="collect-on-run-ended-only" value="true" />
         <option name="clean-up" value="true" />
     </metrics_collector>
diff --git a/tests/FlickerTests/OWNERS b/tests/FlickerTests/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/tests/FlickerTests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index a85e92c..bb03237 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -239,7 +239,7 @@
     bugId: Int = 0,
     enabled: Boolean = bugId == 0
 ) {
-    all(enabled = enabled, bugId = bugId) {
+    all("focusChanges", bugId, enabled) {
         this.focusChanges(windows)
     }
 }
@@ -248,7 +248,7 @@
     bugId: Int = 0,
     enabled: Boolean = bugId == 0
 ) {
-    all(enabled = enabled, bugId = bugId) {
+    all("focusDoesNotChange", bugId, enabled) {
         this.focusDoesNotChange()
     }
 }
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index 7b5dc872..7bd96f5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.server.wm.flicker.ime
 
+import androidx.test.filters.FlakyTest
 import android.view.Surface
 import androidx.test.filters.RequiresDevice
 import androidx.test.platform.app.InstrumentationRegistry
@@ -42,6 +43,7 @@
 @RequiresDevice
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 175027130)
 class ReOpenImeWindowTest(
     testName: String,
     flickerSpec: Flicker
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index 0c584f4..5aef314 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.server.wm.flicker.launch
 
+import androidx.test.filters.FlakyTest
 import android.view.Surface
 import androidx.test.filters.RequiresDevice
 import androidx.test.platform.app.InstrumentationRegistry
@@ -53,6 +54,7 @@
 @RequiresDevice
 @RunWith(Parameterized::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 174658929)
 class OpenAppFromOverviewTest(
     testName: String,
     flickerSpec: Flicker
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 0db064a..9d4a718 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -67,7 +67,7 @@
             val instrumentation = InstrumentationRegistry.getInstrumentation()
             val testApp = StandardAppHelper(instrumentation,
                 "com.android.server.wm.flicker.testapp", "SimpleApp")
-            return FlickerTestRunnerFactory(instrumentation)
+            return FlickerTestRunnerFactory(instrumentation, repetitions = 10)
                 .buildRotationTest { configuration ->
                     withTestName {
                         buildTestTag(
diff --git a/tests/HugeBackup/OWNERS b/tests/HugeBackup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/tests/HugeBackup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/tests/HwAccelerationTest/OWNERS b/tests/HwAccelerationTest/OWNERS
new file mode 100644
index 0000000..c88a9f8
--- /dev/null
+++ b/tests/HwAccelerationTest/OWNERS
@@ -0,0 +1 @@
+include /libs/hwui/OWNERS
diff --git a/tests/Input/OWNERS b/tests/Input/OWNERS
new file mode 100644
index 0000000..d701f23
--- /dev/null
+++ b/tests/Input/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/hardware/input/OWNERS
diff --git a/tests/JobSchedulerPerfTests/OWNERS b/tests/JobSchedulerPerfTests/OWNERS
new file mode 100644
index 0000000..6f207fb1
--- /dev/null
+++ b/tests/JobSchedulerPerfTests/OWNERS
@@ -0,0 +1 @@
+include /apex/jobscheduler/OWNERS
diff --git a/tests/JobSchedulerTestApp/OWNERS b/tests/JobSchedulerTestApp/OWNERS
new file mode 100644
index 0000000..6f207fb1
--- /dev/null
+++ b/tests/JobSchedulerTestApp/OWNERS
@@ -0,0 +1 @@
+include /apex/jobscheduler/OWNERS
diff --git a/tests/LocationTracker/OWNERS b/tests/LocationTracker/OWNERS
new file mode 100644
index 0000000..5ac6028
--- /dev/null
+++ b/tests/LocationTracker/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/location/OWNERS
diff --git a/tests/LowStorageTest/OWNERS b/tests/LowStorageTest/OWNERS
new file mode 100644
index 0000000..6f9dbea
--- /dev/null
+++ b/tests/LowStorageTest/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/os/storage/OWNERS
diff --git a/tests/NetworkSecurityConfigTest/OWNERS b/tests/NetworkSecurityConfigTest/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/tests/PackageWatchdog/OWNERS b/tests/PackageWatchdog/OWNERS
new file mode 100644
index 0000000..d04a706
--- /dev/null
+++ b/tests/PackageWatchdog/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/rollback/OWNERS
diff --git a/tests/PackageWatchdog/src/com/android/server/OWNERS b/tests/PackageWatchdog/src/com/android/server/OWNERS
new file mode 100644
index 0000000..5cf4dcf
--- /dev/null
+++ b/tests/PackageWatchdog/src/com/android/server/OWNERS
@@ -0,0 +1 @@
+per-file PackageWatchdogTest.java = file:/services/core/java/com/android/server/rollback/OWNERS
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 9738e58..104758d 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -22,6 +22,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
@@ -43,10 +44,15 @@
 import android.os.test.TestLooper;
 import android.provider.DeviceConfig;
 import android.util.AtomicFile;
+import android.util.LongArrayQueue;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
 
 import androidx.test.InstrumentationRegistry;
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.util.XmlUtils;
 import com.android.server.PackageWatchdog.HealthCheckState;
 import com.android.server.PackageWatchdog.MonitoredPackage;
 import com.android.server.PackageWatchdog.PackageHealthObserver;
@@ -64,6 +70,7 @@
 import org.mockito.stubbing.Answer;
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -739,7 +746,8 @@
                 false /* hasPassedHealthCheck */);
         MonitoredPackage m2 = wd.newMonitoredPackage(APP_B, LONG_DURATION, false);
         MonitoredPackage m3 = wd.newMonitoredPackage(APP_C, LONG_DURATION, false);
-        MonitoredPackage m4 = wd.newMonitoredPackage(APP_D, LONG_DURATION, SHORT_DURATION, true);
+        MonitoredPackage m4 = wd.newMonitoredPackage(APP_D, LONG_DURATION, SHORT_DURATION, true,
+                new LongArrayQueue());
 
         // Verify transition: inactive -> active -> passed
         // Verify initially inactive
@@ -1210,6 +1218,73 @@
         assertThat(observer.mMitigationCounts).isEqualTo(List.of(1, 2, 3, 3, 2, 3));
     }
 
+    @Test
+    public void testNormalizingMitigationCalls()  {
+        PackageWatchdog watchdog = createWatchdog();
+
+        LongArrayQueue mitigationCalls = new LongArrayQueue();
+        mitigationCalls.addLast(1000);
+        mitigationCalls.addLast(2000);
+        mitigationCalls.addLast(3000);
+
+        MonitoredPackage pkg = watchdog.newMonitoredPackage(
+                "test", 123, 456, true, mitigationCalls);
+
+        // Make current system uptime 10000ms.
+        moveTimeForwardAndDispatch(9999);
+
+        LongArrayQueue expectedCalls = pkg.normalizeMitigationCalls();
+
+        assertThat(expectedCalls.size()).isEqualTo(mitigationCalls.size());
+
+        for (int i = 0; i < mitigationCalls.size(); i++) {
+            assertThat(expectedCalls.get(i)).isEqualTo(mitigationCalls.get(i) - 10000);
+        }
+    }
+
+    /**
+     * Ensure that a {@link MonitoredPackage} may be correctly written and read in order to persist
+     * across reboots.
+     */
+    @Test
+    public void testWritingAndReadingMonitoredPackage() throws Exception {
+        PackageWatchdog watchdog = createWatchdog();
+
+        LongArrayQueue mitigationCalls = new LongArrayQueue();
+        mitigationCalls.addLast(1000);
+        mitigationCalls.addLast(2000);
+        mitigationCalls.addLast(3000);
+        MonitoredPackage writePkg = watchdog.newMonitoredPackage(
+                "test.package", 1000, 2000, true, mitigationCalls);
+
+        // Move time forward so that the current uptime is 4000ms. Therefore, the written mitigation
+        // calls will each be reduced by 4000.
+        moveTimeForwardAndDispatch(3999);
+        LongArrayQueue expectedCalls = new LongArrayQueue();
+        expectedCalls.addLast(-3000);
+        expectedCalls.addLast(-2000);
+        expectedCalls.addLast(-1000);
+        MonitoredPackage expectedPkg = watchdog.newMonitoredPackage(
+                "test.package", 1000, 2000, true, expectedCalls);
+
+        // Write the package
+        File tmpFile = File.createTempFile("package-watchdog-test", ".xml");
+        AtomicFile testFile = new AtomicFile(tmpFile);
+        FileOutputStream stream = testFile.startWrite();
+        TypedXmlSerializer outputSerializer = Xml.resolveSerializer(stream);
+        outputSerializer.startDocument(null, true);
+        writePkg.writeLocked(outputSerializer);
+        outputSerializer.endDocument();
+        testFile.finishWrite(stream);
+
+        // Read the package
+        TypedXmlPullParser parser = Xml.resolvePullParser(testFile.openRead());
+        XmlUtils.beginDocument(parser, "package");
+        MonitoredPackage readPkg = watchdog.parseMonitoredPackage(parser);
+
+        assertTrue(readPkg.isEqualTo(expectedPkg));
+    }
+
     private void adoptShellPermissions(String... permissions) {
         InstrumentationRegistry
                 .getInstrumentation()
diff --git a/tests/PlatformCompatGating/OWNERS b/tests/PlatformCompatGating/OWNERS
new file mode 100644
index 0000000..f8c3520
--- /dev/null
+++ b/tests/PlatformCompatGating/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/compat/OWNERS
diff --git a/tests/RollbackTest/OWNERS b/tests/RollbackTest/OWNERS
new file mode 100644
index 0000000..d04a706
--- /dev/null
+++ b/tests/RollbackTest/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/rollback/OWNERS
diff --git a/tests/RollbackTest/TEST_MAPPING b/tests/RollbackTest/TEST_MAPPING
index 0f4c460..7f9f2dc 100644
--- a/tests/RollbackTest/TEST_MAPPING
+++ b/tests/RollbackTest/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
       "name": "RollbackTest"
     },
diff --git a/tests/SoundTriggerTestApp/OWNERS b/tests/SoundTriggerTestApp/OWNERS
new file mode 100644
index 0000000..816bc6b
--- /dev/null
+++ b/tests/SoundTriggerTestApp/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/media/soundtrigger/OWNERS
diff --git a/tests/SoundTriggerTests/OWNERS b/tests/SoundTriggerTests/OWNERS
new file mode 100644
index 0000000..816bc6b
--- /dev/null
+++ b/tests/SoundTriggerTests/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/media/soundtrigger/OWNERS
diff --git a/tests/StagedInstallTest/OWNERS b/tests/StagedInstallTest/OWNERS
new file mode 100644
index 0000000..d825dfd
--- /dev/null
+++ b/tests/StagedInstallTest/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/OWNERS
diff --git a/tests/StagedInstallTest/TEST_MAPPING b/tests/StagedInstallTest/TEST_MAPPING
index 5a7a5a7..fa2a60b 100644
--- a/tests/StagedInstallTest/TEST_MAPPING
+++ b/tests/StagedInstallTest/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
       "name": "StagedInstallInternalTest"
     }
diff --git a/tests/StatusBar/OWNERS b/tests/StatusBar/OWNERS
new file mode 100644
index 0000000..2e96c97
--- /dev/null
+++ b/tests/StatusBar/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/OWNERS
diff --git a/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceTracingTestBase.kt b/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceTracingTestBase.kt
index cd4b385..273833b 100644
--- a/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceTracingTestBase.kt
+++ b/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceTracingTestBase.kt
@@ -23,7 +23,7 @@
 import androidx.test.ext.junit.rules.ActivityScenarioRule
 import com.android.server.wm.flicker.monitor.LayersTraceMonitor
 import com.android.server.wm.flicker.monitor.withSFTracing
-import com.android.server.wm.flicker.traces.layers.LayersTrace
+import com.android.server.wm.traces.parser.layers.LayersTrace
 import junit.framework.Assert
 import org.junit.After
 import org.junit.Before
@@ -52,7 +52,8 @@
     }
 
     fun withTrace(predicate: (it: MainActivity) -> Unit): LayersTrace {
-        return withSFTracing(instrumentation, TRACE_FLAGS) {
+        return withSFTracing(TRACE_FLAGS,
+                outputDir = instrumentation.targetContext.dataDir.toPath()) {
             scenarioRule.getScenario().onActivity {
                 predicate(it)
             }
diff --git a/tests/TaskOrganizerTest/OWNERS b/tests/TaskOrganizerTest/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/tests/TaskOrganizerTest/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt b/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt
index fe9deae..2e3467a 100644
--- a/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt
+++ b/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt
@@ -68,7 +68,8 @@
         val firstBounds = Rect(0, 0, 1080, 800)
         val secondBounds = Rect(0, 1000, 1080, 1800)
 
-        val trace = withSFTracing(instrumentation, TRACE_FLAGS) {
+        val trace = withSFTracing(TRACE_FLAGS,
+                outputDir = instrumentation.targetContext.dataDir.toPath()) {
             lateinit var resizeReadyLatch: CountDownLatch
             scenarioRule.getScenario().onActivity {
                 resizeReadyLatch = it.resizeTaskView(firstBounds, secondBounds)
@@ -77,17 +78,13 @@
         }
 
         // find the frame which match resized buffer size.
-        var frame: Long = -1
-        loop@ for (trace in trace.entries) {
-            for (layer in trace.flattenedLayers) {
-                if (layer.proto.activeBuffer != null &&
-                        layer.proto.activeBuffer.width == firstBounds.width() &&
-                        layer.proto.activeBuffer.height == firstBounds.height()) {
-                    frame = layer.proto.currFrame
-                    break@loop
-                }
-            }
-        }
+        val frame = trace.entries.flatMap { it.flattenedLayers }
+                .firstOrNull { layer ->
+                    !layer.isActiveBufferEmpty &&
+                        layer.activeBuffer?.width == firstBounds.width() &&
+                        layer.activeBuffer?.height == firstBounds.height()
+                }?.currFrame ?: -1
+
         assertNotEquals(-1, frame)
         // layer bounds should be related to parent surfaceview.
         secondBounds.offsetTo(0, 0)
diff --git a/tests/TelephonyCommonTests/OWNERS b/tests/TelephonyCommonTests/OWNERS
new file mode 100644
index 0000000..640baf2
--- /dev/null
+++ b/tests/TelephonyCommonTests/OWNERS
@@ -0,0 +1 @@
+include /telephony/OWNERS
diff --git a/tests/UsageReportingTest/OWNERS b/tests/UsageReportingTest/OWNERS
new file mode 100644
index 0000000..d3227de
--- /dev/null
+++ b/tests/UsageReportingTest/OWNERS
@@ -0,0 +1 @@
+include /services/usage/OWNERS
diff --git a/tests/UsageStatsPerfTests/OWNERS b/tests/UsageStatsPerfTests/OWNERS
new file mode 100644
index 0000000..d3227de
--- /dev/null
+++ b/tests/UsageStatsPerfTests/OWNERS
@@ -0,0 +1 @@
+include /services/usage/OWNERS
diff --git a/tests/UsageStatsTest/OWNERS b/tests/UsageStatsTest/OWNERS
new file mode 100644
index 0000000..d3227de
--- /dev/null
+++ b/tests/UsageStatsTest/OWNERS
@@ -0,0 +1 @@
+include /services/usage/OWNERS
diff --git a/tests/UsbHostExternalManagmentTest/OWNERS b/tests/UsbHostExternalManagmentTest/OWNERS
new file mode 100644
index 0000000..f7b2a37
--- /dev/null
+++ b/tests/UsbHostExternalManagmentTest/OWNERS
@@ -0,0 +1 @@
+include /services/usb/OWNERS
diff --git a/tests/UsbManagerTests/OWNERS b/tests/UsbManagerTests/OWNERS
new file mode 100644
index 0000000..f7b2a37
--- /dev/null
+++ b/tests/UsbManagerTests/OWNERS
@@ -0,0 +1 @@
+include /services/usb/OWNERS
diff --git a/tests/UsbTests/OWNERS b/tests/UsbTests/OWNERS
new file mode 100644
index 0000000..f7b2a37
--- /dev/null
+++ b/tests/UsbTests/OWNERS
@@ -0,0 +1 @@
+include /services/usb/OWNERS
diff --git a/tests/VoiceInteraction/OWNERS b/tests/VoiceInteraction/OWNERS
new file mode 100644
index 0000000..ef1061b
--- /dev/null
+++ b/tests/VoiceInteraction/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/voice/OWNERS
diff --git a/tests/WindowAnimationJank/OWNERS b/tests/WindowAnimationJank/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/tests/WindowAnimationJank/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/tests/WindowInsetsTests/OWNERS b/tests/WindowInsetsTests/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/tests/WindowInsetsTests/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/tests/backup/OWNERS b/tests/backup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/tests/backup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/tests/benchmarks/src/com/android/server/net/OWNERS b/tests/benchmarks/src/com/android/server/net/OWNERS
new file mode 100644
index 0000000..aa87958
--- /dev/null
+++ b/tests/benchmarks/src/com/android/server/net/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/net/OWNERS
diff --git a/tests/net/common/java/android/net/NetworkProviderTest.kt b/tests/net/common/java/android/net/NetworkProviderTest.kt
index dd3f5be..77e9f12 100644
--- a/tests/net/common/java/android/net/NetworkProviderTest.kt
+++ b/tests/net/common/java/android/net/NetworkProviderTest.kt
@@ -33,6 +33,9 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verifyNoMoreInteractions
 import java.util.UUID
 import kotlin.test.assertEquals
 import kotlin.test.assertNotEquals
@@ -87,8 +90,8 @@
         ) = seenEvents.poll(DEFAULT_TIMEOUT_MS) { it is T && predicate(it) }
     }
 
-    private fun createNetworkProvider(): TestNetworkProvider {
-        return TestNetworkProvider(context, mHandlerThread.looper)
+    private fun createNetworkProvider(ctx: Context = context): TestNetworkProvider {
+        return TestNetworkProvider(ctx, mHandlerThread.looper)
     }
 
     @Test
@@ -169,7 +172,12 @@
 
     @Test
     fun testDeclareNetworkRequestUnfulfillable() {
-        val provider = createNetworkProvider()
+        val mockContext = mock(Context::class.java)
+        val provider = createNetworkProvider(mockContext)
+        // ConnectivityManager not required at creation time
+        verifyNoMoreInteractions(mockContext)
+        doReturn(mCm).`when`(mockContext).getSystemService(Context.CONNECTIVITY_SERVICE)
+
         mCm.registerNetworkProvider(provider)
 
         val specifier = StringNetworkSpecifier(UUID.randomUUID().toString())
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index 835a83e..c5b25bd 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -147,5 +147,11 @@
         assertEquals(resultData.rcvWndScale, wndScale);
         assertEquals(resultData.tos, tos);
         assertEquals(resultData.ttl, ttl);
+
+        final String expected = ""
+                + "android.net.TcpKeepalivePacketDataParcelable{srcAddress: [10, 0, 0, 1],"
+                + " srcPort: 1234, dstAddress: [10, 0, 0, 5], dstPort: 4321, seq: 286331153,"
+                + " ack: 572662306, rcvWnd: 48000, rcvWndScale: 2, tos: 4, ttl: 64}";
+        assertEquals(expected, resultData.toString());
     }
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 5d45737..059e054 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1958,6 +1958,57 @@
     }
 
     @Test
+    public void testOwnerUidChangeBug() throws Exception {
+        // Owner UIDs are not visible without location permission.
+        setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
+                Manifest.permission.ACCESS_FINE_LOCATION);
+
+        final NetworkCapabilities ncTemplate = new NetworkCapabilities();
+        final int originalOwnerUid = Process.myUid();
+        ncTemplate.setOwnerUid(originalOwnerUid);
+
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(),
+                ncTemplate);
+        mWiFiNetworkAgent.connect(false);
+        waitForIdle();
+
+        // Send ConnectivityService an update to the mWiFiNetworkAgent's capabilities that changes
+        // its owner UID.
+        NetworkCapabilities agentCapabilities = mWiFiNetworkAgent.getNetworkCapabilities();
+        assertEquals(originalOwnerUid, agentCapabilities.getOwnerUid());
+        agentCapabilities.setOwnerUid(42);
+        mWiFiNetworkAgent.setNetworkCapabilities(agentCapabilities, true);
+        waitForIdle();
+
+        // Check that the owner UID is not updated.
+        NetworkCapabilities nc = mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork());
+        assertEquals(originalOwnerUid, nc.getOwnerUid());
+
+        // Make an unrelated change to the capabilities.
+        assertFalse(agentCapabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
+        agentCapabilities.addCapability(NET_CAPABILITY_NOT_CONGESTED);
+        mWiFiNetworkAgent.setNetworkCapabilities(agentCapabilities, true);
+        waitForIdle();
+
+        // Check that both the capability change and the owner UID have been modified.
+        // The owner UID is -1 because it is visible only to the UID that owns the network.
+        nc = mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork());
+        assertEquals(-1, nc.getOwnerUid());
+        assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
+
+        // Set the owner back to originalOwnerUid, update the capabilities, and check that it is
+        // visible again.
+        // TODO: should this even be possible?
+        agentCapabilities.setOwnerUid(originalOwnerUid);
+        agentCapabilities.removeCapability(NET_CAPABILITY_NOT_CONGESTED);
+        mWiFiNetworkAgent.setNetworkCapabilities(agentCapabilities, true);
+        waitForIdle();
+
+        nc = mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork());
+        assertEquals(originalOwnerUid, nc.getOwnerUid());
+    }
+
+    @Test
     public void testMultipleLingering() throws Exception {
         // This test would be flaky with the default 120ms timer: that is short enough that
         // lingered networks are torn down before assertions can be run. We don't want to mock the
@@ -2517,7 +2568,10 @@
 
     @Test
     public void testNoMutableNetworkRequests() throws Exception {
-        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
+        // TODO(b/173157160) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"),
+                PendingIntent.FLAG_MUTABLE_UNAUDITED);
         NetworkRequest request1 = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_VALIDATED)
                 .build();
@@ -3177,17 +3231,21 @@
         assertThrows(SecurityException.class, () ->
                 mCm.registerNetworkCallback(r, new NetworkCallback()));
 
+        // TODO(b/173157160) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         assertThrows(SecurityException.class, () ->
                 mCm.registerNetworkCallback(r, PendingIntent.getService(
-                        mServiceContext, 0, new Intent(), 0)));
+                        mServiceContext, 0, new Intent(), PendingIntent.FLAG_MUTABLE_UNAUDITED)));
 
         // Requesting a Network with signal strength should get IllegalArgumentException.
         assertThrows(IllegalArgumentException.class, () ->
                 mCm.requestNetwork(r, new NetworkCallback()));
 
+        // TODO(b/173157160) Please replace FLAG_MUTABLE_UNAUDITED below
+        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
         assertThrows(IllegalArgumentException.class, () ->
                 mCm.requestNetwork(r, PendingIntent.getService(
-                        mServiceContext, 0, new Intent(), 0)));
+                        mServiceContext, 0, new Intent(), PendingIntent.FLAG_MUTABLE_UNAUDITED)));
     }
 
     @Test
@@ -4651,12 +4709,16 @@
         }
         j = 0;
         while (j++ < INTENTS / 2) {
-            PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("a" + j), 0);
+            // TODO(b/173157160) Please replace FLAG_MUTABLE_UNAUDITED below
+            // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+            PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("a" + j), PendingIntent.FLAG_MUTABLE_UNAUDITED);
             mCm.requestNetwork(networkRequest, pi);
             registered.add(pi);
         }
         while (j++ < INTENTS) {
-            PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("b" + j), 0);
+            // TODO(b/173157160) Please replace FLAG_MUTABLE_UNAUDITED below
+            // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+            PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, new Intent("b" + j), PendingIntent.FLAG_MUTABLE_UNAUDITED);
             mCm.registerNetworkCallback(networkRequest, pi);
             registered.add(pi);
         }
@@ -4670,11 +4732,15 @@
         );
         assertThrows(TooManyRequestsException.class, () ->
                 mCm.requestNetwork(networkRequest,
-                        PendingIntent.getBroadcast(mContext, 0, new Intent("c"), 0))
+                        // TODO(b/173157160) Please replace FLAG_MUTABLE_UNAUDITED below
+                        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+                        PendingIntent.getBroadcast(mContext, 0, new Intent("c"), PendingIntent.FLAG_MUTABLE_UNAUDITED))
         );
         assertThrows(TooManyRequestsException.class, () ->
                 mCm.registerNetworkCallback(networkRequest,
-                        PendingIntent.getBroadcast(mContext, 0, new Intent("d"), 0))
+                        // TODO(b/173157160) Please replace FLAG_MUTABLE_UNAUDITED below
+                        // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
+                        PendingIntent.getBroadcast(mContext, 0, new Intent("d"), PendingIntent.FLAG_MUTABLE_UNAUDITED))
         );
 
         for (Object o : registered) {
@@ -4703,16 +4769,20 @@
         waitForIdle();
 
         for (int i = 0; i < MAX_REQUESTS; i++) {
+            // TODO(b/173157160) Please replace FLAG_MUTABLE_UNAUDITED below
+            // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
             PendingIntent pendingIntent =
-                    PendingIntent.getBroadcast(mContext, 0, new Intent("e" + i), 0);
+                    PendingIntent.getBroadcast(mContext, 0, new Intent("e" + i), PendingIntent.FLAG_MUTABLE_UNAUDITED);
             mCm.requestNetwork(networkRequest, pendingIntent);
             mCm.unregisterNetworkCallback(pendingIntent);
         }
         waitForIdle();
 
         for (int i = 0; i < MAX_REQUESTS; i++) {
+            // TODO(b/173157160) Please replace FLAG_MUTABLE_UNAUDITED below
+            // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE.
             PendingIntent pendingIntent =
-                    PendingIntent.getBroadcast(mContext, 0, new Intent("f" + i), 0);
+                    PendingIntent.getBroadcast(mContext, 0, new Intent("f" + i), PendingIntent.FLAG_MUTABLE_UNAUDITED);
             mCm.registerNetworkCallback(networkRequest, pendingIntent);
             mCm.unregisterNetworkCallback(pendingIntent);
         }
diff --git a/tests/net/java/com/android/server/NetworkManagementServiceTest.java b/tests/net/java/com/android/server/NetworkManagementServiceTest.java
index 968b307..ea763d2 100644
--- a/tests/net/java/com/android/server/NetworkManagementServiceTest.java
+++ b/tests/net/java/com/android/server/NetworkManagementServiceTest.java
@@ -16,6 +16,12 @@
 
 package com.android.server;
 
+import static android.util.DebugUtils.valueToString;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -29,15 +35,19 @@
 import android.net.INetd;
 import android.net.INetdUnsolicitedEventListener;
 import android.net.LinkAddress;
+import android.net.NetworkPolicyManager;
 import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.util.ArrayMap;
 
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.app.IBatteryStats;
-import com.android.server.NetworkManagementService.SystemServices;
+import com.android.server.NetworkManagementService.Dependencies;
 import com.android.server.net.BaseNetworkObserver;
 
 import org.junit.After;
@@ -49,13 +59,14 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.function.BiFunction;
+
 /**
  * Tests for {@link NetworkManagementService}.
  */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class NetworkManagementServiceTest {
-
     private NetworkManagementService mNMService;
 
     @Mock private Context mContext;
@@ -66,7 +77,9 @@
     @Captor
     private ArgumentCaptor<INetdUnsolicitedEventListener> mUnsolListenerCaptor;
 
-    private final SystemServices mServices = new SystemServices() {
+    private final MockDependencies mDeps = new MockDependencies();
+
+    private final class MockDependencies extends Dependencies {
         @Override
         public IBinder getService(String name) {
             switch (name) {
@@ -76,14 +89,21 @@
                     throw new UnsupportedOperationException("Unknown service " + name);
             }
         }
+
         @Override
         public void registerLocalService(NetworkManagementInternal nmi) {
         }
+
         @Override
         public INetd getNetd() {
             return mNetdService;
         }
-    };
+
+        @Override
+        public int getCallingUid() {
+            return Process.SYSTEM_UID;
+        }
+    }
 
     @Before
     public void setUp() throws Exception {
@@ -91,7 +111,7 @@
         doNothing().when(mNetdService)
                 .registerUnsolicitedEventListener(mUnsolListenerCaptor.capture());
         // Start the service and wait until it connects to our socket.
-        mNMService = NetworkManagementService.create(mContext, mServices);
+        mNMService = NetworkManagementService.create(mContext, mDeps);
     }
 
     @After
@@ -192,4 +212,105 @@
         // Make sure nothing else was called.
         verifyNoMoreInteractions(observer);
     }
+
+    @Test
+    public void testFirewallEnabled() {
+        mNMService.setFirewallEnabled(true);
+        assertTrue(mNMService.isFirewallEnabled());
+
+        mNMService.setFirewallEnabled(false);
+        assertFalse(mNMService.isFirewallEnabled());
+    }
+
+    private static final int TEST_UID = 111;
+
+    @Test
+    public void testNetworkRestrictedDefault() {
+        assertFalse(mNMService.isNetworkRestricted(TEST_UID));
+    }
+
+    @Test
+    public void testMeteredNetworkRestrictions() throws RemoteException {
+        // Make sure the mocked netd method returns true.
+        doReturn(true).when(mNetdService).bandwidthEnableDataSaver(anyBoolean());
+
+        // Restrict usage of mobile data in background
+        mNMService.setUidMeteredNetworkDenylist(TEST_UID, true);
+        assertTrue("Should be true since mobile data usage is restricted",
+                mNMService.isNetworkRestricted(TEST_UID));
+
+        mNMService.setDataSaverModeEnabled(true);
+        verify(mNetdService).bandwidthEnableDataSaver(true);
+
+        mNMService.setUidMeteredNetworkDenylist(TEST_UID, false);
+        assertTrue("Should be true since data saver is on and the uid is not allowlisted",
+                mNMService.isNetworkRestricted(TEST_UID));
+
+        mNMService.setUidMeteredNetworkAllowlist(TEST_UID, true);
+        assertFalse("Should be false since data saver is on and the uid is allowlisted",
+                mNMService.isNetworkRestricted(TEST_UID));
+
+        // remove uid from allowlist and turn datasaver off again
+        mNMService.setUidMeteredNetworkAllowlist(TEST_UID, false);
+        mNMService.setDataSaverModeEnabled(false);
+        verify(mNetdService).bandwidthEnableDataSaver(false);
+        assertFalse("Network should not be restricted when data saver is off",
+                mNMService.isNetworkRestricted(TEST_UID));
+    }
+
+    @Test
+    public void testFirewallChains() {
+        final ArrayMap<Integer, ArrayMap<Integer, Boolean>> expected = new ArrayMap<>();
+        // Dozable chain
+        final ArrayMap<Integer, Boolean> isRestrictedForDozable = new ArrayMap<>();
+        isRestrictedForDozable.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true);
+        isRestrictedForDozable.put(INetd.FIREWALL_RULE_ALLOW, false);
+        isRestrictedForDozable.put(INetd.FIREWALL_RULE_DENY, true);
+        expected.put(INetd.FIREWALL_CHAIN_DOZABLE, isRestrictedForDozable);
+        // Powersaver chain
+        final ArrayMap<Integer, Boolean> isRestrictedForPowerSave = new ArrayMap<>();
+        isRestrictedForPowerSave.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true);
+        isRestrictedForPowerSave.put(INetd.FIREWALL_RULE_ALLOW, false);
+        isRestrictedForPowerSave.put(INetd.FIREWALL_RULE_DENY, true);
+        expected.put(INetd.FIREWALL_CHAIN_POWERSAVE, isRestrictedForPowerSave);
+        // Standby chain
+        final ArrayMap<Integer, Boolean> isRestrictedForStandby = new ArrayMap<>();
+        isRestrictedForStandby.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, false);
+        isRestrictedForStandby.put(INetd.FIREWALL_RULE_ALLOW, false);
+        isRestrictedForStandby.put(INetd.FIREWALL_RULE_DENY, true);
+        expected.put(INetd.FIREWALL_CHAIN_STANDBY, isRestrictedForStandby);
+        // Restricted mode chain
+        final ArrayMap<Integer, Boolean> isRestrictedForRestrictedMode = new ArrayMap<>();
+        isRestrictedForRestrictedMode.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true);
+        isRestrictedForRestrictedMode.put(INetd.FIREWALL_RULE_ALLOW, false);
+        isRestrictedForRestrictedMode.put(INetd.FIREWALL_RULE_DENY, true);
+        expected.put(INetd.FIREWALL_CHAIN_RESTRICTED, isRestrictedForRestrictedMode);
+
+        final int[] chains = {
+                INetd.FIREWALL_CHAIN_STANDBY,
+                INetd.FIREWALL_CHAIN_POWERSAVE,
+                INetd.FIREWALL_CHAIN_DOZABLE,
+                INetd.FIREWALL_CHAIN_RESTRICTED
+        };
+        final int[] states = {
+                INetd.FIREWALL_RULE_ALLOW,
+                INetd.FIREWALL_RULE_DENY,
+                NetworkPolicyManager.FIREWALL_RULE_DEFAULT
+        };
+        BiFunction<Integer, Integer, String> errorMsg = (chain, state) -> {
+            return String.format("Unexpected value for chain: %s and state: %s",
+                    valueToString(INetd.class, "FIREWALL_CHAIN_", chain),
+                    valueToString(INetd.class, "FIREWALL_RULE_", state));
+        };
+        for (int chain : chains) {
+            final ArrayMap<Integer, Boolean> expectedValues = expected.get(chain);
+            mNMService.setFirewallChainEnabled(chain, true);
+            for (int state : states) {
+                mNMService.setFirewallUidRule(chain, TEST_UID, state);
+                assertEquals(errorMsg.apply(chain, state),
+                        expectedValues.get(state), mNMService.isNetworkRestricted(TEST_UID));
+            }
+            mNMService.setFirewallChainEnabled(chain, false);
+        }
+    }
 }
diff --git a/tests/notification/OWNERS b/tests/notification/OWNERS
new file mode 100644
index 0000000..396fd12
--- /dev/null
+++ b/tests/notification/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/notification/OWNERS
diff --git a/tests/permission/OWNERS b/tests/permission/OWNERS
new file mode 100644
index 0000000..999ea0e
--- /dev/null
+++ b/tests/permission/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/permission/OWNERS
diff --git a/tests/utils/DummyIME/OWNERS b/tests/utils/DummyIME/OWNERS
new file mode 100644
index 0000000..5deb2ce
--- /dev/null
+++ b/tests/utils/DummyIME/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/inputmethod/OWNERS
diff --git a/tests/utils/StubIME/OWNERS b/tests/utils/StubIME/OWNERS
new file mode 100644
index 0000000..5deb2ce
--- /dev/null
+++ b/tests/utils/StubIME/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/inputmethod/OWNERS
diff --git a/tests/utils/hostutils/src/com/android/tests/rollback/OWNERS b/tests/utils/hostutils/src/com/android/tests/rollback/OWNERS
new file mode 100644
index 0000000..d04a706
--- /dev/null
+++ b/tests/utils/hostutils/src/com/android/tests/rollback/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/rollback/OWNERS
diff --git a/tests/utils/testutils/java/com/android/server/accessibility/OWNERS b/tests/utils/testutils/java/com/android/server/accessibility/OWNERS
new file mode 100644
index 0000000..b74281e
--- /dev/null
+++ b/tests/utils/testutils/java/com/android/server/accessibility/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/accessibility/OWNERS
diff --git a/tests/utils/testutils/java/com/android/server/wm/OWNERS b/tests/utils/testutils/java/com/android/server/wm/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/tests/utils/testutils/java/com/android/server/wm/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/tools/aapt/OWNERS b/tools/aapt/OWNERS
new file mode 100644
index 0000000..c232ccd
--- /dev/null
+++ b/tools/aapt/OWNERS
@@ -0,0 +1 @@
+include /tools/aapt2/OWNERS
diff --git a/tools/fonts/OWNERS b/tools/fonts/OWNERS
new file mode 100644
index 0000000..a538331
--- /dev/null
+++ b/tools/fonts/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/graphics/fonts/OWNERS
diff --git a/tools/incident_report/OWNERS b/tools/incident_report/OWNERS
new file mode 100644
index 0000000..f766115
--- /dev/null
+++ b/tools/incident_report/OWNERS
@@ -0,0 +1 @@
+include /cmds/incidentd/OWNERS
diff --git a/tools/incident_section_gen/OWNERS b/tools/incident_section_gen/OWNERS
new file mode 100644
index 0000000..f766115
--- /dev/null
+++ b/tools/incident_section_gen/OWNERS
@@ -0,0 +1 @@
+include /cmds/incidentd/OWNERS
diff --git a/tools/powerstats/OWNERS b/tools/powerstats/OWNERS
new file mode 100644
index 0000000..d68066b
--- /dev/null
+++ b/tools/powerstats/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/power/OWNERS
diff --git a/tools/stats_log_api_gen/OWNERS b/tools/stats_log_api_gen/OWNERS
new file mode 100644
index 0000000..41a0c95
--- /dev/null
+++ b/tools/stats_log_api_gen/OWNERS
@@ -0,0 +1 @@
+yro@google.com
diff --git a/wifi/TEST_MAPPING b/wifi/TEST_MAPPING
index 8c51510..7ddc308 100644
--- a/wifi/TEST_MAPPING
+++ b/wifi/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
       "name": "CtsWifiTestCases",
       "options": [
@@ -11,9 +11,6 @@
   ],
   "mainline-presubmit": [
     {
-      "name": "FrameworksWifiApiTests[com.google.android.wifi.apex]"
-    },
-    {
       "name": "CtsWifiTestCases[com.google.android.wifi.apex]",
       "options": [
         {
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
index ce2b8ca..e11b33e 100644
--- a/wifi/api/current.txt
+++ b/wifi/api/current.txt
@@ -332,6 +332,7 @@
     method public boolean is5GHzBandSupported();
     method public boolean is6GHzBandSupported();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isAutoWakeupEnabled();
+    method public boolean isBridgedApConcurrencySupported();
     method @Deprecated public boolean isDeviceToApRttSupported();
     method public boolean isEasyConnectSupported();
     method public boolean isEnhancedOpenSupported();
@@ -342,6 +343,7 @@
     method @Deprecated public boolean isScanAlwaysAvailable();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isScanThrottleEnabled();
     method public boolean isStaApConcurrencySupported();
+    method public boolean isStaBridgedApConcurrencySupported();
     method public boolean isTdlsSupported();
     method public boolean isWapiSupported();
     method public boolean isWifiEnabled();
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
index 48d9fd4..eba7443 100644
--- a/wifi/api/system-current.txt
+++ b/wifi/api/system-current.txt
@@ -483,6 +483,7 @@
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>);
     method public boolean is60GHzBandSupported();
     method public boolean isApMacRandomizationSupported();
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public boolean isCarrierNetworkOffloadEnabled(int, boolean);
     method public boolean isConnectedMacRandomizationSupported();
     method @Deprecated public boolean isDeviceToDeviceRttSupported();
     method public boolean isPortableHotspotSupported();
@@ -501,6 +502,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public byte[] retrieveSoftApBackupData();
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener);
     method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setAutoWakeupEnabled(boolean);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void setCarrierNetworkOffloadEnabled(int, boolean, boolean);
     method @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS) public void setCoexUnsafeChannels(@NonNull java.util.Set<android.net.wifi.CoexUnsafeChannel>, int);
     method @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) public void setDeviceMobilityState(int);
     method @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void setMacRandomizationSettingPasspointEnabled(@NonNull String, boolean);
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 6dee751..866e913 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -296,4 +296,8 @@
     void startTemporarilyDisablingAllNonCarrierMergedWifi(int subId);
 
     void stopTemporarilyDisablingAllNonCarrierMergedWifi();
+
+    void setCarrierNetworkOffloadEnabled(int subscriptionId, boolean merged, boolean enabled);
+
+    boolean isCarrierNetworkOffloadEnabled(int subscriptionId, boolean merged);
 }
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index fddc889..226d1a3 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -935,6 +935,9 @@
          * on the requested bands (if possible).
          * <p>
          *
+         * Use {@link WifiManager#isBridgedApConcurrencySupported()} to determine
+         * whether or not concurrent APs are supported.
+         *
          * @param bands Array of the {@link #BandType}.
          * @return Builder for chaining.
          * @throws IllegalArgumentException when more than 2 bands are set or an invalid band type
@@ -1007,6 +1010,9 @@
          * The {@link SoftApCapability#getSupportedChannelList(int)} can be used to obtain
          * valid channels in each band.
          *
+         * Use {@link WifiManager#isBridgedApConcurrencySupported()} to determine
+         * whether or not concurrent APs are supported.
+         *
          * <p>
          * If not set, the default for the channel is the special value 0 which has the framework
          * auto-select a valid channel from the band configured with {@link #setBands(int[])}.
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 90edc45..e127ea9 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -1335,6 +1335,16 @@
     }
 
     /**
+     * Initialize the value of the app installed device key and cert flag.
+     *
+     * @param isAppInstalledDeviceKeyAndCert true or false
+     * @hide
+     */
+    public void initIsAppInstalledDeviceKeyAndCert(boolean isAppInstalledDeviceKeyAndCert) {
+        mIsAppInstalledDeviceKeyAndCert = isAppInstalledDeviceKeyAndCert;
+    }
+
+    /**
      * Check if CA certificate was installed by an app, or manually (not by an app). If true,
      * CA certificate will be removed from key storage when this network is removed. If not,
      * then certificates and keys remain persistent until the user manually removes them.
@@ -1348,6 +1358,16 @@
     }
 
     /**
+     * Initialize the value of the app installed root CA cert flag.
+     *
+     * @param isAppInstalledCaCert true or false
+     * @hide
+     */
+    public void initIsAppInstalledCaCert(boolean isAppInstalledCaCert) {
+        mIsAppInstalledCaCert = isAppInstalledCaCert;
+    }
+
+    /**
      * Set the OCSP type.
      * @param ocsp is one of {@link ##OCSP_NONE}, {@link #OCSP_REQUEST_CERT_STATUS},
      *                   {@link #OCSP_REQUIRE_CERT_STATUS} or
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index b8fa1e1..2b931a3 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -53,6 +53,7 @@
 import android.os.RemoteException;
 import android.os.WorkSource;
 import android.os.connectivity.WifiActivityEnergyInfo;
+import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.CloseGuard;
@@ -2488,6 +2489,12 @@
     /** @hide */
     public static final long WIFI_FEATURE_SAE_PK          = 0x10000000000L; // SAE-PK
 
+    /** @hide */
+    public static final long WIFI_FEATURE_STA_BRIDGED_AP       = 0x20000000000L; // STA + Bridged AP
+
+    /** @hide */
+    public static final long WIFI_FEATURE_BRIDGED_AP           = 0x40000000000L; // Bridged AP
+
     private long getSupportedFeatures() {
         try {
             return mService.getSupportedFeatures();
@@ -2688,6 +2695,40 @@
     }
 
     /**
+     * Query whether the device supports Station (STA) + Bridged access point (AP)
+     * concurrency or not.
+     *
+     * The bridged AP support means that the device supports AP + AP concurrency with the 2 APs
+     * bridged together.
+     *
+     * See {@link SoftApConfiguration.Builder#setBands(int[])}
+     * or {@link SoftApConfiguration.Builder#setChannels(SparseIntArray)} to configure bridged AP
+     * when the bridged AP supported.
+     *
+     * @return true if this device supports STA + bridged AP concurrency, false otherwise.
+     */
+    public boolean isStaBridgedApConcurrencySupported() {
+        return isFeatureSupported(WIFI_FEATURE_STA_BRIDGED_AP);
+    }
+
+    /**
+     * Query whether the device supports Bridged Access point (AP) concurrency or not.
+     *
+     * The bridged AP support means that the device supports AP + AP concurrency with the 2 APs
+     * bridged together.
+     *
+     * See {@link SoftApConfiguration.Builder#setBands(int[])}
+     * or {@link SoftApConfiguration.Builder#setChannels(SparseIntArray)} to configure bridged AP
+     * when the bridged AP supported.
+     *
+     * @return true if this device supports bridged AP concurrency, false otherwise.
+     */
+    public boolean isBridgedApConcurrencySupported() {
+        return isFeatureSupported(WIFI_FEATURE_BRIDGED_AP);
+    }
+
+
+    /**
      * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and
      * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}.
      *
@@ -6721,4 +6762,63 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Sets the state of carrier offload on merged or unmerged networks for specified subscription.
+     *
+     * <p>
+     * When a subscription's carrier network offload is disabled, all network suggestions related to
+     * this subscription will not be considered for auto join.
+     * <p>
+     * If calling app want disable all carrier network offload from a specified subscription, should
+     * call this API twice to disable both merged and unmerged carrier network suggestions.
+     *
+     * @param subscriptionId See {@link SubscriptionInfo#getSubscriptionId()}.
+     * @param merged True for carrier merged network, false otherwise.
+     *               See {@link WifiNetworkSuggestion.Builder#setCarrierMerged(boolean)}
+     * @param enabled True for enable carrier network offload, false otherwise.
+     * @see #isCarrierNetworkOffloadEnabled(int, boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_SETUP_WIZARD})
+    public void setCarrierNetworkOffloadEnabled(int subscriptionId, boolean merged,
+            boolean enabled) {
+        if (!SdkLevel.isAtLeastS()) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            mService.setCarrierNetworkOffloadEnabled(subscriptionId, merged, enabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get the carrier network offload state for merged or unmerged networks for specified
+     * subscription.
+     * @param subscriptionId subscription ID see {@link SubscriptionInfo#getSubscriptionId()}
+     * @param merged True for carrier merged network, false otherwise.
+     *               See {@link WifiNetworkSuggestion.Builder#setCarrierMerged(boolean)}
+     * @return True to indicate that carrier network offload is enabled, false otherwise.
+     * @see #setCarrierNetworkOffloadEnabled(int, boolean, boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_SETUP_WIZARD})
+    public boolean isCarrierNetworkOffloadEnabled(int subscriptionId, boolean merged) {
+        if (!SdkLevel.isAtLeastS()) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            return mService.isCarrierNetworkOffloadEnabled(subscriptionId, merged);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
 }
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index e606d53..b7450c5 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -917,6 +917,9 @@
             mPasspointConfiguration.setCarrierId(mCarrierId);
             mPasspointConfiguration.setSubscriptionId(mSubscriptionId);
             mPasspointConfiguration.setMeteredOverride(wifiConfiguration.meteredOverride);
+            mPasspointConfiguration.setOemPrivate(mIsNetworkOemPrivate);
+            mPasspointConfiguration.setOemPaid(mIsNetworkOemPaid);
+            mPasspointConfiguration.setCarrierMerged(mIsCarrierMerged);
             wifiConfiguration.macRandomizationSetting = mIsEnhancedMacRandomizationEnabled
                     ? WifiConfiguration.RANDOMIZATION_ENHANCED
                     : WifiConfiguration.RANDOMIZATION_PERSISTENT;
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index e19b095..540bf2a 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -774,9 +774,13 @@
                                     (byte[]) msg.obj);
                             break;
                         case CALLBACK_MATCH_EXPIRED:
+                            if (!SdkLevel.isAtLeastS()) {
+                                break;
+                            }
                             mOriginalCallback
                                     .onServiceLost(new PeerHandle(msg.arg1),
                                             WIFI_AWARE_DISCOVERY_LOST_REASON_PEER_NOT_VISIBLE);
+                            break;
                     }
                 }
             };
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index 357c5bc..006fbaa 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -474,6 +474,27 @@
      */
     private boolean mIsEnhancedMacRandomizationEnabled = false;
 
+
+    /**
+     * Indicate whether the network is oem paid or not. Networks are considered oem paid
+     * if the corresponding connection is only available to system apps.
+     * @hide
+     */
+    private boolean mIsOemPaid;
+
+    /**
+     * Indicate whether the network is oem private or not. Networks are considered oem private
+     * if the corresponding connection is only available to system apps.
+     * @hide
+     */
+    private boolean mIsOemPrivate;
+
+    /**
+     * Indicate whether or not the network is a carrier merged network.
+     * @hide
+     */
+    private boolean mIsCarrierMerged;
+
     /**
      * Indicates if the end user has expressed an explicit opinion about the
      * meteredness of this network, such as through the Settings app.
@@ -589,6 +610,54 @@
     }
 
     /**
+     * Set whether the network is oem paid or not.
+     * @hide
+     */
+    public void setOemPaid(boolean isOemPaid) {
+        mIsOemPaid = isOemPaid;
+    }
+
+    /**
+     * Get whether the network is oem paid or not.
+     * @hide
+     */
+    public boolean isOemPaid() {
+        return mIsOemPaid;
+    }
+
+    /**
+     * Set whether the network is oem private or not.
+     * @hide
+     */
+    public void setOemPrivate(boolean isOemPrivate) {
+        mIsOemPrivate = isOemPrivate;
+    }
+
+    /**
+     * Get whether the network is oem private or not.
+     * @hide
+     */
+    public boolean isOemPrivate() {
+        return mIsOemPrivate;
+    }
+
+    /**
+     * Set whether the network is carrier merged or not.
+     * @hide
+     */
+    public void setCarrierMerged(boolean isCarrierMerged) {
+        mIsCarrierMerged = isCarrierMerged;
+    }
+
+    /**
+     * Get whether the network is carrier merged or not.
+     * @hide
+     */
+    public boolean isCarrierMerged() {
+        return mIsCarrierMerged;
+    }
+
+    /**
      * Constructor for creating PasspointConfiguration with default values.
      */
     public PasspointConfiguration() {}
@@ -635,6 +704,9 @@
         mIsMacRandomizationEnabled = source.mIsMacRandomizationEnabled;
         mIsEnhancedMacRandomizationEnabled = source.mIsEnhancedMacRandomizationEnabled;
         mMeteredOverride = source.mMeteredOverride;
+        mIsCarrierMerged = source.mIsCarrierMerged;
+        mIsOemPaid = source.mIsOemPaid;
+        mIsOemPrivate = source.mIsOemPrivate;
     }
 
     @Override
@@ -669,6 +741,9 @@
         dest.writeBoolean(mIsEnhancedMacRandomizationEnabled);
         dest.writeInt(mMeteredOverride);
         dest.writeInt(mSubscriptionId);
+        dest.writeBoolean(mIsCarrierMerged);
+        dest.writeBoolean(mIsOemPaid);
+        dest.writeBoolean(mIsOemPrivate);
     }
 
     @Override
@@ -700,6 +775,9 @@
                 && mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes
                 && mCarrierId == that.mCarrierId
                 && mSubscriptionId == that.mSubscriptionId
+                && mIsOemPrivate == that.mIsOemPrivate
+                && mIsOemPaid == that.mIsOemPaid
+                && mIsCarrierMerged == that.mIsCarrierMerged
                 && mIsAutojoinEnabled == that.mIsAutojoinEnabled
                 && mIsMacRandomizationEnabled == that.mIsMacRandomizationEnabled
                 && mIsEnhancedMacRandomizationEnabled == that.mIsEnhancedMacRandomizationEnabled
@@ -715,7 +793,8 @@
                 mSubscriptionExpirationTimeMillis, mUsageLimitUsageTimePeriodInMinutes,
                 mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes,
                 mServiceFriendlyNames, mCarrierId, mIsAutojoinEnabled, mIsMacRandomizationEnabled,
-                mIsEnhancedMacRandomizationEnabled, mMeteredOverride, mSubscriptionId);
+                mIsEnhancedMacRandomizationEnabled, mMeteredOverride, mSubscriptionId,
+                mIsCarrierMerged, mIsOemPaid, mIsOemPrivate);
     }
 
     @Override
@@ -774,6 +853,9 @@
         builder.append("mIsMacRandomizationEnabled:" + mIsMacRandomizationEnabled);
         builder.append("mIsEnhancedMacRandomizationEnabled:" + mIsEnhancedMacRandomizationEnabled);
         builder.append("mMeteredOverride:" + mMeteredOverride);
+        builder.append("mIsCarrierMerged:" + mIsCarrierMerged);
+        builder.append("mIsOemPaid:" + mIsOemPaid);
+        builder.append("mIsOemPrivate" + mIsOemPrivate);
         return builder.toString();
     }
 
@@ -884,6 +966,10 @@
                 config.mIsEnhancedMacRandomizationEnabled = in.readBoolean();
                 config.mMeteredOverride = in.readInt();
                 config.mSubscriptionId = in.readInt();
+                config.mIsCarrierMerged = in.readBoolean();
+                config.mIsOemPaid = in.readBoolean();
+                config.mIsOemPrivate = in.readBoolean();
+
                 return config;
             }
 
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 39f6f57..52e9139 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -136,6 +136,7 @@
     private static final String[] TEST_MAC_ADDRESSES = {"da:a1:19:0:0:0"};
     private static final int TEST_AP_FREQUENCY = 2412;
     private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ;
+    private static final int TEST_SUB_ID = 3;
 
     @Mock Context mContext;
     @Mock android.net.wifi.IWifiManager mWifiService;
@@ -2583,10 +2584,29 @@
 
     @Test
     public void testGetNetworkSuggestionUserApprovalStatus() throws Exception {
+        assumeTrue(SdkLevel.isAtLeastS());
+
         when(mWifiService.getNetworkSuggestionUserApprovalStatus(TEST_PACKAGE_NAME))
                 .thenReturn(WifiManager.STATUS_SUGGESTION_APPROVAL_APPROVED_BY_USER);
         assertEquals(WifiManager.STATUS_SUGGESTION_APPROVAL_APPROVED_BY_USER,
                 mWifiManager.getNetworkSuggestionUserApprovalStatus());
         verify(mWifiService).getNetworkSuggestionUserApprovalStatus(TEST_PACKAGE_NAME);
     }
+
+    @Test
+    public void testSetCarrierNetworkOffload() throws Exception {
+        assumeTrue(SdkLevel.isAtLeastS());
+        mWifiManager.setCarrierNetworkOffloadEnabled(TEST_SUB_ID, true, false);
+        verify(mWifiService).setCarrierNetworkOffloadEnabled(TEST_SUB_ID,
+                true, false);
+    }
+
+    @Test
+    public void testGetCarrierNetworkOffload() throws Exception {
+        assumeTrue(SdkLevel.isAtLeastS());
+        when(mWifiService.isCarrierNetworkOffloadEnabled(TEST_SUB_ID, false)).thenReturn(true);
+        assertTrue(mWifiManager.isCarrierNetworkOffloadEnabled(TEST_SUB_ID, false));
+        verify(mWifiService).isCarrierNetworkOffloadEnabled(TEST_SUB_ID, false);
+    }
+
 }
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index 643a78c..5e82918 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -809,7 +809,7 @@
     /**
      * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
      * when both {@link WifiNetworkSuggestion.Builder#setWpa3Passphrase(String)} and
-     * {@link WifiNetworkSuggestion.Builderi
+     * {@link WifiNetworkSuggestion.Builder
      * #setWpa3EnterpriseStandardModeConfig(WifiEnterpriseConfig)}
      * are invoked.
      */
@@ -1310,6 +1310,7 @@
                 .build();
         assertTrue(suggestion.isOemPaid());
         assertFalse(suggestion.isUserAllowedToManuallyConnect);
+        assertTrue(suggestion.getPasspointConfig().isOemPaid());
     }
 
     /**
@@ -1345,6 +1346,7 @@
                 .build();
         assertTrue(suggestion.isOemPrivate());
         assertFalse(suggestion.isUserAllowedToManuallyConnect);
+        assertTrue(suggestion.getPasspointConfig().isOemPrivate());
     }
 
     /**
@@ -1439,6 +1441,25 @@
     }
 
     /**
+     * Validate {@link WifiNetworkSuggestion.Builder#setCarrierMerged(boolean)} (boolean)} set the
+     * correct value to the passpoint network.
+     */
+    @Test
+    public void testSetCarrierMergedNetworkOnPasspointNetwork() {
+        assumeTrue(SdkLevel.isAtLeastS());
+
+        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
+        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+                .setPasspointConfig(passpointConfiguration)
+                .setSubscriptionId(1)
+                .setCarrierMerged(true)
+                .setIsMetered(true)
+                .build();
+        assertTrue(suggestion.isCarrierMerged());
+        assertTrue(suggestion.getPasspointConfig().isCarrierMerged());
+    }
+
+    /**
      * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
      * when set both {@link WifiNetworkSuggestion.Builder#setCarrierMerged(boolean)} (boolean)}
      * to true on a network is not metered.
