Merge "Merge commit 'ae63546d19f91931a9a05015b149ddc19091c895' into manual_merge_ae63546d19f91931a9a05015b149ddc19091c895"
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index cf286e6..360ddd4 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -69,9 +69,11 @@
         "src/external/GpuStatsPuller.cpp",
         "src/external/Perfetto.cpp",
         "src/external/PowerStatsPuller.cpp",
+        "src/external/PullResultReceiver.cpp",
         "src/external/puller_util.cpp",
         "src/external/ResourceHealthManagerPuller.cpp",
         "src/external/StatsCallbackPuller.cpp",
+        "src/external/StatsCallbackPullerDeprecated.cpp",
         "src/external/StatsCompanionServicePuller.cpp",
         "src/external/StatsPuller.cpp",
         "src/external/StatsPullerManager.cpp",
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 2c325ba6..1fd3abf 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1293,7 +1293,11 @@
 Status StatsService::registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownNs,
                                     int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
                                     const sp<android::os::IPullAtomCallback>& pullerCallback) {
+    ENFORCE_UID(AID_SYSTEM);
+
     VLOG("StatsService::registerPuller called.");
+    mPullerManager->RegisterPullAtomCallback(uid, atomTag, coolDownNs, timeoutNs, additiveFields,
+                                             pullerCallback);
     return Status::ok();
 }
 
diff --git a/cmds/statsd/src/external/PullResultReceiver.cpp b/cmds/statsd/src/external/PullResultReceiver.cpp
new file mode 100644
index 0000000..6bd0545
--- /dev/null
+++ b/cmds/statsd/src/external/PullResultReceiver.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PullResultReceiver.h"
+
+using namespace android::binder;
+using namespace android::util;
+using namespace std;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+PullResultReceiver::PullResultReceiver(
+        std::function<void(int32_t, bool, const vector<android::util::StatsEvent>&)> pullFinishCb)
+    : pullFinishCallback(std::move(pullFinishCb)) {
+}
+
+Status PullResultReceiver::pullFinished(int32_t atomTag, bool success,
+                                        const vector<StatsEvent>& output) {
+    pullFinishCallback(atomTag, success, output);
+    return Status::ok();
+}
+
+PullResultReceiver::~PullResultReceiver() {
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/external/PullResultReceiver.h b/cmds/statsd/src/external/PullResultReceiver.h
new file mode 100644
index 0000000..f731f77
--- /dev/null
+++ b/cmds/statsd/src/external/PullResultReceiver.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/os/BnPullAtomResultReceiver.h>
+
+using namespace std;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class PullResultReceiver : public BnPullAtomResultReceiver {
+public:
+    PullResultReceiver(function<void(int32_t, bool, const vector<android::util::StatsEvent>&)>
+                               pullFinishCallback);
+    ~PullResultReceiver();
+
+    /**
+     * Binder call for finishing a pull.
+     */
+    binder::Status pullFinished(int32_t atomTag, bool success,
+                                        const vector<android::util::StatsEvent>& output) override;
+
+private:
+    function<void(int32_t, bool, const vector<android::util::StatsEvent>&)> pullFinishCallback;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.cpp b/cmds/statsd/src/external/StatsCallbackPuller.cpp
index d718273..92db684 100644
--- a/cmds/statsd/src/external/StatsCallbackPuller.cpp
+++ b/cmds/statsd/src/external/StatsCallbackPuller.cpp
@@ -17,21 +17,27 @@
 #define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
-#include <android/os/IStatsPullerCallback.h>
-
 #include "StatsCallbackPuller.h"
+
+#include <android/os/IPullAtomCallback.h>
+#include <android/util/StatsEvent.h>
+
+#include "PullResultReceiver.h"
+#include "StatsPullerManager.h"
 #include "logd/LogEvent.h"
 #include "stats_log_util.h"
 
 using namespace android::binder;
+using namespace android::util;
+using namespace std;
 
 namespace android {
 namespace os {
 namespace statsd {
 
-StatsCallbackPuller::StatsCallbackPuller(int tagId, const sp<IStatsPullerCallback>& callback) :
-        StatsPuller(tagId), mCallback(callback) {
-        VLOG("StatsCallbackPuller created for tag %d", tagId);
+StatsCallbackPuller::StatsCallbackPuller(int tagId, const sp<IPullAtomCallback>& callback)
+    : StatsPuller(tagId), mCallback(callback) {
+    VLOG("StatsCallbackPuller created for tag %d", tagId);
 }
 
 bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
@@ -40,20 +46,57 @@
         ALOGW("No callback registered");
         return false;
     }
-    int64_t wallClockTimeNs = getWallClockNs();
-    int64_t elapsedTimeNs = getElapsedRealtimeNs();
-    vector<StatsLogEventWrapper> returned_value;
-    Status status = mCallback->pullData(mTagId, elapsedTimeNs, wallClockTimeNs, &returned_value);
+
+    // Shared variables needed in the result receiver.
+    shared_ptr<mutex> cv_mutex = make_shared<mutex>();
+    shared_ptr<condition_variable> cv = make_shared<condition_variable>();
+    shared_ptr<bool> pullFinish = make_shared<bool>(false);
+    shared_ptr<bool> pullSuccess = make_shared<bool>(false);
+    shared_ptr<vector<shared_ptr<LogEvent>>> sharedData =
+            make_shared<vector<shared_ptr<LogEvent>>>();
+
+    sp<PullResultReceiver> resultReceiver = new PullResultReceiver(
+            [cv_mutex, cv, pullFinish, pullSuccess, sharedData](
+                    int32_t atomTag, bool success, const vector<StatsEvent>& output) {
+                // This is the result of the pull, executing in a statsd binder thread.
+                // The pull could have taken a long time, and we should only modify
+                // data (the output param) if the pointer is in scope and the pull did not time out.
+                {
+                    lock_guard<mutex> lk(*cv_mutex);
+                    // TODO: fill the shared vector of LogEvents once StatsEvent is complete.
+                    *pullSuccess = success;
+                    *pullFinish = true;
+                }
+                cv->notify_one();
+            });
+
+    // Initiate the pull.
+    Status status = mCallback->onPullAtom(mTagId, resultReceiver);
     if (!status.isOk()) {
-        ALOGW("StatsCallbackPuller::pull failed for %d", mTagId);
         return false;
     }
-    data->clear();
-    for (const StatsLogEventWrapper& it: returned_value) {
-        LogEvent::createLogEvents(it, *data);
+
+    {
+        unique_lock<mutex> unique_lk(*cv_mutex);
+        int64_t pullTimeoutNs =
+                StatsPullerManager::kAllPullAtomInfo.at({.atomTag = mTagId}).pullTimeoutNs;
+        // Wait until the pull finishes, or until the pull timeout.
+        cv->wait_for(unique_lk, chrono::nanoseconds(pullTimeoutNs),
+                     [pullFinish] { return *pullFinish; });
+        if (!*pullFinish) {
+            // Note: The parent stats puller will also note that there was a timeout and that the
+            // cache should be cleared. Once we migrate all pullers to this callback, we could
+            // consolidate the logic.
+            return true;
+        } else {
+            // Only copy the data if we did not timeout and the pull was successful.
+            if (pullSuccess) {
+                *data = std::move(*sharedData);
+            }
+            VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
+            return *pullSuccess;
+        }
     }
-    VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
-    return true;
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/external/StatsCallbackPuller.h b/cmds/statsd/src/external/StatsCallbackPuller.h
index c4bfa89..ce506c7 100644
--- a/cmds/statsd/src/external/StatsCallbackPuller.h
+++ b/cmds/statsd/src/external/StatsCallbackPuller.h
@@ -16,8 +16,9 @@
 
 #pragma once
 
-#include <android/os/IStatsPullerCallback.h>
+#include <android/os/IPullAtomCallback.h>
 #include <utils/String16.h>
+
 #include "StatsPuller.h"
 
 namespace android {
@@ -26,11 +27,11 @@
 
 class StatsCallbackPuller : public StatsPuller {
 public:
-    explicit StatsCallbackPuller(int tagId, const sp<IStatsPullerCallback>& callback);
+    explicit StatsCallbackPuller(int tagId, const sp<IPullAtomCallback>& callback);
 
 private:
     bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
-    const sp<IStatsPullerCallback> mCallback;
+    const sp<IPullAtomCallback> mCallback;
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp
new file mode 100644
index 0000000..4f88a91
--- /dev/null
+++ b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define DEBUG false  // STOPSHIP if true
+#include "Log.h"
+
+#include "StatsCallbackPullerDeprecated.h"
+
+#include <android/os/IStatsPullerCallback.h>
+
+#include "logd/LogEvent.h"
+#include "stats_log_util.h"
+
+using namespace android::binder;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+StatsCallbackPullerDeprecated::StatsCallbackPullerDeprecated(
+        int tagId, const sp<IStatsPullerCallback>& callback)
+    : StatsPuller(tagId), mCallback(callback) {
+    VLOG("StatsCallbackPuller created for tag %d", tagId);
+}
+
+bool StatsCallbackPullerDeprecated::PullInternal(vector<shared_ptr<LogEvent>>* data) {
+    VLOG("StatsCallbackPuller called for tag %d", mTagId)
+    if (mCallback == nullptr) {
+        ALOGW("No callback registered");
+        return false;
+    }
+    int64_t wallClockTimeNs = getWallClockNs();
+    int64_t elapsedTimeNs = getElapsedRealtimeNs();
+    vector<StatsLogEventWrapper> returned_value;
+    Status status = mCallback->pullData(mTagId, elapsedTimeNs, wallClockTimeNs, &returned_value);
+    if (!status.isOk()) {
+        ALOGW("StatsCallbackPuller::pull failed for %d", mTagId);
+        return false;
+    }
+    data->clear();
+    for (const StatsLogEventWrapper& it : returned_value) {
+        LogEvent::createLogEvents(it, *data);
+    }
+    VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
+    return true;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h
new file mode 100644
index 0000000..0289029
--- /dev/null
+++ b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/os/IStatsPullerCallback.h>
+#include <utils/String16.h>
+
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class StatsCallbackPullerDeprecated : public StatsPuller {
+public:
+    explicit StatsCallbackPullerDeprecated(int tagId, const sp<IStatsPullerCallback>& callback);
+
+private:
+    bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
+    const sp<IStatsPullerCallback> mCallback;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp
index 9552c0a..3c6bc2d 100644
--- a/cmds/statsd/src/external/StatsPuller.cpp
+++ b/cmds/statsd/src/external/StatsPuller.cpp
@@ -40,8 +40,9 @@
     lock_guard<std::mutex> lock(mLock);
     int64_t elapsedTimeNs = getElapsedRealtimeNs();
     StatsdStats::getInstance().notePull(mTagId);
-    const bool shouldUseCache = elapsedTimeNs - mLastPullTimeNs <
-                                StatsPullerManager::kAllPullAtomInfo.at(mTagId).coolDownNs;
+    const bool shouldUseCache =
+            elapsedTimeNs - mLastPullTimeNs <
+            StatsPullerManager::kAllPullAtomInfo.at({.atomTag = mTagId}).coolDownNs;
     if (shouldUseCache) {
         if (mHasGoodData) {
             (*data) = mCachedData;
@@ -63,7 +64,8 @@
     const int64_t pullDurationNs = getElapsedRealtimeNs() - elapsedTimeNs;
     StatsdStats::getInstance().notePullTime(mTagId, pullDurationNs);
     const bool pullTimeOut =
-            pullDurationNs > StatsPullerManager::kAllPullAtomInfo.at(mTagId).pullTimeoutNs;
+            pullDurationNs >
+            StatsPullerManager::kAllPullAtomInfo.at({.atomTag = mTagId}).pullTimeoutNs;
     if (pullTimeOut) {
         // Something went wrong. Discard the data.
         clearCacheLocked();
@@ -100,7 +102,7 @@
 
 int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) {
     if (timestampNs - mLastPullTimeNs >
-        StatsPullerManager::kAllPullAtomInfo.at(mTagId).coolDownNs) {
+        StatsPullerManager::kAllPullAtomInfo.at({.atomTag = mTagId}).coolDownNs) {
         return clearCache();
     } else {
         return 0;
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 535fcfb..ce27ce6 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -19,6 +19,7 @@
 
 #include "StatsPullerManager.h"
 
+#include <android/os/IPullAtomCallback.h>
 #include <android/os/IStatsCompanionService.h>
 #include <android/os/IStatsPullerCallback.h>
 #include <cutils/log.h>
@@ -37,6 +38,7 @@
 #include "PowerStatsPuller.h"
 #include "ResourceHealthManagerPuller.h"
 #include "StatsCallbackPuller.h"
+#include "StatsCallbackPullerDeprecated.h"
 #include "StatsCompanionServicePuller.h"
 #include "SubsystemSleepStatePuller.h"
 #include "SurfaceflingerStatsPuller.h"
@@ -57,224 +59,226 @@
 // Values smaller than this may require to update the alarm.
 const int64_t NO_ALARM_UPDATE = INT64_MAX;
 
-std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
+std::map<PullerKey, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
         // wifi_bytes_transfer
-        {android::util::WIFI_BYTES_TRANSFER,
+        {{.atomTag = android::util::WIFI_BYTES_TRANSFER},
          {.additiveFields = {2, 3, 4, 5},
           .puller = new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER)}},
         // wifi_bytes_transfer_by_fg_bg
-        {android::util::WIFI_BYTES_TRANSFER_BY_FG_BG,
+        {{.atomTag = android::util::WIFI_BYTES_TRANSFER_BY_FG_BG},
          {.additiveFields = {3, 4, 5, 6},
           .puller = new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER_BY_FG_BG)}},
         // mobile_bytes_transfer
-        {android::util::MOBILE_BYTES_TRANSFER,
+        {{.atomTag = android::util::MOBILE_BYTES_TRANSFER},
          {.additiveFields = {2, 3, 4, 5},
           .puller = new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER)}},
         // mobile_bytes_transfer_by_fg_bg
-        {android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG,
+        {{.atomTag = android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG},
          {.additiveFields = {3, 4, 5, 6},
           .puller =
                   new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG)}},
         // bluetooth_bytes_transfer
-        {android::util::BLUETOOTH_BYTES_TRANSFER,
+        {{.atomTag = android::util::BLUETOOTH_BYTES_TRANSFER},
          {.additiveFields = {2, 3},
           .puller = new StatsCompanionServicePuller(android::util::BLUETOOTH_BYTES_TRANSFER)}},
         // kernel_wakelock
-        {android::util::KERNEL_WAKELOCK,
+        {{.atomTag = android::util::KERNEL_WAKELOCK},
          {.puller = new StatsCompanionServicePuller(android::util::KERNEL_WAKELOCK)}},
         // subsystem_sleep_state
-        {android::util::SUBSYSTEM_SLEEP_STATE, {.puller = new SubsystemSleepStatePuller()}},
+        {{.atomTag = android::util::SUBSYSTEM_SLEEP_STATE},
+         {.puller = new SubsystemSleepStatePuller()}},
         // on_device_power_measurement
-        {android::util::ON_DEVICE_POWER_MEASUREMENT, {.puller = new PowerStatsPuller()}},
+        {{.atomTag = android::util::ON_DEVICE_POWER_MEASUREMENT},
+         {.puller = new PowerStatsPuller()}},
         // cpu_time_per_freq
-        {android::util::CPU_TIME_PER_FREQ,
+        {{.atomTag = android::util::CPU_TIME_PER_FREQ},
          {.additiveFields = {3},
           .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_FREQ)}},
         // cpu_time_per_uid
-        {android::util::CPU_TIME_PER_UID,
+        {{.atomTag = android::util::CPU_TIME_PER_UID},
          {.additiveFields = {2, 3},
           .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID)}},
         // cpu_time_per_uid_freq
         // the throttling is 3sec, handled in
         // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
-        {android::util::CPU_TIME_PER_UID_FREQ,
+        {{.atomTag = android::util::CPU_TIME_PER_UID_FREQ},
          {.additiveFields = {4},
           .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_UID_FREQ)}},
         // cpu_active_time
         // the throttling is 3sec, handled in
         // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
-        {android::util::CPU_ACTIVE_TIME,
+        {{.atomTag = android::util::CPU_ACTIVE_TIME},
          {.additiveFields = {2},
           .puller = new StatsCompanionServicePuller(android::util::CPU_ACTIVE_TIME)}},
         // cpu_cluster_time
         // the throttling is 3sec, handled in
         // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
-        {android::util::CPU_CLUSTER_TIME,
+        {{.atomTag = android::util::CPU_CLUSTER_TIME},
          {.additiveFields = {3},
           .puller = new StatsCompanionServicePuller(android::util::CPU_CLUSTER_TIME)}},
         // wifi_activity_energy_info
-        {android::util::WIFI_ACTIVITY_INFO,
+        {{.atomTag = android::util::WIFI_ACTIVITY_INFO},
          {.puller = new StatsCompanionServicePuller(android::util::WIFI_ACTIVITY_INFO)}},
         // modem_activity_info
-        {android::util::MODEM_ACTIVITY_INFO,
+        {{.atomTag = android::util::MODEM_ACTIVITY_INFO},
          {.puller = new StatsCompanionServicePuller(android::util::MODEM_ACTIVITY_INFO)}},
         // bluetooth_activity_info
-        {android::util::BLUETOOTH_ACTIVITY_INFO,
+        {{.atomTag = android::util::BLUETOOTH_ACTIVITY_INFO},
          {.puller = new StatsCompanionServicePuller(android::util::BLUETOOTH_ACTIVITY_INFO)}},
         // system_elapsed_realtime
-        {android::util::SYSTEM_ELAPSED_REALTIME,
+        {{.atomTag = android::util::SYSTEM_ELAPSED_REALTIME},
          {.coolDownNs = NS_PER_SEC,
           .puller = new StatsCompanionServicePuller(android::util::SYSTEM_ELAPSED_REALTIME),
           .pullTimeoutNs = NS_PER_SEC / 2,
          }},
         // system_uptime
-        {android::util::SYSTEM_UPTIME,
+        {{.atomTag = android::util::SYSTEM_UPTIME},
          {.puller = new StatsCompanionServicePuller(android::util::SYSTEM_UPTIME)}},
         // remaining_battery_capacity
-        {android::util::REMAINING_BATTERY_CAPACITY,
+        {{.atomTag = android::util::REMAINING_BATTERY_CAPACITY},
          {.puller = new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}},
         // full_battery_capacity
-        {android::util::FULL_BATTERY_CAPACITY,
+        {{.atomTag = android::util::FULL_BATTERY_CAPACITY},
          {.puller = new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}},
         // battery_voltage
-        {android::util::BATTERY_VOLTAGE,
+        {{.atomTag = android::util::BATTERY_VOLTAGE},
          {.puller = new ResourceHealthManagerPuller(android::util::BATTERY_VOLTAGE)}},
         // battery_level
-        {android::util::BATTERY_LEVEL,
+        {{.atomTag = android::util::BATTERY_LEVEL},
          {.puller = new ResourceHealthManagerPuller(android::util::BATTERY_LEVEL)}},
         // battery_cycle_count
-        {android::util::BATTERY_CYCLE_COUNT,
+        {{.atomTag = android::util::BATTERY_CYCLE_COUNT},
          {.puller = new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}},
         // process_memory_state
-        {android::util::PROCESS_MEMORY_STATE,
+        {{.atomTag = android::util::PROCESS_MEMORY_STATE},
          {.additiveFields = {4, 5, 6, 7, 8},
           .puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
         // process_memory_high_water_mark
-        {android::util::PROCESS_MEMORY_HIGH_WATER_MARK,
+        {{.atomTag = android::util::PROCESS_MEMORY_HIGH_WATER_MARK},
          {.puller =
                   new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}},
         // process_memory_snapshot
-        {android::util::PROCESS_MEMORY_SNAPSHOT,
+        {{.atomTag = android::util::PROCESS_MEMORY_SNAPSHOT},
          {.puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_SNAPSHOT)}},
         // system_ion_heap_size
-        {android::util::SYSTEM_ION_HEAP_SIZE,
+        {{.atomTag = android::util::SYSTEM_ION_HEAP_SIZE},
          {.puller = new StatsCompanionServicePuller(android::util::SYSTEM_ION_HEAP_SIZE)}},
         // process_system_ion_heap_size
-        {android::util::PROCESS_SYSTEM_ION_HEAP_SIZE,
+        {{.atomTag = android::util::PROCESS_SYSTEM_ION_HEAP_SIZE},
          {.puller = new StatsCompanionServicePuller(android::util::PROCESS_SYSTEM_ION_HEAP_SIZE)}},
         // temperature
-        {android::util::TEMPERATURE,
+        {{.atomTag = android::util::TEMPERATURE},
          {.puller = new StatsCompanionServicePuller(android::util::TEMPERATURE)}},
         // cooling_device
-        {android::util::COOLING_DEVICE,
+        {{.atomTag = android::util::COOLING_DEVICE},
          {.puller = new StatsCompanionServicePuller(android::util::COOLING_DEVICE)}},
         // binder_calls
-        {android::util::BINDER_CALLS,
+        {{.atomTag = android::util::BINDER_CALLS},
          {.additiveFields = {4, 5, 6, 8, 12},
           .puller = new StatsCompanionServicePuller(android::util::BINDER_CALLS)}},
         // binder_calls_exceptions
-        {android::util::BINDER_CALLS_EXCEPTIONS,
+        {{.atomTag = android::util::BINDER_CALLS_EXCEPTIONS},
          {.puller = new StatsCompanionServicePuller(android::util::BINDER_CALLS_EXCEPTIONS)}},
         // looper_stats
-        {android::util::LOOPER_STATS,
+        {{.atomTag = android::util::LOOPER_STATS},
          {.additiveFields = {5, 6, 7, 8, 9},
           .puller = new StatsCompanionServicePuller(android::util::LOOPER_STATS)}},
         // Disk Stats
-        {android::util::DISK_STATS,
+        {{.atomTag = android::util::DISK_STATS},
          {.puller = new StatsCompanionServicePuller(android::util::DISK_STATS)}},
         // Directory usage
-        {android::util::DIRECTORY_USAGE,
+        {{.atomTag = android::util::DIRECTORY_USAGE},
          {.puller = new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}},
         // Size of app's code, data, and cache
-        {android::util::APP_SIZE,
+        {{.atomTag = android::util::APP_SIZE},
          {.puller = new StatsCompanionServicePuller(android::util::APP_SIZE)}},
         // Size of specific categories of files. Eg. Music.
-        {android::util::CATEGORY_SIZE,
+        {{.atomTag = android::util::CATEGORY_SIZE},
          {.puller = new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}},
         // Number of fingerprints enrolled for each user.
-        {android::util::NUM_FINGERPRINTS_ENROLLED,
+        {{.atomTag = android::util::NUM_FINGERPRINTS_ENROLLED},
          {.puller = new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS_ENROLLED)}},
         // Number of faces enrolled for each user.
-        {android::util::NUM_FACES_ENROLLED,
+        {{.atomTag = android::util::NUM_FACES_ENROLLED},
          {.puller = new StatsCompanionServicePuller(android::util::NUM_FACES_ENROLLED)}},
         // ProcStats.
-        {android::util::PROC_STATS,
+        {{.atomTag = android::util::PROC_STATS},
          {.puller = new StatsCompanionServicePuller(android::util::PROC_STATS)}},
         // ProcStatsPkgProc.
-        {android::util::PROC_STATS_PKG_PROC,
+        {{.atomTag = android::util::PROC_STATS_PKG_PROC},
          {.puller = new StatsCompanionServicePuller(android::util::PROC_STATS_PKG_PROC)}},
         // Disk I/O stats per uid.
-        {android::util::DISK_IO,
+        {{.atomTag = android::util::DISK_IO},
          {.additiveFields = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
           .coolDownNs = 3 * NS_PER_SEC,
           .puller = new StatsCompanionServicePuller(android::util::DISK_IO)}},
         // PowerProfile constants for power model calculations.
-        {android::util::POWER_PROFILE,
+        {{.atomTag = android::util::POWER_PROFILE},
          {.puller = new StatsCompanionServicePuller(android::util::POWER_PROFILE)}},
         // Process cpu stats. Min cool-down is 5 sec, inline with what AcitivityManagerService uses.
-        {android::util::PROCESS_CPU_TIME,
+        {{.atomTag = android::util::PROCESS_CPU_TIME},
          {.coolDownNs = 5 * NS_PER_SEC /* min cool-down in seconds*/,
           .puller = new StatsCompanionServicePuller(android::util::PROCESS_CPU_TIME)}},
-        {android::util::CPU_TIME_PER_THREAD_FREQ,
+        {{.atomTag = android::util::CPU_TIME_PER_THREAD_FREQ},
          {.additiveFields = {7, 9, 11, 13, 15, 17, 19, 21},
           .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_THREAD_FREQ)}},
         // DeviceCalculatedPowerUse.
-        {android::util::DEVICE_CALCULATED_POWER_USE,
+        {{.atomTag = android::util::DEVICE_CALCULATED_POWER_USE},
          {.puller = new StatsCompanionServicePuller(android::util::DEVICE_CALCULATED_POWER_USE)}},
         // DeviceCalculatedPowerBlameUid.
-        {android::util::DEVICE_CALCULATED_POWER_BLAME_UID,
+        {{.atomTag = android::util::DEVICE_CALCULATED_POWER_BLAME_UID},
          {.puller = new StatsCompanionServicePuller(
                   android::util::DEVICE_CALCULATED_POWER_BLAME_UID)}},
         // DeviceCalculatedPowerBlameOther.
-        {android::util::DEVICE_CALCULATED_POWER_BLAME_OTHER,
+        {{.atomTag = android::util::DEVICE_CALCULATED_POWER_BLAME_OTHER},
          {.puller = new StatsCompanionServicePuller(
                   android::util::DEVICE_CALCULATED_POWER_BLAME_OTHER)}},
         // DebugElapsedClock.
-        {android::util::DEBUG_ELAPSED_CLOCK,
+        {{.atomTag = android::util::DEBUG_ELAPSED_CLOCK},
          {.additiveFields = {1, 2, 3, 4},
           .puller = new StatsCompanionServicePuller(android::util::DEBUG_ELAPSED_CLOCK)}},
         // DebugFailingElapsedClock.
-        {android::util::DEBUG_FAILING_ELAPSED_CLOCK,
+        {{.atomTag = android::util::DEBUG_FAILING_ELAPSED_CLOCK},
          {.additiveFields = {1, 2, 3, 4},
           .puller = new StatsCompanionServicePuller(android::util::DEBUG_FAILING_ELAPSED_CLOCK)}},
         // BuildInformation.
-        {android::util::BUILD_INFORMATION,
+        {{.atomTag = android::util::BUILD_INFORMATION},
          {.puller = new StatsCompanionServicePuller(android::util::BUILD_INFORMATION)}},
         // RoleHolder.
-        {android::util::ROLE_HOLDER,
+        {{.atomTag = android::util::ROLE_HOLDER},
          {.puller = new StatsCompanionServicePuller(android::util::ROLE_HOLDER)}},
         // PermissionState.
-        {android::util::DANGEROUS_PERMISSION_STATE,
+        {{.atomTag = android::util::DANGEROUS_PERMISSION_STATE},
          {.puller = new StatsCompanionServicePuller(android::util::DANGEROUS_PERMISSION_STATE)}},
         // TrainInfo.
-        {android::util::TRAIN_INFO, {.puller = new TrainInfoPuller()}},
+        {{.atomTag = android::util::TRAIN_INFO}, {.puller = new TrainInfoPuller()}},
         // TimeZoneDataInfo.
-        {android::util::TIME_ZONE_DATA_INFO,
+        {{.atomTag = android::util::TIME_ZONE_DATA_INFO},
          {.puller = new StatsCompanionServicePuller(android::util::TIME_ZONE_DATA_INFO)}},
         // ExternalStorageInfo
-        {android::util::EXTERNAL_STORAGE_INFO,
+        {{.atomTag = android::util::EXTERNAL_STORAGE_INFO},
          {.puller = new StatsCompanionServicePuller(android::util::EXTERNAL_STORAGE_INFO)}},
         // GpuStatsGlobalInfo
-        {android::util::GPU_STATS_GLOBAL_INFO,
+        {{.atomTag = android::util::GPU_STATS_GLOBAL_INFO},
          {.puller = new GpuStatsPuller(android::util::GPU_STATS_GLOBAL_INFO)}},
         // GpuStatsAppInfo
-        {android::util::GPU_STATS_APP_INFO,
+        {{.atomTag = android::util::GPU_STATS_APP_INFO},
          {.puller = new GpuStatsPuller(android::util::GPU_STATS_APP_INFO)}},
         // AppsOnExternalStorageInfo
-        {android::util::APPS_ON_EXTERNAL_STORAGE_INFO,
+        {{.atomTag = android::util::APPS_ON_EXTERNAL_STORAGE_INFO},
          {.puller = new StatsCompanionServicePuller(android::util::APPS_ON_EXTERNAL_STORAGE_INFO)}},
         // Face Settings
-        {android::util::FACE_SETTINGS,
+        {{.atomTag = android::util::FACE_SETTINGS},
          {.puller = new StatsCompanionServicePuller(android::util::FACE_SETTINGS)}},
         // App ops
-        {android::util::APP_OPS,
+        {{.atomTag = android::util::APP_OPS},
          {.puller = new StatsCompanionServicePuller(android::util::APP_OPS)}},
         // SurfaceflingerStatsGlobalInfo
-        {android::util::SURFACEFLINGER_STATS_GLOBAL_INFO,
+        {{.atomTag = android::util::SURFACEFLINGER_STATS_GLOBAL_INFO},
          {.puller =
                   new SurfaceflingerStatsPuller(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO)}},
         // VmsClientStats
-        {android::util::VMS_CLIENT_STATS,
+        {{.atomTag = android::util::VMS_CLIENT_STATS},
          {.additiveFields = {5, 6, 7, 8, 9, 10},
           .puller = new CarStatsPuller(android::util::VMS_CLIENT_STATS)}},
 };
@@ -285,8 +289,8 @@
 bool StatsPullerManager::Pull(int tagId, vector<shared_ptr<LogEvent>>* data) {
     VLOG("Initiating pulling %d", tagId);
 
-    if (kAllPullAtomInfo.find(tagId) != kAllPullAtomInfo.end()) {
-        bool ret = kAllPullAtomInfo.find(tagId)->second.puller->Pull(data);
+    if (kAllPullAtomInfo.find({.atomTag = tagId}) != kAllPullAtomInfo.end()) {
+        bool ret = kAllPullAtomInfo.find({.atomTag = tagId})->second.puller->Pull(data);
         VLOG("pulled %d items", (int)data->size());
         if (!ret) {
             StatsdStats::getInstance().notePullFailed(tagId);
@@ -300,7 +304,8 @@
 
 bool StatsPullerManager::PullerForMatcherExists(int tagId) const {
     // Vendor pulled atoms might be registered after we parse the config.
-    return isVendorPulledAtom(tagId) || kAllPullAtomInfo.find(tagId) != kAllPullAtomInfo.end();
+    return isVendorPulledAtom(tagId) ||
+           kAllPullAtomInfo.find({.atomTag = tagId}) != kAllPullAtomInfo.end();
 }
 
 void StatsPullerManager::updateAlarmLocked() {
@@ -469,6 +474,7 @@
     return totalCleared;
 }
 
+// Deprecated, remove after puller API is complete.
 void StatsPullerManager::RegisterPullerCallback(int32_t atomTag,
         const sp<IStatsPullerCallback>& callback) {
     AutoMutex _l(mLock);
@@ -479,7 +485,22 @@
     }
     VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
     StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
-    kAllPullAtomInfo[atomTag] = {.puller = new StatsCallbackPuller(atomTag, callback)};
+    kAllPullAtomInfo[{.atomTag = atomTag}] = {
+            .puller = new StatsCallbackPullerDeprecated(atomTag, callback)};
+}
+
+void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag,
+                                                  const int64_t coolDownNs, const int64_t timeoutNs,
+                                                  const vector<int32_t>& additiveFields,
+                                                  const sp<IPullAtomCallback>& callback) {
+    AutoMutex _l(mLock);
+    VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
+    // TODO: linkToDeath with the callback so that we can remove it and delete the puller.
+    StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
+    kAllPullAtomInfo[{.atomTag = atomTag}] = {.additiveFields = additiveFields,
+                                              .coolDownNs = coolDownNs,
+                                              .pullTimeoutNs = timeoutNs,
+                                              .puller = new StatsCallbackPuller(atomTag, callback)};
 }
 
 void StatsPullerManager::UnregisterPullerCallback(int32_t atomTag) {
@@ -489,7 +510,7 @@
         return;
     }
     StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
-    kAllPullAtomInfo.erase(atomTag);
+    kAllPullAtomInfo.erase({.atomTag = atomTag});
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 4ea1386..1bd9f92 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -16,15 +16,18 @@
 
 #pragma once
 
+#include <android/os/IPullAtomCallback.h>
 #include <android/os/IStatsCompanionService.h>
 #include <android/os/IStatsPullerCallback.h>
 #include <binder/IServiceManager.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
+
 #include <list>
 #include <string>
 #include <unordered_map>
 #include <vector>
+
 #include "PullDataReceiver.h"
 #include "StatsPuller.h"
 #include "guardrail/StatsdStats.h"
@@ -53,6 +56,27 @@
     int64_t pullTimeoutNs = StatsdStats::kPullMaxDelayNs;
 } PullAtomInfo;
 
+typedef struct PullerKey {
+    // The uid of the process that registers this puller.
+    const int uid = -1;
+    // The atom that this puller is for.
+    const int atomTag;
+
+    bool operator<(const PullerKey& that) const {
+        if (uid < that.uid) {
+            return true;
+        }
+        if (uid > that.uid) {
+            return false;
+        }
+        return atomTag < that.atomTag;
+    };
+
+    bool operator==(const PullerKey& that) const {
+        return uid == that.uid && atomTag == that.atomTag;
+    };
+} PullerKey;
+
 class StatsPullerManager : public virtual RefBase {
 public:
     StatsPullerManager();
@@ -92,12 +116,16 @@
 
     void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
 
-    void RegisterPullerCallback(int32_t atomTag,
-                                const sp<IStatsPullerCallback>& callback);
+    // Deprecated, remove after puller API is complete.
+    void RegisterPullerCallback(int32_t atomTag, const sp<IStatsPullerCallback>& callback);
+
+    void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs,
+                                  const int64_t timeoutNs, const vector<int32_t>& additiveFields,
+                                  const sp<IPullAtomCallback>& callback);
 
     void UnregisterPullerCallback(int32_t atomTag);
 
-    static std::map<int, PullAtomInfo> kAllPullAtomInfo;
+    static std::map<PullerKey, PullAtomInfo> kAllPullAtomInfo;
 
 private:
     sp<IStatsCompanionService> mStatsCompanionService = nullptr;
diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp
index 0b9b6ab..53fa630 100644
--- a/cmds/statsd/src/external/puller_util.cpp
+++ b/cmds/statsd/src/external/puller_util.cpp
@@ -55,7 +55,7 @@
  */
 void mapAndMergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const sp<UidMap>& uidMap,
                                       int tagId) {
-    if (StatsPullerManager::kAllPullAtomInfo.find(tagId) ==
+    if (StatsPullerManager::kAllPullAtomInfo.find({.atomTag = tagId}) ==
         StatsPullerManager::kAllPullAtomInfo.end()) {
         VLOG("Unknown pull atom id %d", tagId);
         return;
@@ -121,7 +121,7 @@
 
     vector<shared_ptr<LogEvent>> mergedData;
     const vector<int>& additiveFieldsVec =
-            StatsPullerManager::kAllPullAtomInfo.find(tagId)->second.additiveFields;
+            StatsPullerManager::kAllPullAtomInfo.find({.atomTag = tagId})->second.additiveFields;
     const set<int> additiveFields(additiveFieldsVec.begin(), additiveFieldsVec.end());
     bool needMerge = true;
 
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 92bfee2..38ae5da 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -517,7 +517,7 @@
         }
     }
 
-    private static class  PullAtomCallbackInternal extends IPullAtomCallback.Stub {
+    private static class PullAtomCallbackInternal extends IPullAtomCallback.Stub {
         public final int mAtomId;
         public final StatsPullAtomCallback mCallback;
         public final Executor mExecutor;
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index d58d858..5cc0e0e 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -66,6 +66,7 @@
 
 import com.android.internal.R;
 
+import java.text.NumberFormat;
 import java.util.ArrayList;
 
 /**
@@ -241,6 +242,8 @@
 
     private boolean mAggregatedIsVisible;
 
+    private CharSequence mCustomStateDescription = null;
+
     private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>();
 
     /**
@@ -1551,9 +1554,54 @@
         }
     }
 
+    private float getPercent(int progress) {
+        final float maxProgress = getMax();
+        final float minProgress = getMin();
+        final float currentProgress = progress;
+        final float diffProgress = maxProgress - minProgress;
+        if (diffProgress <= 0.0f) {
+            return 0.0f;
+        }
+        final float percent = (currentProgress - minProgress) / diffProgress;
+        return Math.max(0.0f, Math.min(1.0f, percent));
+    }
+
+    /**
+     * Default percentage format of the state description based on progress, for example,
+     * "50 percent".
+     *
+     * @param progress the progress value, between {@link #getMin()} and {@link #getMax()}
+     * @return state description based on progress
+     */
+    private CharSequence formatStateDescription(int progress) {
+        return NumberFormat.getPercentInstance(mContext.getResources().getConfiguration().locale)
+                .format(getPercent(progress));
+    }
+
+    /**
+     * This function is called when an instance or subclass sets the state description. Once this
+     * is called and the argument is not null, the app developer will be responsible for updating
+     * state description when progress changes and the default state description will not be used.
+     * App developers can restore the default behavior by setting the argument to null. If set
+     * progress is called first and then setStateDescription is called, two state change events
+     * will be merged by event throttling and we can still get the correct state description.
+     *
+     * @param stateDescription The state description.
+     */
+    @Override
+    public void setStateDescription(@Nullable CharSequence stateDescription) {
+        mCustomStateDescription = stateDescription;
+        if (stateDescription == null) {
+            super.setStateDescription(formatStateDescription(mProgress));
+        } else {
+            super.setStateDescription(stateDescription);
+        }
+    }
+
     void onProgressRefresh(float scale, boolean fromUser, int progress) {
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+        if (AccessibilityManager.getInstance(mContext).isEnabled()
+                && mCustomStateDescription == null) {
+            super.setStateDescription(formatStateDescription(mProgress));
         }
     }
 
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 653d381..56e8790 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -244,7 +244,8 @@
     optional int32 num_drawn_windows = 15;
     optional bool all_drawn = 16;
     optional bool last_all_drawn = 17;
-    optional bool removed = 18;
+    // Will be removed soon
+    optional bool removed = 18 [deprecated=true];
     optional IdentifierProto starting_window = 19;
     optional bool starting_displayed = 20;
     optional bool starting_moved = 21;
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 753f8a0..ed19a37 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -169,12 +169,6 @@
       "group": "WM_DEBUG_RESIZE",
       "at": "com\/android\/server\/wm\/WindowState.java"
     },
-    "-1797409732": {
-      "message": "Skipping %s because %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "-1782453012": {
       "message": "Checking theme of starting window: 0x%x",
       "level": "VERBOSE",
@@ -1453,12 +1447,6 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimation.java"
     },
-    "789829331": {
-      "message": "Aborted starting %s: removed=%b startingData=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
     "791468751": {
       "message": "Pausing rotation during re-position",
       "level": "DEBUG",
@@ -1927,6 +1915,12 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "1822843721": {
+      "message": "Aborted starting %s: startingData=%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_STARTING_WINDOW",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "1831008694": {
       "message": "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s surfaceInsets=%s",
       "level": "DEBUG",
diff --git a/location/TEST_MAPPING b/location/TEST_MAPPING
new file mode 100644
index 0000000..2f38627
--- /dev/null
+++ b/location/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsLocationCoarseTestCases"
+    },
+    {
+      "name": "CtsLocationNoneTestCases"
+    }
+  ]
+}
diff --git a/media/jni/soundpool/StreamManager.cpp b/media/jni/soundpool/StreamManager.cpp
index 8928c47..64f81d5 100644
--- a/media/jni/soundpool/StreamManager.cpp
+++ b/media/jni/soundpool/StreamManager.cpp
@@ -38,7 +38,7 @@
 // kPlayOnCallingThread = true prior to R.
 // Changing to false means calls to play() are almost instantaneous instead of taking around
 // ~10ms to launch the AudioTrack. It is perhaps 100x faster.
-static constexpr bool kPlayOnCallingThread = false;
+static constexpr bool kPlayOnCallingThread = true;
 
 // Amount of time for a StreamManager thread to wait before closing.
 static constexpr int64_t kWaitTimeBeforeCloseNs = 9 * NANOS_PER_SECOND;
@@ -167,6 +167,7 @@
                 if (!stream->getPairStream()->hasSound()) {
                     if (stream->getSoundID() == soundID) {
                         newStream = stream;
+                        fromAvailableQueue = false;
                         break;
                     } else if (newStream == nullptr) {
                         newStream = stream;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 021e7e1..89aad8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -333,7 +333,6 @@
     }
 
     private boolean hideSilentNotificationsOnLockscreen() {
-        // TODO(b/140058091)
         return whitelistIpcs(() -> Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0);
     }
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 5522396..94793d0 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -14,6 +14,15 @@
                   "exclude-annotation": "androidx.test.filters.FlakyTest"
                 }
             ]
+        },
+        {
+            "name": "CtsLocationFineTestCases"
+        },
+        {
+            "name": "CtsLocationCoarseTestCases"
+        },
+        {
+            "name": "CtsLocationNoneTestCases"
         }
     ]
 }
diff --git a/services/core/java/com/android/server/location/TEST_MAPPING b/services/core/java/com/android/server/location/TEST_MAPPING
new file mode 100644
index 0000000..2e21fa6
--- /dev/null
+++ b/services/core/java/com/android/server/location/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsLocationCoarseTestCases"
+    },
+    {
+      "name": "CtsLocationNoneTestCases"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 8039724..c96943f 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -185,7 +185,6 @@
 import static com.android.server.wm.AppWindowTokenProto.NAME;
 import static com.android.server.wm.AppWindowTokenProto.NUM_DRAWN_WINDOWS;
 import static com.android.server.wm.AppWindowTokenProto.NUM_INTERESTING_WINDOWS;
-import static com.android.server.wm.AppWindowTokenProto.REMOVED;
 import static com.android.server.wm.AppWindowTokenProto.REPORTED_DRAWN;
 import static com.android.server.wm.AppWindowTokenProto.REPORTED_VISIBLE;
 import static com.android.server.wm.AppWindowTokenProto.STARTING_DISPLAYED;
@@ -631,9 +630,6 @@
     // Last visibility state we reported to the app token.
     boolean reportedVisible;
 
-    // Set to true when the token has been removed from the window mgr.
-    boolean removed;
-
     boolean mDisablePreviewScreenshots;
 
     // Information about an application starting window if displayed.
@@ -878,9 +874,8 @@
             pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn);
             pw.println(")");
         }
-        if (mStartingData != null || removed || firstWindowDrawn || mIsExiting) {
+        if (mStartingData != null || firstWindowDrawn || mIsExiting) {
             pw.print(prefix); pw.print("startingData="); pw.print(mStartingData);
-            pw.print(" removed="); pw.print(removed);
             pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
             pw.print(" mIsExiting="); pw.println(mIsExiting);
         }
@@ -1750,12 +1745,10 @@
             if (surface != null) {
                 boolean abort = false;
                 synchronized (mWmService.mGlobalLock) {
-                    // If the window was successfully added, then
-                    // we need to remove it.
-                    if (removed || mStartingData == null) {
-                        ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
-                                "Aborted starting %s: removed=%b startingData=%s",
-                                ActivityRecord.this, removed, mStartingData);
+                    // If the window was successfully added, then we need to remove it.
+                    if (mStartingData == null) {
+                        ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Aborted starting %s: startingData=%s",
+                                ActivityRecord.this, mStartingData);
 
                         startingWindow = null;
                         mStartingData = null;
@@ -2010,12 +2003,8 @@
         setMainWindowOpaque(occludesParent);
         mWmService.mWindowPlacerLocked.requestTraversal();
 
-        if (changed && task != null) {
-            if (!occludesParent) {
-                getActivityStack().convertActivityToTranslucent(this);
-            }
-            // Keep track of the number of fullscreen activities in this task.
-            task.numFullscreen += occludesParent ? +1 : -1;
+        if (changed && task != null && !occludesParent) {
+            getActivityStack().convertActivityToTranslucent(this);
         }
         // Always ensure visibility if this activity doesn't occlude parent, so the
         // {@link #returningOptions} of the activity under this one can be applied in
@@ -3040,7 +3029,6 @@
             removeIfPossible();
         }
 
-        removed = true;
         stopFreezingScreen(true, true);
 
         final DisplayContent dc = getDisplayContent();
@@ -4134,11 +4122,6 @@
         scheduleAnimation();
     }
 
-    @Override
-    void onAppTransitionDone() {
-        sendingToBottom = false;
-    }
-
     /**
      * See {@link Activity#setDisablePreviewScreenshots}.
      */
@@ -6090,10 +6073,10 @@
             return mOrientation;
         }
 
-        // The {@link ActivityRecord} should only specify an orientation when it is not closing or
-        // going to the bottom. Allowing closing {@link ActivityRecord} to participate can lead to
-        // an Activity in another task being started in the wrong orientation during the transition.
-        if (!(sendingToBottom || getDisplayContent().mClosingApps.contains(this))
+        // The {@link ActivityRecord} should only specify an orientation when it is not closing.
+        // Allowing closing {@link ActivityRecord} to participate can lead to an Activity in another
+        // task being started in the wrong orientation during the transition.
+        if (!getDisplayContent().mClosingApps.contains(this)
                 && (isVisible() || getDisplayContent().mOpeningApps.contains(this))) {
             return mOrientation;
         }
@@ -7348,7 +7331,6 @@
         proto.write(NUM_DRAWN_WINDOWS, mNumDrawnWindows);
         proto.write(ALL_DRAWN, allDrawn);
         proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
-        proto.write(REMOVED, removed);
         if (startingWindow != null) {
             startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
         }
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 8385232..d7e6852 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2896,7 +2896,7 @@
         Task task = null;
         if (!newTask) {
             // If starting in an existing task, find where that is...
-            boolean startIt = true;
+            boolean isOccluded = false;
             for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
                 task = getChildAt(taskNdx);
                 if (task.getTopNonFinishingActivity() == null) {
@@ -2904,10 +2904,10 @@
                     continue;
                 }
                 if (task == rTask) {
-                    // Here it is!  Now, if this is not yet visible to the
-                    // user, then just add it without starting; it will
-                    // get started when the user navigates back to it.
-                    if (!startIt) {
+                    // Here it is!  Now, if this is not yet visible (occluded by another task) to
+                    // the user, then just add it without starting; it will get started when the
+                    // user navigates back to it.
+                    if (isOccluded) {
                         if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
                                 + task, new RuntimeException("here").fillInStackTrace());
                         rTask.positionChildAtTop(r);
@@ -2915,8 +2915,8 @@
                         return;
                     }
                     break;
-                } else if (task.numFullscreen > 0) {
-                    startIt = false;
+                } else if (!isOccluded) {
+                    isOccluded = task.forAllActivities(ActivityRecord::occludesParent);
                 }
             }
         }
@@ -4670,9 +4670,6 @@
         }
         positionChildAt(position, task, includingParents);
         task.updateTaskMovement(toTop);
-        if (getDisplayContent().mAppTransition.isTransitionSet()) {
-            task.setSendingToBottom(!toTop);
-        }
         getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
 
 
@@ -5214,9 +5211,6 @@
         child.updateTaskMovement(true);
 
         final DisplayContent displayContent = getDisplayContent();
-        if (displayContent.mAppTransition.isTransitionSet()) {
-            child.setSendingToBottom(false);
-        }
         displayContent.layoutAndAssignWindowLayersIfNeeded();
     }
 
@@ -5238,10 +5232,6 @@
         }
 
         positionChildAt(POSITION_BOTTOM, child, includingParents);
-
-        if (getDisplayContent().mAppTransition.isTransitionSet()) {
-            child.setSendingToBottom(true);
-        }
         getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
     }
 
@@ -5284,9 +5274,6 @@
         task.updateTaskMovement(isTop);
         if (isTop) {
             final DisplayContent displayContent = getDisplayContent();
-            if (displayContent.mAppTransition.isTransitionSet()) {
-                task.setSendingToBottom(false);
-            }
             displayContent.layoutAndAssignWindowLayersIfNeeded();
         }
     }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index b4dd55d..098c978 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -601,13 +601,6 @@
 
         final ActivityRecord activity = w.mActivityRecord;
 
-        // If this window's application has been removed, just skip it.
-        if (activity!= null && (activity.removed || activity.sendingToBottom)) {
-            ProtoLog.v(WM_DEBUG_FOCUS, "Skipping %s because %s", activity,
-                    (activity.removed ? "removed" : "sendingToBottom"));
-            return false;
-        }
-
         if (focusedApp == null) {
             ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
                     "findFocusedWindow: focusedApp=null using new focus @ %s", w);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 96bac88..ba3b8b7 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -252,8 +252,6 @@
     boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
                                 // was changed.
 
-    int numFullscreen;      // Number of fullscreen activities.
-
     /** Can't be put in lockTask mode. */
     final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
     /** Can enter app pinning with user approval. Can never start over existing lockTask task. */
@@ -1210,9 +1208,6 @@
         ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addChild: %s at top.", this);
         r.inHistory = true;
 
-        if (r.occludesParent()) {
-            numFullscreen++;
-        }
         // Only set this based on the first activity
         if (!hadChild) {
             if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
@@ -1256,9 +1251,6 @@
         }
 
         super.removeChild(r);
-        if (r.occludesParent()) {
-            numFullscreen--;
-        }
         if (r.isPersistable()) {
             mAtmService.notifyTaskPersisterLocked(this, false);
         }
@@ -2255,7 +2247,7 @@
             // We want to place all non-overlay activities below overlays.
             while (maxPosition > 0) {
                 final ActivityRecord current = mChildren.get(maxPosition - 1);
-                if (current.mTaskOverlay && !current.removed) {
+                if (current.mTaskOverlay) {
                     --maxPosition;
                     continue;
                 }
@@ -2266,17 +2258,6 @@
             }
         }
 
-        if (suggestedPosition >= maxPosition) {
-            return Math.min(maxPosition, suggestedPosition);
-        }
-
-        for (int pos = 0; pos < maxPosition && pos < suggestedPosition; ++pos) {
-            // TODO: Confirm that this is the behavior we want long term.
-            if (mChildren.get(pos).removed) {
-                // suggestedPosition assumes removed tokens are actually gone.
-                ++suggestedPosition;
-            }
-        }
         return Math.min(maxPosition, suggestedPosition);
     }
 
@@ -2339,12 +2320,6 @@
         mPreserveNonFloatingState = stack.inPinnedWindowingMode();
     }
 
-    void setSendingToBottom(boolean toBottom) {
-        for (int appTokenNdx = 0; appTokenNdx < mChildren.size(); appTokenNdx++) {
-            mChildren.get(appTokenNdx).sendingToBottom = toBottom;
-        }
-    }
-
     public int setBounds(Rect bounds, boolean forceResize) {
         final int boundsChanged = setBounds(bounds);
 
@@ -2981,10 +2956,9 @@
             pw.print(prefix); pw.print("mActivityComponent=");
             pw.println(realActivity.flattenToShortString());
         }
-        if (autoRemoveRecents || isPersistable || !isActivityTypeStandard() || numFullscreen != 0) {
+        if (autoRemoveRecents || isPersistable || !isActivityTypeStandard()) {
             pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
             pw.print(" isPersistable="); pw.print(isPersistable);
-            pw.print(" numFullscreen="); pw.print(numFullscreen);
             pw.print(" activityType="); pw.println(getActivityType());
         }
         if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 519cc21..57e02a8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1473,7 +1473,7 @@
                     ProtoLog.w(WM_ERROR, "Attempted to add window with non-application token "
                             + ".%s Aborting.", token);
                     return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
-                } else if (activity.removed) {
+                } else if (activity.getParent() == null) {
                     ProtoLog.w(WM_ERROR, "Attempted to add window with exiting application token "
                             + ".%s Aborting.", token);
                     return WindowManagerGlobal.ADD_APP_EXITING;
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 88a1458..057f493 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -82,10 +82,6 @@
     // will be shown.
     boolean waitingToShow;
 
-    // Set to true when this token is in a pending transaction where its
-    // windows will be put to the bottom of the list.
-    boolean sendingToBottom;
-
     /** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */
     final boolean mOwnerCanManageAppTokens;
 
@@ -298,9 +294,8 @@
         pw.print(prefix); pw.print("windowType="); pw.print(windowType);
                 pw.print(" hidden="); pw.print(mHidden);
                 pw.print(" hasVisible="); pw.println(hasVisible);
-        if (waitingToShow || sendingToBottom) {
+        if (waitingToShow) {
             pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
-                    pw.print(" sendingToBottom="); pw.print(sendingToBottom);
         }
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index bd336ad..1c15096 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -262,7 +262,6 @@
 
         mActivity.setOccludesParent(true);
         mActivity.setHidden(true);
-        mActivity.sendingToBottom = true;
         // Can not specify orientation if app isn't visible even though it occludes parent.
         assertEquals(SCREEN_ORIENTATION_UNSET, mActivity.getOrientation());
         // Can specify orientation if the current orientation candidate is orientation behind.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
index 5877041..f5e65b1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
@@ -102,10 +102,7 @@
                 WindowTestUtils.createTestActivityRecord(mDisplayContent);
         task2.addChild(activity2, 0);
         activity2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
-
         assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation());
-        task2.setSendingToBottom(true);
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation());
     }
 
     @Test