Merge "[VCN20] Change requestBackgroundNetwork argument order"
diff --git a/Android.bp b/Android.bp
index 1415b6a..084c9f5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -252,11 +252,6 @@
     installable: false,
 }
 
-filegroup {
-    name: "framework-jarjar-rules",
-    srcs: ["framework-jarjar-rules.txt"],
-}
-
 java_library {
     name: "framework-minus-apex",
     defaults: ["framework-aidl-export-defaults"],
@@ -273,7 +268,7 @@
         "--multi-dex",
     ],
     installable: true,
-    jarjar_rules: ":framework-jarjar-rules",
+    jarjar_rules: "framework-jarjar-rules.txt",
     javac_shard_size: 150,
     plugins: [
         "view-inspector-annotation-processor",
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 33fd399..f67174a 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -17,7 +17,7 @@
 
 strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT}
 
-hidden_api_txt_checksorted_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
+hidden_api_txt_checksorted_hook = ${REPO_ROOT}/tools/platform-compat/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
 
 hidden_api_txt_exclude_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/exclude.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
 
diff --git a/StubLibraries.bp b/StubLibraries.bp
index ae92e79..3f4e689 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -93,6 +93,8 @@
     ],
     api_levels_annotations_enabled: false,
     filter_packages: packages_to_document,
+    defaults_visibility: ["//visibility:private"],
+    visibility: ["//frameworks/base/api"],
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -120,13 +122,19 @@
     },
     dists: [
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/public/api",
             dest: "android-non-updatable.txt",
             tag: ".api.txt",
         },
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/public/api",
             dest: "android-non-updatable-removed.txt",
             tag: ".removed-api.txt",
@@ -134,21 +142,18 @@
     ],
 }
 
-priv_apps =
-    " --show-annotation android.annotation.SystemApi\\(" +
-        "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" +
+priv_apps = " --show-annotation android.annotation.SystemApi\\(" +
+    "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" +
     "\\)"
 
-priv_apps_in_stubs =
-    " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" +
-        "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" +
+priv_apps_in_stubs = " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" +
+    "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" +
     "\\)"
 
 test = " --show-annotation android.annotation.TestApi"
 
-module_libs =
-    " --show-annotation android.annotation.SystemApi\\(" +
-        "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" +
+module_libs = " --show-annotation android.annotation.SystemApi\\(" +
+    "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" +
     "\\)"
 
 droidstubs {
@@ -163,7 +168,7 @@
         last_released: {
             api_file: ":android-non-updatable.api.system.latest",
             removed_api_file: ":android-non-updatable-removed.api.system.latest",
-            baseline_file: ":android-non-updatable-incompatibilities.api.system.latest"
+            baseline_file: ":android-non-updatable-incompatibilities.api.system.latest",
         },
         api_lint: {
             enabled: true,
@@ -173,13 +178,19 @@
     },
     dists: [
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/system/api",
             dest: "android-non-updatable.txt",
             tag: ".api.txt",
         },
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/system/api",
             dest: "android-non-updatable-removed.txt",
             tag: ".removed-api.txt",
@@ -203,25 +214,37 @@
     },
     dists: [
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/test/api",
             dest: "android.txt",
             tag: ".api.txt",
         },
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/test/api",
             dest: "removed.txt",
             tag: ".removed-api.txt",
         },
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/test/api",
             dest: "android-non-updatable.txt",
             tag: ".api.txt",
         },
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/test/api",
             dest: "android-non-updatable-removed.txt",
             tag: ".removed-api.txt",
