add owners to manage gs-common am: edf8707658 am: 9eaa8d078d am: 8e43cfa48e

Original change: https://android-review.googlesource.com/c/device/google/gs-common/+/2185155

Change-Id: I2d076f4f236ae5d16bb75f9640aad1d9b26ea65e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/powerstats/AocStateResidencyDataProvider.cpp b/powerstats/AocStateResidencyDataProvider.cpp
index c64496d..38cd85f 100644
--- a/powerstats/AocStateResidencyDataProvider.cpp
+++ b/powerstats/AocStateResidencyDataProvider.cpp
@@ -24,12 +24,12 @@
 namespace power {
 namespace stats {
 
-AocStateResidencyDataProvider::AocStateResidencyDataProvider(std::vector<std::pair<std::string,
-        std::string>> ids, std::vector<std::pair<std::string, std::string>> states) {
-    // AoC stats are reported in ticks of 244.140625ns. The transform
-    // function converts ticks to milliseconds.
-    // 1000000 / 244.140625 = 4096.
-    static const uint64_t AOC_CLK = 4096;
+AocStateResidencyDataProvider::AocStateResidencyDataProvider(
+        std::vector<std::pair<std::string, std::string>> ids,
+        std::vector<std::pair<std::string, std::string>> states,
+        const uint64_t aocClock) {
+    // AoC stats are reported in ticks.
+    static const uint64_t AOC_CLK = aocClock;
     std::function<uint64_t(uint64_t)> aocTickToMs = [](uint64_t a) { return a / AOC_CLK; };
     GenericStateResidencyDataProvider::StateResidencyConfig config = {
             .entryCountSupported = true,
diff --git a/powerstats/AocTimedStateResidencyDataProvider.cpp b/powerstats/AocTimedStateResidencyDataProvider.cpp
new file mode 100644
index 0000000..ead2a42
--- /dev/null
+++ b/powerstats/AocTimedStateResidencyDataProvider.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "AocTimedStateResidencyDataProvider.h"
+
+#include <android-base/logging.h>
+#include <chrono>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace power {
+namespace stats {
+
+AocTimedStateResidencyDataProvider::AocTimedStateResidencyDataProvider(
+    std::vector<std::pair<std::string, std::string>> ids,
+    std::vector<std::pair<std::string, std::string>> states,
+    const uint64_t timeoutMillis,
+    const uint64_t aocClock)
+    : AocStateResidencyDataProvider(ids, states, aocClock) {
+  static const uint64_t DEFAULT_MAX_TIME_PER_STATE_MILLIS = 120;
+
+  mTimeoutMillis =
+      timeoutMillis == 0 ? DEFAULT_MAX_TIME_PER_STATE_MILLIS * states.size() : timeoutMillis;
+
+  mAsyncThread = std::thread(&AocTimedStateResidencyDataProvider::getStateResidenciesAsync, this);
+}
+
+bool AocTimedStateResidencyDataProvider::getStateResidencies(
+    std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
+  bool ret = true;
+  std::unique_lock<std::mutex> statusLock(mStatusMutex);
+
+  if (mAsyncStatus != COMPLETED) {
+    LOG(ERROR) << "The async thread is not ready: " << mAsyncStatus;
+    return false;
+  }
+
+  mStateResidencies.clear();
+
+  mAsyncStatus = RUN;
+  mRunCond.notify_one();
+
+  auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(mTimeoutMillis);
+  auto isCompleted =
+      mCompletedCond.wait_until(statusLock, timeout, [this]{ return mAsyncStatus == COMPLETED; });
+
+  if (isCompleted) {
+    for (const auto &residency : mStateResidencies) {
+      residencies->emplace(residency.first, residency.second);
+    }
+  } else {
+    LOG(ERROR) << __func__ << " for AoC timed out: " << mTimeoutMillis << " ms";
+    ret = false;
+  }
+
+  return ret;
+}
+
+void AocTimedStateResidencyDataProvider::getStateResidenciesAsync() {
+  std::unique_lock<std::mutex> statusLock(mStatusMutex);
+
+  mAsyncStatus = COMPLETED;
+
+  while (1) {
+    mRunCond.wait(statusLock, [this]{ return mAsyncStatus == RUN; });
+
+    mAsyncStatus = RUNNING;
+    statusLock.unlock();
+
+    // States from the same power entity are merged.
+    for (const auto &providerList : mProviders) {
+      int32_t stateId = 0;
+      std::string curEntity = providerList.first;
+      std::vector<StateResidency> stateResidencies;
+
+      // Iterate over each provider in the providerList, appending each of the states
+      for (const auto &provider : providerList.second) {
+        std::unordered_map<std::string, std::vector<StateResidency>> residency;
+        provider->getStateResidencies(&residency);
+
+        // Each provider should only return data for curEntity but checking anyway
+        if (residency.find(curEntity) != residency.end()) {
+          for (auto &r : residency.at(curEntity)) {
+            /*
+             * Modifying stateId here because we are stitching together infos from
+             * multiple GenericStateResidencyDataProviders. stateId must be modified
+             * to maintain uniqueness for a given entity
+             */
+            r.id = stateId++;
+            stateResidencies.push_back(r);
+          }
+        }
+      }
+      mStateResidencies.emplace(curEntity, stateResidencies);
+    }
+
+    statusLock.lock();
+    mAsyncStatus = COMPLETED;
+    mCompletedCond.notify_one();
+  } // while loop
+}
+
+}  // namespace stats
+}  // namespace power
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/powerstats/include/AocStateResidencyDataProvider.h b/powerstats/include/AocStateResidencyDataProvider.h
index 5008912..708ea4c 100644
--- a/powerstats/include/AocStateResidencyDataProvider.h
+++ b/powerstats/include/AocStateResidencyDataProvider.h
@@ -27,13 +27,14 @@
 class AocStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
   public:
     AocStateResidencyDataProvider(std::vector<std::pair<std::string, std::string>> ids,
-                                  std::vector<std::pair<std::string, std::string>> states);
+                                  std::vector<std::pair<std::string, std::string>> states,
+                                  const uint64_t aocClock);
     ~AocStateResidencyDataProvider() = default;
     bool getStateResidencies(
         std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
     std::unordered_map<std::string, std::vector<State>> getInfo() override;
 
-  private:
+  protected:
     std::unordered_map<std::string /* entity name */,
         std::vector<std::unique_ptr<GenericStateResidencyDataProvider>> /* providers */> mProviders;
 };
@@ -42,4 +43,4 @@
 }  // namespace power
 }  // namespace hardware
 }  // namespace android