@@ -249,13 +272,19 @@
     },
     dists: [
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/module-lib/api",
             dest: "android-non-updatable.txt",
             tag: ".api.txt",
         },
         {
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             dir: "apistubs/android/module-lib/api",
             dest: "android-non-updatable-removed.txt",
             tag: ".removed-api.txt",
@@ -307,10 +336,15 @@
     java_version: "1.8",
     compile_dex: true,
     dist: {
-        targets: ["sdk", "win_sdk"],
+        targets: [
+            "sdk",
+            "win_sdk",
+        ],
         tag: ".jar",
         dest: "android-non-updatable.jar",
-    }
+    },
+    defaults_visibility: ["//visibility:private"],
+    visibility: ["//visibility:private"],
 }
 
 java_library_static {
@@ -326,7 +360,7 @@
 java_library_static {
     name: "android-non-updatable.stubs.system",
     defaults: ["android-non-updatable_defaults_stubs_current"],
-    srcs: [ ":system-api-stubs-docs-non-updatable" ],
+    srcs: [":system-api-stubs-docs-non-updatable"],
     libs: modules_system_stubs,
     dist: {
         dir: "apistubs/android/system",
@@ -364,15 +398,21 @@
     system_modules: "none",
     java_version: "1.8",
     compile_dex: true,
+    defaults_visibility: ["//visibility:private"],
+    visibility: ["//visibility:public"],
 }
 
 java_defaults {
     name: "android_stubs_dists_default",
     dist: {
-        targets: ["sdk", "win_sdk"],
+        targets: [
+            "sdk",
+            "win_sdk",
+        ],
         tag: ".jar",
         dest: "android.jar",
     },
+    defaults_visibility: ["//frameworks/base/services"],
 }
 
 java_library_static {
@@ -400,7 +440,10 @@
     dists: [
         {
             // Legacy dist path
-            targets: ["sdk", "win_sdk"],
+            targets: [
+                "sdk",
+                "win_sdk",
+            ],
             tag: ".jar",
             dest: "android_system.jar",
         },
@@ -422,14 +465,6 @@
     dist: {
         dir: "apistubs/android/test",
     },
-    dists: [
-        {
-            // Legacy dist path
-            targets: ["sdk", "win_sdk"],
-            tag: ".jar",
-            dest: "android_test.jar",
-        },
-    ],
 }
 
 java_library_static {
@@ -477,6 +512,7 @@
         "metalava-manual",
     ],
     args: priv_apps,
+    visibility: ["//visibility:private"],
 }
 
 java_library_static {
@@ -486,4 +522,5 @@
     srcs: [
         ":hwbinder-stubs-docs",
     ],
+    visibility: ["//visibility:public"],
 }
diff --git a/apex/media/framework/lint-baseline.xml b/apex/media/framework/lint-baseline.xml
new file mode 100644
index 0000000..29adf1d
--- /dev/null
+++ b/apex/media/framework/lint-baseline.xml
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#mediaFormat`"
+        errorLine1="            this.mediaFormat = mediaFormat;"
+        errorLine2="            ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="271"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#drmInitData`"
+        errorLine1="            this.drmInitData = drmInitData;"
+        errorLine2="            ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="272"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+        errorLine1="            this.timeMicros = timeMicros;"
+        errorLine2="            ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="293"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+        errorLine1="            this.position = position;"
+        errorLine2="            ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="294"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+        errorLine1="            return &quot;[timeMicros=&quot; + timeMicros + &quot;, position=&quot; + position + &quot;]&quot;;"
+        errorLine2="                                                                 ~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="300"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+        errorLine1="            return &quot;[timeMicros=&quot; + timeMicros + &quot;, position=&quot; + position + &quot;]&quot;;"
+        errorLine2="                                    ~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="300"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level R (current min is 29): `android.media.MediaParser.SeekPoint`"
+        errorLine1="            SeekPoint other = (SeekPoint) obj;"
+        errorLine2="                               ~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="311"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+        errorLine1="            return timeMicros == other.timeMicros &amp;&amp; position == other.position;"
+        errorLine2="                                                     ~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="312"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+        errorLine1="            return timeMicros == other.timeMicros &amp;&amp; position == other.position;"
+        errorLine2="                                                                 ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="312"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+        errorLine1="            return timeMicros == other.timeMicros &amp;&amp; position == other.position;"
+        errorLine2="                   ~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="312"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+        errorLine1="            return timeMicros == other.timeMicros &amp;&amp; position == other.position;"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="312"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+        errorLine1="            int result = (int) timeMicros;"
+        errorLine2="                               ~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="317"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+        errorLine1="            result = 31 * result + (int) position;"
+        errorLine2="                                         ~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="318"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`"
+        errorLine1="    public interface SeekableInputReader extends InputReader {"
+        errorLine2="                                                 ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="350"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `SeekableInputReader` to `InputReader` requires API level 30 (current min is 29)"
+        errorLine1="        mExoDataReader.mInputReader = seekableInputReader;"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="1198"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+        errorLine1="            mPendingSeekPosition = seekPoint.position;"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="1284"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+        errorLine1="            mPendingSeekTimeMicros = seekPoint.timeMicros;"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="1285"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
+        errorLine1="            mExtractor.seek(seekPoint.position, seekPoint.timeMicros);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="1287"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
+        errorLine1="            mExtractor.seek(seekPoint.position, seekPoint.timeMicros);"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="1287"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level R (current min is 29): `android.media.DrmInitData.SchemeInitData#uuid`"
+        errorLine1="                if (schemeInitData.uuid.equals(schemeUuid)) {"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="1566"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`"
+        errorLine1="    private static final class DataReaderAdapter implements InputReader {"
+        errorLine2="                                                            ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="1859"
+            column="61"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`"
+        errorLine1="    private static final class ParsableByteArrayAdapter implements InputReader {"
+        errorLine2="                                                                   ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
+            line="1892"
+            column="68"/>
+    </issue>
+
+</issues>
diff --git a/boot/hiddenapi/OWNERS b/boot/hiddenapi/OWNERS
index 5d869fc..74a3dc0 100644
--- a/boot/hiddenapi/OWNERS
+++ b/boot/hiddenapi/OWNERS
@@ -1,7 +1,5 @@
 # compat-team@ for changes to hiddenapi files
-andreionea@google.com
-mathewi@google.com
-satayev@google.com
+file:tools/platform-compat:/OWNERS
 
 # Escalations:
 per-file hiddenapi-* = bdc@google.com, narayan@google.com
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
new file mode 100644
index 0000000..99c39f6
--- /dev/null
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -0,0 +1,392 @@
+/*
+ * 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, bool useUids) {
+    std::lock_guard<std::mutex> _l(mLock);
+    return PullLocked(tagId, configKey, eventTimeNs, data, useUids);
+}
+
+bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
+                              vector<std::shared_ptr<LogEvent>>* data, bool useUids) {
+    std::lock_guard<std::mutex> _l(mLock);
+    return PullLocked(tagId, uids, eventTimeNs, data, useUids);
+}
+
+bool StatsPullerManager::PullLocked(int tagId, const ConfigKey& configKey,
+                                    const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
+                                    bool useUids) {
+    vector<int32_t> uids;
+    if (useUids) {
+        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, useUids);
+}
+
+bool StatsPullerManager::PullLocked(int tagId, const vector<int32_t>& uids,
+                                    const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
+                                    bool useUids) {
+    VLOG("Initiating pulling %d", tagId);
+    if (useUids) {
+        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.
+    } else {
+        PullerKey key = {.atomTag = tagId, .uid = -1};
+        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;
+        }
+        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,
+                                                  bool useUid) {
+    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 = useUid ? uid : -1};
+    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,
+                                                    bool useUids) {
+    std::lock_guard<std::mutex> _l(mLock);
+    PullerKey key = {.atomTag = atomTag, .uid = useUids ? uid : -1};
+    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/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
new file mode 100644
index 0000000..4f03172
--- /dev/null
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -0,0 +1,618 @@
+/*
+ * 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 <log/log.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);
+    }
+
+    if (mValues.size() - 1 > INT8_MAX) {
+        mValid = false;
+    } else if (mValues.size() - 1 > firstUidInChainIndex) {
+        // At least one node was successfully parsed.
+        mAttributionChainStartIndex = static_cast<int8_t>(firstUidInChainIndex);
+        mAttributionChainEndIndex = static_cast<int8_t>(mValues.size() - 1);
+    }
+
+    if (mValid) {
+        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() || mValues.size() - 1 > INT8_MAX || !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;
+    }
+
+    if (static_cast<int>(mValues.size() - 1) < firstUidInChainIndex) { // AttributionChain is empty.
+        mValid = false;
+        android_errorWriteLog(0x534e4554, "174485572");
+        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;
+    }
+
+    if (mValues.size() - 1 > INT8_MAX) {
+        android_errorWriteLog(0x534e4554, "174488848");
+        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/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
new file mode 100644
index 0000000..aed2547
--- /dev/null
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -0,0 +1,481 @@
+// 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/base/cmds/statsd/src/atoms.pb.h"
+#include "frameworks/base/core/proto/android/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);
+}
+
+TEST(LogEventTest, TestExclusiveStateAnnotationAfterTooManyFields) {
+    AStatsEvent* event = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(event, 100);
+
+    const unsigned int numAttributionNodes = 64;
+
+    uint32_t uids[numAttributionNodes];
+    const char* tags[numAttributionNodes];
+
+    for (unsigned int i = 1; i <= numAttributionNodes; i++) {
+        uids[i-1] = i;
+        tags[i-1] = std::to_string(i).c_str();
+    }
+
+    AStatsEvent_writeAttributionChain(event, uids, tags, numAttributionNodes);
+    AStatsEvent_writeInt32(event, 1);
+    AStatsEvent_addBoolAnnotation(event, ANNOTATION_ID_EXCLUSIVE_STATE, true);
+
+    AStatsEvent_build(event);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
+
+    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
+    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
+    EXPECT_EQ(-1, logEvent.getExclusiveStateFieldIndex());
+
+    AStatsEvent_release(event);
+}
+
+TEST(LogEventTest, TestUidAnnotationAfterTooManyFields) {
+    AStatsEvent* event = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(event, 100);
+
+    const unsigned int numAttributionNodes = 64;
+
+    uint32_t uids[numAttributionNodes];
+    const char* tags[numAttributionNodes];
+
+    for (unsigned int i = 1; i <= numAttributionNodes; i++) {
+        uids[i-1] = i;
+        tags[i-1] = std::to_string(i).c_str();
+    }
+
+    AStatsEvent_writeAttributionChain(event, uids, tags, numAttributionNodes);
+    AStatsEvent_writeInt32(event, 1);
+    AStatsEvent_addBoolAnnotation(event, ANNOTATION_ID_IS_UID, true);
+
+    AStatsEvent_build(event);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
+
+    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
+    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
+    EXPECT_EQ(-1, logEvent.getUidFieldIndex());
+
+    AStatsEvent_release(event);
+}
+
+TEST(LogEventTest, TestAttributionChainEndIndexAfterTooManyFields) {
+    AStatsEvent* event = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(event, 100);
+
+    const unsigned int numAttributionNodes = 65;
+
+    uint32_t uids[numAttributionNodes];
+    const char* tags[numAttributionNodes];
+
+    for (unsigned int i = 1; i <= numAttributionNodes; i++) {
+        uids[i-1] = i;
+        tags[i-1] = std::to_string(i).c_str();
+    }
+
+    AStatsEvent_writeAttributionChain(event, uids, tags, numAttributionNodes);
+
+    AStatsEvent_build(event);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
+
+    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
+    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
+    EXPECT_FALSE(logEvent.hasAttributionChain());
+
+    AStatsEvent_release(event);
+}
+
+TEST(LogEventTest, TestEmptyAttributionChainWithPrimaryFieldFirstUidAnnotation) {
+    AStatsEvent* event = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(event, 100);
+
+    uint32_t uids[] = {};
+    const char* tags[] = {};
+
+    AStatsEvent_writeInt32(event, 10);
+    AStatsEvent_writeAttributionChain(event, uids, tags, 0);
+    AStatsEvent_addBoolAnnotation(event, ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true);
+
+    AStatsEvent_build(event);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
+
+    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
+    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
+
+    AStatsEvent_release(event);
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index e7a7fd2..b1e3e14 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -98,7 +98,7 @@
   }
 
   public class VpnManager {
-    field @Deprecated public static final int TYPE_VPN_LEGACY = 3; // 0x3
+    field public static final int TYPE_VPN_LEGACY = 3; // 0x3
     field public static final int TYPE_VPN_NONE = -1; // 0xffffffff
     field public static final int TYPE_VPN_OEM = 4; // 0x4
     field public static final int TYPE_VPN_PLATFORM = 2; // 0x2
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 1102a0d..9e82cfb 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1502,6 +1502,8 @@
   }
 
   public static interface BluetoothAdapter.OobDataCallback {
+    method public void onError(int);
+    method public void onOobData(int, @Nullable android.bluetooth.OobData);
   }
 
   public final class BluetoothDevice implements android.os.Parcelable {
@@ -6099,10 +6101,6 @@
 
 package android.net {
 
-  public class DnsResolverServiceManager {
-    method @NonNull @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public static android.os.IBinder getService(@NonNull android.content.Context);
-  }
-
   public class EthernetManager {
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
   }
@@ -6735,16 +6733,16 @@
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
-    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnStateCallback);
+    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean);
     method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
-    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnStateCallback(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnStateCallback);
+    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
     field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
   }
 
-  public static interface NfcAdapter.ControllerAlwaysOnStateCallback {
-    method public void onStateChanged(boolean);
+  public static interface NfcAdapter.ControllerAlwaysOnListener {
+    method public void onControllerAlwaysOnChanged(boolean);
   }
 
   public static interface NfcAdapter.NfcUnlockHandler {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index f7b101d..fd6d47e 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1009,6 +1009,10 @@
     method public static void setServiceForTest(@Nullable android.os.IBinder);
   }
 
+  public class NetworkWatchlistManager {
+    method @Nullable public byte[] getWatchlistConfigHash();
+  }
+
   public class TrafficStats {
     method public static long getLoopbackRxBytes();
     method public static long getLoopbackRxPackets();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 694c519..c4cdbbc 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -7636,8 +7636,8 @@
                 } else if (collectionMode == COLLECT_SYNC
                         // Only collect app-ops when the proxy is trusted
                         && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
-                        myUid) == PackageManager.PERMISSION_GRANTED
-                        || isTrustedVoiceServiceProxy(mContext, mContext.getOpPackageName(), op))) {
+                        myUid) == PackageManager.PERMISSION_GRANTED || isTrustedVoiceServiceProxy(
+                        mContext, mContext.getOpPackageName(), op, mContext.getUserId()))) {
                     collectNotedOpSync(op, proxiedAttributionTag);
                 }
             }
@@ -7655,7 +7655,7 @@
      * @hide
      */
     public static boolean isTrustedVoiceServiceProxy(Context context, String packageName,
-            int code) {
+            int code, int userId) {
         // This is a workaround for R QPR, new API change is not allowed. We only allow the current
         // voice recognizer is also the voice interactor to noteproxy op.
         if (code != OP_RECORD_AUDIO) {
@@ -7667,7 +7667,7 @@
         final String voiceRecognitionServicePackageName =
                 getComponentPackageNameFromString(voiceRecognitionComponent);
         return (Objects.equals(packageName, voiceRecognitionServicePackageName))
-                && isPackagePreInstalled(context, packageName);
+                && isPackagePreInstalled(context, packageName, userId);
     }
 
     private static String getComponentPackageNameFromString(String from) {
@@ -7675,10 +7675,10 @@
         return componentName != null ? componentName.getPackageName() : "";
     }
 
-    private static boolean isPackagePreInstalled(Context context, String packageName) {
+    private static boolean isPackagePreInstalled(Context context, String packageName, int userId) {
         try {
             final PackageManager pm = context.getPackageManager();
-            final ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
+            final ApplicationInfo info = pm.getApplicationInfoAsUser(packageName, 0, userId);
             return ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
         } catch (PackageManager.NameNotFoundException e) {
             return false;
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index 854f5a4..87f48c0 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -614,7 +614,7 @@
      * tombstone traces will be returned for
      * {@link #REASON_CRASH_NATIVE}, with an InputStream containing a protobuf with
      * <a href="https://android.googlesource.com/platform/system/core/+/refs/heads/master/debuggerd/proto/tombstone.proto">this schema</a>.
-     * Note thatbecause these traces are kept in a separate global circular buffer, crashes may be
+     * Note that because these traces are kept in a separate global circular buffer, crashes may be
      * overwritten by newer crashes (including from other applications), so this may still return
      * null.
      *
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 7d62327..3802289 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -3062,8 +3062,6 @@
          *
          * @param transport - whether the {@link OobData} is generated for LE or Classic.
          * @param oobData - data generated in the host stack(LE) or controller (Classic)
-         *
-         * @hide
          */
         void onOobData(@Transport int transport, @Nullable OobData oobData);
 
@@ -3071,8 +3069,6 @@
          * Provides feedback when things don't go as expected.
          *
          * @param errorCode - the code descibing the type of error that occurred.
-         *
-         * @hide
          */
         void onError(@OobError int errorCode);
     }
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
index 08d694e..d6868e0 100644
--- a/core/java/android/bluetooth/OobData.java
+++ b/core/java/android/bluetooth/OobData.java
@@ -830,7 +830,7 @@
     @Nullable
     @SystemApi
     public byte[] getLeAppearance() {
-        return mLeTemporaryKey;
+        return mLeAppearance;
     }
 
     /**
diff --git a/core/java/android/net/DnsResolverServiceManager.java b/core/java/android/net/DnsResolverServiceManager.java
deleted file mode 100644
index 1597322..0000000
--- a/core/java/android/net/DnsResolverServiceManager.java
+++ /dev/null
@@ -1,63 +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.net;
-
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.ServiceManager;
-
-import java.util.Objects;
-
-/**
- * Provides a way to obtain the DnsResolver binder objects.
- *
- * @hide
- */
-@SystemApi
-public class DnsResolverServiceManager {
-    /**
-     * Name to retrieve a {@link android.net.IDnsResolver} IBinder.
-     */
-    private static final String DNS_RESOLVER_SERVICE = "dnsresolver";
-
-    private DnsResolverServiceManager() {}
-
-    /**
-     * Get an {@link IBinder} representing the DnsResolver stable AIDL interface
-     *
-     * @param context the context for permission check.
-     * @return {@link android.net.IDnsResolver} IBinder.
-     */
-    @NonNull
-    @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
-    public static IBinder getService(@NonNull final Context context) {
-        Objects.requireNonNull(context);
-        context.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
-                "DnsResolverServiceManager");
-        try {
-            return ServiceManager.getServiceOrThrow(DNS_RESOLVER_SERVICE);
-        } catch (ServiceManager.ServiceNotFoundException e) {
-            // Catch ServiceManager#ServiceNotFoundException and rethrow IllegalStateException
-            // because ServiceManager#ServiceNotFoundException is @hide so that it can't be listed
-            // on the system api. Thus, rethrow IllegalStateException if dns resolver service cannot
-            // be found.
-            throw new IllegalStateException("Cannot find dns resolver service.");
-        }
-    }
-}
diff --git a/core/java/android/net/NetworkWatchlistManager.java b/core/java/android/net/NetworkWatchlistManager.java
index 8f6510e..da01dcb 100644
--- a/core/java/android/net/NetworkWatchlistManager.java
+++ b/core/java/android/net/NetworkWatchlistManager.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -31,6 +32,7 @@
  * Class that manage network watchlist in system.
  * @hide
  */
+@TestApi
 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
 @SystemService(Context.NETWORK_WATCHLIST_SERVICE)
 public class NetworkWatchlistManager {
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index 5f65d46..662ebb3 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -78,10 +78,8 @@
 
     /**
      * An IPsec VPN created by the built-in LegacyVpnRunner.
-     * @deprecated new Android devices should use VPN_TYPE_PLATFORM instead.
      * @hide
      */
-    @Deprecated
     @SystemApi(client = MODULE_LIBRARIES)
     public static final int TYPE_VPN_LEGACY = 3;
 
@@ -418,4 +416,4 @@
             throw e.rethrowFromSystemServer();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index d5cc01a..cb9a3e4 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -24,7 +24,7 @@
 import android.nfc.TechListParcel;
 import android.nfc.IAppCallback;
 import android.nfc.INfcAdapterExtras;
-import android.nfc.INfcControllerAlwaysOnStateCallback;
+import android.nfc.INfcControllerAlwaysOnListener;
 import android.nfc.INfcTag;
 import android.nfc.INfcCardEmulation;
 import android.nfc.INfcFCardEmulation;
@@ -76,6 +76,6 @@
     boolean setControllerAlwaysOn(boolean value);
     boolean isControllerAlwaysOn();
     boolean isControllerAlwaysOnSupported();
-    void registerControllerAlwaysOnStateCallback(in INfcControllerAlwaysOnStateCallback callback);
-    void unregisterControllerAlwaysOnStateCallback(in INfcControllerAlwaysOnStateCallback callback);
+    void registerControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
+    void unregisterControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
 }
diff --git a/core/java/android/nfc/INfcControllerAlwaysOnStateCallback.aidl b/core/java/android/nfc/INfcControllerAlwaysOnListener.aidl
similarity index 87%
rename from core/java/android/nfc/INfcControllerAlwaysOnStateCallback.aidl
rename to core/java/android/nfc/INfcControllerAlwaysOnListener.aidl
index 1e4fdd7..1bb7680 100644
--- a/core/java/android/nfc/INfcControllerAlwaysOnStateCallback.aidl
+++ b/core/java/android/nfc/INfcControllerAlwaysOnListener.aidl
@@ -19,11 +19,11 @@
 /**
  * @hide
  */
-oneway interface INfcControllerAlwaysOnStateCallback {
+oneway interface INfcControllerAlwaysOnListener {
   /**
    * Called whenever the controller always on state changes
    *
    * @param isEnabled true if the state is enabled, false otherwise
    */
-  void onControllerAlwaysOnStateChanged(boolean isEnabled);
+  void onControllerAlwaysOnChanged(boolean isEnabled);
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index bbf802c..64c1211 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -67,7 +67,7 @@
 public final class NfcAdapter {
     static final String TAG = "NFC";
 
-    private final NfcControllerAlwaysOnStateListener mControllerAlwaysOnStateListener;
+    private final NfcControllerAlwaysOnListener mControllerAlwaysOnListener;
 
     /**
      * Intent to start an activity when a tag with NDEF payload is discovered.
@@ -418,19 +418,19 @@
     }
 
     /**
-     * A callback to be invoked when NFC controller always on state changes.
-     * <p>Register your {@code ControllerAlwaysOnStateCallback} implementation with {@link
-     * NfcAdapter#registerControllerAlwaysOnStateCallback} and disable it with {@link
-     * NfcAdapter#unregisterControllerAlwaysOnStateCallback}.
-     * @see #registerControllerAlwaysOnStateCallback
+     * A listener to be invoked when NFC controller always on state changes.
+     * <p>Register your {@code ControllerAlwaysOnListener} implementation with {@link
+     * NfcAdapter#registerControllerAlwaysOnListener} and disable it with {@link
+     * NfcAdapter#unregisterControllerAlwaysOnListener}.
+     * @see #registerControllerAlwaysOnListener
      * @hide
      */
     @SystemApi
-    public interface ControllerAlwaysOnStateCallback {
+    public interface ControllerAlwaysOnListener {
         /**
          * Called on NFC controller always on state changes
          */
-        void onStateChanged(boolean isEnabled);
+        void onControllerAlwaysOnChanged(boolean isEnabled);
     }
 
     /**
@@ -748,7 +748,7 @@
         mNfcUnlockHandlers = new HashMap<NfcUnlockHandler, INfcUnlockHandler>();
         mTagRemovedListener = null;
         mLock = new Object();
-        mControllerAlwaysOnStateListener = new NfcControllerAlwaysOnStateListener(getService());
+        mControllerAlwaysOnListener = new NfcControllerAlwaysOnListener(getService());
     }
 
     /**
@@ -2246,12 +2246,12 @@
      * <p>This API is for the NFCC internal state management. It allows to discriminate
      * the controller function from the NFC function by keeping the NFC controller on without
      * any NFC RF enabled if necessary.
-     * <p>This call is asynchronous. Register a callback {@link #ControllerAlwaysOnStateCallback}
-     * by {@link #registerControllerAlwaysOnStateCallback} to find out when the operation is
+     * <p>This call is asynchronous. Register a listener {@link #ControllerAlwaysOnListener}
+     * by {@link #registerControllerAlwaysOnListener} to find out when the operation is
      * complete.
      * <p>If this returns true, then either NFCC always on state has been set based on the value,
-     * or a {@link ControllerAlwaysOnStateCallback#onStateChanged(boolean)} will be invoked to
-     * indicate the state change.
+     * or a {@link ControllerAlwaysOnListener#onControllerAlwaysOnChanged(boolean)} will be invoked
+     * to indicate the state change.
      * If this returns false, then there is some problem that prevents an attempt to turn NFCC
      * always on.
      * @param value if true the NFCC will be kept on (with no RF enabled if NFC adapter is
@@ -2344,37 +2344,37 @@
     }
 
     /**
-     * Register a {@link ControllerAlwaysOnStateCallback} to listen for NFC controller always on
+     * Register a {@link ControllerAlwaysOnListener} to listen for NFC controller always on
      * state changes
-     * <p>The provided callback will be invoked by the given {@link Executor}.
+     * <p>The provided listener will be invoked by the given {@link Executor}.
      *
-     * @param executor an {@link Executor} to execute given callback
-     * @param callback user implementation of the {@link ControllerAlwaysOnStateCallback}
+     * @param executor an {@link Executor} to execute given listener
+     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public void registerControllerAlwaysOnStateCallback(
+    public void registerControllerAlwaysOnListener(
             @NonNull @CallbackExecutor Executor executor,
-            @NonNull ControllerAlwaysOnStateCallback callback) {
-        mControllerAlwaysOnStateListener.register(executor, callback);
+            @NonNull ControllerAlwaysOnListener listener) {
+        mControllerAlwaysOnListener.register(executor, listener);
     }
 
     /**
-     * Unregister the specified {@link ControllerAlwaysOnStateCallback}
-     * <p>The same {@link ControllerAlwaysOnStateCallback} object used when calling
-     * {@link #registerControllerAlwaysOnStateCallback(Executor, ControllerAlwaysOnStateCallback)}
+     * Unregister the specified {@link ControllerAlwaysOnListener}
+     * <p>The same {@link ControllerAlwaysOnListener} object used when calling
+     * {@link #registerControllerAlwaysOnListener(Executor, ControllerAlwaysOnListener)}
      * must be used.
      *
-     * <p>Callbacks are automatically unregistered when application process goes away
+     * <p>Listeners are automatically unregistered when application process goes away
      *
-     * @param callback user implementation of the {@link ControllerAlwaysOnStateCallback}
+     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public void unregisterControllerAlwaysOnStateCallback(
-            @NonNull ControllerAlwaysOnStateCallback callback) {
-        mControllerAlwaysOnStateListener.unregister(callback);
+    public void unregisterControllerAlwaysOnListener(
+            @NonNull ControllerAlwaysOnListener listener) {
+        mControllerAlwaysOnListener.unregister(listener);
     }
 }
diff --git a/core/java/android/nfc/NfcControllerAlwaysOnListener.java b/core/java/android/nfc/NfcControllerAlwaysOnListener.java
new file mode 100644
index 0000000..96707bb
--- /dev/null
+++ b/core/java/android/nfc/NfcControllerAlwaysOnListener.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.nfc;
+
+import android.annotation.NonNull;
+import android.nfc.NfcAdapter.ControllerAlwaysOnListener;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * @hide
+ */
+public class NfcControllerAlwaysOnListener extends INfcControllerAlwaysOnListener.Stub {
+    private static final String TAG = NfcControllerAlwaysOnListener.class.getSimpleName();
+
+    private final INfcAdapter mAdapter;
+
+    private final Map<ControllerAlwaysOnListener, Executor> mListenerMap = new HashMap<>();
+
+    private boolean mCurrentState = false;
+    private boolean mIsRegistered = false;
+
+    public NfcControllerAlwaysOnListener(@NonNull INfcAdapter adapter) {
+        mAdapter = adapter;
+    }
+
+    /**
+     * Register a {@link ControllerAlwaysOnListener} with this
+     * {@link NfcControllerAlwaysOnListener}
+     *
+     * @param executor an {@link Executor} to execute given listener
+     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
+     */
+    public void register(@NonNull Executor executor,
+            @NonNull ControllerAlwaysOnListener listener) {
+        synchronized (this) {
+            if (mListenerMap.containsKey(listener)) {
+                return;
+            }
+
+            mListenerMap.put(listener, executor);
+            if (!mIsRegistered) {
+                try {
+                    mAdapter.registerControllerAlwaysOnListener(this);
+                    mIsRegistered = true;
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Failed to register");
+                }
+            }
+        }
+    }
+
+    /**
+     * Unregister the specified {@link ControllerAlwaysOnListener}
+     *
+     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
+     */
+    public void unregister(@NonNull ControllerAlwaysOnListener listener) {
+        synchronized (this) {
+            if (!mListenerMap.containsKey(listener)) {
+                return;
+            }
+
+            mListenerMap.remove(listener);
+
+            if (mListenerMap.isEmpty() && mIsRegistered) {
+                try {
+                    mAdapter.unregisterControllerAlwaysOnListener(this);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Failed to unregister");
+                }
+                mIsRegistered = false;
+            }
+        }
+    }
+
+    private void sendCurrentState(@NonNull ControllerAlwaysOnListener listener) {
+        synchronized (this) {
+            Executor executor = mListenerMap.get(listener);
+
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                executor.execute(() -> listener.onControllerAlwaysOnChanged(
+                        mCurrentState));
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+    }
+
+    @Override
+    public void onControllerAlwaysOnChanged(boolean isEnabled) {
+        synchronized (this) {
+            mCurrentState = isEnabled;
+            for (ControllerAlwaysOnListener cb : mListenerMap.keySet()) {
+                sendCurrentState(cb);
+            }
+        }
+    }
+}
+
diff --git a/core/java/android/nfc/NfcControllerAlwaysOnStateListener.java b/core/java/android/nfc/NfcControllerAlwaysOnStateListener.java
deleted file mode 100644
index 69a9ec7..0000000
--- a/core/java/android/nfc/NfcControllerAlwaysOnStateListener.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.ControllerAlwaysOnStateCallback;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public class NfcControllerAlwaysOnStateListener extends INfcControllerAlwaysOnStateCallback.Stub {
-    private static final String TAG = "NfcControllerAlwaysOnStateListener";
-
-    private final INfcAdapter mAdapter;
-
-    private final Map<ControllerAlwaysOnStateCallback, Executor> mCallbackMap = new HashMap<>();
-
-    private boolean mCurrentState = false;
-    private boolean mIsRegistered = false;
-
-    public NfcControllerAlwaysOnStateListener(@NonNull INfcAdapter adapter) {
-        mAdapter = adapter;
-    }
-
-    /**
-     * Register a {@link ControllerAlwaysOnStateCallback} with this
-     * {@link NfcControllerAlwaysOnStateListener}
-     *
-     * @param executor an {@link Executor} to execute given callback
-     * @param callback user implementation of the {@link ControllerAlwaysOnStateCallback}
-     */
-    public void register(@NonNull Executor executor,
-            @NonNull ControllerAlwaysOnStateCallback callback) {
-        synchronized (this) {
-            if (mCallbackMap.containsKey(callback)) {
-                return;
-            }
-
-            mCallbackMap.put(callback, executor);
-            if (!mIsRegistered) {
-                try {
-                    mAdapter.registerControllerAlwaysOnStateCallback(this);
-                    mIsRegistered = true;
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to register ControllerAlwaysOnStateListener");
-                }
-            }
-        }
-    }
-
-    /**
-     * Unregister the specified {@link ControllerAlwaysOnStateCallback}
-     *
-     * @param callback user implementation of the {@link ControllerAlwaysOnStateCallback}
-     */
-    public void unregister(@NonNull ControllerAlwaysOnStateCallback callback) {
-        synchronized (this) {
-            if (!mCallbackMap.containsKey(callback)) {
-                return;
-            }
-
-            mCallbackMap.remove(callback);
-
-            if (mCallbackMap.isEmpty() && mIsRegistered) {
-                try {
-                    mAdapter.unregisterControllerAlwaysOnStateCallback(this);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to unregister ControllerAlwaysOnStateListener");
-                }
-                mIsRegistered = false;
-            }
-        }
-    }
-
-    private void sendCurrentState(@NonNull ControllerAlwaysOnStateCallback callback) {
-        synchronized (this) {
-            Executor executor = mCallbackMap.get(callback);
-
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                executor.execute(() -> callback.onStateChanged(
-                        mCurrentState));
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void onControllerAlwaysOnStateChanged(boolean isEnabled) {
-        synchronized (this) {
-            mCurrentState = isEnabled;
-            for (ControllerAlwaysOnStateCallback cb : mCallbackMap.keySet()) {
-                sendCurrentState(cb);
-            }
-        }
-    }
-}
-
diff --git a/core/java/android/nfc/TEST_MAPPING b/core/java/android/nfc/TEST_MAPPING
new file mode 100644
index 0000000..71ad687
--- /dev/null
+++ b/core/java/android/nfc/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "NfcManagerTests"
+    }
+  ]
+}
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index a42448c..b474d7c 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -169,8 +169,9 @@
     public @interface ResumeOnRebootRebootErrorCode {}
 
     /**
-     * The preparation of resume on reboot succeeds. Don't expose it because a successful reboot
-     * should just reboot the device.
+     * The preparation of resume on reboot succeeds.
+     *
+     * <p> Don't expose it because a successful reboot should just reboot the device.
      *  @hide
      */
     public static final int RESUME_ON_REBOOT_REBOOT_ERROR_NONE = 0;
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index b111ec3..161d10a 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -796,13 +796,14 @@
     /**
      * Notify {@link PhysicalChannelConfig} has changed for a specific subscription.
      *
+     * @param slotIndex for which physical channel configs changed.
      * @param subId the subId
      * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
      */
-    public void notifyPhysicalChannelConfigForSubscriber(
-            int subId, List<PhysicalChannelConfig> configs) {
+    public void notifyPhysicalChannelConfigForSubscriber(int slotIndex, int subId,
+            List<PhysicalChannelConfig> configs) {
         try {
-            sRegistry.notifyPhysicalChannelConfigForSubscriber(subId, configs);
+            sRegistry.notifyPhysicalChannelConfigForSubscriber(slotIndex, subId, configs);
         } catch (RemoteException ex) {
             // system server crash
         }
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 965971d..7a3fd91 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -91,7 +91,7 @@
     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 notifyPhysicalChannelConfigForSubscriber(in int subId,
+    void notifyPhysicalChannelConfigForSubscriber(in int phoneId, in int subId,
             in List<PhysicalChannelConfig> configs);
     void notifyDataEnabled(in int phoneId, int subId, boolean enabled, int reason);
     void notifyAllowedNetworkTypesChanged(in int phoneId, in int subId, in int reason, in long allowedNetworkType);
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index a23fc4b..7ee846e 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -1,12 +1,15 @@
 package com.android.internal.util;
 
+import static android.content.Intent.ACTION_USER_SWITCHED;
 import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -161,8 +164,21 @@
     private ServiceConnection mScreenshotConnection = null;
     private final Context mContext;
 
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            synchronized (mScreenshotLock) {
+                if (ACTION_USER_SWITCHED.equals(intent.getAction())) {
+                    resetConnection();
+                }
+            }
+        }
+    };
+
     public ScreenshotHelper(Context context) {
         mContext = context;
+        IntentFilter filter = new IntentFilter(ACTION_USER_SWITCHED);
+        mContext.registerReceiver(mBroadcastReceiver, filter);
     }
 
     /**
@@ -279,9 +295,8 @@
             final Runnable mScreenshotTimeout = () -> {
                 synchronized (mScreenshotLock) {
                     if (mScreenshotConnection != null) {
-                        mContext.unbindService(mScreenshotConnection);
-                        mScreenshotConnection = null;
-                        mScreenshotService = null;
+                        Log.e(TAG, "Timed out before getting screenshot capture response");
+                        resetConnection();
                         notifyScreenshotError();
                     }
                 }
@@ -304,11 +319,7 @@
                             break;
                         case SCREENSHOT_MSG_PROCESS_COMPLETE:
                             synchronized (mScreenshotLock) {
-                                if (mScreenshotConnection != null) {
-                                    mContext.unbindService(mScreenshotConnection);
-                                    mScreenshotConnection = null;
-                                    mScreenshotService = null;
-                                }
+                                resetConnection();
                             }
                             break;
                     }
@@ -348,9 +359,7 @@
                     public void onServiceDisconnected(ComponentName name) {
                         synchronized (mScreenshotLock) {
                             if (mScreenshotConnection != null) {
-                                mContext.unbindService(mScreenshotConnection);
-                                mScreenshotConnection = null;
-                                mScreenshotService = null;
+                                resetConnection();
                                 // only log an error if we're still within the timeout period
                                 if (handler.hasCallbacks(mScreenshotTimeout)) {
                                     handler.removeCallbacks(mScreenshotTimeout);
@@ -383,6 +392,17 @@
     }
 
     /**
+     * Unbinds the current screenshot connection (if any).
+     */
+    private void resetConnection() {
+        if (mScreenshotConnection != null) {
+            mContext.unbindService(mScreenshotConnection);
+            mScreenshotConnection = null;
+            mScreenshotService = null;
+        }
+    }
+
+    /**
      * Notifies the screenshot service to show an error.
      */
     private void notifyScreenshotError() {
diff --git a/core/java/com/android/internal/widget/LockSettingsInternal.java b/core/java/com/android/internal/widget/LockSettingsInternal.java
index f5df3ab..940979d 100644
--- a/core/java/com/android/internal/widget/LockSettingsInternal.java
+++ b/core/java/com/android/internal/widget/LockSettingsInternal.java
@@ -16,15 +16,41 @@
 
 package com.android.internal.widget;
 
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.app.admin.PasswordMetrics;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 /**
  * LockSettingsService local system service interface.
  *
  * @hide Only for use within the system server.
  */
 public abstract class LockSettingsInternal {
+    /** ErrorCode for armRebootEscrow failures. **/
+    @IntDef(prefix = {"ARM_REBOOT_ERROR_"}, value = {
+            ARM_REBOOT_ERROR_NONE,
+            ARM_REBOOT_ERROR_UNSPECIFIED,
+            ARM_REBOOT_ERROR_ESCROW_NOT_READY,
+            ARM_REBOOT_ERROR_NO_PROVIDER,
+            ARM_REBOOT_ERROR_PROVIDER_MISMATCH,
+            ARM_REBOOT_ERROR_NO_ESCROW_KEY,
+            ARM_REBOOT_ERROR_KEYSTORE_FAILURE,
+            ARM_REBOOT_ERROR_STORE_ESCROW_KEY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ArmRebootEscrowErrorCode {}
+
+    public static final int ARM_REBOOT_ERROR_NONE = 0;
+    public static final int ARM_REBOOT_ERROR_UNSPECIFIED = 1;
+    public static final int ARM_REBOOT_ERROR_ESCROW_NOT_READY = 2;
+    public static final int ARM_REBOOT_ERROR_NO_PROVIDER = 3;
+    public static final int ARM_REBOOT_ERROR_PROVIDER_MISMATCH = 4;
+    public static final int ARM_REBOOT_ERROR_NO_ESCROW_KEY = 5;
+    public static final int ARM_REBOOT_ERROR_KEYSTORE_FAILURE = 6;
+    public static final int ARM_REBOOT_ERROR_STORE_ESCROW_KEY = 7;
+    // TODO(b/183140900) split store escrow key errors into detailed ones.
 
     /**
      * Create an escrow token for the current user, which can later be used to unlock FBE
@@ -104,9 +130,9 @@
      * Should be called immediately before rebooting for an update. This depends on {@link
      * #prepareRebootEscrow()} having been called and the escrow completing.
      *
-     * @return true if the arming worked
+     * @return ARM_ERROR_NONE if the arming worked
      */
-    public abstract boolean armRebootEscrow();
+    public abstract @ArmRebootEscrowErrorCode int armRebootEscrow();
 
 
     /**
diff --git a/core/proto/android/internal/OWNERS b/core/proto/android/internal/OWNERS
new file mode 100644
index 0000000..24e24c2
--- /dev/null
+++ b/core/proto/android/internal/OWNERS
@@ -0,0 +1,2 @@
+# Binder
+per-file binder_latency.proto = file:/core/java/com/android/internal/os/BINDER_OWNERS
\ No newline at end of file
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
index b0c1f25..100eb99 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java
@@ -76,6 +76,7 @@
     private Context mContext;
     protected List<ScanResult> mLastScanResult;
     protected Object mWifiScanResultLock = new Object();
+    public TetheringManager mTetheringManager;
 
     /* Control Wifi States */
     public WifiManager mWifiManager;
@@ -129,6 +130,7 @@
         mCm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
         // Get an instance of WifiManager
         mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
+        mTetheringManager = mContext.getSystemService(TetheringManager.class);
 
         // register a connectivity receiver for CONNECTIVITY_ACTION;
         mConnectivityReceiver = new ConnectivityReceiver();
@@ -216,13 +218,13 @@
      */
     protected boolean waitForTetherStateChange(long timeout) {
         long startTime = SystemClock.uptimeMillis();
-        String[] wifiRegexes = mCm.getTetherableWifiRegexs();
+        String[] wifiRegexes = mTetheringManager.getTetherableWifiRegexs();
         while (true) {
             if ((SystemClock.uptimeMillis() - startTime) > timeout) {
                 return false;
             }
-            String[] active = mCm.getTetheredIfaces();
-            String[] error = mCm.getTetheringErroredIfaces();
+            String[] active = mTetheringManager.getTetheredIfaces();
+            String[] error = mTetheringManager.getTetheringErroredIfaces();
             for (String iface: active) {
                 for (String regex: wifiRegexes) {
                     if (iface.matches(regex)) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java
index a296ca2..09ea34e 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiConfigurationHelper.java
@@ -244,17 +244,19 @@
 
         IpConfiguration ipConfiguration = config.getIpConfiguration();
         if (jsonConfig.has("ip")) {
-            StaticIpConfiguration staticIpConfig = new StaticIpConfiguration();
-
             InetAddress ipAddress = getInetAddress(jsonConfig.getString("ip"));
             int prefixLength = getPrefixLength(jsonConfig.getInt("prefix_length"));
-            staticIpConfig.ipAddress = new LinkAddress(ipAddress, prefixLength);
-            staticIpConfig.gateway = getInetAddress(jsonConfig.getString("gateway"));
-            staticIpConfig.dnsServers.add(getInetAddress(jsonConfig.getString("dns1")));
-            staticIpConfig.dnsServers.add(getInetAddress(jsonConfig.getString("dns2")));
+
+            final StaticIpConfiguration.Builder builder = new StaticIpConfiguration.Builder();
+            builder.setIpAddress(new LinkAddress(ipAddress, prefixLength));
+            builder.setGateway(getInetAddress(jsonConfig.getString("gateway")));
+            final ArrayList<InetAddress> dnsServers = new ArrayList<>();
+            dnsServers.add(getInetAddress(jsonConfig.getString("dns1")));
+            dnsServers.add(getInetAddress(jsonConfig.getString("dns2")));
+            builder.setDnsServers(dnsServers);
+            ipConfiguration.setStaticIpConfiguration(builder.build());
 
             ipConfiguration.setIpAssignment(IpAssignment.STATIC);
-            ipConfiguration.setStaticIpConfiguration(staticIpConfig);
         } else {
             ipConfiguration.setIpAssignment(IpAssignment.DHCP);
         }
diff --git a/core/tests/nfctests/Android.bp b/core/tests/nfctests/Android.bp
new file mode 100644
index 0000000..335cea1
--- /dev/null
+++ b/core/tests/nfctests/Android.bp
@@ -0,0 +1,38 @@
+// Copyright 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+    name: "NfcManagerTests",
+    static_libs: [
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "mockito-target-minus-junit4",
+    ],
+    libs: [
+        "android.test.runner",
+    ],
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+    test_suites: ["device-tests"],
+}
diff --git a/core/tests/nfctests/AndroidManifest.xml b/core/tests/nfctests/AndroidManifest.xml
new file mode 100644
index 0000000..99e2c34c
--- /dev/null
+++ b/core/tests/nfctests/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="android.nfc">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!-- This is a self-instrumenting test package. -->
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.nfc"
+                     android:label="NFC Manager Tests">
+    </instrumentation>
+
+</manifest>
+
diff --git a/core/tests/nfctests/AndroidTest.xml b/core/tests/nfctests/AndroidTest.xml
new file mode 100644
index 0000000..490d6f5
--- /dev/null
+++ b/core/tests/nfctests/AndroidTest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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 NFC Manager test cases">
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-suite-tag" value="apct-instrumentation"/>
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="NfcManagerTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-tag" value="NfcManagerTests"/>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.nfc" />
+        <option name="hidden-api-checks" value="false"/>
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
+    </test>
+</configuration>
diff --git a/core/tests/nfctests/OWNERS b/core/tests/nfctests/OWNERS
new file mode 100644
index 0000000..34b095c
--- /dev/null
+++ b/core/tests/nfctests/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/nfc/OWNERS
diff --git a/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
new file mode 100644
index 0000000..43f9b6f
--- /dev/null
+++ b/core/tests/nfctests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.nfc;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.doNothing;
+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.nfc.NfcAdapter.ControllerAlwaysOnListener;
+import android.os.RemoteException;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Test of {@link NfcControllerAlwaysOnListener}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NfcControllerAlwaysOnListenerTest {
+
+    private INfcAdapter mNfcAdapter = mock(INfcAdapter.class);
+
+    private Throwable mThrowRemoteException = new RemoteException("RemoteException");
+
+    private static Executor getExecutor() {
+        return new Executor() {
+            @Override
+            public void execute(Runnable command) {
+                command.run();
+            }
+        };
+    }
+
+    private static void verifyListenerInvoked(ControllerAlwaysOnListener listener) {
+        verify(listener, times(1)).onControllerAlwaysOnChanged(anyBoolean());
+    }
+
+    @Test
+    public void testRegister_RegisterUnregister() throws RemoteException {
+        NfcControllerAlwaysOnListener mListener =
+                new NfcControllerAlwaysOnListener(mNfcAdapter);
+        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
+        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
+
+        // Verify that the state listener registered with the NFC Adapter
+        mListener.register(getExecutor(), mockListener1);
+        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
+
+        // Register a second client and no new call to NFC Adapter
+        mListener.register(getExecutor(), mockListener2);
+        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
+
+        // Unregister first listener
+        mListener.unregister(mockListener1);
+        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
+        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
+
+        // Unregister second listener and the state listener registered with the NFC Adapter
+        mListener.unregister(mockListener2);
+        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
+        verify(mNfcAdapter, times(1)).unregisterControllerAlwaysOnListener(any());
+    }
+
+    @Test
+    public void testRegister_FirstRegisterFails() throws RemoteException {
+        NfcControllerAlwaysOnListener mListener =
+                new NfcControllerAlwaysOnListener(mNfcAdapter);
+        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
+        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
+
+        // Throw a remote exception whenever first registering
+        doThrow(mThrowRemoteException).when(mNfcAdapter).registerControllerAlwaysOnListener(
+                any());
+
+        mListener.register(getExecutor(), mockListener1);
+        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
+
+        // No longer throw an exception, instead succeed
+        doNothing().when(mNfcAdapter).registerControllerAlwaysOnListener(any());
+
+        // Register a different listener
+        mListener.register(getExecutor(), mockListener2);
+        verify(mNfcAdapter, times(2)).registerControllerAlwaysOnListener(any());
+
+        // Ensure first and second listener were invoked
+        mListener.onControllerAlwaysOnChanged(true);
+        verifyListenerInvoked(mockListener1);
+        verifyListenerInvoked(mockListener2);
+    }
+
+    @Test
+    public void testRegister_RegisterSameListenerTwice() throws RemoteException {
+        NfcControllerAlwaysOnListener mListener =
+                new NfcControllerAlwaysOnListener(mNfcAdapter);
+        ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
+
+        // Register the same listener Twice
+        mListener.register(getExecutor(), mockListener);
+        mListener.register(getExecutor(), mockListener);
+        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
+
+        // Invoke a state change and ensure the listener is only called once
+        mListener.onControllerAlwaysOnChanged(true);
+        verifyListenerInvoked(mockListener);
+    }
+
+    @Test
+    public void testNotify_AllListenersNotified() throws RemoteException {
+
+        NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
+        List<ControllerAlwaysOnListener> mockListeners = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
+            listener.register(getExecutor(), mockListener);
+            mockListeners.add(mockListener);
+        }
+
+        // Invoke a state change and ensure all listeners are invoked
+        listener.onControllerAlwaysOnChanged(true);
+        for (ControllerAlwaysOnListener mListener : mockListeners) {
+            verifyListenerInvoked(mListener);
+        }
+    }
+
+    @Test
+    public void testStateChange_CorrectValue() {
+        runStateChangeValue(true, true);
+        runStateChangeValue(false, false);
+
+    }
+
+    private void runStateChangeValue(boolean isEnabledIn, boolean isEnabledOut) {
+        NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
+        ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
+        listener.register(getExecutor(), mockListener);
+        listener.onControllerAlwaysOnChanged(isEnabledIn);
+        verify(mockListener, times(1)).onControllerAlwaysOnChanged(isEnabledOut);
+        verify(mockListener, times(0)).onControllerAlwaysOnChanged(!isEnabledOut);
+    }
+}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index aef68d0..4d418c3 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -383,6 +383,7 @@
         <permission name="android.permission.SUSPEND_APPS" />
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
         <permission name="android.permission.USE_RESERVED_DISK"/>
+        <permission name="android.permission.UWB_PRIVILEGED"/>
         <permission name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE"/>
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
         <permission name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
@@ -459,6 +460,15 @@
         <permission name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" />
         <!-- Permission required for CTS test - CtsAlarmManagerTestCases -->
         <permission name="android.permission.SCHEDULE_PRIORITIZED_ALARM" />
+        <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
+        <permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" />
+        <permission name="android.permission.READ_LOGS" />
+        <permission name="android.permission.BRIGHTNESS_SLIDER_USAGE" />
+        <permission name="android.permission.ACCESS_AMBIENT_LIGHT_STATS" />
+        <permission name="android.permission.CONFIGURE_DISPLAY_BRIGHTNESS" />
+        <permission name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER" />
+        <permission name="android.permission.SET_MEDIA_KEY_LISTENER" />
+        <permission name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
index ea9b52c..e4e5b9f 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/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index e501e12..5ac059b 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -17,6 +17,7 @@
 package com.android.companiondevicemanager;
 
 import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress;
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
 import static java.util.Objects.requireNonNull;
 
@@ -58,6 +59,8 @@
             Log.e(LOG_TAG, "About to show UI, but no devices to show");
         }
 
+        getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+
         if (getService().mRequest.isSingleDevice()) {
             setContentView(R.layout.device_confirmation);
             final DeviceFilterPair selectedDevice = getService().mDevicesFound.get(0);
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
index 92a792b..a2e218d 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
@@ -68,5 +68,11 @@
                     return cm.startOrGetTestNetworkManager();
                 }
         );
+
+        SystemServiceRegistry.registerContextAwareService(
+                DnsResolverServiceManager.DNS_RESOLVER_SERVICE,
+                DnsResolverServiceManager.class,
+                (context, serviceBinder) -> new DnsResolverServiceManager(serviceBinder)
+        );
     }
 }
diff --git a/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java b/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java
new file mode 100644
index 0000000..79009e8
--- /dev/null
+++ b/packages/Connectivity/framework/src/android/net/DnsResolverServiceManager.java
@@ -0,0 +1,45 @@
+/*
+ * 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.net;
+
+import android.annotation.NonNull;
+import android.os.IBinder;
+
+/**
+ * Provides a way to obtain the DnsResolver binder objects.
+ *
+ * @hide
+ */
+public class DnsResolverServiceManager {
+    /** Service name for the DNS resolver. Keep in sync with DnsResolverService.h */
+    public static final String DNS_RESOLVER_SERVICE = "dnsresolver";
+
+    private final IBinder mResolver;
+
+    DnsResolverServiceManager(IBinder resolver) {
+        mResolver = resolver;
+    }
+
+    /**
+     * Get an {@link IBinder} representing the DnsResolver stable AIDL interface
+     *
+     * @return {@link android.net.IDnsResolver} IBinder.
+     */
+    @NonNull
+    public IBinder getService() {
+        return mResolver;
+    }
+}
diff --git a/packages/Connectivity/framework/src/android/net/LinkProperties.java b/packages/Connectivity/framework/src/android/net/LinkProperties.java
index e41ed72..99f48b4 100644
--- a/packages/Connectivity/framework/src/android/net/LinkProperties.java
+++ b/packages/Connectivity/framework/src/android/net/LinkProperties.java
@@ -686,8 +686,8 @@
     }
 
     /**
-     * Adds a {@link RouteInfo} to this {@code LinkProperties}, if a {@link RouteInfo}
-     * with the same {@link RouteInfo.RouteKey} with different properties
+     * Adds a {@link RouteInfo} to this {@code LinkProperties}. If there is a {@link RouteInfo}
+     * with the same destination, gateway and interface with different properties
      * (e.g., different MTU), it will be updated. If the {@link RouteInfo} had an
      * interface name set and that differs from the interface set for this
      * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown.
diff --git a/packages/SettingsLib/ActionBarShadow/lint-baseline.xml b/packages/SettingsLib/ActionBarShadow/lint-baseline.xml
new file mode 100644
index 0000000..4d5de5f
--- /dev/null
+++ b/packages/SettingsLib/ActionBarShadow/lint-baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.view.View#setOnScrollChangeListener`"
+        errorLine1="            mScrollView.setOnScrollChangeListener(mScrollChangeWatcher);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java"
+            line="81"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.view.View#setOnScrollChangeListener`"
+        errorLine1="        mScrollView.setOnScrollChangeListener(null);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java"
+            line="88"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 23 (current min is 21): `android.view.View.OnScrollChangeListener`"
+        errorLine1="    final class ScrollChangeWatcher implements View.OnScrollChangeListener {"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/ActionBarShadow/src/com/android/settingslib/widget/ActionBarShadowController.java"
+            line="95"
+            column="48"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
new file mode 100644
index 0000000..a19f7af
--- /dev/null
+++ b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="`android:Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)"
+        errorLine1="    &lt;style name=&quot;SettingsActionButton&quot; parent=&quot;android:Widget.DeviceDefault.Button.Borderless.Colored&quot;>"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml"
+            line="19"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`android:drawableTint` requires API level 23 (current min is 21)"
+        errorLine1="        &lt;item name=&quot;android:drawableTint&quot;>@*android:color/btn_colored_borderless_text_material&lt;/item>"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/ActionButtonsPreference/res/values/styles.xml"
+            line="21"
+            column="15"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/AdaptiveIcon/lint-baseline.xml b/packages/SettingsLib/AdaptiveIcon/lint-baseline.xml
new file mode 100644
index 0000000..01a0495
--- /dev/null
+++ b/packages/SettingsLib/AdaptiveIcon/lint-baseline.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColor`"
+        errorLine1="                                .getColor(colorRes, null /* theme */);"
+        errorLine2="                                 ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java"
+            line="75"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getColor`"
+        errorLine1="        setBackgroundColor(context.getColor(R.color.homepage_generic_icon_background));"
+        errorLine2="                                   ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java"
+            line="87"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 23 (current min is 21): `android.graphics.drawable.DrawableWrapper`"
+        errorLine1="public class AdaptiveOutlineDrawable extends DrawableWrapper {"
+        errorLine2="                                             ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+            line="46"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.graphics.drawable.DrawableWrapper`"
+        errorLine1="        super(new AdaptiveIconShapeDrawable(resources));"
+        errorLine2="        ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+            line="67"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.graphics.drawable.DrawableWrapper`"
+        errorLine1="        super(new AdaptiveIconShapeDrawable(resources));"
+        errorLine2="        ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+            line="74"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.graphics.drawable.DrawableWrapper#getDrawable`"
+        errorLine1="        getDrawable().setTint(Color.WHITE);"
+        errorLine2="        ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+            line="82"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColor`"
+        errorLine1="        return resources.getColor(resId, /* theme */ null);"
+        errorLine2="                         ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java"
+            line="107"
+            column="26"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/BarChartPreference/lint-baseline.xml b/packages/SettingsLib/BarChartPreference/lint-baseline.xml
new file mode 100644
index 0000000..f1043bb
--- /dev/null
+++ b/packages/SettingsLib/BarChartPreference/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="`@android:style/Widget.DeviceDefault.Button.Borderless.Colored` requires API level 28 (current min is 21)"
+        errorLine1="           parent=&quot;@android:style/Widget.DeviceDefault.Button.Borderless.Colored&quot;>"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/BarChartPreference/res/values/styles.xml"
+            line="35"
+            column="12"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/HelpUtils/lint-baseline.xml b/packages/SettingsLib/HelpUtils/lint-baseline.xml
new file mode 100644
index 0000000..940f027
--- /dev/null
+++ b/packages/SettingsLib/HelpUtils/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 28 (current min is 21): `android.content.pm.PackageInfo#getLongVersionCode`"
+        errorLine1="                sCachedVersionCode = Long.toString(info.getLongVersionCode());"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java"
+            line="239"
+            column="57"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/ProgressBar/lint-baseline.xml b/packages/SettingsLib/ProgressBar/lint-baseline.xml
new file mode 100644
index 0000000..03d0f3f
--- /dev/null
+++ b/packages/SettingsLib/ProgressBar/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="`?android:attr/colorSecondary` requires API level 25 (current min is 21)"
+        errorLine1="        android:background=&quot;?android:attr/colorSecondary&quot; />"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/ProgressBar/res/layout/progress_header.xml"
+            line="27"
+            column="9"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml b/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml
new file mode 100644
index 0000000..173c735
--- /dev/null
+++ b/packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        ComponentName adminComponent = userContext.getSystemService("
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java"
+            line="59"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        UserManager um = context.getSystemService(UserManager.class);"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java"
+            line="101"
+            column="34"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/SettingsSpinner/lint-baseline.xml b/packages/SettingsLib/SettingsSpinner/lint-baseline.xml
new file mode 100644
index 0000000..ae1ed38e
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.widget.Spinner`"
+        errorLine1="        super(context, attrs, defStyleAttr, defStyleRes, mode, null);"
+        errorLine2="        ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java"
+            line="122"
+            column="9"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/Tile/lint-baseline.xml b/packages/SettingsLib/Tile/lint-baseline.xml
new file mode 100644
index 0000000..2b093dd
--- /dev/null
+++ b/packages/SettingsLib/Tile/lint-baseline.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `java.lang.Iterable#forEach`"
+        errorLine1="        controllers.forEach(controller -> {"
+        errorLine2="                    ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/SwitchesProvider.java"
+            line="79"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.os.Parcel#readBoolean`"
+        errorLine1="        final boolean isProviderTile = in.readBoolean();"
+        errorLine2="                                          ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+            line="83"
+            column="43"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.os.Parcel#writeBoolean`"
+        errorLine1="        dest.writeBoolean(this instanceof ProviderTile);"
+        errorLine2="             ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+            line="102"
+            column="14"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#createWithResource`"
+        errorLine1="            final Icon icon = Icon.createWithResource(componentInfo.packageName, iconResId);"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+            line="314"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#setTint`"
+        errorLine1="                icon.setTint(tintColor);"
+        errorLine2="                     ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+            line="320"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.os.Parcel#readBoolean`"
+        errorLine1="            final boolean isProviderTile = source.readBoolean();"
+        errorLine2="                                                  ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java"
+            line="364"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.content.Context#getAttributionTag`"
+        errorLine1="            return provider.call(context.getPackageName(), context.getAttributionTag(),"
+        errorLine2="                                                                   ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java"
+            line="558"
+            column="68"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/Utils/lint-baseline.xml b/packages/SettingsLib/Utils/lint-baseline.xml
new file mode 100644
index 0000000..93cf3cc
--- /dev/null
+++ b/packages/SettingsLib/Utils/lint-baseline.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        return context.getSystemService(UserManager.class).isManagedProfile(userId)"
+        errorLine2="                       ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/Utils/src/com/android/settingslib/utils/applications/AppUtils.java"
+            line="55"
+            column="24"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsLib/lint-baseline.xml b/packages/SettingsLib/lint-baseline.xml
new file mode 100644
index 0000000..403de43
--- /dev/null
+++ b/packages/SettingsLib/lint-baseline.xml
@@ -0,0 +1,4118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        return mContext.getSystemService(UserManager.class).isAdminUser();"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java"
+            line="63"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                mContext.getSystemService(CarrierConfigManager.class);"
+        errorLine2="                         ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java"
+            line="74"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager`"
+        errorLine1="                mContext.getSystemService(CarrierConfigManager.class);"
+        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java"
+            line="74"
+            column="43"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.telephony.SubscriptionManager#getDefaultDataSubscriptionId`"
+        errorLine1="        final int subId = SubscriptionManager.getDefaultDataSubscriptionId();"
+        errorLine2="                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java"
+            line="75"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager#getConfigForSubId`"
+        errorLine1="            config = configManager.getConfigForSubId(subId);"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java"
+            line="78"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.os.BaseBundle#getBoolean`"
+        errorLine1="        return config != null &amp;&amp; config.getBoolean("
+        errorLine2="                                        ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java"
+            line="80"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.telephony.SubscriptionManager#getDefaultDataSubscriptionId`"
+        errorLine1="        final int subId = SubscriptionManager.getDefaultDataSubscriptionId();"
+        errorLine2="                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java"
+            line="106"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.telephony.SubscriptionManager#isValidSubscriptionId`"
+        errorLine1="        if (!SubscriptionManager.isValidSubscriptionId(subId)) {"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java"
+            line="107"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.telephony.ims.ImsMmTelManager#getRegistrationState`"
+        errorLine1="            imsMmTelManager.getRegistrationState(executors, stateCallback);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java"
+            line="116"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mCM = context.getSystemService(ConnectivityManager.class);"
+        errorLine2="                      ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java"
+            line="54"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.net.ConnectivityManager#getActiveNetwork`"
+        errorLine1="        LinkProperties prop = cm.getLinkProperties(cm.getActiveNetwork());"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractIpAddressPreferenceController.java"
+            line="96"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.os.Build#getSerial`"
+        errorLine1="        this(context, Build.getSerial());"
+        errorLine2="                            ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractSerialNumberPreferenceController.java"
+            line="40"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        return mContext.getSystemService(UserManager.class).isAdminUser()"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractSimStatusImeiInfoPreferenceController.java"
+            line="33"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mWifiManager = context.getSystemService(WifiManager.class);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java"
+            line="56"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="    private final ArraySet&lt;ScanResult> mScanResults = new ArraySet&lt;>();"
+        errorLine2="                                                      ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="167"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="    private final ArraySet&lt;ScanResult> mExtraScanResults = new ArraySet&lt;>();"
+        errorLine2="                                                           ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="174"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getUniqueId`"
+        errorLine1="        mPasspointUniqueId = config.getUniqueId();"
+        errorLine2="                                    ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="368"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getHomeSp`"
+        errorLine1="        mFqdn = config.getHomeSp().getFqdn();"
+        errorLine2="                       ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="369"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.net.wifi.hotspot2.pps.HomeSp#getFqdn`"
+        errorLine1="        mFqdn = config.getHomeSp().getFqdn();"
+        errorLine2="                                   ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="369"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getHomeSp`"
+        errorLine1="        mProviderFriendlyName = config.getHomeSp().getFriendlyName();"
+        errorLine2="                                       ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="370"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.net.wifi.hotspot2.pps.HomeSp#getFriendlyName`"
+        errorLine1="        mProviderFriendlyName = config.getHomeSp().getFriendlyName();"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="370"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getSubscriptionExpirationTimeMillis`"
+        errorLine1="        mSubscriptionExpirationTimeInMillis = config.getSubscriptionExpirationTimeMillis();"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="371"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#isOsuProvisioned`"
+        errorLine1="        if (config.isOsuProvisioned()) {"
+        errorLine2="                   ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="372"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`"
+        errorLine1="        mPasspointUniqueId = config.getKey();"
+        errorLine2="                                    ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="389"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#calculateSignalLevel`"
+        errorLine1="        int difference = wifiManager.calculateSignalLevel(other.mRssi)"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="470"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#calculateSignalLevel`"
+        errorLine1="                - wifiManager.calculateSignalLevel(mRssi);"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="471"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="The type of the for loop iterated value is android.util.ArraySet&lt;android.net.wifi.ScanResult>, which requires API level 23 (current min is 21)"
+        errorLine1="            for (ScanResult result : mScanResults) {"
+        errorLine2="                                     ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="578"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="The type of the for loop iterated value is android.util.ArraySet&lt;android.net.wifi.ScanResult>, which requires API level 23 (current min is 21)"
+        errorLine1="                for (ScanResult result : mScanResults) {"
+        errorLine2="                                         ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="667"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`"
+        errorLine1="        if (config.isPasspoint()) {"
+        errorLine2="                   ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="695"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`"
+        errorLine1="            return getKey(config.getKey());"
+        errorLine2="                                 ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="696"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`"
+        errorLine1="            if (otherApSecurity == SECURITY_SAE &amp;&amp; getWifiManager().isWpa3SaeSupported()) {"
+        errorLine2="                                                                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="755"
+            column="69"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`"
+        errorLine1="            if (otherApSecurity == SECURITY_OWE &amp;&amp; getWifiManager().isEnhancedOpenSupported()) {"
+        errorLine2="                                                                    ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="768"
+            column="69"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`"
+        errorLine1="        if (config.isPasspoint()) {"
+        errorLine2="                   ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="784"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`"
+        errorLine1="            return (isPasspoint() &amp;&amp; config.getKey().equals(mConfig.getKey()));"
+        errorLine2="                                            ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="785"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`"
+        errorLine1="            return (isPasspoint() &amp;&amp; config.getKey().equals(mConfig.getKey()));"
+        errorLine2="                                                                    ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="785"
+            column="69"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`"
+        errorLine1="            if (configSecurity == SECURITY_SAE &amp;&amp; getWifiManager().isWpa3SaeSupported()) {"
+        errorLine2="                                                                   ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="795"
+            column="68"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`"
+        errorLine1="            if (configSecurity == SECURITY_OWE &amp;&amp; getWifiManager().isEnhancedOpenSupported()) {"
+        errorLine2="                                                                   ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="803"
+            column="68"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`"
+        errorLine1="        if (!config.isPasspoint() &amp;&amp; !isSameSsidOrBssid(wifiInfo)) {"
+        errorLine2="                    ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="817"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`"
+        errorLine1="                    &amp;&amp; getWifiManager().isWpa3SaeSupported()) {"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="838"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`"
+        errorLine1="            if (scanResultSccurity == SECURITY_OWE &amp;&amp; getWifiManager().isEnhancedOpenSupported()) {"
+        errorLine2="                                                                       ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="852"
+            column="72"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#calculateSignalLevel`"
+        errorLine1="        return getWifiManager().calculateSignalLevel(mRssi);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="892"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="        Set&lt;ScanResult> allScans = new ArraySet&lt;>();"
+        errorLine2="                                   ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="905"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `ArraySet` to `Set` requires API level 23 (current min is 21)"
+        errorLine1="        Set&lt;ScanResult> allScans = new ArraySet&lt;>();"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="905"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `ArraySet` to `Collection` requires API level 23 (current min is 21)"
+        errorLine1="            allScans.addAll(mScanResults);"
+        errorLine2="                            ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="907"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `ArraySet` to `Collection` requires API level 23 (current min is 21)"
+        errorLine1="            allScans.addAll(mExtraScanResults);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="908"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="The type of the for loop iterated value is android.util.ArraySet&lt;android.net.wifi.ScanResult>, which requires API level 23 (current min is 21)"
+        errorLine1="            for (ScanResult result : mScanResults) {"
+        errorLine2="                                     ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="934"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`"
+        errorLine1="        if (mConfig != null &amp;&amp; mConfig.isPasspoint()) {"
+        errorLine2="                                       ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1069"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#providerFriendlyName`"
+        errorLine1="            return mConfig.providerFriendlyName;"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1070"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#providerFriendlyName`"
+        errorLine1="            return mConfig.providerFriendlyName;"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1121"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`"
+        errorLine1="        return mConfig != null &amp;&amp; mConfig.isPasspoint();"
+        errorLine2="                                          ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1266"
+            column="43"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 28 (current min is 21): `android.content.Context#getMainExecutor`"
+        errorLine1="                mContext.getMainExecutor(),"
+        errorLine2="                         ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1315"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiInfo#getPasspointFqdn`"
+        errorLine1="                    &amp;&amp; TextUtils.equals(info.getPasspointFqdn(), mConfig.FQDN)"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1332"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiInfo#getPasspointProviderFriendlyName`"
+        errorLine1="                    &amp;&amp; TextUtils.equals(info.getPasspointProviderFriendlyName(),"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1333"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#providerFriendlyName`"
+        errorLine1="                    mConfig.providerFriendlyName));"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1334"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                final NetworkScoreManager networkScoreManager = context.getSystemService("
+        errorLine2="                                                                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1654"
+            column="73"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="            WifiManager wifiManager = context.getSystemService(WifiManager.class);"
+        errorLine2="                                              ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1670"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`"
+        errorLine1="            return wifiManager.isWpa3SaeSupported() ? SECURITY_SAE : SECURITY_PSK;"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1753"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`"
+        errorLine1="            return wifiManager.isEnhancedOpenSupported() ? SECURITY_OWE : SECURITY_NONE;"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1758"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.hotspot2.PasspointConfiguration#getUniqueId`"
+        errorLine1="            String uniqueId = passpointConfig.getUniqueId();"
+        errorLine2="                                              ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1975"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiConfiguration#getKey`"
+        errorLine1="                if (TextUtils.equals(config.getKey(), uniqueId)) {"
+        errorLine2="                                            ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java"
+            line="1979"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        final AccessibilityManager accessibilityManager = ctx.getSystemService("
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityButtonHelper.java"
+            line="37"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="            enabledServices = new ArraySet&lt;>(1);"
+        errorLine2="                              ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java"
+            line="131"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `ArraySet` to `Set` requires API level 23 (current min is 21)"
+        errorLine1="            enabledServices = new ArraySet&lt;>(1);"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java"
+            line="131"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="            return mContext.getSystemService(UserManager.class);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java"
+            line="418"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.content.pm.PackageManager#getModuleInfo`"
+        errorLine1="            pm.getModuleInfo(packageName, 0 /* flags */);"
+        errorLine2="               ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java"
+            line="154"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mUm = mContext.getSystemService(UserManager.class);"
+        errorLine2="                       ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="198"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mStats = mContext.getSystemService(StorageStatsManager.class);"
+        errorLine2="                          ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="199"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`"
+        errorLine1="        mStats = mContext.getSystemService(StorageStatsManager.class);"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="199"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.content.pm.PackageManager#getInstalledModules`"
+        errorLine1="        final List&lt;ModuleInfo> moduleInfos = mPm.getInstalledModules(0 /* flags */);"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="215"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.content.pm.ModuleInfo#getPackageName`"
+        errorLine1="            mSystemModules.put(info.getPackageName(), info.isHidden());"
+        errorLine2="                                    ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="217"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.content.pm.ModuleInfo#isHidden`"
+        errorLine1="            mSystemModules.put(info.getPackageName(), info.isHidden());"
+        errorLine2="                                                           ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="217"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager#queryStatsForPackage`"
+        errorLine1="                                        mStats.queryStatsForPackage("
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="527"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#storageUuid`"
+        errorLine1="                                                entry.info.storageUuid,"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="528"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#storageUuid`"
+        errorLine1="                                                entry.info.storageUuid.toString(), entry.info.uid);"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="533"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`"
+        errorLine1="                                legacy.dataSize = stats.getDataBytes();"
+        errorLine2="                                                        ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="536"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getCacheBytes`"
+        errorLine1="                                legacy.cacheSize = Math.min(stats.getCacheBytes(), cacheQuota);"
+        errorLine2="                                                                  ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="537"
+            column="67"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#storageUuid`"
+        errorLine1="                                        mCurComputingSizeUuid = entry.info.storageUuid;"
+        errorLine2="                                                                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="1287"
+            column="65"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager#queryStatsForPackage`"
+        errorLine1="                                                        mStats.queryStatsForPackage("
+        errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="1295"
+            column="64"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`"
+        errorLine1="                                                legacy.dataSize = stats.getDataBytes();"
+        errorLine2="                                                                        ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="1304"
+            column="73"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getCacheBytes`"
+        errorLine1="                                                legacy.cacheSize = stats.getCacheBytes();"
+        errorLine2="                                                                         ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="1305"
+            column="74"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#category`"
+        errorLine1="                        || info.info.category == ApplicationInfo.CATEGORY_GAME;"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="1927"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#category`"
+        errorLine1="                isMusicApp = entry.info.category == ApplicationInfo.CATEGORY_AUDIO;"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="1986"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#category`"
+        errorLine1="                isMovieApp = entry.info.category == ApplicationInfo.CATEGORY_VIDEO;"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="2001"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 26 (current min is 21): `android.content.pm.ApplicationInfo#category`"
+        errorLine1="                        isPhotosApp = entry.info.category == ApplicationInfo.CATEGORY_IMAGE;"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java"
+            line="2017"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        if (context.getSystemService(PowerManager.class).setPowerSaveModeEnabled(enable)) {"
+        errorLine2="                    ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java"
+            line="132"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getColor`"
+        errorLine1="                context.getColor(R.color.meter_background_color), batteryLevel);"
+        errorLine2="                        ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawable.java"
+            line="71"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.graphics.drawable.LayerDrawable#setLayerGravity`"
+        errorLine1="        drawable.setLayerGravity(0 /* index of deviceDrawable */, Gravity.START);"
+        errorLine2="                 ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawable.java"
+            line="78"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.graphics.drawable.LayerDrawable#setLayerInsetStart`"
+        errorLine1="        drawable.setLayerInsetStart(1 /* index of batteryDrawable */,"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawable.java"
+            line="80"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.graphics.drawable.LayerDrawable#setLayerInsetTop`"
+        errorLine1="        drawable.setLayerInsetTop(1 /* index of batteryDrawable */,"
+        errorLine2="                 ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/BluetoothDeviceLayerDrawable.java"
+            line="82"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`"
+        errorLine1="                    + mDevice.getAlias() + &quot;, newProfileState &quot; + newProfileState);"
+        errorLine2="                              ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java"
+            line="155"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`"
+        errorLine1="        final String aliasName = mDevice.getAlias();"
+        errorLine2="                                         ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java"
+            line="431"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`"
+        errorLine1="        return !TextUtils.isEmpty(mDevice.getAlias());"
+        errorLine2="                                          ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java"
+            line="489"
+            column="43"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`"
+        errorLine1="            Log.d(TAG, &quot;updating profiles for &quot; + mDevice.getAlias());"
+        errorLine2="                                                          ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java"
+            line="638"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.bluetooth.BluetoothDevice#getAlias`"
+        errorLine1="        String name = device.getAlias();"
+        errorLine2="                             ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java"
+            line="171"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColor`"
+        errorLine1="        mImportantConversationColor = context.getResources().getColor("
+        errorLine2="                                                             ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java"
+            line="82"
+            column="62"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 25 (current min is 21): `android.content.pm.LauncherApps#getShortcutIconDrawable`"
+        errorLine1="        return mLauncherApps.getShortcutIconDrawable(shortcutInfo, mFillResIconDpi);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java"
+            line="90"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="75"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 23 (current min is 21): `android.app.usage.NetworkStatsManager`"
+        errorLine1="        mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class);"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="75"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`"
+        errorLine1="                return bucket.getRxBytes() + bucket.getTxBytes();"
+        errorLine2="                              ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="171"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`"
+        errorLine1="                return bucket.getRxBytes() + bucket.getTxBytes();"
+        errorLine2="                                                    ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="171"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getEndTimeStamp`"
+        errorLine1="            .append(&quot;bucketDuration=&quot;).append(bucket.getEndTimeStamp() - bucket.getStartTimeStamp())"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="196"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getStartTimeStamp`"
+        errorLine1="            .append(&quot;bucketDuration=&quot;).append(bucket.getEndTimeStamp() - bucket.getStartTimeStamp())"
+        errorLine2="                                                                                ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="196"
+            column="81"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getStartTimeStamp`"
+        errorLine1="            .append(&quot;,bucketStart=&quot;).append(bucket.getStartTimeStamp())"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="197"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`"
+        errorLine1="            .append(&quot;,rxBytes=&quot;).append(bucket.getRxBytes())"
+        errorLine2="                                               ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="198"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxPackets`"
+        errorLine1="            .append(&quot;,rxPackets=&quot;).append(bucket.getRxPackets())"
+        errorLine2="                                                 ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="199"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`"
+        errorLine1="            .append(&quot;,txBytes=&quot;).append(bucket.getTxBytes())"
+        errorLine2="                                               ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="200"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxPackets`"
+        errorLine1="            .append(&quot;,txPackets=&quot;).append(bucket.getTxPackets())"
+        errorLine2="                                                 ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="201"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.telephony.SubscriptionManager#isValidSubscriptionId`"
+        errorLine1="        if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="210"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.telephony.SubscriptionManager#getDefaultDataSubscriptionId`"
+        errorLine1="            subscriptionId = SubscriptionManager.getDefaultDataSubscriptionId();"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="211"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.telephony.SubscriptionManager#isValidSubscriptionId`"
+        errorLine1="        if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="215"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.telephony.SubscriptionManager#from`"
+        errorLine1="            int[] activeSubIds = SubscriptionManager.from(mContext).getActiveSubscriptionIdList();"
+        errorLine2="                                                     ~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="216"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        return mContext.getSystemService("
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="222"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.telephony.TelephonyManager#createForSubscriptionId`"
+        errorLine1="                TelephonyManager.class).createForSubscriptionId(subscriptionId);"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="223"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.telephony.TelephonyManager#setDataEnabled`"
+        errorLine1="        getTelephonyManager().setDataEnabled(enabled);"
+        errorLine2="                              ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="228"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 21): `android.telephony.TelephonyManager#isDataCapable`"
+        errorLine1="        return getTelephonyManager().isDataCapable()"
+        errorLine2="                                     ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="236"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.telephony.TelephonyManager#isDataEnabled`"
+        errorLine1="        return getTelephonyManager().isDataEnabled();"
+        errorLine2="                                     ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java"
+            line="241"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);"
+        errorLine2="                                                          ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java"
+            line="40"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.telephony.TelephonyManager#getSubscriptionId`"
+        errorLine1="        final int mobileDefaultSubId = telephonyManager.getSubscriptionId();"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java"
+            line="41"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                context.getSystemService(SubscriptionManager.class);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java"
+            line="44"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 22 (current min is 21): `android.telephony.SubscriptionManager`"
+        errorLine1="                context.getSystemService(SubscriptionManager.class);"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java"
+            line="44"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.telephony.SubscriptionInfo#getSubscriptionId`"
+        errorLine1="            if ((subInfo != null) &amp;&amp; (subInfo.getSubscriptionId() == subId)) {"
+        errorLine2="                                              ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java"
+            line="53"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.telephony.TelephonyManager#createForSubscriptionId`"
+        errorLine1="                .createForSubscriptionId(subId).getMergedImsisFromGroup();"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java"
+            line="65"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="            final TelephonyManager telephonyManager = context.getSystemService("
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java"
+            line="182"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.telephony.TelephonyManager#createForSubscriptionId`"
+        errorLine1="            final String rawNumber = telephonyManager.createForSubscriptionId("
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java"
+            line="184"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.telephony.SubscriptionInfo#getSubscriptionId`"
+        errorLine1="                    subscriptionInfo.getSubscriptionId()).getLine1Number();"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java"
+            line="185"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="            final TelephonyManager telephonyManager = context.getSystemService("
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java"
+            line="197"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.telephony.TelephonyManager#createForSubscriptionId`"
+        errorLine1="                final String rawNumber = telephonyManager.createForSubscriptionId("
+        errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java"
+            line="201"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.telephony.SubscriptionInfo#getSubscriptionId`"
+        errorLine1="                        subscriptionInfo.getSubscriptionId()).getLine1Number();"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java"
+            line="202"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.service.notification.Condition#newId`"
+        errorLine1="        mForeverId =  Condition.newId(mContext).appendPath(&quot;forever&quot;).build();"
+        errorLine2="                                ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="106"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#state`"
+        errorLine1="        final boolean enabled = condition.state == Condition.STATE_TRUE;"
+        errorLine2="                                ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="190"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`"
+        errorLine1="        return condition != null ? condition.id : null;"
+        errorLine2="                                   ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="254"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.service.notification.Condition#newId`"
+        errorLine1="        Uri foreverId = Condition.newId(mContext).appendPath(&quot;forever&quot;).build();"
+        errorLine2="                                  ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="258"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `new android.service.notification.Condition`"
+        errorLine1="        return new Condition(foreverId, foreverSummary(mContext), &quot;&quot;, &quot;&quot;, 0 /*icon*/,"
+        errorLine2="               ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="259"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`"
+        errorLine1="        return c != null &amp;&amp; ZenModeConfig.isValidCountdownToAlarmConditionId(c.id);"
+        errorLine2="                                                                             ~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="270"
+            column="78"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`"
+        errorLine1="        return c != null &amp;&amp; ZenModeConfig.isValidCountdownConditionId(c.id);"
+        errorLine2="                                                                      ~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="275"
+            column="71"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`"
+        errorLine1="        return c != null &amp;&amp; mForeverId.equals(c.id);"
+        errorLine2="                                              ~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="279"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#line1`"
+        errorLine1="        final String line1 = !TextUtils.isEmpty(condition.line1) ? condition.line1"
+        errorLine2="                                                ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="341"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#line1`"
+        errorLine1="        final String line1 = !TextUtils.isEmpty(condition.line1) ? condition.line1"
+        errorLine2="                                                                   ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="341"
+            column="68"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#summary`"
+        errorLine1="                : condition.summary;"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="342"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#line2`"
+        errorLine1="        final String line2 = condition.line2;"
+        errorLine2="                             ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="343"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#summary`"
+        errorLine1="                plusButton.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="388"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#summary`"
+        errorLine1="                plusButton.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));"
+        errorLine2="                                                                         ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="388"
+            column="74"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.NotificationManager#getNotificationPolicy`"
+        errorLine1="        boolean allowAlarms = (mNotificationManager.getNotificationPolicy().priorityCategories"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="466"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 23 (current min is 21): `android.app.NotificationManager.Policy#priorityCategories`"
+        errorLine1="        boolean allowAlarms = (mNotificationManager.getNotificationPolicy().priorityCategories"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="466"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#id`"
+        errorLine1="            final long time = ZenModeConfig.tryParseCountdownConditionId(condition.id);"
+        errorLine2="                                                                         ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java"
+            line="483"
+            column="74"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 29 (current min is 21): `android.bluetooth.BluetoothHearingAid`"
+        errorLine1="            mService = (BluetoothHearingAid) proxy;"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java"
+            line="59"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `BluetoothHearingAid` to `BluetoothProfile` requires API level 29 (current min is 21)"
+        errorLine1="                                                                       mService);"
+        errorLine2="                                                                       ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java"
+            line="257"
+            column="72"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 28 (current min is 21): `android.bluetooth.BluetoothHidDevice`"
+        errorLine1="            mService = (BluetoothHidDevice) proxy;"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java"
+            line="63"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `BluetoothHidDevice` to `BluetoothProfile` requires API level 28 (current min is 21)"
+        errorLine1="                        mService);"
+        errorLine2="                        ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java"
+            line="173"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#loadDrawable`"
+        errorLine1="            drawable = icon.loadDrawable(mContext);"
+        errorLine2="                            ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/IconCache.java"
+            line="45"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`"
+        errorLine1="        return mRouteInfo.getName().toString();"
+        errorLine2="                          ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java"
+            line="51"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getClientPackageName`"
+        errorLine1="        return mRouteInfo.getClientPackageName() != null"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java"
+            line="56"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getFeatures`"
+        errorLine1="        final List&lt;String> features = mRouteInfo.getFeatures();"
+        errorLine2="                                                 ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java"
+            line="93"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getId`"
+        errorLine1="        if (info != null &amp;&amp; info.getSelectableRoutes().contains(device.mRouteInfo.getId())) {"
+        errorLine2="                                                                                  ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="131"
+            column="83"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getSelectableRoutes`"
+        errorLine1="        if (info != null &amp;&amp; info.getSelectableRoutes().contains(device.mRouteInfo.getId())) {"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="131"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getId`"
+        errorLine1="        if (info != null &amp;&amp; info.getSelectedRoutes().contains(device.mRouteInfo.getId())) {"
+        errorLine2="                                                                                ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="162"
+            column="81"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getSelectedRoutes`"
+        errorLine1="        if (info != null &amp;&amp; info.getSelectedRoutes().contains(device.mRouteInfo.getId())) {"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="162"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`"
+        errorLine1="                Log.d(TAG, route.getName() + &quot; is deselectable for &quot; + mPackageName);"
+        errorLine2="                                 ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="238"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getVolumeMax`"
+        errorLine1="            return info.getVolumeMax();"
+        errorLine2="                        ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="320"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getVolume`"
+        errorLine1="            return info.getVolume();"
+        errorLine2="                        ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="341"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getName`"
+        errorLine1="            return info.getName();"
+        errorLine2="                        ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="357"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`"
+        errorLine1="                Log.d(TAG, &quot;buildAllRoutes() route : &quot; + route.getName() + &quot;, volume : &quot;"
+        errorLine2="                                                               ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="378"
+            column="64"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getVolume`"
+        errorLine1="                        + route.getVolume() + &quot;, type : &quot; + route.getType());"
+        errorLine2="                                ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="379"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#isSystemRoute`"
+        errorLine1="            if (route.isSystemRoute()) {"
+        errorLine2="                      ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="381"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`"
+        errorLine1="                Log.d(TAG, &quot;buildAvailableRoutes() route : &quot; + route.getName() + &quot;, volume : &quot;"
+        errorLine2="                                                                     ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="394"
+            column="70"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getVolume`"
+        errorLine1="                        + route.getVolume() + &quot;, type : &quot; + route.getType());"
+        errorLine2="                                ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="395"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getId`"
+        errorLine1="                        &amp;&amp; getRoutingSessionInfo().getSelectedRoutes().contains(route.getId())"
+        errorLine2="                                                                                      ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="414"
+            column="87"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getSelectedRoutes`"
+        errorLine1="                        &amp;&amp; getRoutingSessionInfo().getSelectedRoutes().contains(route.getId())"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="414"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getName`"
+        errorLine1="                Log.d(TAG, &quot;onTransferred() oldSession : &quot; + oldSession.getName()"
+        errorLine2="                                                                        ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="479"
+            column="73"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getName`"
+        errorLine1="                        + &quot;, newSession : &quot; + newSession.getName());"
+        errorLine2="                                                         ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java"
+            line="480"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`"
+        errorLine1="        mImm = fragment.getContext().getSystemService(InputMethodManager.class);"
+        errorLine2="                        ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManager.java"
+            line="55"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mImm = fragment.getContext().getSystemService(InputMethodManager.class);"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManager.java"
+            line="55"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `java.util.ArrayList#sort`"
+        errorLine1="        subtypePreferences.sort((lhs, rhs) -> {"
+        errorLine2="                           ~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManager.java"
+            line="161"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.Fragment#getContext`"
+        errorLine1="                    mFragment, mFragment.getContext().getContentResolver(),"
+        errorLine2="                                         ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManager.java"
+            line="212"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mImm = fragment.getContext().getSystemService(InputMethodManager.class);"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManagerCompat.java"
+            line="56"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `java.util.ArrayList#sort`"
+        errorLine1="        subtypePreferences.sort((lhs, rhs) -> {"
+        errorLine2="                           ~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeEnablerManagerCompat.java"
+            line="162"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.icu.text.ListFormatter#format`"
+        errorLine1="                ListFormatter.getInstance(locale).format((Object[]) subtypeNames), locale);"
+        errorLine2="                                                  ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java"
+            line="400"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.icu.text.ListFormatter#getInstance`"
+        errorLine1="                ListFormatter.getInstance(locale).format((Object[]) subtypeNames), locale);"
+        errorLine2="                              ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java"
+            line="400"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.content.res.Configuration#getLocales`"
+        errorLine1="        final Locale configurationLocale = configuration.getLocales().get(0);"
+        errorLine2="                                                         ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java"
+            line="415"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.os.LocaleList#get`"
+        errorLine1="        final Locale configurationLocale = configuration.getLocales().get(0);"
+        errorLine2="                                                                      ~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java"
+            line="415"
+            column="71"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.icu.text.ListFormatter#format`"
+        errorLine1="                ListFormatter.getInstance(locale).format((Object[]) subtypeNames), locale);"
+        errorLine2="                                                  ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompat.java"
+            line="400"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.icu.text.ListFormatter#getInstance`"
+        errorLine1="                ListFormatter.getInstance(locale).format((Object[]) subtypeNames), locale);"
+        errorLine2="                              ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompat.java"
+            line="400"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.content.res.Configuration#getLocales`"
+        errorLine1="        final Locale configurationLocale = configuration.getLocales().get(0);"
+        errorLine2="                                                         ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompat.java"
+            line="415"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.os.LocaleList#get`"
+        errorLine1="        final Locale configurationLocale = configuration.getLocales().get(0);"
+        errorLine2="                                                                      ~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilCompat.java"
+            line="415"
+            column="71"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.content.pm.ComponentInfo#directBootAware`"
+        errorLine1="            if (mImi.getServiceInfo().directBootAware || isTv()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java"
+            line="162"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.content.pm.ComponentInfo#directBootAware`"
+        errorLine1="            if (mImi.getServiceInfo().directBootAware || isTv()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java"
+            line="257"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mImm = context.getSystemService(InputMethodManager.class);"
+        errorLine2="                       ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java"
+            line="61"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.RoutingSessionInfo#getId`"
+        errorLine1="            if (TextUtils.equals(sessionId, info.getId())) {"
+        errorLine2="                                                 ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java"
+            line="343"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColorStateList`"
+        errorLine1="                mContext.getResources().getColorStateList("
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java"
+            line="142"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getVolumeMax`"
+        errorLine1="        return mRouteInfo.getVolumeMax();"
+        errorLine2="                          ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java"
+            line="211"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getVolume`"
+        errorLine1="        return mRouteInfo.getVolume();"
+        errorLine2="                          ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java"
+            line="220"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getClientPackageName`"
+        errorLine1="        return mRouteInfo.getClientPackageName();"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java"
+            line="229"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getFeatures`"
+        errorLine1="        return mRouteInfo.getFeatures();"
+        errorLine2="                          ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java"
+            line="361"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getId`"
+        errorLine1="        return route.getId();"
+        errorLine2="                     ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java"
+            line="57"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`"
+        errorLine1="            final long total = bucket == null ? 0L : bucket.getRxBytes() + bucket.getTxBytes();"
+        errorLine2="                                                            ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java"
+            line="48"
+            column="61"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`"
+        errorLine1="            final long total = bucket == null ? 0L : bucket.getRxBytes() + bucket.getTxBytes();"
+        errorLine2="                                                                                  ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java"
+            line="48"
+            column="83"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`"
+        errorLine1="                    usage = bucket.getRxBytes() + bucket.getTxBytes();"
+        errorLine2="                                   ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java"
+            line="86"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`"
+        errorLine1="                    usage = bucket.getRxBytes() + bucket.getTxBytes();"
+        errorLine2="                                                         ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java"
+            line="86"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 23 (current min is 21): `android.app.usage.NetworkStatsManager`"
+        errorLine1="        mNetworkStatsManager = (NetworkStatsManager)"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java"
+            line="62"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.app.usage.NetworkStats.Bucket`"
+        errorLine1="            final NetworkStats.Bucket bucket = new NetworkStats.Bucket();"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java"
+            line="163"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats#getNextBucket`"
+        errorLine1="            while (stats.hasNextBucket() &amp;&amp; stats.getNextBucket(bucket)) {"
+        errorLine2="                                                  ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java"
+            line="164"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats#hasNextBucket`"
+        errorLine1="            while (stats.hasNextBucket() &amp;&amp; stats.getNextBucket(bucket)) {"
+        errorLine2="                         ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java"
+            line="164"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getRxBytes`"
+        errorLine1="                bytes += bucket.getRxBytes() + bucket.getTxBytes();"
+        errorLine2="                                ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java"
+            line="165"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.app.usage.NetworkStats.Bucket#getTxBytes`"
+        errorLine1="                bytes += bucket.getRxBytes() + bucket.getTxBytes();"
+        errorLine2="                                                      ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java"
+            line="165"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 21): `com.google.android.collect.Lists#newArrayList`"
+        errorLine1="    private ArrayList&lt;NetworkPolicy> mPolicies = Lists.newArrayList();"
+        errorLine2="                                                       ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java"
+            line="54"
+            column="56"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 23 (current min is 21): `android.app.usage.NetworkStatsManager`"
+        errorLine1="        mNetworkStatsManager = (NetworkStatsManager)"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/NetworkStatsSummaryLoader.java"
+            line="44"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                context.getSystemService(PermissionControllerManager.class);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsSummaryHelper.java"
+            line="32"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.media.MediaRoute2Info#getName`"
+        errorLine1="                name = mRouteInfo.getName();"
+        errorLine2="                                  ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java"
+            line="71"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.content.res.Configuration#getLocales`"
+        errorLine1="        final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);"
+        errorLine2="                                                                               ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="179"
+            column="80"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.os.LocaleList#get`"
+        errorLine1="        final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);"
+        errorLine2="                                                                                            ~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="179"
+            column="93"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#getInstance`"
+        errorLine1="        final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);"
+        errorLine2="                                                 ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="180"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.MeasureFormat.FormatWidth#SHORT`"
+        errorLine1="        final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);"
+        errorLine2="                                                                            ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="180"
+            column="77"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`"
+        errorLine1="        final Measure daysMeasure = new Measure(2, MeasureUnit.DAY);"
+        errorLine2="                                    ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="182"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)"
+        errorLine1="        final Measure daysMeasure = new Measure(2, MeasureUnit.DAY);"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="182"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#DAY`"
+        errorLine1="        final Measure daysMeasure = new Measure(2, MeasureUnit.DAY);"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="182"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#formatMeasures`"
+        errorLine1="                        frmt.formatMeasures(daysMeasure))"
+        errorLine2="                             ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="186"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#formatMeasures`"
+        errorLine1="                        frmt.formatMeasures(daysMeasure),"
+        errorLine2="                             ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="189"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.DateFormat#getInstanceForSkeleton`"
+        errorLine1="        DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton);"
+        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="220"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.DateFormat#format`"
+        errorLine1="        return fmt.format(date);"
+        errorLine2="                   ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="222"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.DateFormat#getInstanceForSkeleton`"
+        errorLine1="        DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton);"
+        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="234"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.DateFormat#format`"
+        errorLine1="        CharSequence timeString = fmt.format(date);"
+        errorLine2="                                      ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java"
+            line="236"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="    private final ArraySet&lt;String> mWhitelistedApps = new ArraySet&lt;>();"
+        errorLine2="                                                      ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java"
+            line="49"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="    private final ArraySet&lt;String> mSysWhitelistedApps = new ArraySet&lt;>();"
+        errorLine2="                                                         ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java"
+            line="50"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="    private final ArraySet&lt;String> mSysWhitelistedAppsExceptIdle = new ArraySet&lt;>();"
+        errorLine2="                                                                   ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java"
+            line="51"
+            column="68"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="    private final ArraySet&lt;String> mDefaultActiveApps = new ArraySet&lt;>();"
+        errorLine2="                                                        ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java"
+            line="52"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        final DevicePolicyManager devicePolicyManager = mAppContext.getSystemService("
+        errorLine2="                                                                    ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java"
+            line="98"
+            column="69"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java"
+            line="43"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`"
+        errorLine1="        final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);"
+        errorLine2="                                                                   ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java"
+            line="43"
+            column="68"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java"
+            line="62"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`"
+        errorLine1="        final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);"
+        errorLine2="                                                                   ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java"
+            line="62"
+            column="68"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.os.UserHandle#getUserHandleForUid`"
+        errorLine1="            UserHandle user = UserHandle.getUserHandleForUid(uid);"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java"
+            line="102"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.os.UserHandle#getUserHandleForUid`"
+        errorLine1="            final UserHandle user = UserHandle.getUserHandleForUid(uid);"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java"
+            line="97"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getColor`"
+        errorLine1="            final int disabledColor = context.getColor(R.color.disabled_text_color);"
+        errorLine2="                                              ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java"
+            line="581"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="        private Set&lt;Setting> mSettingsBeingLoaded = new ArraySet&lt;Setting>();"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/location/SettingsInjector.java"
+            line="361"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 23 (current min is 21): `android.graphics.drawable.DrawableWrapper`"
+        errorLine1="public class SignalDrawable extends DrawableWrapper {"
+        errorLine2="                                    ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java"
+            line="45"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.graphics.drawable.DrawableWrapper`"
+        errorLine1="        super(context.getDrawable(com.android.internal.R.drawable.ic_signal_cellular));"
+        errorLine2="        ~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java"
+            line="87"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.content.res.Resources#getFloat`"
+        errorLine1="        mCutoutWidthFraction = context.getResources().getFloat("
+        errorLine2="                                                      ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java"
+            line="92"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.content.res.Resources#getFloat`"
+        errorLine1="        mCutoutHeightFraction = context.getResources().getFloat("
+        errorLine2="                                                       ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java"
+            line="94"
+            column="56"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getColor`"
+        errorLine1="        mTransparentPaint.setColor(context.getColor(android.R.color.transparent));"
+        errorLine2="                                           ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java"
+            line="101"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Drawable#getLayoutDirection`"
+        errorLine1="        boolean isRtl = getLayoutDirection() == LayoutDirection.RTL;"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java"
+            line="190"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                context.getSystemService(CarrierConfigManager.class);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java"
+            line="33"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager`"
+        errorLine1="                context.getSystemService(CarrierConfigManager.class);"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java"
+            line="33"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.telephony.CarrierConfigManager#getConfigForSubId`"
+        errorLine1="            bundle = carrierConfigMgr.getConfigForSubId(subscriptionId);"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java"
+            line="36"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.os.BaseBundle#getBoolean`"
+        errorLine1="        return (bundle != null &amp;&amp; bundle.getBoolean("
+        errorLine2="                                         ~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java"
+            line="38"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="    private static final Set&lt;Uri> sRegisteredUris = new ArraySet&lt;>();"
+        errorLine2="                                                    ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/SliceBroadcastRelay.java"
+            line="47"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mUser = mContext.getSystemService(UserManager.class);"
+        errorLine2="                         ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="107"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mStats = mContext.getSystemService(StorageStatsManager.class);"
+        errorLine2="                          ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="108"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`"
+        errorLine1="        mStats = mContext.getSystemService(StorageStatsManager.class);"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="108"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getTotalBytes`"
+        errorLine1="                addValue(details.usersSize, user.id, stats.getTotalBytes());"
+        errorLine2="                                                           ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="188"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getAudioBytes`"
+        errorLine1="                mediaMap.put(Environment.DIRECTORY_MUSIC, stats.getAudioBytes());"
+        errorLine2="                                                                ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="191"
+            column="65"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getVideoBytes`"
+        errorLine1="                mediaMap.put(Environment.DIRECTORY_MOVIES, stats.getVideoBytes());"
+        errorLine2="                                                                 ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="192"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getImageBytes`"
+        errorLine1="                mediaMap.put(Environment.DIRECTORY_PICTURES, stats.getImageBytes());"
+        errorLine2="                                                                   ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="193"
+            column="68"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getAudioBytes`"
+        errorLine1="                final long miscBytes = stats.getTotalBytes() - stats.getAudioBytes()"
+        errorLine2="                                                                     ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="195"
+            column="70"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getTotalBytes`"
+        errorLine1="                final long miscBytes = stats.getTotalBytes() - stats.getAudioBytes()"
+        errorLine2="                                             ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="195"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getImageBytes`"
+        errorLine1="                        - stats.getVideoBytes() - stats.getImageBytes();"
+        errorLine2="                                                        ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="196"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getVideoBytes`"
+        errorLine1="                        - stats.getVideoBytes() - stats.getImageBytes();"
+        errorLine2="                                ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="196"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`"
+        errorLine1="                addValue(details.usersSize, user.id, stats.getDataBytes());"
+        errorLine2="                                                           ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="219"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`"
+        errorLine1="                addValue(details.appsSize, user.id, stats.getCodeBytes() + stats.getDataBytes());"
+        errorLine2="                                                                                 ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="220"
+            column="82"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getCacheBytes`"
+        errorLine1="                details.cacheSize += stats.getCacheBytes();"
+        errorLine2="                                           ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java"
+            line="222"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        mStorageStatsManager = context.getSystemService(StorageStatsManager.class);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="36"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Class requires API level 26 (current min is 21): `android.app.usage.StorageStatsManager`"
+        errorLine1="        mStorageStatsManager = context.getSystemService(StorageStatsManager.class);"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="36"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getTotalBytes`"
+        errorLine1="            totalBytes = stats.getTotalBytes();"
+        errorLine2="                               ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="90"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getAudioBytes`"
+        errorLine1="            audioBytes = stats.getAudioBytes();"
+        errorLine2="                               ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="91"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getVideoBytes`"
+        errorLine1="            videoBytes = stats.getVideoBytes();"
+        errorLine2="                               ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="92"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getImageBytes`"
+        errorLine1="            imageBytes = stats.getImageBytes();"
+        errorLine2="                               ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="93"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.ExternalStorageStats#getAppBytes`"
+        errorLine1="            appBytes = stats.getAppBytes();"
+        errorLine2="                             ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="94"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`"
+        errorLine1="            return mStats.getDataBytes();"
+        errorLine2="                          ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="127"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getCacheBytes`"
+        errorLine1="            return mStats.getCacheBytes();"
+        errorLine2="                          ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="131"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getAppBytes`"
+        errorLine1="            return mStats.getAppBytes() + mStats.getDataBytes();"
+        errorLine2="                          ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="135"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.app.usage.StorageStats#getDataBytes`"
+        errorLine1="            return mStats.getAppBytes() + mStats.getDataBytes();"
+        errorLine2="                                                 ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java"
+            line="135"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`"
+        errorLine1="            measureList.add(new Measure(days, MeasureUnit.DAY));"
+        errorLine2="                            ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="77"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)"
+        errorLine1="            measureList.add(new Measure(days, MeasureUnit.DAY));"
+        errorLine2="                                              ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="77"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#DAY`"
+        errorLine1="            measureList.add(new Measure(days, MeasureUnit.DAY));"
+        errorLine2="                                              ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="77"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`"
+        errorLine1="            measureList.add(new Measure(hours, MeasureUnit.HOUR));"
+        errorLine2="                            ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="80"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)"
+        errorLine1="            measureList.add(new Measure(hours, MeasureUnit.HOUR));"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="80"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#HOUR`"
+        errorLine1="            measureList.add(new Measure(hours, MeasureUnit.HOUR));"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="80"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`"
+        errorLine1="            measureList.add(new Measure(minutes, MeasureUnit.MINUTE));"
+        errorLine2="                            ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="83"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)"
+        errorLine1="            measureList.add(new Measure(minutes, MeasureUnit.MINUTE));"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="83"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#MINUTE`"
+        errorLine1="            measureList.add(new Measure(minutes, MeasureUnit.MINUTE));"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="83"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`"
+        errorLine1="            measureList.add(new Measure(seconds, MeasureUnit.SECOND));"
+        errorLine2="                            ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="86"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)"
+        errorLine1="            measureList.add(new Measure(seconds, MeasureUnit.SECOND));"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="86"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#SECOND`"
+        errorLine1="            measureList.add(new Measure(seconds, MeasureUnit.SECOND));"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="86"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `new android.icu.util.Measure`"
+        errorLine1="            measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));"
+        errorLine2="                            ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="90"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `TimeUnit` to `MeasureUnit` requires API level 24 (current min is 21)"
+        errorLine1="            measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="90"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#MINUTE`"
+        errorLine1="            measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));"
+        errorLine2="                                                                              ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="90"
+            column="79"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#SECOND`"
+        errorLine1="            measureList.add(new Measure(0, withSeconds ? MeasureUnit.SECOND : MeasureUnit.MINUTE));"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="90"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#getInstance`"
+        errorLine1="        final MeasureFormat measureFormat = MeasureFormat.getInstance("
+        errorLine2="                                                          ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="95"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.MeasureFormat.FormatWidth#SHORT`"
+        errorLine1="                locale, FormatWidth.SHORT);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="96"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.MeasureFormat#formatMeasures`"
+        errorLine1="        sb.append(measureFormat.formatMeasures(measureArray));"
+        errorLine2="                                ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="97"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.util.Measure#getUnit`"
+        errorLine1="        if (measureArray.length == 1 &amp;&amp; MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {"
+        errorLine2="                                                                                  ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="99"
+            column="83"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.util.MeasureUnit#MINUTE`"
+        errorLine1="        if (measureArray.length == 1 &amp;&amp; MeasureUnit.MINUTE.equals(measureArray[0].getUnit())) {"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="99"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.RelativeUnit#MINUTES`"
+        errorLine1="            unit = RelativeUnit.MINUTES;"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="132"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.RelativeUnit#HOURS`"
+        errorLine1="            unit = RelativeUnit.HOURS;"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="136"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.RelativeUnit#DAYS`"
+        errorLine1="            unit = RelativeUnit.DAYS;"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="140"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter#getInstance`"
+        errorLine1="        final RelativeDateTimeFormatter formatter = RelativeDateTimeFormatter.getInstance("
+        errorLine2="                                                                              ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="146"
+            column="79"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.util.ULocale#forLocale`"
+        errorLine1="                ULocale.forLocale(locale),"
+        errorLine2="                        ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="147"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.DisplayContext#CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE`"
+        errorLine1="                android.icu.text.DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="150"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter#format`"
+        errorLine1="        return formatter.format(value, RelativeDateTimeFormatter.Direction.LAST, unit);"
+        errorLine2="                         ~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="152"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.Direction#LAST`"
+        errorLine1="        return formatter.format(value, RelativeDateTimeFormatter.Direction.LAST, unit);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="152"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.RelativeDateTimeFormatter.Style#LONG`"
+        errorLine1="                RelativeDateTimeFormatter.Style.LONG);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/utils/StringUtil.java"
+            line="174"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.content.Context#bindServiceAsUser`"
+        errorLine1="        mContext.bindServiceAsUser(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE,"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionController.java"
+            line="83"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `new android.net.NetworkInfo`"
+        errorLine1="            mNetworkInfo = new NetworkInfo("
+        errorLine2="                           ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java"
+            line="110"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        WifiManager wifiManager = mContext.getSystemService(WifiManager.class);"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java"
+            line="130"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#getMaxSignalLevel`"
+        errorLine1="        int maxSignalLevel = wifiManager.getMaxSignalLevel();"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/TestAccessPointBuilder.java"
+            line="131"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java"
+            line="26"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.graphics.Paint#setBlendMode`"
+        errorLine1="        p.blendMode = BlendMode.SRC"
+        errorLine2="          ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="115"
+            column="11"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#SRC`"
+        errorLine1="        p.blendMode = BlendMode.SRC"
+        errorLine2="                      ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="115"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#SRC`"
+        errorLine1="        p.blendMode = BlendMode.SRC"
+        errorLine2="                      ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="115"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.graphics.Paint#setBlendMode`"
+        errorLine1="        p.blendMode = BlendMode.CLEAR"
+        errorLine2="          ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="124"
+            column="11"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#CLEAR`"
+        errorLine1="        p.blendMode = BlendMode.CLEAR"
+        errorLine2="                      ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="124"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#CLEAR`"
+        errorLine1="        p.blendMode = BlendMode.CLEAR"
+        errorLine2="                      ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="124"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.graphics.Paint#setBlendMode`"
+        errorLine1="        p.blendMode = BlendMode.SRC"
+        errorLine2="          ~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="143"
+            column="11"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#SRC`"
+        errorLine1="        p.blendMode = BlendMode.SRC"
+        errorLine2="                      ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="143"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 21): `android.graphics.BlendMode#SRC`"
+        errorLine1="        p.blendMode = BlendMode.SRC"
+        errorLine2="                      ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="143"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.graphics.Canvas#clipOutPath`"
+        errorLine1="            c.clipOutPath(scaledBolt)"
+        errorLine2="              ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt"
+            line="240"
+            column="15"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.os.UserManager#supportsMultipleUsers`"
+        errorLine1="                detail.label = res.getString(UserManager.supportsMultipleUsers()"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java"
+            line="120"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                final TetheringManager tm = mContext.getSystemService(TetheringManager.class);"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java"
+            line="126"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="            boolean isManaged = context.getSystemService(DevicePolicyManager.class)"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java"
+            line="176"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.telephony.TelephonyManager#isVoiceCapable`"
+        errorLine1="        return telephony != null &amp;&amp; telephony.isVoiceCapable();"
+        errorLine2="                                              ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/volume/Util.java"
+            line="185"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        LocationManager locationManager = context.getSystemService(LocationManager.class);"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java"
+            line="82"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.res.Resources#getColorStateList`"
+        errorLine1="                context.getResources().getColorStateList(resId, context.getTheme());"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java"
+            line="246"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        return !context.getSystemService(TelephonyManager.class).isDataCapable();"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java"
+            line="438"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 21): `android.telephony.TelephonyManager#isDataCapable`"
+        errorLine1="        return !context.getSystemService(TelephonyManager.class).isDataCapable();"
+        errorLine2="                                                                 ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java"
+            line="438"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="        final AudioManager audioManager = context.getSystemService(AudioManager.class);"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java"
+            line="459"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.content.pm.PackageItemInfo#loadUnbadgedIcon`"
+        errorLine1="        return getBadgedIcon(context, appInfo.loadUnbadgedIcon(context.getPackageManager()),"
+        errorLine2="                                              ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java"
+            line="527"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.os.UserHandle#getUserHandleForUid`"
+        errorLine1="                UserHandle.getUserHandleForUid(appInfo.uid));"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/Utils.java"
+            line="528"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.net.wifi.WifiConfiguration#isPasspoint`"
+        errorLine1="            if (network.isPasspoint()) {"
+        errorLine2="                        ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiSavedConfigUtils.java"
+            line="46"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.net.wifi.WifiManager#getPasspointConfigurations`"
+        errorLine1="                    wifiManager.getPasspointConfigurations();"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiSavedConfigUtils.java"
+            line="57"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.NetworkRequest.Builder#clearCapabilities`"
+        errorLine1="            .clearCapabilities()"
+        errorLine2="             ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+            line="60"
+            column="14"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.NetworkCapabilities#getTransportInfo`"
+        errorLine1="            WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();"
+        errorLine2="                                                               ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+            line="69"
+            column="64"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `TransportInfo` to `WifiInfo` requires API level 29 (current min is 21)"
+        errorLine1="            WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+            line="69"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.net.ConnectivityManager#registerNetworkCallback`"
+        errorLine1="            mConnectivityManager.registerNetworkCallback("
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+            line="134"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.net.ConnectivityManager#registerDefaultNetworkCallback`"
+        errorLine1="            mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback, mHandler);"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+            line="136"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiInfo#getPasspointProviderFriendlyName`"
+        errorLine1="                    ssid = mWifiInfo.getPasspointProviderFriendlyName();"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+            line="164"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiInfo#getPasspointProviderFriendlyName`"
+        errorLine1="                ssid = mWifiInfo.getPasspointProviderFriendlyName();"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+            line="192"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiManager#calculateSignalLevel`"
+        errorLine1="        level = mWifiManager.calculateSignalLevel(rssi);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java"
+            line="208"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="    private final Set&lt;NetworkKey> mRequestedScores = new ArraySet&lt;>();"
+        errorLine2="                                                     ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="147"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                context.getSystemService(WifiManager.class),"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="208"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                context.getSystemService(ConnectivityManager.class),"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="209"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                context.getSystemService(NetworkScoreManager.class),"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="210"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                context.getSystemService(WifiManager.class),"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="219"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                context.getSystemService(ConnectivityManager.class),"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="220"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `android.content.Context#getSystemService`"
+        errorLine1="                context.getSystemService(NetworkScoreManager.class),"
+        errorLine2="                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="221"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.NetworkRequest.Builder#clearCapabilities`"
+        errorLine1="                .clearCapabilities()"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="243"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 26 (current min is 21): `android.net.ConnectivityManager#registerNetworkCallback`"
+        errorLine1="            mConnectivityManager.registerNetworkCallback("
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="348"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 23 (current min is 21): `new android.util.ArraySet`"
+        errorLine1="        Set&lt;String> seenFQDNs = new ArraySet&lt;>();"
+        errorLine2="                                ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="688"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `ArraySet` to `Set` requires API level 23 (current min is 21)"
+        errorLine1="        Set&lt;String> seenFQDNs = new ArraySet&lt;>();"
+        errorLine2="                                ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="688"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isEnhancedOpenSupported`"
+        errorLine1="        final boolean isOweSupported = mWifiManager.isEnhancedOpenSupported();"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="1116"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SaeSupported`"
+        errorLine1="        final boolean isSaeSupported = mWifiManager.isWpa3SaeSupported();"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="1117"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 21): `android.net.wifi.WifiManager#isWpa3SuiteBSupported`"
+        errorLine1="        final boolean isSuiteBSupported = mWifiManager.isWpa3SuiteBSupported();"
+        errorLine2="                                                       ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java"
+            line="1118"
+            column="56"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 21): `android.net.wifi.WifiInfo#getWifiStandard`"
+        errorLine1="            visibility.append(&quot; standard = &quot;).append(info.getWifiStandard());"
+        errorLine2="                                                          ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java"
+            line="103"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.service.notification.Condition#line1`"
+        errorLine1="                radioContentText = condition.line1;"
+        errorLine2="                                   ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java"
+            line="285"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.view.View#setAccessibilityTraversalAfter`"
+        errorLine1="                radio.setAccessibilityTraversalAfter(lastView.getId());"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java"
+            line="54"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 22 (current min is 21): `android.view.View#setAccessibilityTraversalAfter`"
+        errorLine1="            if (contentClick != null) contentClick.setAccessibilityTraversalAfter(radio.getId());"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java"
+            line="57"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getInstance`"
+        errorLine1="        TimeZoneFormat tzFormatter = TimeZoneFormat.getInstance(locale);"
+        errorLine2="                                                    ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="99"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames#getInstance`"
+        errorLine1="        TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);"
+        errorLine2="                                                    ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="101"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames#getInstance`"
+        errorLine1="        final TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);"
+        errorLine2="                                                          ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="114"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.util.TimeZone#getCanonicalID`"
+        errorLine1="            String canonicalZoneId = android.icu.util.TimeZone.getCanonicalID(tz.getID());"
+        errorLine2="                                                               ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="222"
+            column="64"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames#getExemplarLocationName`"
+        errorLine1="            displayName = timeZoneNames.getExemplarLocationName(canonicalZoneId);"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="226"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames.NameType#LONG_DAYLIGHT`"
+        errorLine1="                tz.inDaylightTime(now) ? TimeZoneNames.NameType.LONG_DAYLIGHT"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="242"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames.NameType#LONG_STANDARD`"
+        errorLine1="                        : TimeZoneNames.NameType.LONG_STANDARD;"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="243"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneNames#getDisplayName`"
+        errorLine1="        return names.getDisplayName(getCanonicalZoneId(tz), nameType, now.getTime());"
+        errorLine2="                     ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="244"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.util.TimeZone#getCanonicalID`"
+        errorLine1="        final String canonicalId = android.icu.util.TimeZone.getCanonicalID(id);"
+        errorLine2="                                                             ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="249"
+            column="62"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getGMTPattern`"
+        errorLine1="        final String gmtPattern = tzFormatter.getGMTPattern();"
+        errorLine2="                                              ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="290"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat.GMTOffsetPatternType#NEGATIVE_HM`"
+        errorLine1="            patternType = TimeZoneFormat.GMTOffsetPatternType.NEGATIVE_HM;"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="312"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat.GMTOffsetPatternType#POSITIVE_HM`"
+        errorLine1="            patternType = TimeZoneFormat.GMTOffsetPatternType.POSITIVE_HM;"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="314"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getGMTOffsetPattern`"
+        errorLine1="        final String gmtOffsetPattern = tzFormatter.getGMTOffsetPattern(patternType);"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="316"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getGMTOffsetDigits`"
+        errorLine1="        final String localizedDigits = tzFormatter.getGMTOffsetDigits();"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="317"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 24 (current min is 21): `android.icu.text.TimeZoneFormat#getInstance`"
+        errorLine1="            final TimeZoneFormat tzFormatter = TimeZoneFormat.getInstance(locale);"
+        errorLine2="                                                              ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java"
+            line="377"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`?android:attr/colorError` requires API level 26 (current min is 21)"
+        errorLine1="    &lt;item android:color=&quot;?android:attr/colorError&quot; />"
+        errorLine2="          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/res/color/batterymeter_plus_color.xml"
+            line="17"
+            column="11"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`@android:id/switch_widget` requires API level 24 (current min is 21)"
+        errorLine1="        android:id=&quot;@android:id/switch_widget&quot;"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/res/layout/restricted_switch_widget.xml"
+            line="26"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`?android:attr/dialogPreferredPadding` requires API level 22 (current min is 21)"
+        errorLine1="        android:paddingStart=&quot;?android:attr/dialogPreferredPadding&quot;"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/res/layout/settings_dialog_title.xml"
+            line="30"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`?android:attr/dialogPreferredPadding` requires API level 22 (current min is 21)"
+        errorLine1="        android:paddingEnd=&quot;?android:attr/dialogPreferredPadding&quot;"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/res/layout/settings_dialog_title.xml"
+            line="31"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`?android:attr/colorError` requires API level 26 (current min is 21)"
+        errorLine1="            android:textColor=&quot;?android:attr/colorError&quot;/>"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml"
+            line="58"
+            column="13"/>
+    </issue>
+
+</issues>
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index cb610fc..bcde584 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -89,7 +89,7 @@
                         return value == null || value.length() < MAX_LENGTH;
                     }
                 });
-        VALIDATORS.put(System.FONT_SCALE, new InclusiveFloatRangeValidator(0.85f, 1.3f));
+        VALIDATORS.put(System.FONT_SCALE, new InclusiveFloatRangeValidator(0.25f, 5.0f));
         VALIDATORS.put(System.DIM_SCREEN, BOOLEAN_VALIDATOR);
         VALIDATORS.put(
                 System.DISPLAY_COLOR_MODE,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index bd5f8ab..9a3b76f 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -39,6 +39,75 @@
     <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+    <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
+    <uses-permission android:name="android.permission.RECEIVE_MMS" />
+    <uses-permission android:name="android.permission.READ_CELL_BROADCASTS" />
+    <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
+    <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
+    <uses-permission android:name="android.permission.USE_SIP" />
+    <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
+    <uses-permission android:name="android.permission.ACCEPT_HANDOVER" />
+    <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
+    <uses-permission android:name="android.permission.BODY_SENSORS" />
+    <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
+    <uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
+    <uses-permission android:name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" />
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.BRIGHTNESS_SLIDER_USAGE" />
+    <uses-permission android:name="android.permission.ACCESS_AMBIENT_LIGHT_STATS" />
+    <uses-permission android:name="android.permission.CONFIGURE_DISPLAY_BRIGHTNESS" />
+    <uses-permission android:name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER" />
+    <uses-permission android:name="android.permission.SET_MEDIA_KEY_LISTENER" />
+    <uses-permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE" />
+    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
+    <uses-permission android:name="android.permission.CALL_COMPANION_APP" />
+    <uses-permission android:name="android.permission.USE_FINGERPRINT" />
+    <uses-permission android:name="android.permission.READ_PROFILE" />
+    <uses-permission android:name="android.permission.WRITE_PROFILE" />
+    <uses-permission android:name="android.permission.READ_SOCIAL_STREAM" />
+    <uses-permission android:name="android.permission.WRITE_SOCIAL_STREAM" />
+    <uses-permission android:name="android.permission.WRITE_SMS" />
+    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
+    <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ" />
+    <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE" />
+    <uses-permission android:name="android.permission.FLASHLIGHT" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.NFC" />
+    <uses-permission android:name="android.permission.NFC_TRANSACTION_EVENT" />
+    <uses-permission android:name="android.permission.NFC_PREFERRED_PAYMENT_INFO" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
+    <uses-permission android:name="android.permission.TRANSMIT_IR" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.REQUEST_PASSWORD_COMPLEXITY" />
+    <uses-permission android:name="android.permission.GET_TASKS" />
+    <uses-permission android:name="android.permission.RESTART_PACKAGES" />
+    <uses-permission android:name="android.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND" />
+    <uses-permission android:name="android.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND" />
+    <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_WATCH" />
+    <uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS" />
+    <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
+    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
+    <uses-permission android:name="android.permission.READ_SYNC_STATS" />
+    <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />
+    <uses-permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS" />
+    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
+    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
+    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
+    <uses-permission android:name="android.permission.PERSISTENT_ACTIVITY" />
+    <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
+    <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
+    <uses-permission android:name="android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE" />
+    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
+    <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
+    <uses-permission android:name="android.permission.READ_INSTALL_SESSIONS" />
+    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
     <!-- ACCESS_BACKGROUND_LOCATION is needed for testing purposes only. -->
     <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
@@ -387,6 +456,9 @@
     <!-- Permission required for CTS test - CtsAlarmManagerTestCases -->
     <uses-permission android:name="android.permission.SCHEDULE_PRIORITIZED_ALARM" />
 
+    <!-- Permission required for CTS test - CtsUwbTestCases -->
+    <uses-permission android:name="android.permission.UWB_PRIVILEGED" />
+
     <application android:label="@string/app_label"
                 android:theme="@android:style/Theme.DeviceDefault.DayNight"
                 android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SystemUI/shared/lint-baseline.xml b/packages/SystemUI/shared/lint-baseline.xml
new file mode 100644
index 0000000..8021fbf
--- /dev/null
+++ b/packages/SystemUI/shared/lint-baseline.xml
@@ -0,0 +1,367 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.os.RemoteException#rethrowFromSystemServer`"
+        errorLine1="            throw e.rethrowFromSystemServer();"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java"
+            line="109"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.graphics.Bitmap#wrapHardwareBuffer`"
+        errorLine1="        return Bitmap.wrapHardwareBuffer(Objects.requireNonNull(buffer), colorSpace);"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/BitmapUtil.java"
+            line="84"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `new android.util.ArraySet`"
+        errorLine1="        mPluginActions = new ArraySet&lt;>(mSharedPrefs.getStringSet(PLUGIN_ACTIONS, null));"
+        errorLine2="                         ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginPrefs.java"
+            line="41"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `new android.util.ArraySet`"
+        errorLine1="        return new ArraySet&lt;>(mPluginActions);"
+        errorLine2="               ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginPrefs.java"
+            line="45"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 28 (current min is 26): `android.graphics.Bitmap#createBitmap`"
+        errorLine1="        return Bitmap.createBitmap(picture);"
+        errorLine2="                      ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/RecentsTransition.java"
+            line="113"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#release`"
+        errorLine1="        leash.mSurfaceControl.release();"
+        errorLine2="                              ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java"
+            line="86"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#release`"
+        errorLine1="            mStartLeash.release();"
+        errorLine2="                        ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java"
+            line="88"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`"
+        errorLine1="        return mSurfaceControl != null &amp;&amp; mSurfaceControl.isValid();"
+        errorLine2="                                                          ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceControlCompat.java"
+            line="41"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`"
+        errorLine1="            mSurfaceControlViewHost.release();"
+        errorLine2="                                    ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java"
+            line="61"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.SurfaceView#getHostToken`"
+        errorLine1="        bundle.putBinder(KEY_HOST_TOKEN, surfaceView.getHostToken());"
+        errorLine2="                                                     ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestUtils.java"
+            line="34"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`"
+        errorLine1="        bundle.putParcelable(KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl());"
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestUtils.java"
+            line="35"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `SurfaceControl` to `Parcelable` requires API level 29 (current min is 26)"
+        errorLine1="        bundle.putParcelable(KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl());"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestUtils.java"
+            line="35"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`"
+        errorLine1="                if (mBarrierSurfaceControl == null || !mBarrierSurfaceControl.isValid()) {"
+        errorLine2="                                                                              ~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+            line="106"
+            column="79"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+        errorLine1="                Transaction t = new Transaction();"
+        errorLine2="                                ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+            line="112"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+        errorLine1="                t.apply();"
+        errorLine2="                  ~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+            line="119"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+        errorLine1="                t.setAlpha(surface, alpha);"
+        errorLine2="                  ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+            line="361"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+        errorLine1="                t.setLayer(surface, layer);"
+        errorLine2="                  ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java"
+            line="364"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#origActivity`"
+        errorLine1="            ComponentName sourceComponent = t.origActivity != null"
+        errorLine2="                                            ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+            line="84"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#origActivity`"
+        errorLine1="                    ? t.origActivity"
+        errorLine2="                      ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+            line="86"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskId`"
+        errorLine1="            this.id = t.taskId;"
+        errorLine2="                      ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+            line="89"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#baseIntent`"
+        errorLine1="            this.baseIntent = t.baseIntent;"
+        errorLine2="                              ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+            line="91"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskDescription`"
+        errorLine1="        ActivityManager.TaskDescription td = taskInfo.taskDescription;"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+            line="280"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`"
+        errorLine1="                taskInfo.supportsSplitScreenMultiWindow, isLocked, td, taskInfo.topActivity);"
+        errorLine2="                                                                       ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java"
+            line="284"
+            column="72"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`"
+        errorLine1="        return info.topActivity;"
+        errorLine2="               ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java"
+            line="42"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskDescription`"
+        errorLine1="        return info.taskDescription;"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java"
+            line="46"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`"
+        errorLine1="        onTaskMovedToFront(taskInfo.taskId);"
+        errorLine2="                           ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java"
+            line="86"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`"
+        errorLine1="        mTransaction = new Transaction();"
+        errorLine2="                       ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+            line="31"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`"
+        errorLine1="        mTransaction.apply();"
+        errorLine2="                     ~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+            line="35"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setBufferSize`"
+        errorLine1="        mTransaction.setBufferSize(surfaceControl.mSurfaceControl, w, h);"
+        errorLine2="                     ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+            line="54"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`"
+        errorLine1="        mTransaction.setLayer(surfaceControl.mSurfaceControl, z);"
+        errorLine2="                     ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+            line="59"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`"
+        errorLine1="        mTransaction.setAlpha(surfaceControl.mSurfaceControl, alpha);"
+        errorLine2="                     ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java"
+            line="64"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+        errorLine1="                .getFloat(Resources.getSystem().getIdentifier("
+        errorLine2="                 ~~~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java"
+            line="46"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `RecordingCanvas` to `Canvas` requires API level 29 (current min is 26)"
+        errorLine1="            WindowCallbacksCompat.this.onPostDraw(canvas);"
+        errorLine2="                                                  ~~~~~~">
+        <location
+            file="frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java"
+            line="59"
+            column="51"/>
+    </issue>
+
+</issues>
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index efb3768..a39f8f6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -616,7 +616,9 @@
     }
 
     private static IDnsResolver getDnsResolver(Context context) {
-        return IDnsResolver.Stub.asInterface(DnsResolverServiceManager.getService(context));
+        final DnsResolverServiceManager dsm = context.getSystemService(
+                DnsResolverServiceManager.class);
+        return IDnsResolver.Stub.asInterface(dsm.getService());
     }
 
     /** Handler thread used for all of the handlers below. */
@@ -6142,6 +6144,7 @@
     @Override
     public int registerNetworkProvider(Messenger messenger, String name) {
         enforceNetworkFactoryOrSettingsPermission();
+        Objects.requireNonNull(messenger, "messenger must be non-null");
         NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
                 nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger));
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
@@ -9074,6 +9077,7 @@
     @Override
     public void unregisterConnectivityDiagnosticsCallback(
             @NonNull IConnectivityDiagnosticsCallback callback) {
+        Objects.requireNonNull(callback, "callback must be non-null");
         mConnectivityDiagnosticsHandler.sendMessage(
                 mConnectivityDiagnosticsHandler.obtainMessage(
                         ConnectivityDiagnosticsHandler
@@ -9444,6 +9448,7 @@
      */
     @Override
     public void unregisterQosCallback(@NonNull final IQosCallback callback) {
+        Objects.requireNonNull(callback, "callback must be non-null");
         mQosCallbackTracker.unregisterCallback(callback);
     }
 
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 0affda4..d9ecdda 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -313,7 +313,7 @@
 
     private final LocalLog mListenLog = new LocalLog(200);
 
-    private List<PhysicalChannelConfig> mPhysicalChannelConfigs;
+    private List<List<PhysicalChannelConfig>> mPhysicalChannelConfigs;
 
     private boolean[] mIsDataEnabled;
 
@@ -583,9 +583,9 @@
             mPreciseDataConnectionStates.add(new ArrayMap<>());
             mBarringInfo.add(i, new BarringInfo());
             mTelephonyDisplayInfos[i] = null;
-            mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build());
             mIsDataEnabled[i] = false;
             mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
+            mPhysicalChannelConfigs.add(i, new ArrayList<>());
             mAllowedNetworkTypeReason[i] = -1;
             mAllowedNetworkTypeValue[i] = -1;
             mLinkCapacityEstimateLists.add(i, new ArrayList<>());
@@ -683,9 +683,9 @@
             mPreciseDataConnectionStates.add(new ArrayMap<>());
             mBarringInfo.add(i, new BarringInfo());
             mTelephonyDisplayInfos[i] = null;
-            mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build());
             mIsDataEnabled[i] = false;
             mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
+            mPhysicalChannelConfigs.add(i, new ArrayList<>());
             mAllowedNetworkTypeReason[i] = -1;
             mAllowedNetworkTypeValue[i] = -1;
             mLinkCapacityEstimateLists.add(i, new ArrayList<>());
@@ -1176,8 +1176,9 @@
                     try {
                         r.callback.onPhysicalChannelConfigChanged(
                                 shouldSanitizeLocationForPhysicalChannelConfig(r)
-                                        ? getLocationSanitizedConfigs(mPhysicalChannelConfigs)
-                                        : mPhysicalChannelConfigs);
+                                        ? getLocationSanitizedConfigs(
+                                                mPhysicalChannelConfigs.get(phoneId))
+                                        : mPhysicalChannelConfigs.get(phoneId));
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -2369,11 +2370,12 @@
      * Send a notification to registrants that the configs of physical channel has changed for
      * a particular subscription.
      *
+     * @param phoneId the phone id.
      * @param subId the subId
      * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
      */
-    public void notifyPhysicalChannelConfigForSubscriber(
-            int subId, List<PhysicalChannelConfig> configs) {
+    public void notifyPhysicalChannelConfigForSubscriber(int phoneId, int subId,
+            List<PhysicalChannelConfig> configs) {
         if (!checkNotifyPermission("notifyPhysicalChannelConfig()")) {
             return;
         }
@@ -2385,9 +2387,8 @@
         }
 
         synchronized (mRecords) {
-            int phoneId = SubscriptionManager.getPhoneId(subId);
             if (validatePhoneId(phoneId)) {
-                mPhysicalChannelConfigs.set(phoneId, configs.get(phoneId));
+                mPhysicalChannelConfigs.set(phoneId, configs);
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)
@@ -2594,6 +2595,7 @@
                 pw.println("mDataEnabledReason=" + mDataEnabledReason);
                 pw.println("mAllowedNetworkTypeReason=" + mAllowedNetworkTypeReason[i]);
                 pw.println("mAllowedNetworkTypeValue=" + mAllowedNetworkTypeValue[i]);
+                pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs.get(i));
                 pw.println("mLinkCapacityEstimateList=" + mLinkCapacityEstimateLists.get(i));
                 pw.decreaseIndent();
             }
@@ -2604,7 +2606,6 @@
             pw.println("mEmergencyNumberList=" + mEmergencyNumberList);
             pw.println("mDefaultPhoneId=" + mDefaultPhoneId);
             pw.println("mDefaultSubId=" + mDefaultSubId);
-            pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs);
 
             pw.decreaseIndent();
 
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index f2236d7..db8dc71 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3003,8 +3003,8 @@
 
         // This is a workaround for R QPR, new API change is not allowed. We only allow the current
         // voice recognizer is also the voice interactor to noteproxy op.
-        final boolean isTrustVoiceServiceProxy =
-                AppOpsManager.isTrustedVoiceServiceProxy(mContext, proxyPackageName, code);
+        final boolean isTrustVoiceServiceProxy = AppOpsManager.isTrustedVoiceServiceProxy(mContext,
+                proxyPackageName, code, UserHandle.getUserId(proxyUid));
         final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid;
         final boolean isProxyTrusted = mContext.checkPermission(
                 Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid)
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index 5bd3c57..8017a44 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -841,6 +841,9 @@
     }
 
     private void injectBestLocation(Location location) {
+        if (location.isFromMockProvider()) {
+            return;
+        }
         if (DEBUG) {
             Log.d(TAG, "injectBestLocation: " + location);
         }
@@ -942,6 +945,9 @@
     }
 
     private void injectLocation(Location location) {
+        if (location.isFromMockProvider()) {
+            return;
+        }
         if (location.hasAccuracy()) {
             if (DEBUG) {
                 Log.d(TAG, "injectLocation: " + location);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index f96fa09..ca5f7b3 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1259,7 +1259,8 @@
         return getCredentialTypeInternal(userId) != CREDENTIAL_TYPE_NONE;
     }
 
-    private void setKeystorePassword(byte[] password, int userHandle) {
+    @VisibleForTesting /** Note: this method is overridden in unit tests */
+    void setKeystorePassword(byte[] password, int userHandle) {
         AndroidKeyStoreMaintenance.onUserPasswordChanged(userHandle, password);
     }
 
@@ -3488,7 +3489,7 @@
         }
 
         @Override
-        public boolean armRebootEscrow() {
+        public @ArmRebootEscrowErrorCode int armRebootEscrow() {
             return mRebootEscrowManager.armRebootEscrowIfNeeded();
         }
 
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 76ecc1a..c01523a 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -18,6 +18,15 @@
 
 import static android.os.UserHandle.USER_SYSTEM;
 
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_ESCROW_NOT_READY;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_KEYSTORE_FAILURE;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NONE;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NO_ESCROW_KEY;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NO_PROVIDER;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_PROVIDER_MISMATCH;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_STORE_ESCROW_KEY;
+import static com.android.internal.widget.LockSettingsInternal.ArmRebootEscrowErrorCode;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
@@ -577,16 +586,14 @@
         mRebootEscrowWanted = false;
         setRebootEscrowReady(false);
 
-
         RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider();
         if (rebootEscrowProvider == null) {
-            Slog.w(TAG,
-                    "Had reboot escrow data for users, but RebootEscrowProvider is unavailable");
-            return;
+            Slog.w(TAG, "RebootEscrowProvider is unavailable for clear request");
+        } else {
+            rebootEscrowProvider.clearRebootEscrowKey();
         }
 
         clearMetricsStorage();
-        rebootEscrowProvider.clearRebootEscrowKey();
 
         List<UserInfo> users = mUserManager.getUsers();
         for (UserInfo user : users) {
@@ -596,20 +603,30 @@
         mEventLog.addEntry(RebootEscrowEvent.CLEARED_LSKF_REQUEST);
     }
 
-    boolean armRebootEscrowIfNeeded() {
+    @ArmRebootEscrowErrorCode int armRebootEscrowIfNeeded() {
         if (!mRebootEscrowReady) {
-            return false;
+            return ARM_REBOOT_ERROR_ESCROW_NOT_READY;
         }
 
         RebootEscrowProviderInterface rebootEscrowProvider = mInjector.getRebootEscrowProvider();
         if (rebootEscrowProvider == null) {
             Slog.w(TAG,
                     "Had reboot escrow data for users, but RebootEscrowProvider is unavailable");
-            return false;
+            clearRebootEscrowIfNeeded();
+            return ARM_REBOOT_ERROR_NO_PROVIDER;
         }
 
+        int expectedProviderType = mInjector.serverBasedResumeOnReboot()
+                ? RebootEscrowProviderInterface.TYPE_SERVER_BASED
+                : RebootEscrowProviderInterface.TYPE_HAL;
         int actualProviderType = rebootEscrowProvider.getType();
-        // TODO(b/183140900) Fail the reboot if provider type mismatches.
+        if (expectedProviderType != actualProviderType) {
+            Slog.w(TAG, "Expect reboot escrow provider " + expectedProviderType
+                    + ", but the RoR is prepared with " + actualProviderType
+                    + ". Please prepare the RoR again.");
+            clearRebootEscrowIfNeeded();
+            return ARM_REBOOT_ERROR_PROVIDER_MISMATCH;
+        }
 
         RebootEscrowKey escrowKey;
         synchronized (mKeyGenerationLock) {
@@ -618,30 +635,38 @@
 
         if (escrowKey == null) {
             Slog.e(TAG, "Escrow key is null, but escrow was marked as ready");
-            return false;
+            clearRebootEscrowIfNeeded();
+            return ARM_REBOOT_ERROR_NO_ESCROW_KEY;
         }
 
         // We will use the same key from keystore to encrypt the escrow key and escrow data blob.
         SecretKey kk = mKeyStoreManager.getKeyStoreEncryptionKey();
         if (kk == null) {
             Slog.e(TAG, "Failed to get encryption key from keystore.");
-            return false;
-        }
-        boolean armedRebootEscrow = rebootEscrowProvider.storeRebootEscrowKey(escrowKey, kk);
-        if (armedRebootEscrow) {
-            mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM);
-            mStorage.setLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, mInjector.getCurrentTimeMillis(),
-                    USER_SYSTEM);
-            // Store the vbmeta digest of both slots.
-            mStorage.setString(REBOOT_ESCROW_KEY_VBMETA_DIGEST, mInjector.getVbmetaDigest(false),
-                    USER_SYSTEM);
-            mStorage.setString(REBOOT_ESCROW_KEY_OTHER_VBMETA_DIGEST,
-                    mInjector.getVbmetaDigest(true), USER_SYSTEM);
-            mStorage.setInt(REBOOT_ESCROW_KEY_PROVIDER, actualProviderType, USER_SYSTEM);
-            mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS);
+            clearRebootEscrowIfNeeded();
+            return ARM_REBOOT_ERROR_KEYSTORE_FAILURE;
         }
 
-        return armedRebootEscrow;
+        // TODO(b/183140900) design detailed errors for store escrow key errors.
+        // We don't clear rebootEscrow here, because some errors may be recoverable, e.g. network
+        // unavailable for server based provider.
+        boolean armedRebootEscrow = rebootEscrowProvider.storeRebootEscrowKey(escrowKey, kk);
+        if (!armedRebootEscrow) {
+            return ARM_REBOOT_ERROR_STORE_ESCROW_KEY;
+        }
+
+        mStorage.setInt(REBOOT_ESCROW_ARMED_KEY, mInjector.getBootCount(), USER_SYSTEM);
+        mStorage.setLong(REBOOT_ESCROW_KEY_ARMED_TIMESTAMP, mInjector.getCurrentTimeMillis(),
+                USER_SYSTEM);
+        // Store the vbmeta digest of both slots.
+        mStorage.setString(REBOOT_ESCROW_KEY_VBMETA_DIGEST, mInjector.getVbmetaDigest(false),
+                USER_SYSTEM);
+        mStorage.setString(REBOOT_ESCROW_KEY_OTHER_VBMETA_DIGEST,
+                mInjector.getVbmetaDigest(true), USER_SYSTEM);
+        mStorage.setInt(REBOOT_ESCROW_KEY_PROVIDER, actualProviderType, USER_SYSTEM);
+        mEventLog.addEntry(RebootEscrowEvent.SET_ARMED_STATUS);
+
+        return ARM_REBOOT_ERROR_NONE;
     }
 
     private void setRebootEscrowReady(boolean ready) {
@@ -663,10 +688,6 @@
     }
 
     boolean clearRebootEscrow() {
-        if (mInjector.getRebootEscrowProvider() == null) {
-            return false;
-        }
-
         clearRebootEscrowIfNeeded();
         return true;
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 58ffba2..48fee0b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -33,6 +33,8 @@
 import static android.content.Intent.EXTRA_VERSION_CODE;
 import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
+import static android.content.Intent.CATEGORY_BROWSABLE;
+import static android.content.Intent.CATEGORY_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index 6ea030f..81a51e2 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -25,6 +25,8 @@
 import static android.os.RecoverySystem.ResumeOnRebootRebootErrorCode;
 import static android.os.UserHandle.USER_SYSTEM;
 
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NONE;
+
 import android.annotation.IntDef;
 import android.content.Context;
 import android.content.IntentSender;
@@ -47,6 +49,7 @@
 import android.provider.DeviceConfig;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.FastImmutableArraySet;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -143,7 +146,7 @@
      */
     @IntDef({ ROR_NEED_PREPARATION,
             ROR_SKIP_PREPARATION_AND_NOTIFY,
-            ROR_SKIP_PREPARATION_NOT_NOTIFY})
+            ROR_SKIP_PREPARATION_NOT_NOTIFY })
     private @interface ResumeOnRebootActionsOnRequest {}
 
     /**
@@ -151,10 +154,43 @@
      */
     @IntDef({ ROR_NOT_REQUESTED,
             ROR_REQUESTED_NEED_CLEAR,
-            ROR_REQUESTED_SKIP_CLEAR})
+            ROR_REQUESTED_SKIP_CLEAR })
     private @interface ResumeOnRebootActionsOnClear {}
 
     /**
+     * Fatal arm escrow errors from lock settings that means the RoR is in a bad state. So clients
+     * need to prepare RoR again.
+     */
+    static final FastImmutableArraySet<Integer> FATAL_ARM_ESCROW_ERRORS =
+            new FastImmutableArraySet<>(new Integer[]{
+                    LockSettingsInternal.ARM_REBOOT_ERROR_ESCROW_NOT_READY,
+                    LockSettingsInternal.ARM_REBOOT_ERROR_NO_PROVIDER,
+                    LockSettingsInternal.ARM_REBOOT_ERROR_PROVIDER_MISMATCH,
+                    LockSettingsInternal.ARM_REBOOT_ERROR_NO_ESCROW_KEY,
+                    LockSettingsInternal.ARM_REBOOT_ERROR_KEYSTORE_FAILURE,
+            });
+
+    /**
+     * The error details for ArmRebootEscrow. It contains error codes from RecoverySystemService
+     * and LockSettingsService.
+     */
+    static class RebootPreparationError {
+        final @ResumeOnRebootRebootErrorCode int mRebootErrorCode;
+        final int mProviderErrorCode;  // The supplemental error code from lock settings
+
+        RebootPreparationError(int rebootErrorCode, int providerErrorCode) {
+            mRebootErrorCode = rebootErrorCode;
+            mProviderErrorCode = providerErrorCode;
+        }
+
+        int getErrorCodeForMetrics() {
+            // The ResumeOnRebootRebootErrorCode are aligned with 1000; so it's safe to add them
+            // for metrics purpose.
+            return mRebootErrorCode + mProviderErrorCode;
+        }
+    }
+
+    /**
      * Manages shared preference, i.e. the storage used for metrics reporting.
      */
     public static class PreferencesManager {
@@ -709,34 +745,40 @@
         return true;
     }
 
-    private @ResumeOnRebootRebootErrorCode int armRebootEscrow(String packageName,
+    private RebootPreparationError armRebootEscrow(String packageName,
             boolean slotSwitch) {
         if (packageName == null) {
             Slog.w(TAG, "Missing packageName when rebooting with lskf.");
-            return RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME;
+            return new RebootPreparationError(
+                    RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME, ARM_REBOOT_ERROR_NONE);
         }
         if (!isLskfCaptured(packageName)) {
-            return RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED;
+            return new RebootPreparationError(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED,
+                    ARM_REBOOT_ERROR_NONE);
         }
 
         if (!verifySlotForNextBoot(slotSwitch)) {
-            return RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH;
+            return new RebootPreparationError(RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH,
+                    ARM_REBOOT_ERROR_NONE);
         }
 
         final long origId = Binder.clearCallingIdentity();
-        boolean result;
+        int providerErrorCode;
         try {
-            result = mInjector.getLockSettingsService().armRebootEscrow();
+            providerErrorCode = mInjector.getLockSettingsService().armRebootEscrow();
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
 
-        if (!result) {
-            Slog.w(TAG, "Failure to escrow key for reboot");
-            return RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE;
+        if (providerErrorCode != ARM_REBOOT_ERROR_NONE) {
+            Slog.w(TAG, "Failure to escrow key for reboot, providerErrorCode: "
+                    + providerErrorCode);
+            return new RebootPreparationError(
+                    RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE, providerErrorCode);
         }
 
-        return RESUME_ON_REBOOT_REBOOT_ERROR_NONE;
+        return new RebootPreparationError(RESUME_ON_REBOOT_REBOOT_ERROR_NONE,
+                ARM_REBOOT_ERROR_NONE);
     }
 
     private boolean useServerBasedRoR() {
@@ -750,7 +792,7 @@
     }
 
     private void reportMetricsOnRebootWithLskf(String packageName, boolean slotSwitch,
-            @ResumeOnRebootRebootErrorCode int errorCode) {
+            RebootPreparationError escrowError) {
         int uid = mInjector.getUidFromPackageName(packageName);
         boolean serverBased = useServerBasedRoR();
         int preparedClientCount;
@@ -773,15 +815,31 @@
                         + " request count %d, lskf captured count %d, duration since lskf captured"
                         + " %d seconds.", packageName, preparedClientCount, requestCount,
                 lskfCapturedCount, durationSeconds));
-        mInjector.reportRebootEscrowRebootMetrics(errorCode, uid, preparedClientCount,
-                requestCount, slotSwitch, serverBased, durationSeconds, lskfCapturedCount);
+        mInjector.reportRebootEscrowRebootMetrics(escrowError.getErrorCodeForMetrics(), uid,
+                preparedClientCount, requestCount, slotSwitch, serverBased, durationSeconds,
+                lskfCapturedCount);
+    }
+
+    private void clearRoRPreparationStateOnRebootFailure(RebootPreparationError escrowError) {
+        if (!FATAL_ARM_ESCROW_ERRORS.contains(escrowError.mProviderErrorCode)) {
+            return;
+        }
+
+        Slog.w(TAG, "Clearing resume on reboot states for all clients on arm escrow error: "
+                + escrowError.mProviderErrorCode);
+        synchronized (this) {
+            mCallerPendingRequest.clear();
+            mCallerPreparedForReboot.clear();
+        }
     }
 
     private @ResumeOnRebootRebootErrorCode int rebootWithLskfImpl(String packageName, String reason,
             boolean slotSwitch) {
-        @ResumeOnRebootRebootErrorCode int errorCode = armRebootEscrow(packageName, slotSwitch);
-        reportMetricsOnRebootWithLskf(packageName, slotSwitch, errorCode);
+        RebootPreparationError escrowError = armRebootEscrow(packageName, slotSwitch);
+        reportMetricsOnRebootWithLskf(packageName, slotSwitch, escrowError);
+        clearRoRPreparationStateOnRebootFailure(escrowError);
 
+        @ResumeOnRebootRebootErrorCode int errorCode = escrowError.mRebootErrorCode;
         if (errorCode != RESUME_ON_REBOOT_REBOOT_ERROR_NONE) {
             return errorCode;
         }
diff --git a/services/core/java/com/android/server/trust/OWNERS b/services/core/java/com/android/server/trust/OWNERS
index b039c4b..e2c6ce1 100644
--- a/services/core/java/com/android/server/trust/OWNERS
+++ b/services/core/java/com/android/server/trust/OWNERS
@@ -1 +1 @@
-include /core/java/android/app/trust/OWNERS
+include /core/java/android/service/trust/OWNERS
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 5fde550..7a6d310 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -191,19 +191,18 @@
     static std::array<std::atomic<HalSupport>,
                       static_cast<int32_t>(Boost::DISPLAY_UPDATE_IMMINENT) + 1>
             boostSupportedArray = {HalSupport::UNKNOWN};
+    size_t idx = static_cast<size_t>(boost);
 
     // Quick return if boost is not supported by HAL
-    if (boost > Boost::DISPLAY_UPDATE_IMMINENT ||
-        boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::OFF) {
+    if (idx >= boostSupportedArray.size() || boostSupportedArray[idx] == HalSupport::OFF) {
         ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str());
         return;
     }
 
-    if (boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::UNKNOWN) {
+    if (boostSupportedArray[idx] == HalSupport::UNKNOWN) {
         bool isSupported = false;
         handle->isBoostSupported(boost, &isSupported);
-        boostSupportedArray[static_cast<int32_t>(boost)] =
-            isSupported ? HalSupport::ON : HalSupport::OFF;
+        boostSupportedArray[idx] = isSupported ? HalSupport::ON : HalSupport::OFF;
         if (!isSupported) {
             ALOGV("Skipped setPowerBoost %s because HAL doesn't support it",
                   toString(boost).c_str());
@@ -231,19 +230,18 @@
     // Need to increase the array if more mode supported.
     static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Mode::DISPLAY_INACTIVE) + 1>
             modeSupportedArray = {HalSupport::UNKNOWN};
+    size_t idx = static_cast<size_t>(mode);
 
     // Quick return if mode is not supported by HAL
-    if (mode > Mode::DISPLAY_INACTIVE ||
-        modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::OFF) {
+    if (idx >= modeSupportedArray.size() || modeSupportedArray[idx] == HalSupport::OFF) {
         ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
         return false;
     }
 
-    if (modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::UNKNOWN) {
+    if (modeSupportedArray[idx] == HalSupport::UNKNOWN) {
         bool isSupported = false;
         handle->isModeSupported(mode, &isSupported);
-        modeSupportedArray[static_cast<int32_t>(mode)] =
-            isSupported ? HalSupport::ON : HalSupport::OFF;
+        modeSupportedArray[idx] = isSupported ? HalSupport::ON : HalSupport::OFF;
         if (!isSupported) {
             ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
             return false;
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 1db5fcc..41562bb 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -208,4 +208,9 @@
             parcel.recycle();
         }
     }
-}
+
+    @Override
+    void setKeystorePassword(byte[] password, int userHandle) {
+
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
index 691d174..f2bb1d6 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
@@ -87,6 +87,11 @@
     }
 
     @Override
+    String getRebootEscrowFile(int userId) {
+        return makeDirs(mStorageDir, super.getRebootEscrowFile(userId)).getAbsolutePath();
+    }
+
+    @Override
     protected File getSyntheticPasswordDirectoryForUser(int userId) {
         return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser(
                 userId).getAbsolutePath());
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
index 2b9a05c..efa1b04 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
@@ -20,11 +20,16 @@
 import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.TrustManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
+import android.os.Handler;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
 
@@ -94,4 +99,11 @@
     public int checkCallingOrSelfPermission(String permission) {
         return PackageManager.PERMISSION_GRANTED;
     }
+
+    @Override
+    public Intent registerReceiverAsUser(BroadcastReceiver receiver,
+            UserHandle user, IntentFilter filter, String broadcastPermission,
+            Handler scheduler) {
+        return null;
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
index 8c08226..49a54ec 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -21,6 +21,11 @@
 import static android.content.pm.UserInfo.FLAG_PROFILE;
 import static android.os.UserHandle.USER_SYSTEM;
 
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_ESCROW_NOT_READY;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NONE;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_PROVIDER_MISMATCH;
+import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_STORE_ESCROW_KEY;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -327,7 +332,7 @@
 
         assertNull(
                 mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         assertNotNull(
                 mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));
         verify(mRebootEscrow).storeKey(any());
@@ -351,7 +356,7 @@
 
         when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
                 .thenAnswer(invocation -> invocation.getArgument(0));
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
 
         assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
@@ -373,7 +378,7 @@
         assertNull(
                 mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));
         doThrow(ServiceSpecificException.class).when(mRebootEscrow).storeKey(any());
-        assertFalse(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_STORE_ESCROW_KEY, mService.armRebootEscrowIfNeeded());
         verify(mRebootEscrow).storeKey(any());
     }
 
@@ -396,7 +401,7 @@
 
         assertNull(
                 mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         assertNotNull(
                 mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));
         verify(mRebootEscrow, times(1)).storeKey(any());
@@ -408,15 +413,24 @@
 
     @Test
     public void armService_NoInitialization_Failure() throws Exception {
-        assertFalse(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_ESCROW_NOT_READY, mService.armRebootEscrowIfNeeded());
         verifyNoMoreInteractions(mRebootEscrow);
     }
 
     @Test
     public void armService_RebootEscrowServiceException_Failure() throws Exception {
+        RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+        mService.setRebootEscrowListener(mockListener);
+        mService.prepareRebootEscrow();
+
+        clearInvocations(mRebootEscrow);
+        mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+        verify(mockListener).onPreparedForReboot(eq(true));
+        verify(mRebootEscrow, never()).storeKey(any());
+
         doThrow(RemoteException.class).when(mRebootEscrow).storeKey(any());
-        assertFalse(mService.armRebootEscrowIfNeeded());
-        verifyNoMoreInteractions(mRebootEscrow);
+        assertEquals(ARM_REBOOT_ERROR_STORE_ESCROW_KEY, mService.armRebootEscrowIfNeeded());
+        verify(mRebootEscrow).storeKey(any());
     }
 
     @Test
@@ -439,7 +453,7 @@
         verify(mRebootEscrow, never()).storeKey(any());
 
         ArgumentCaptor<byte[]> keyByteCaptor = ArgumentCaptor.forClass(byte[].class);
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         verify(mRebootEscrow).storeKey(keyByteCaptor.capture());
         verify(mKeyStoreManager).getKeyStoreEncryptionKey();
 
@@ -483,7 +497,7 @@
         // Use x -> x for both wrap & unwrap functions.
         when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
                 .thenAnswer(invocation -> invocation.getArgument(0));
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
         assertTrue(mStorage.hasRebootEscrowServerBlob());
 
@@ -520,7 +534,7 @@
         // Use x -> x for both wrap & unwrap functions.
         when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
                 .thenAnswer(invocation -> invocation.getArgument(0));
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
         assertTrue(mStorage.hasRebootEscrowServerBlob());
 
@@ -557,7 +571,7 @@
         // Use x -> x for both wrap & unwrap functions.
         when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
                 .thenAnswer(invocation -> invocation.getArgument(0));
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
         assertTrue(mStorage.hasRebootEscrowServerBlob());
 
@@ -597,7 +611,7 @@
         // Use x -> x for both wrap & unwrap functions.
         when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
                 .thenAnswer(invocation -> invocation.getArgument(0));
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
         assertTrue(mStorage.hasRebootEscrowServerBlob());
 
@@ -635,7 +649,7 @@
 
         verify(mRebootEscrow, never()).storeKey(any());
 
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         verify(mRebootEscrow).storeKey(any());
 
         assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
@@ -695,7 +709,7 @@
         verify(mRebootEscrow, never()).storeKey(any());
 
         ArgumentCaptor<byte[]> keyByteCaptor = ArgumentCaptor.forClass(byte[].class);
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         verify(mRebootEscrow).storeKey(keyByteCaptor.capture());
 
         assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
@@ -732,8 +746,7 @@
         verify(mockListener).onPreparedForReboot(eq(true));
 
         verify(mRebootEscrow, never()).storeKey(any());
-
-        assertTrue(mService.armRebootEscrowIfNeeded());
+        assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
         verify(mRebootEscrow).storeKey(any());
 
         assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
@@ -756,4 +769,28 @@
         assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_LOAD_ESCROW_KEY),
                 metricsErrorCodeCaptor.getValue());
     }
+
+    @Test
+    public void armServiceProviderMismatch_Failure() throws Exception {
+        RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+        mService.setRebootEscrowListener(mockListener);
+        mService.prepareRebootEscrow();
+
+        clearInvocations(mRebootEscrow);
+        mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
+        verify(mockListener).onPreparedForReboot(eq(true));
+        assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
+        verify(mRebootEscrow, never()).storeKey(any());
+
+        assertNull(
+                mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));
+        // Change the provider to server based, expect the reboot to fail
+        when(mInjected.forceServerBased()).thenReturn(true);
+        assertEquals(ARM_REBOOT_ERROR_PROVIDER_MISMATCH, mService.armRebootEscrowIfNeeded());
+        assertNull(
+                mStorage.getString(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, null, USER_SYSTEM));
+        // Verify that the escrow key & data have been cleared.
+        verify(mRebootEscrow).storeKey(eq(new byte[32]));
+        assertFalse(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
index 2b358ea..b64810b 100644
--- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
@@ -18,11 +18,14 @@
 
 import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME;
 import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED;
+import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE;
 import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.AdditionalMatchers.not;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -31,6 +34,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -91,7 +95,8 @@
         mUncryptUpdateFileWriter = mock(FileWriter.class);
         mLockSettingsInternal = mock(LockSettingsInternal.class);
 
-        when(mLockSettingsInternal.armRebootEscrow()).thenReturn(true);
+        doReturn(LockSettingsInternal.ARM_REBOOT_ERROR_NONE).when(mLockSettingsInternal)
+                .armRebootEscrow();
 
         Looper looper = InstrumentationRegistry.getContext().getMainLooper();
         mIPowerManager = mock(IPowerManager.class);
@@ -489,4 +494,27 @@
     }
 
     // TODO(xunchang) add more multi client tests
+
+    @Test
+    public void rebootWithLskf_armEscrowDataFatalError_Failure() throws Exception {
+        doReturn(LockSettingsInternal.ARM_REBOOT_ERROR_PROVIDER_MISMATCH)
+                .when(mLockSettingsInternal).armRebootEscrow();
+
+        assertTrue(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null));
+        mRecoverySystemService.onPreparedForReboot(true);
+        assertTrue(mRecoverySystemService.isLskfCaptured(FAKE_OTA_PACKAGE_NAME));
+
+        when(mSharedPreferences.getInt(eq(FAKE_OTA_PACKAGE_NAME
+                + RecoverySystemService.REQUEST_LSKF_COUNT_PREF_SUFFIX), anyInt())).thenReturn(1);
+        when(mSharedPreferences.getInt(eq(RecoverySystemService.LSKF_CAPTURED_COUNT_PREF),
+                anyInt())).thenReturn(1);
+        assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE,
+                mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true));
+        // Verify that the RoR preparation state has been cleared.
+        assertFalse(mRecoverySystemService.isLskfCaptured(FAKE_OTA_PACKAGE_NAME));
+        verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(5004 /* provider mismatch */),
+                eq(1000), eq(1) /* client count */, eq(1) /* request count */,
+                eq(true) /* slot switch */, anyBoolean(), anyInt(),
+                eq(1) /* lskf capture count */);
+    }
 }
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index f6d18fc..96e715e 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -637,18 +637,18 @@
             this.band = band;
             this.downlinkLowKhz = downlinkLowKhz;
             this.downlinkOffset = downlinkOffset;
+            this.downlinkRange = downlinkRange;
             this.uplinkLowKhz = uplinkLowKhz;
             this.uplinkOffset = uplinkOffset;
-            this.downlinkRange = downlinkRange;
             this.uplinkRange = uplinkRange;
         }
 
         int band;
         int downlinkLowKhz;
         int downlinkOffset;
+        int downlinkRange;
         int uplinkLowKhz;
         int uplinkOffset;
-        int downlinkRange;
         int uplinkRange;
     }
 
diff --git a/telephony/java/android/telephony/AccessNetworkUtils.java b/telephony/java/android/telephony/AccessNetworkUtils.java
index f29f3bd..6b82045 100644
--- a/telephony/java/android/telephony/AccessNetworkUtils.java
+++ b/telephony/java/android/telephony/AccessNetworkUtils.java
@@ -598,7 +598,8 @@
                             : earfcnFrequency.downlinkOffset;
                     break;
                 } else {
-                    Log.e(TAG, "Band and the range of EARFCN are not consistent.");
+                    Rlog.w(TAG,"Band and the range of EARFCN are not consistent: band = " + band
+                            + " ,earfcn = " + earfcn + " ,isUplink = " + isUplink);
                     return INVALID_FREQUENCY;
                 }
             }
@@ -617,7 +618,7 @@
     }
 
     private static boolean isInEarfcnRange(int earfcn, EutranBandArfcnFrequency earfcnFrequency,
-                                           boolean isUplink) {
+            boolean isUplink) {
         if (isUplink) {
             return earfcn >= earfcnFrequency.uplinkOffset && earfcn <= earfcnFrequency.uplinkRange;
         } else {
@@ -640,7 +641,8 @@
                             : uarfcnFrequency.downlinkOffset;
                     break;
                 } else {
-                    Log.e(TAG, "Band and the range of UARFCN are not consistent.");
+                    Rlog.w(TAG,"Band and the range of UARFCN are not consistent: band = " + band
+                            + " ,uarfcn = " + uarfcn + " ,isUplink = " + isUplink);
                     return INVALID_FREQUENCY;
                 }
             }
@@ -716,7 +718,8 @@
                             arfcnOffset);
                     break;
                 } else {
-                    Log.e(TAG, "Band and the range of ARFCN are not consistent.");
+                    Rlog.w(TAG,"Band and the range of ARFCN are not consistent: band = " + band
+                            + " ,arfcn = " + arfcn + " ,isUplink = " + isUplink);
                     return INVALID_FREQUENCY;
                 }
             }
@@ -733,7 +736,7 @@
      * Downlink actual frequency(kHz) = Uplink actual frequency + 10
      */
     private static int convertArfcnToFrequency(int arfcn, int uplinkFrequencyFirstKhz,
-                                               int arfcnOffset) {
+            int arfcnOffset) {
         return uplinkFrequencyFirstKhz + 200 * (arfcn - arfcnOffset);
     }
 
diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
index 454d5b5..2b45b3d 100644
--- a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
+++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
@@ -44,6 +44,9 @@
             setSubscriberId("MySubId")
             setPartialConnectivityAcceptable(false)
             setUnvalidatedConnectivityAcceptable(true)
+            if (isAtLeastS()) {
+                setBypassableVpn(true)
+            }
         }.build()
         if (isAtLeastS()) {
             // From S, the config will have 12 items
@@ -66,6 +69,7 @@
             if (isAtLeastS()) {
                 setNat64DetectionEnabled(false)
                 setProvisioningNotificationEnabled(false)
+                setBypassableVpn(true)
             }
         }.build()
 
@@ -78,6 +82,7 @@
         if (isAtLeastS()) {
             assertFalse(config.isNat64DetectionEnabled())
             assertFalse(config.isProvisioningNotificationEnabled())
+            assertTrue(config.isBypassableVpn())
         } else {
             assertTrue(config.isNat64DetectionEnabled())
             assertTrue(config.isProvisioningNotificationEnabled())
diff --git a/tools/hiddenapi/checksorted_sha.sh b/tools/hiddenapi/checksorted_sha.sh
deleted file mode 100755
index 451fed6..0000000
--- a/tools/hiddenapi/checksorted_sha.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-set -e
-LOCAL_DIR="$( dirname ${BASH_SOURCE} )"
-git show --name-only --pretty=format: $1 | grep "boot/hiddenapi/hiddenapi-.*txt" | while read file; do
-    diff <(git show $1:$file) <(git show $1:$file | $LOCAL_DIR/sort_api.sh )  || {
-      echo -e "\e[1m\e[31m$file $1 is not sorted or contains duplicates. To sort it correctly:\e[0m"
-      echo -e "\e[33m${LOCAL_DIR}/sort_api.sh $2/frameworks/base/$file\e[0m"
-      exit 1
-    }
-done
diff --git a/tools/hiddenapi/exclude.sh b/tools/hiddenapi/exclude.sh
index 822aba4..8b18f9b 100755
--- a/tools/hiddenapi/exclude.sh
+++ b/tools/hiddenapi/exclude.sh
@@ -10,7 +10,6 @@
   android.system \
   android.test \
   com.android.bouncycastle \
-  com.android.i18n.phonenumbers \
   com.android.okhttp \
   com.sun \
   dalvik \
diff --git a/tools/hiddenapi/sort_api.sh b/tools/hiddenapi/sort_api.sh
deleted file mode 100755
index 710da40..0000000
--- a/tools/hiddenapi/sort_api.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-set -e
-if [ -z "$1" ]; then
-  source_list=/dev/stdin
-  dest_list=/dev/stdout
-else
-  source_list="$1"
-  dest_list="$1"
-fi
-# Load the file
-readarray A < "$source_list"
-# Sort
-IFS=$'\n'
-# Stash away comments
-C=( $(grep -E '^#' <<< "${A[*]}" || :) )
-A=( $(grep -v -E '^#' <<< "${A[*]}" || :) )
-# Sort entries
-A=( $(LC_COLLATE=C sort -f <<< "${A[*]}") )
-A=( $(uniq <<< "${A[*]}") )
-# Concatenate comments and entries
-A=( ${C[*]} ${A[*]} )
-unset IFS
-# Dump array back into the file
-if [ ${#A[@]} -ne 0 ]; then
-  printf '%s\n' "${A[@]}" > "$dest_list"
-fi