-}  // namespace aidl
\ No newline at end of file
+}  // namespace aidl
diff --git a/powerstats/include/AocTimedStateResidencyDataProvider.h b/powerstats/include/AocTimedStateResidencyDataProvider.h
new file mode 100644
index 0000000..8611ae6
--- /dev/null
+++ b/powerstats/include/AocTimedStateResidencyDataProvider.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "AocStateResidencyDataProvider.h"
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <PowerStatsAidl.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace power {
+namespace stats {
+
+enum AsyncStatus {
+  COMPLETED,
+  RUN,
+  RUNNING
+};
+
+class AocTimedStateResidencyDataProvider : public AocStateResidencyDataProvider {
+ public:
+  AocTimedStateResidencyDataProvider(
+      std::vector<std::pair<std::string, std::string>> ids,
+      std::vector<std::pair<std::string, std::string>> states,
+      const uint64_t timeoutMillis,
+      const uint64_t aocClock);
+  ~AocTimedStateResidencyDataProvider() = default;
+
+  bool getStateResidencies(
+      std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
+
+ private:
+  void getStateResidenciesAsync();
+
+  uint64_t mTimeoutMillis;
+  std::thread mAsyncThread;
+  std::mutex mStatusMutex;
+  std::condition_variable mRunCond;
+  std::condition_variable mCompletedCond;
+  std::unordered_map<std::string, std::vector<StateResidency>> mStateResidencies;
+  AsyncStatus mAsyncStatus;
+};
+
+}  // namespace stats
+}  // namespace power
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl