diff --git a/powerstats/Android.bp b/powerstats/Android.bp
index fa73e51..7c7066c 100644
--- a/powerstats/Android.bp
+++ b/powerstats/Android.bp
@@ -23,50 +23,11 @@
 }
 
 cc_binary {
-    // TODO(b/167628903) : remove this
-    name: "android.hardware.power.stats@1.0-service.gs101",
-    header_libs: [
-        "device_kernel_headers",
-    ],
-    relative_install_path: "hw",
-    init_rc: ["android.hardware.power.stats@1.0-service.gs101.rc"],
-    vintf_fragments: ["android.hardware.power.stats@1.0-service.gs101.xml"],
-    srcs: [
-        "AocStateResidencyDataProvider.cpp",
-        "DvfsStateResidencyDataProvider.cpp",
-        "RailDataProvider.cpp",
-        "service.cpp",
-        "UfsStateResidencyDataProvider.cpp",
-    ],
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-    static_libs: [
-       "libpixelpowerstats",
-    ],
-    shared_libs: [
-        "android.hardware.power.stats@1.0",
-        "pixelpowerstats_provider_aidl_interface-cpp",
-        "libbase",
-        "libbinder",
-        "libcutils",
-        "libfmq",
-        "libhidlbase",
-        "liblog",
-        "libutils",
-    ],
-    vendor: true,
-}
-
-cc_binary {
     name: "android.hardware.power.stats-service.pixel",
     init_rc: ["android.hardware.power.stats-service.pixel.rc"],
     vintf_fragments: ["android.hardware.power.stats-service.pixel.xml"],
     srcs: [
-        "AocStateResidencyDataProviderAidl.cpp",
-        "DvfsStateResidencyDataProviderAidl.cpp",
-        "serviceaidl.cpp"
+        "*.cpp",
     ],
     cflags: [
         "-Wall",
diff --git a/powerstats/AocStateResidencyDataProvider.cpp b/powerstats/AocStateResidencyDataProvider.cpp
index 41c75bc..c64496d 100644
--- a/powerstats/AocStateResidencyDataProvider.cpp
+++ b/powerstats/AocStateResidencyDataProvider.cpp
@@ -13,29 +13,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define LOG_TAG "libpixelpowerstats"
 
 #include "AocStateResidencyDataProvider.h"
 
 #include <android-base/logging.h>
 
-#include <utility>
-
+namespace aidl {
 namespace android {
 namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
+namespace power {
+namespace stats {
 
-AocStateResidencyDataProvider::AocStateResidencyDataProvider(
-        std::vector<std::pair<uint32_t, std::string>> ids,
-        std::vector<std::pair<std::string, std::string>> states) {
+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;
     std::function<uint64_t(uint64_t)> aocTickToMs = [](uint64_t a) { return a / AOC_CLK; };
-    StateResidencyConfig config = {
+    GenericStateResidencyDataProvider::StateResidencyConfig config = {
             .entryCountSupported = true,
             .entryCountPrefix = "Counter:",
             .totalTimeSupported = true,
@@ -45,61 +41,88 @@
             .lastEntryPrefix = "Time last entered:",
             .lastEntryTransform = aocTickToMs,
     };
-    uint32_t state_id;
-    for (auto &id : ids) {
-        state_id = 1;
-        for (auto &state : states) {
+    for (const auto &id : ids) {
+        for (const auto &state : states) {
             std::vector<std::pair<std::string, std::string>> aocStateHeaders = {
-                    std::make_pair(state.first, ""),
+                std::make_pair(state.first, ""),
             };
+            std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
+            cfgs.emplace_back(generateGenericStateResidencyConfigs(config, aocStateHeaders),
+                    id.first, "");
             std::unique_ptr<GenericStateResidencyDataProvider> sdp(
-                    new GenericStateResidencyDataProvider(id.second + state.second));
-            sdp->addEntity(id.first, PowerEntityConfig(state_id++, "",
-                                                       generateGenericStateResidencyConfigs(
-                                                               config, aocStateHeaders)));
-            mProviders.push_back(std::move(sdp));
+                    new GenericStateResidencyDataProvider(id.second + state.second, cfgs));
+            mProviders[id.first].push_back(std::move(sdp));
         }
     }
 }
 
-bool AocStateResidencyDataProvider::getResults(
-        std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
-    for (auto &provider : mProviders) {
-        provider->getResults(results);
-    }
-    return true;
-}
-
-std::vector<PowerEntityStateSpace> AocStateResidencyDataProvider::getStateSpaces() {
-    // Return state spaces based on all configured providers.
+bool AocStateResidencyDataProvider::getStateResidencies(
+        std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
     // States from the same power entity are merged.
-    std::map<uint32_t, PowerEntityStateSpace> stateSpaces;
-    for (auto &provider : mProviders) {
-        for (auto &stateSpace : provider->getStateSpaces()) {
-            auto it = stateSpaces.find(stateSpace.powerEntityId);
-            if (it != stateSpaces.end()) {
-                auto &states = it->second.states;
-                auto size = states.size();
-                states.resize(size + stateSpace.states.size());
-                for (uint32_t i = 0; i < stateSpace.states.size(); i++) {
-                    states[size + i] = stateSpace.states[i];
+    bool ret = true;
+    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;
+            ret &= 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);
                 }
-            } else {
-                stateSpaces.insert(std::pair<uint32_t, PowerEntityStateSpace>(
-                        stateSpace.powerEntityId, stateSpace));
             }
         }
-    }
 
-    std::vector<PowerEntityStateSpace> ret;
-    for (auto &stateSpace : stateSpaces) {
-        ret.push_back(stateSpace.second);
+        residencies->emplace(curEntity, stateResidencies);
     }
     return ret;
 }
 
-}  // namespace powerstats
-}  // namespace pixel
-}  // namespace google
+std::unordered_map<std::string, std::vector<State>> AocStateResidencyDataProvider::getInfo() {
+    // States from the same power entity are merged
+    std::unordered_map<std::string, std::vector<State>> infos;
+    for (const auto &providerList : mProviders) {
+        int32_t stateId = 0;
+        std::string curEntity = providerList.first;
+        std::vector<State> stateInfos;
+
+        // 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<State>> info = provider->getInfo();
+
+            // Each provider should only return data for curEntity but checking anyway
+            if (info.find(curEntity) != info.end()) {
+                for (auto &i : info.at(curEntity)) {
+                    /*
+                     * Modifying stateId because we are stitching together infos from
+                     * multiple GenericStateResidencyDataProviders. stateId must be modified
+                     * to maintain uniqueness for a given entity
+                     */
+                    i.id = stateId++;
+                    stateInfos.push_back(i);
+                }
+            }
+        }
+
+        infos.emplace(curEntity, stateInfos);
+    }
+
+    return infos;
+}
+
+}  // namespace stats
+}  // namespace power
 }  // namespace hardware
 }  // namespace android
+}  // namespace aidl
diff --git a/powerstats/AocStateResidencyDataProvider.h b/powerstats/AocStateResidencyDataProvider.h
index eef7ce7..5008912 100644
--- a/powerstats/AocStateResidencyDataProvider.h
+++ b/powerstats/AocStateResidencyDataProvider.h
@@ -13,35 +13,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef HARDWARE_GOOGLE_PIXEL_POWERSTATS_AOCSTATERESIDENCYDATAPROVIDER_H
-#define HARDWARE_GOOGLE_PIXEL_POWERSTATS_AOCSTATERESIDENCYDATAPROVIDER_H
+#pragma once
 
-#include <pixelpowerstats/GenericStateResidencyDataProvider.h>
-#include <pixelpowerstats/PowerStats.h>
+#include <dataproviders/GenericStateResidencyDataProvider.h>
+#include <PowerStatsAidl.h>
 
+namespace aidl {
 namespace android {
 namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
+namespace power {
+namespace stats {
 
-class AocStateResidencyDataProvider : public IStateResidencyDataProvider {
+class AocStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
   public:
-    AocStateResidencyDataProvider(std::vector<std::pair<uint32_t, std::string>> ids,
+    AocStateResidencyDataProvider(std::vector<std::pair<std::string, std::string>> ids,
                                   std::vector<std::pair<std::string, std::string>> states);
     ~AocStateResidencyDataProvider() = default;
-    bool getResults(
-            std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) override;
-    std::vector<PowerEntityStateSpace> getStateSpaces() override;
+    bool getStateResidencies(
+        std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
+    std::unordered_map<std::string, std::vector<State>> getInfo() override;
 
   private:
-    std::vector<std::unique_ptr<GenericStateResidencyDataProvider>> mProviders;
+    std::unordered_map<std::string /* entity name */,
+        std::vector<std::unique_ptr<GenericStateResidencyDataProvider>> /* providers */> mProviders;
 };
 
-}  // namespace powerstats
-}  // namespace pixel
-}  // namespace google
+}  // namespace stats
+}  // namespace power
 }  // namespace hardware
 }  // namespace android
-
-#endif  // HARDWARE_GOOGLE_PIXEL_POWERSTATS_AOCSTATERESIDENCYDATAPROVIDER_H
+}  // namespace aidl
\ No newline at end of file
diff --git a/powerstats/AocStateResidencyDataProviderAidl.cpp b/powerstats/AocStateResidencyDataProviderAidl.cpp
deleted file mode 100644
index 3759a66..0000000
--- a/powerstats/AocStateResidencyDataProviderAidl.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "AocStateResidencyDataProviderAidl.h"
-
-#include <android-base/logging.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-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;
-    std::function<uint64_t(uint64_t)> aocTickToMs = [](uint64_t a) { return a / AOC_CLK; };
-    GenericStateResidencyDataProvider::StateResidencyConfig config = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "Counter:",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "Cumulative time:",
-            .totalTimeTransform = aocTickToMs,
-            .lastEntrySupported = true,
-            .lastEntryPrefix = "Time last entered:",
-            .lastEntryTransform = aocTickToMs,
-    };
-    for (const auto &id : ids) {
-        for (const auto &state : states) {
-            std::vector<std::pair<std::string, std::string>> aocStateHeaders = {
-                std::make_pair(state.first, ""),
-            };
-            std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
-            cfgs.emplace_back(generateGenericStateResidencyConfigs(config, aocStateHeaders),
-                    id.first, "");
-            std::unique_ptr<GenericStateResidencyDataProvider> sdp(
-                    new GenericStateResidencyDataProvider(id.second + state.second, cfgs));
-            mProviders[id.first].push_back(std::move(sdp));
-        }
-    }
-}
-
-bool AocStateResidencyDataProvider::getStateResidencies(
-        std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
-    // States from the same power entity are merged.
-    bool ret = true;
-    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;
-            ret &= 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);
-                }
-            }
-        }
-
-        residencies->emplace(curEntity, stateResidencies);
-    }
-    return ret;
-}
-
-std::unordered_map<std::string, std::vector<State>> AocStateResidencyDataProvider::getInfo() {
-    // States from the same power entity are merged
-    std::unordered_map<std::string, std::vector<State>> infos;
-    for (const auto &providerList : mProviders) {
-        int32_t stateId = 0;
-        std::string curEntity = providerList.first;
-        std::vector<State> stateInfos;
-
-        // 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<State>> info = provider->getInfo();
-
-            // Each provider should only return data for curEntity but checking anyway
-            if (info.find(curEntity) != info.end()) {
-                for (auto &i : info.at(curEntity)) {
-                    /*
-                     * Modifying stateId because we are stitching together infos from
-                     * multiple GenericStateResidencyDataProviders. stateId must be modified
-                     * to maintain uniqueness for a given entity
-                     */
-                    i.id = stateId++;
-                    stateInfos.push_back(i);
-                }
-            }
-        }
-
-        infos.emplace(curEntity, stateInfos);
-    }
-
-    return infos;
-}
-
-}  // namespace stats
-}  // namespace power
-}  // namespace hardware
-}  // namespace android
-}  // namespace aidl
diff --git a/powerstats/AocStateResidencyDataProviderAidl.h b/powerstats/AocStateResidencyDataProviderAidl.h
deleted file mode 100644
index 5008912..0000000
--- a/powerstats/AocStateResidencyDataProviderAidl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <dataproviders/GenericStateResidencyDataProvider.h>
-#include <PowerStatsAidl.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-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);
-    ~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:
-    std::unordered_map<std::string /* entity name */,
-        std::vector<std::unique_ptr<GenericStateResidencyDataProvider>> /* providers */> mProviders;
-};
-
-}  // namespace stats
-}  // namespace power
-}  // namespace hardware
-}  // namespace android
-}  // namespace aidl
\ No newline at end of file
diff --git a/powerstats/DvfsStateResidencyDataProvider.cpp b/powerstats/DvfsStateResidencyDataProvider.cpp
index 95289bd..511159e 100644
--- a/powerstats/DvfsStateResidencyDataProvider.cpp
+++ b/powerstats/DvfsStateResidencyDataProvider.cpp
@@ -13,8 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define LOG_TAG "libpixelpowerstats"
-
 #include "DvfsStateResidencyDataProvider.h"
 
 #include <android-base/logging.h>
@@ -29,97 +27,90 @@
 using android::base::StartsWith;
 using android::base::Trim;
 
+static const std::string nameSuffix = "-DVFS";
+
+namespace aidl {
 namespace android {
 namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
+namespace power {
+namespace stats {
 
-DvfsStateResidencyDataProvider::DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate)
-    : mPath(std::move(path)), mClockRate(clockRate) {}
+DvfsStateResidencyDataProvider::DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate,
+        std::vector<Config> cfgs)
+    : mPath(std::move(path)), mClockRate(clockRate), mPowerEntities(std::move(cfgs)) {}
 
-void DvfsStateResidencyDataProvider::addEntity(
-        uint32_t id, std::string name, std::vector<std::pair<std::string, std::string>> states) {
-    mPowerEntities.push_back({id, name, states});
-}
-
-int32_t DvfsStateResidencyDataProvider::matchEntity(char *line) {
-    for (auto const &entity : mPowerEntities) {
-        if (entity.powerEntityName == Trim(std::string(line))) {
-            return entity.powerEntityId;
+int32_t DvfsStateResidencyDataProvider::matchEntity(char const *line) {
+    for (int32_t i = 0; i < mPowerEntities.size(); i++) {
+        if (mPowerEntities[i].powerEntityName == Trim(std::string(line))) {
+            return i;
         }
     }
     return -1;
 }
 
-int32_t DvfsStateResidencyDataProvider::matchState(char *line, int32_t entityId) {
-    uint32_t stateId = 0;
-    for (auto const &entity : mPowerEntities) {
-        if (entityId == entity.powerEntityId) {
-            for (auto const &state : entity.states) {
-                if (StartsWith(Trim(std::string(line)), state.second)) {
-                    return stateId;
-                }
-                stateId++;
-            }
-            return -1;
+int32_t DvfsStateResidencyDataProvider::matchState(char const *line, const Config& powerEntity) {
+    for (int32_t i = 0; i < powerEntity.states.size(); i++) {
+        if (StartsWith(Trim(std::string(line)), powerEntity.states[i].second)) {
+            return i;
         }
     }
     return -1;
 }
 
-bool DvfsStateResidencyDataProvider::parseState(char *line, uint64_t &duration, uint64_t &count) {
+bool DvfsStateResidencyDataProvider::parseState(char const *line, uint64_t *duration,
+        uint64_t *count) {
     std::vector<std::string> parts = Split(line, " ");
     if (parts.size() != 7) {
         return false;
     }
-    if (!ParseUint(Trim(parts[3]), &count)) {
+    if (!ParseUint(Trim(parts[3]), count)) {
         return false;
     }
-    if (!ParseUint(Trim(parts[6]), &duration)) {
+    if (!ParseUint(Trim(parts[6]), duration)) {
         return false;
     }
     return true;
 }
 
-bool DvfsStateResidencyDataProvider::getResults(
-        std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
+bool DvfsStateResidencyDataProvider::getStateResidencies(
+        std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
     std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(mPath.c_str(), "r"), fclose);
     if (!fp) {
-        PLOG(ERROR) << __func__ << ":Failed to open file " << mPath
-                    << " Error = " << strerror(errno);
+        PLOG(ERROR) << __func__ << ":Failed to open file " << mPath;
         return false;
     }
 
-    for (auto const &stateSpace : getStateSpaces()) {
-        PowerEntityStateResidencyResult result = {.powerEntityId = stateSpace.powerEntityId};
-        result.stateResidencyData.resize(stateSpace.states.size());
-        for (uint32_t i = 0; i < result.stateResidencyData.size(); i++) {
-            result.stateResidencyData[i].powerEntityStateId =
-                    stateSpace.states[i].powerEntityStateId;
+    for (const Config &powerEntity : mPowerEntities) {
+        std::vector<StateResidency> stateResidency(powerEntity.states.size());
+        for (int32_t i = 0; i < stateResidency.size(); i++) {
+            stateResidency[i].id = i;
         }
-        results.insert(std::make_pair(stateSpace.powerEntityId, result));
+        residencies->emplace(powerEntity.powerEntityName + nameSuffix, stateResidency);
     }
 
     size_t len = 0;
     char *line = nullptr;
 
-    int32_t temp = -1, entityId = -1, stateId = -1;
+    int32_t temp, powerEntityIndex, stateId = -1;
     uint64_t duration, count;
+    auto it = residencies->end();
 
     while (getline(&line, &len, fp.get()) != -1) {
         temp = matchEntity(line);
-        // Assign entityId only when a new valid entity is encountered.
+        // Assign new index only when a new valid entity is encountered.
         if (temp >= 0) {
-            entityId = temp;
+            powerEntityIndex = temp;
+            it = residencies->find(mPowerEntities[powerEntityIndex].powerEntityName + nameSuffix);
         }
-        if (entityId >= 0) {
-            stateId = matchState(line, entityId);
+
+        if (it != residencies->end()) {
+            stateId = matchState(line, mPowerEntities[powerEntityIndex]);
+
             if (stateId >= 0) {
-                if (parseState(line, duration, count)) {
-                    results[entityId].stateResidencyData[stateId].totalTimeInStateMs =
+                if (parseState(line, &duration, &count)) {
+                    it->second[stateId].totalTimeInStateMs =
                             duration / mClockRate;
-                    results[entityId].stateResidencyData[stateId].totalStateEntryCount = count;
+                    it->second[stateId].totalStateEntryCount = count;
                 } else {
                     LOG(ERROR) << "Failed to parse duration and count from [" << std::string(line)
                                << "]";
@@ -134,25 +125,25 @@
     return true;
 }
 
-std::vector<PowerEntityStateSpace> DvfsStateResidencyDataProvider::getStateSpaces() {
-    std::vector<PowerEntityStateSpace> stateSpaces;
-    stateSpaces.reserve(mPowerEntities.size());
+std::unordered_map<std::string, std::vector<State>> DvfsStateResidencyDataProvider::getInfo() {
+    std::unordered_map<std::string, std::vector<State>> info;
     for (auto const &entity : mPowerEntities) {
-        PowerEntityStateSpace s = {.powerEntityId = entity.powerEntityId};
-        s.states.resize(entity.states.size());
-        uint32_t stateId = 0;
+        std::vector<State> stateInfo(entity.states.size());
+        int32_t stateId = 0;
         for (auto const &state : entity.states) {
-            s.states[stateId] = {.powerEntityStateId = stateId,
-                                 .powerEntityStateName = state.first};
+            stateInfo[stateId] = State{
+                .id = stateId,
+                .name = state.first
+            };
             stateId++;
         }
-        stateSpaces.emplace_back(s);
+        info.emplace(entity.powerEntityName + nameSuffix, stateInfo);
     }
-    return stateSpaces;
+    return info;
 }
 
-}  // namespace powerstats
-}  // namespace pixel
-}  // namespace google
+}  // namespace stats
+}  // namespace power
 }  // namespace hardware
 }  // namespace android
+}  // namespace aidl
diff --git a/powerstats/DvfsStateResidencyDataProvider.h b/powerstats/DvfsStateResidencyDataProvider.h
index ffa1414..ca8ab22 100644
--- a/powerstats/DvfsStateResidencyDataProvider.h
+++ b/powerstats/DvfsStateResidencyDataProvider.h
@@ -13,71 +13,56 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef HARDWARE_GOOGLE_PIXEL_POWERSTATS_DVFSSTATERESIDENCYDATAPROVIDER_H
-#define HARDWARE_GOOGLE_PIXEL_POWERSTATS_DVFSSTATERESIDENCYDATAPROVIDER_H
+#pragma once
 
-#include <pixelpowerstats/PowerStats.h>
+#include <PowerStatsAidl.h>
 
+namespace aidl {
 namespace android {
 namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
+namespace power {
+namespace stats {
 
-class DvfsStateResidencyDataProvider : public IStateResidencyDataProvider {
+class DvfsStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
   public:
-    /*
-     * path - path to dvfs sysfs node.
-     * clockRate - clock rate in KHz.
-     */
-    DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate);
-    ~DvfsStateResidencyDataProvider() = default;
-
-    /*
-     * id - the power entity id
-     * name - the power entity name to parse from sysfs node
-     * frequencies - list of pairs (frequency display name, frequency in sysfs
-     *               node).
-     */
-    void addEntity(uint32_t id, std::string name,
-                   std::vector<std::pair<std::string, std::string>> frequencies);
-
-    /*
-     * See IStateResidencyDataProvider::getResults.
-     */
-    bool getResults(
-            std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) override;
-
-    /*
-     * See IStateResidencyDataProvider::getStateSpaces.
-     */
-    std::vector<PowerEntityStateSpace> getStateSpaces() override;
-
-  private:
-    int32_t matchEntity(char *line);
-    int32_t matchState(char *line, int32_t entityId);
-    bool parseState(char *line, uint64_t &duration, uint64_t &count);
-
-    const std::string mPath;
-    const uint64_t mClockRate;
-
-    struct config {
-        // Power entity id.
-        uint32_t powerEntityId;
-
+    class Config {
+      public:
         // Power entity name to parse.
         std::string powerEntityName;
 
         // List of state pairs (name to display, name to parse).
         std::vector<std::pair<std::string, std::string>> states;
     };
-    std::vector<config> mPowerEntities;
+    /*
+     * path - path to dvfs sysfs node.
+     * clockRate - clock rate in KHz.
+     */
+    DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate, std::vector<Config> cfgs);
+    ~DvfsStateResidencyDataProvider() = default;
+
+    /*
+     * See IStateResidencyDataProvider::getStateResidencies
+     */
+    bool getStateResidencies(
+        std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
+
+    /*
+     * See IStateResidencyDataProvider::getInfo
+     */
+    std::unordered_map<std::string, std::vector<State>> getInfo() override;
+
+  private:
+    int32_t matchEntity(char const *line);
+    int32_t matchState(char const *line, const Config& powerEntity);
+    bool parseState(char const *line, uint64_t *duration, uint64_t *count);
+
+    const std::string mPath;
+    const uint64_t mClockRate;
+    std::vector<Config> mPowerEntities;
 };
 
-}  // namespace powerstats
-}  // namespace pixel
-}  // namespace google
+}  // namespace stats
+}  // namespace power
 }  // namespace hardware
 }  // namespace android
-
-#endif  // HARDWARE_GOOGLE_PIXEL_POWERSTATS_DVFSSTATERESIDENCYDATAPROVIDER_H
+}  // namespace aidl
diff --git a/powerstats/DvfsStateResidencyDataProviderAidl.cpp b/powerstats/DvfsStateResidencyDataProviderAidl.cpp
deleted file mode 100644
index ca6ea9a..0000000
--- a/powerstats/DvfsStateResidencyDataProviderAidl.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "DvfsStateResidencyDataProviderAidl.h"
-
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-
-#include <string>
-#include <utility>
-
-using android::base::ParseUint;
-using android::base::Split;
-using android::base::StartsWith;
-using android::base::Trim;
-
-static const std::string nameSuffix = "-DVFS";
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-DvfsStateResidencyDataProvider::DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate,
-        std::vector<Config> cfgs)
-    : mPath(std::move(path)), mClockRate(clockRate), mPowerEntities(std::move(cfgs)) {}
-
-int32_t DvfsStateResidencyDataProvider::matchEntity(char const *line) {
-    for (int32_t i = 0; i < mPowerEntities.size(); i++) {
-        if (mPowerEntities[i].powerEntityName == Trim(std::string(line))) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-int32_t DvfsStateResidencyDataProvider::matchState(char const *line, const Config& powerEntity) {
-    for (int32_t i = 0; i < powerEntity.states.size(); i++) {
-        if (StartsWith(Trim(std::string(line)), powerEntity.states[i].second)) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-bool DvfsStateResidencyDataProvider::parseState(char const *line, uint64_t *duration,
-        uint64_t *count) {
-    std::vector<std::string> parts = Split(line, " ");
-    if (parts.size() != 7) {
-        return false;
-    }
-    if (!ParseUint(Trim(parts[3]), count)) {
-        return false;
-    }
-    if (!ParseUint(Trim(parts[6]), duration)) {
-        return false;
-    }
-    return true;
-}
-
-bool DvfsStateResidencyDataProvider::getStateResidencies(
-        std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
-    std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(mPath.c_str(), "r"), fclose);
-    if (!fp) {
-        PLOG(ERROR) << __func__ << ":Failed to open file " << mPath;
-        return false;
-    }
-
-    for (const Config &powerEntity : mPowerEntities) {
-        std::vector<StateResidency> stateResidency(powerEntity.states.size());
-        for (int32_t i = 0; i < stateResidency.size(); i++) {
-            stateResidency[i].id = i;
-        }
-        residencies->emplace(powerEntity.powerEntityName + nameSuffix, stateResidency);
-    }
-
-    size_t len = 0;
-    char *line = nullptr;
-
-    int32_t temp, powerEntityIndex, stateId = -1;
-    uint64_t duration, count;
-    auto it = residencies->end();
-
-    while (getline(&line, &len, fp.get()) != -1) {
-        temp = matchEntity(line);
-        // Assign new index only when a new valid entity is encountered.
-        if (temp >= 0) {
-            powerEntityIndex = temp;
-            it = residencies->find(mPowerEntities[powerEntityIndex].powerEntityName + nameSuffix);
-        }
-
-        if (it != residencies->end()) {
-            stateId = matchState(line, mPowerEntities[powerEntityIndex]);
-
-            if (stateId >= 0) {
-                if (parseState(line, &duration, &count)) {
-                    it->second[stateId].totalTimeInStateMs =
-                            duration / mClockRate;
-                    it->second[stateId].totalStateEntryCount = count;
-                } else {
-                    LOG(ERROR) << "Failed to parse duration and count from [" << std::string(line)
-                               << "]";
-                    return false;
-                }
-            }
-        }
-    }
-
-    free(line);
-
-    return true;
-}
-
-std::unordered_map<std::string, std::vector<State>> DvfsStateResidencyDataProvider::getInfo() {
-    std::unordered_map<std::string, std::vector<State>> info;
-    for (auto const &entity : mPowerEntities) {
-        std::vector<State> stateInfo(entity.states.size());
-        int32_t stateId = 0;
-        for (auto const &state : entity.states) {
-            stateInfo[stateId] = State{
-                .id = stateId,
-                .name = state.first
-            };
-            stateId++;
-        }
-        info.emplace(entity.powerEntityName + nameSuffix, stateInfo);
-    }
-    return info;
-}
-
-}  // namespace stats
-}  // namespace power
-}  // namespace hardware
-}  // namespace android
-}  // namespace aidl
diff --git a/powerstats/DvfsStateResidencyDataProviderAidl.h b/powerstats/DvfsStateResidencyDataProviderAidl.h
deleted file mode 100644
index ca8ab22..0000000
--- a/powerstats/DvfsStateResidencyDataProviderAidl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <PowerStatsAidl.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class DvfsStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
-  public:
-    class Config {
-      public:
-        // Power entity name to parse.
-        std::string powerEntityName;
-
-        // List of state pairs (name to display, name to parse).
-        std::vector<std::pair<std::string, std::string>> states;
-    };
-    /*
-     * path - path to dvfs sysfs node.
-     * clockRate - clock rate in KHz.
-     */
-    DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate, std::vector<Config> cfgs);
-    ~DvfsStateResidencyDataProvider() = default;
-
-    /*
-     * See IStateResidencyDataProvider::getStateResidencies
-     */
-    bool getStateResidencies(
-        std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
-
-    /*
-     * See IStateResidencyDataProvider::getInfo
-     */
-    std::unordered_map<std::string, std::vector<State>> getInfo() override;
-
-  private:
-    int32_t matchEntity(char const *line);
-    int32_t matchState(char const *line, const Config& powerEntity);
-    bool parseState(char const *line, uint64_t *duration, uint64_t *count);
-
-    const std::string mPath;
-    const uint64_t mClockRate;
-    std::vector<Config> mPowerEntities;
-};
-
-}  // namespace stats
-}  // namespace power
-}  // namespace hardware
-}  // namespace android
-}  // namespace aidl
diff --git a/powerstats/RailDataProvider.cpp b/powerstats/RailDataProvider.cpp
deleted file mode 100644
index d0efc17..0000000
--- a/powerstats/RailDataProvider.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "libpixelpowerstats"
-
-#include "RailDataProvider.h"
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <inttypes.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <exception>
-#include <thread>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-#define MAX_FILE_PATH_LEN 128
-#define MAX_DEVICE_NAME_LEN 64
-#define MAX_QUEUE_SIZE 8192
-
-constexpr char kIioDirRoot[] = "/sys/bus/iio/devices/";
-const char *const kDeviceNames[] = {"s2mpg10-odpm", "s2mpg11-odpm"};
-constexpr char kDeviceType[] = "iio:device";
-constexpr uint32_t MAX_SAMPLING_RATE = 10;
-constexpr uint64_t WRITE_TIMEOUT_NS = 1000000000;
-
-#define MAX_RAIL_NAME_LEN 50
-#define STR(s) #s
-#define XSTR(s) STR(s)
-
-void RailDataProvider::findIioPowerMonitorNodes() {
-    struct dirent *ent;
-    int fd;
-    char devName[MAX_DEVICE_NAME_LEN];
-    char filePath[MAX_FILE_PATH_LEN];
-    DIR *iioDir = opendir(kIioDirRoot);
-    if (!iioDir) {
-        ALOGE("Error opening directory: %s, error: %d", kIioDirRoot, errno);
-        return;
-    }
-    while (ent = readdir(iioDir), ent) {
-        if (strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0 &&
-                strlen(ent->d_name) > strlen(kDeviceType) &&
-                strncmp(ent->d_name, kDeviceType, strlen(kDeviceType)) == 0) {
-            snprintf(filePath, MAX_FILE_PATH_LEN, "%s/%s", ent->d_name, "name");
-            fd = openat(dirfd(iioDir), filePath, O_RDONLY);
-            if (fd < 0) {
-                ALOGW("Failed to open directory: %s, error: %d", filePath, errno);
-                continue;
-            }
-            if (read(fd, devName, MAX_DEVICE_NAME_LEN) < 0) {
-                ALOGW("Failed to read device name from file: %s(%d)", filePath, fd);
-                close(fd);
-                continue;
-            }
-
-            for (const auto &kDeviceName : kDeviceNames) {
-                if (strncmp(devName, kDeviceName, strlen(kDeviceName)) == 0) {
-                    snprintf(filePath, MAX_FILE_PATH_LEN, "%s/%s", kIioDirRoot, ent->d_name);
-                    mOdpm.devicePaths.push_back(filePath);
-                }
-            }
-            close(fd);
-        }
-    }
-    closedir(iioDir);
-    return;
-}
-
-size_t RailDataProvider::parsePowerRails() {
-    std::string data;
-    std::string railFileName;
-    std::string spsFileName;
-    uint32_t index = 0;
-    uint32_t samplingRate;
-    for (const auto &path : mOdpm.devicePaths) {
-        railFileName = path + "/enabled_rails";
-        spsFileName = path + "/sampling_rate";
-        if (!android::base::ReadFileToString(spsFileName, &data)) {
-            ALOGW("Error reading file: %s", spsFileName.c_str());
-            continue;
-        }
-        samplingRate = strtoul(data.c_str(), NULL, 10);
-        if (!samplingRate || samplingRate == ULONG_MAX) {
-            ALOGE("Error parsing: %s", spsFileName.c_str());
-            break;
-        }
-        if (!android::base::ReadFileToString(railFileName, &data)) {
-            ALOGW("Error reading file: %s", railFileName.c_str());
-            continue;
-        }
-        std::istringstream railNames(data);
-        std::string line;
-        while (std::getline(railNames, line)) {
-            std::vector<std::string> words = android::base::Split(line, ":][");
-            if (words.size() == 4) {
-                const std::string channelName = words[1];
-                if (mOdpm.railsInfo.count(channelName) == 0) {
-                    const std::string subsysName = words[3];
-                    mOdpm.railsInfo.emplace(channelName, RailData{.devicePath = path,
-                                                            .index = index,
-                                                            .subsysName = subsysName,
-                                                            .samplingRate = samplingRate});
-                    index++;
-                } else {
-                    ALOGW("There exists rails with the same name (not supported): %s." \
-                        " Only the last occurrence of rail energy will be provided.",
-                        channelName.c_str());
-                }
-            } else {
-                ALOGW("Unexpected format in file: %s", railFileName.c_str());
-            }
-        }
-    }
-    return index;
-}
-
-int RailDataProvider::parseIioEnergyNodeString(const std::string &contents, OnDeviceMmt &odpm) {
-    std::istringstream energyData(contents);
-    std::string line;
-
-    int ret = 0;
-    uint64_t timestamp = 0;
-    bool timestampRead = false;
-
-    while (std::getline(energyData, line)) {
-        bool parseLineSuccess = false;
-
-        if (timestampRead == false) {
-            /* Read timestamp from boot (ms) */
-            if (sscanf(line.c_str(), "t=%" PRIu64, &timestamp) == 1) {
-                if (timestamp == 0 || timestamp == ULLONG_MAX) {
-                    ALOGW("Potentially wrong timestamp: %" PRIu64, timestamp);
-                }
-                timestampRead = true;
-                parseLineSuccess = true;
-            }
-
-        } else {
-            /* Read rail energy */
-            uint64_t energy = 0;
-            char railNameRaw[MAX_RAIL_NAME_LEN + 1];
-            if (sscanf(line.c_str(),
-                       "CH%*d(T=%*" PRIu64 ")[%" XSTR(MAX_RAIL_NAME_LEN) "[^]]], %" PRIu64,
-                       railNameRaw, &energy) == 2) {
-                std::string railName(railNameRaw);
-
-                /* If the count == 0, the rail may not be enabled */
-                /* The count cannot be > 1; mChannelIds is a map */
-                if (odpm.railsInfo.count(railName) == 1) {
-                    size_t index = odpm.railsInfo[railName].index;
-                    odpm.reading[index].index = index;
-                    odpm.reading[index].timestamp = timestamp;
-                    odpm.reading[index].energy = energy;
-                    if (odpm.reading[index].energy == ULLONG_MAX) {
-                        ALOGW("Potentially wrong energy value on rail: %s", railName.c_str());
-                    }
-                }
-                parseLineSuccess = true;
-            }
-        }
-
-        if (parseLineSuccess == false) {
-            ret = -1;
-            break;
-        }
-    }
-
-    return ret;
-}
-
-int RailDataProvider::parseIioEnergyNode(std::string devName) {
-    int ret;
-    std::string data;
-    std::string fileName = devName + "/energy_value";
-    if (!android::base::ReadFileToString(fileName, &data)) {
-        ALOGE("Error reading file: %s", fileName.c_str());
-        return -1;
-    }
-
-    ret = parseIioEnergyNodeString(data, mOdpm);
-    if (ret != 0) {
-        ALOGW("Unexpected format in file: %s", fileName.c_str());
-    }
-    return ret;
-}
-
-Status RailDataProvider::parseIioEnergyNodes() {
-    Status ret = Status::SUCCESS;
-    if (mOdpm.hwEnabled == false) {
-        return Status::NOT_SUPPORTED;
-    }
-
-    for (const auto &devicePath : mOdpm.devicePaths) {
-        if (parseIioEnergyNode(devicePath) < 0) {
-            ALOGE("Error in parsing power stats");
-            ret = Status::FILESYSTEM_ERROR;
-            break;
-        }
-    }
-    return ret;
-}
-
-RailDataProvider::RailDataProvider() {
-    findIioPowerMonitorNodes();
-    size_t numRails = parsePowerRails();
-    if (mOdpm.devicePaths.empty() || numRails == 0) {
-        mOdpm.hwEnabled = false;
-    } else {
-        mOdpm.hwEnabled = true;
-        mOdpm.reading.resize(numRails);
-    }
-}
-
-Return<void> RailDataProvider::getRailInfo(IPowerStats::getRailInfo_cb _hidl_cb) {
-    hidl_vec<RailInfo> rInfo;
-    Status ret = Status::SUCCESS;
-    size_t index;
-    std::lock_guard<std::mutex> _lock(mOdpm.mLock);
-    if (mOdpm.hwEnabled == false) {
-        ALOGI("getRailInfo not supported");
-        _hidl_cb(rInfo, Status::NOT_SUPPORTED);
-        return Void();
-    }
-    rInfo.resize(mOdpm.railsInfo.size());
-    for (const auto &railData : mOdpm.railsInfo) {
-        index = railData.second.index;
-        rInfo[index].railName = railData.first;
-        rInfo[index].subsysName = railData.second.subsysName;
-        rInfo[index].index = index;
-        rInfo[index].samplingRate = railData.second.samplingRate;
-    }
-    _hidl_cb(rInfo, ret);
-    return Void();
-}
-
-Return<void> RailDataProvider::getEnergyData(const hidl_vec<uint32_t> &railIndices,
-                                             IPowerStats::getEnergyData_cb _hidl_cb) {
-    hidl_vec<EnergyData> eVal;
-    std::lock_guard<std::mutex> _lock(mOdpm.mLock);
-    Status ret = parseIioEnergyNodes();
-
-    if (ret != Status::SUCCESS) {
-        ALOGE("Failed to getEnergyData");
-        _hidl_cb(eVal, ret);
-        return Void();
-    }
-
-    if (railIndices.size() == 0) {
-        eVal.resize(mOdpm.railsInfo.size());
-        memcpy(&eVal[0], &mOdpm.reading[0], mOdpm.reading.size() * sizeof(EnergyData));
-    } else {
-        eVal.resize(railIndices.size());
-        int i = 0;
-        for (const auto &railIndex : railIndices) {
-            if (railIndex >= mOdpm.reading.size()) {
-                ret = Status::INVALID_INPUT;
-                eVal.resize(0);
-                break;
-            }
-            memcpy(&eVal[i], &mOdpm.reading[railIndex], sizeof(EnergyData));
-            i++;
-        }
-    }
-    _hidl_cb(eVal, ret);
-    return Void();
-}
-
-Return<void> RailDataProvider::streamEnergyData(uint32_t timeMs, uint32_t samplingRate,
-                                                IPowerStats::streamEnergyData_cb _hidl_cb) {
-    std::lock_guard<std::mutex> _lock(mOdpm.mLock);
-    if (mOdpm.fmqSynchronized != nullptr) {
-        _hidl_cb(MessageQueueSync::Descriptor(), 0, 0, Status::INSUFFICIENT_RESOURCES);
-        return Void();
-    }
-    uint32_t sps = std::min(samplingRate, MAX_SAMPLING_RATE);
-    uint32_t numSamples = timeMs * sps / 1000;
-    mOdpm.fmqSynchronized.reset(new (std::nothrow) MessageQueueSync(MAX_QUEUE_SIZE, true));
-    if (mOdpm.fmqSynchronized == nullptr || mOdpm.fmqSynchronized->isValid() == false) {
-        mOdpm.fmqSynchronized = nullptr;
-        _hidl_cb(MessageQueueSync::Descriptor(), 0, 0, Status::INSUFFICIENT_RESOURCES);
-        return Void();
-    }
-    std::thread pollThread = std::thread([this, sps, numSamples]() {
-        uint64_t sleepTimeUs = 1000000 / sps;
-        uint32_t currSamples = 0;
-        while (currSamples < numSamples) {
-            mOdpm.mLock.lock();
-            if (parseIioEnergyNodes() == Status::SUCCESS) {
-                mOdpm.fmqSynchronized->writeBlocking(&mOdpm.reading[0], mOdpm.reading.size(),
-                                                     WRITE_TIMEOUT_NS);
-                mOdpm.mLock.unlock();
-                currSamples++;
-                if (usleep(sleepTimeUs) < 0) {
-                    ALOGW("Sleep interrupted");
-                    break;
-                }
-            } else {
-                mOdpm.mLock.unlock();
-                break;
-            }
-        }
-        mOdpm.mLock.lock();
-        mOdpm.fmqSynchronized = nullptr;
-        mOdpm.mLock.unlock();
-        return;
-    });
-    pollThread.detach();
-    _hidl_cb(*(mOdpm.fmqSynchronized)->getDesc(), numSamples, mOdpm.reading.size(),
-             Status::SUCCESS);
-    return Void();
-}
-
-}  // namespace powerstats
-}  // namespace pixel
-}  // namespace google
-}  // namespace hardware
-}  // namespace android
diff --git a/powerstats/RailDataProvider.h b/powerstats/RailDataProvider.h
deleted file mode 100644
index 61313e2..0000000
--- a/powerstats/RailDataProvider.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef ANDROID_HARDWARE_POWERSTATS_RAILDATAPROVIDER_H
-#define ANDROID_HARDWARE_POWERSTATS_RAILDATAPROVIDER_H
-
-#include <fmq/MessageQueue.h>
-#include <pixelpowerstats/PowerStats.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-typedef MessageQueue<EnergyData, kSynchronizedReadWrite> MessageQueueSync;
-struct RailData {
-    std::string devicePath;
-    uint32_t index;
-    std::string subsysName;
-    uint32_t samplingRate;
-};
-
-struct OnDeviceMmt {
-    std::mutex mLock;
-    bool hwEnabled;
-    std::vector<std::string> devicePaths;
-    std::map<std::string, RailData> railsInfo;
-    std::vector<EnergyData> reading;
-    std::unique_ptr<MessageQueueSync> fmqSynchronized;
-};
-
-class RailDataProvider : public IRailDataProvider {
-public:
-    RailDataProvider();
-    // Methods from ::android::hardware::power::stats::V1_0::IPowerStats follow.
-    Return<void> getRailInfo(IPowerStats::getRailInfo_cb _hidl_cb) override;
-    Return<void> getEnergyData(const hidl_vec<uint32_t>& railIndices,
-                        IPowerStats::getEnergyData_cb _hidl_cb) override;
-    Return<void> streamEnergyData(uint32_t timeMs, uint32_t samplingRate,
-                        IPowerStats::streamEnergyData_cb _hidl_cb) override;
- private:
-     OnDeviceMmt mOdpm;
-     void findIioPowerMonitorNodes();
-     size_t parsePowerRails();
-     int parseIioEnergyNodeString(const std::string &contents,
-                    OnDeviceMmt &odpm);
-     int parseIioEnergyNode(std::string devName);
-     Status parseIioEnergyNodes();
-};
-
-}  // namespace powerstats
-}  // namespace pixel
-}  // namespace google
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_POWERSTATS_RAILDATAPROVIDER_H
diff --git a/powerstats/UfsStateResidencyDataProvider.cpp b/powerstats/UfsStateResidencyDataProvider.cpp
deleted file mode 100644
index 7ca6f3b..0000000
--- a/powerstats/UfsStateResidencyDataProvider.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define LOG_TAG "libpixelpowerstats"
-
-#include "UfsStateResidencyDataProvider.h"
-
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-
-#include <string>
-#include <utility>
-
-using android::base::ParseUint;
-using android::base::Split;
-using android::base::StartsWith;
-using android::base::Trim;
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-const uint32_t HIBERNATE_STATE_ID = 0;
-
-UfsStateResidencyDataProvider::UfsStateResidencyDataProvider(uint32_t powerEntityId)
-    : mPowerEntityId(powerEntityId) {}
-
-bool UfsStateResidencyDataProvider::getResults(
-        std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
-    PowerEntityStateResidencyResult result = {
-            .powerEntityId = mPowerEntityId,
-            .stateResidencyData = {{.powerEntityStateId = HIBERNATE_STATE_ID}}};
-
-    // The transform function converts microseconds to milliseconds.
-    std::function<uint64_t(uint64_t)> usecToMs = [](uint64_t a) { return a / 1000; };
-
-    std::string prefix = "/sys/bus/platform/devices/14700000.ufs/ufs_stats/";
-
-    result.stateResidencyData[0].totalTimeInStateMs =
-            usecToMs(readStat(prefix + "hibern8_total_us"));
-    result.stateResidencyData[0].totalStateEntryCount = readStat(prefix + "hibern8_exit_cnt");
-    result.stateResidencyData[0].lastEntryTimestampMs =
-            usecToMs(readStat(prefix + "last_hibern8_enter_time"));
-    results.insert(std::make_pair(mPowerEntityId, result));
-    return true;
-}
-
-std::vector<PowerEntityStateSpace> UfsStateResidencyDataProvider::getStateSpaces() {
-    return {{.powerEntityId = mPowerEntityId,
-             .states = {{.powerEntityStateId = HIBERNATE_STATE_ID,
-                         .powerEntityStateName = "HIBERN8"}}}};
-}
-
-uint64_t UfsStateResidencyDataProvider::readStat(std::string path) {
-    std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(path.c_str(), "r"), fclose);
-    if (!fp) {
-        PLOG(ERROR) << __func__ << ":Failed to open file " << path
-                    << " Error = " << strerror(errno);
-        return 0;
-    }
-    const size_t size = 20;
-    char buf[size];
-    (void)fread(&buf, sizeof(char), size, fp.get());
-    uint64_t ret;
-    if (!ParseUint(Trim(std::string(buf)), &ret)) {
-        LOG(ERROR) << "Failed to parse uint64 from [" << std::string(buf) << "]";
-    }
-    return ret;
-}
-
-}  // namespace powerstats
-}  // namespace pixel
-}  // namespace google
-}  // namespace hardware
-}  // namespace android
diff --git a/powerstats/UfsStateResidencyDataProvider.h b/powerstats/UfsStateResidencyDataProvider.h
deleted file mode 100644
index 8d1ea73..0000000
--- a/powerstats/UfsStateResidencyDataProvider.h
+++ /dev/null
@@ -1,58 +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.
- */
-#ifndef HARDWARE_GOOGLE_PIXEL_POWERSTATS_UFSSTATERESIDENCYDATAPROVIDER_H
-#define HARDWARE_GOOGLE_PIXEL_POWERSTATS_UFSSTATERESIDENCYDATAPROVIDER_H
-
-#include <pixelpowerstats/PowerStats.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-class UfsStateResidencyDataProvider : public IStateResidencyDataProvider {
-  public:
-    /*
-     * powerEntityId - id for the UFS power entity.
-     */
-    UfsStateResidencyDataProvider(uint32_t powerEntityId);
-    ~UfsStateResidencyDataProvider() = default;
-
-    /*
-     * See IStateResidencyDataProvider::getResults.
-     */
-    bool getResults(
-            std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) override;
-
-    /*
-     * See IStateResidencyDataProvider::getStateSpaces.
-     */
-    std::vector<PowerEntityStateSpace> getStateSpaces() override;
-
-  private:
-    uint64_t readStat(std::string path);
-
-    uint32_t mPowerEntityId;
-};
-
-}  // namespace powerstats
-}  // namespace pixel
-}  // namespace google
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HARDWARE_GOOGLE_PIXEL_POWERSTATS_UFSSTATERESIDENCYDATAPROVIDER_H
diff --git a/powerstats/android.hardware.power.stats@1.0-service.gs101.rc b/powerstats/android.hardware.power.stats@1.0-service.gs101.rc
deleted file mode 100644
index afc3580..0000000
--- a/powerstats/android.hardware.power.stats@1.0-service.gs101.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.power.stats-hal-1-0 /vendor/bin/hw/android.hardware.power.stats@1.0-service.gs101
-    interface android.hardware.power.stats@1.0::IPowerStats default
-    class hal
-    user system
-    group system
diff --git a/powerstats/android.hardware.power.stats@1.0-service.gs101.xml b/powerstats/android.hardware.power.stats@1.0-service.gs101.xml
deleted file mode 100644
index 2e9956f..0000000
--- a/powerstats/android.hardware.power.stats@1.0-service.gs101.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest version="1.0" type="device">
-    <hal format="hidl">
-        <name>android.hardware.power.stats</name>
-        <transport>hwbinder</transport>
-        <version>1.0</version>
-        <interface>
-           <name>IPowerStats</name>
-           <instance>default</instance>
-        </interface>
-    </hal>
-</manifest>
diff --git a/powerstats/service.cpp b/powerstats/service.cpp
index 4cf1f35..632de32 100644
--- a/powerstats/service.cpp
+++ b/powerstats/service.cpp
@@ -14,313 +14,174 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.power.stats@1.0-service.gs101"
+#define LOG_TAG "android.hardware.power.stats-service.pixel"
 
-#include <android/log.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <hidl/HidlTransportSupport.h>
-#include <pixelpowerstats/AidlStateResidencyDataProvider.h>
-#include <pixelpowerstats/GenericStateResidencyDataProvider.h>
-#include <pixelpowerstats/PowerStats.h>
-
+#include <PowerStatsAidl.h>
 #include "AocStateResidencyDataProvider.h"
 #include "DvfsStateResidencyDataProvider.h"
-#include "RailDataProvider.h"
-#include "UfsStateResidencyDataProvider.h"
+#include <dataproviders/DisplayStateResidencyDataProvider.h>
+#include <dataproviders/GenericStateResidencyDataProvider.h>
+#include <dataproviders/IioEnergyMeterDataProvider.h>
+#include <dataproviders/PowerStatsEnergyConsumer.h>
+#include <dataproviders/PowerStatsEnergyAttribution.h>
+#include <dataproviders/PixelStateResidencyDataProvider.h>
 
-using android::OK;
-using android::sp;
-using android::status_t;
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <log/log.h>
 
-// libhwbinder:
-using android::hardware::configureRpcThreadpool;
-using android::hardware::joinRpcThreadpool;
+using aidl::android::hardware::power::stats::AocStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::DisplayStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::DvfsStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::EnergyConsumerType;
+using aidl::android::hardware::power::stats::GenericStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::IioEnergyMeterDataProvider;
+using aidl::android::hardware::power::stats::PixelStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::PowerStats;
+using aidl::android::hardware::power::stats::PowerStatsEnergyConsumer;
 
-// Generated HIDL files
-using android::hardware::power::stats::V1_0::IPowerStats;
-using android::hardware::power::stats::V1_0::PowerEntityType;
-using android::hardware::power::stats::V1_0::implementation::PowerStats;
+constexpr char kBootHwSoCRev[] = "ro.boot.hw.soc.rev";
 
-// Pixel specific
-using android::hardware::google::pixel::powerstats::AidlStateResidencyDataProvider;
-using android::hardware::google::pixel::powerstats::AocStateResidencyDataProvider;
-using android::hardware::google::pixel::powerstats::DvfsStateResidencyDataProvider;
-using android::hardware::google::pixel::powerstats::generateGenericStateResidencyConfigs;
-using android::hardware::google::pixel::powerstats::GenericStateResidencyDataProvider;
-using android::hardware::google::pixel::powerstats::PowerEntityConfig;
-using android::hardware::google::pixel::powerstats::RailDataProvider;
-using android::hardware::google::pixel::powerstats::StateResidencyConfig;
-using android::hardware::google::pixel::powerstats::UfsStateResidencyDataProvider;
-
-// A constant to represnt the number of nanoseconds in one millisecond.
-static const int NS_TO_MS = 1000000;
-
-void addAoCStats(PowerStats *const service) {
+void addAoC(std::shared_ptr<PowerStats> p) {
     std::string prefix = "/sys/devices/platform/19000000.aoc/control/";
 
     // Add AoC cores (a32, ff1, hf0, and hf1)
-    std::vector<std::pair<uint32_t, std::string>> coreIds = {
-            {service->addPowerEntity("AoC-A32", PowerEntityType::SUBSYSTEM), prefix + "a32_"},
-            {service->addPowerEntity("AoC-FF1", PowerEntityType::SUBSYSTEM), prefix + "ff1_"},
-            {service->addPowerEntity("AoC-HF1", PowerEntityType::SUBSYSTEM), prefix + "hf1_"},
-            {service->addPowerEntity("AoC-HF0", PowerEntityType::SUBSYSTEM), prefix + "hf0_"},
+    std::vector<std::pair<std::string, std::string>> coreIds = {
+            {"AoC-A32", prefix + "a32_"},
+            {"AoC-FF1", prefix + "ff1_"},
+            {"AoC-HF1", prefix + "hf1_"},
+            {"AoC-HF0", prefix + "hf0_"},
     };
     std::vector<std::pair<std::string, std::string>> coreStates = {
             {"DWN", "off"}, {"RET", "retention"}, {"WFI", "wfi"}};
-    service->addStateResidencyDataProvider(new AocStateResidencyDataProvider(coreIds, coreStates));
+    p->addStateResidencyDataProvider(std::make_shared<AocStateResidencyDataProvider>(coreIds,
+            coreStates));
 
     // Add AoC voltage stats
-    std::vector<std::pair<uint32_t, std::string>> voltageIds = {
-            {service->addPowerEntity("AoC-Voltage", PowerEntityType::SUBSYSTEM),
-             prefix + "voltage_"},
+    std::vector<std::pair<std::string, std::string>> voltageIds = {
+            {"AoC-Voltage", prefix + "voltage_"},
     };
     std::vector<std::pair<std::string, std::string>> voltageStates = {{"NOM", "nominal"},
                                                                       {"SUD", "super_underdrive"},
                                                                       {"UUD", "ultra_underdrive"},
                                                                       {"UD", "underdrive"}};
-    service->addStateResidencyDataProvider(
-            new AocStateResidencyDataProvider(voltageIds, voltageStates));
+    p->addStateResidencyDataProvider(
+            std::make_shared<AocStateResidencyDataProvider>(voltageIds, voltageStates));
 
     // Add AoC monitor mode
-    std::vector<std::pair<uint32_t, std::string>> monitorIds = {
-            {service->addPowerEntity("AoC", PowerEntityType::SUBSYSTEM), prefix + "monitor_"},
+    std::vector<std::pair<std::string, std::string>> monitorIds = {
+            {"AoC", prefix + "monitor_"},
     };
     std::vector<std::pair<std::string, std::string>> monitorStates = {
             {"MON", "mode"},
     };
-    service->addStateResidencyDataProvider(
-            new AocStateResidencyDataProvider(monitorIds, monitorStates));
+    p->addStateResidencyDataProvider(
+            std::make_shared<AocStateResidencyDataProvider>(monitorIds, monitorStates));
 }
 
-void addCpuCStateStats(PowerStats *const service) {
-    // CPU stats are reported in nanoseconds. The transform function
-    // converts nanoseconds to milliseconds.
-    std::function<uint64_t(uint64_t)> cpuNsToMs = [](uint64_t a) { return a / NS_TO_MS; };
-    StateResidencyConfig cStateConfig = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "down_count:",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "total_down_time_ns:",
-            .totalTimeTransform = cpuNsToMs,
-            .lastEntrySupported = true,
-            .lastEntryPrefix = "last_down_time_ns:",
-            .lastEntryTransform = cpuNsToMs,
-    };
+void addDvfsStats(std::shared_ptr<PowerStats> p) {
+    // A constant to represent the number of nanoseconds in one millisecond
+    const int NS_TO_MS = 1000000;
 
-    sp<GenericStateResidencyDataProvider> cStateSdp = new GenericStateResidencyDataProvider(
-            "/sys/devices/platform/1742048c.acpm_stats/core_stats");
-    for (std::string state :
-         {"CORE00", "CORE01", "CORE02", "CORE03", "CORE10", "CORE11", "CORE20", "CORE21"}) {
-        cStateSdp->addEntity(service->addPowerEntity(state, PowerEntityType::SUBSYSTEM),
-                             PowerEntityConfig("CORES:", generateGenericStateResidencyConfigs(
-                                                                 cStateConfig,
-                                                                 {std::make_pair("DOWN", state)})));
-    }
-    for (std::string state : {"CLUSTER0", "CLUSTER1", "CLUSTER2"}) {
-        cStateSdp->addEntity(
-                service->addPowerEntity(state, PowerEntityType::SUBSYSTEM),
-                PowerEntityConfig("CLUSTERS:",
-                                  generateGenericStateResidencyConfigs(
-                                          cStateConfig, {std::make_pair("DOWN", state)})));
-    }
-    service->addStateResidencyDataProvider(cStateSdp);
+    std::vector<DvfsStateResidencyDataProvider::Config> cfgs;
+
+    cfgs.push_back({"MIF", {
+        std::make_pair("3172KHz", "3172000"),
+        std::make_pair("2730KHz", "2730000"),
+        std::make_pair("2535KHz", "2535000"),
+        std::make_pair("2288KHz", "2288000"),
+        std::make_pair("2028KHz", "2028000"),
+        std::make_pair("1716KHz", "1716000"),
+        std::make_pair("1539KHz", "1539000"),
+        std::make_pair("1352KHz", "1352000"),
+        std::make_pair("1014KHz", "1014000"),
+        std::make_pair("845KHz", "845000"),
+        std::make_pair("676KHz", "676000"),
+        std::make_pair("546KHz", "546000"),
+        std::make_pair("421KHz", "421000"),
+        std::make_pair("0KHz", "0"),
+    }});
+
+    cfgs.push_back({"CL0", {
+        std::make_pair("2024KHz", "2024000"),
+        std::make_pair("1950KHz", "1950000"),
+        std::make_pair("1868KHz", "1868000"),
+        std::make_pair("1803KHz", "1803000"),
+        std::make_pair("1745KHz", "1745000"),
+        std::make_pair("1704KHz", "1704000"),
+        std::make_pair("1598KHz", "1598000"),
+        std::make_pair("1459KHz", "1459000"),
+        std::make_pair("1401KHz", "1401000"),
+        std::make_pair("1328KHz", "1328000"),
+        std::make_pair("1197KHz", "1197000"),
+        std::make_pair("1098KHz", "1098000"),
+        std::make_pair("930KHz", "930000"),
+        std::make_pair("889KHz", "889000"),
+        std::make_pair("738KHz", "738000"),
+        std::make_pair("574KHz", "574000"),
+        std::make_pair("300KHz", "300000"),
+        std::make_pair("0KHz", "0"),
+    }});
+
+    cfgs.push_back({"CL1", {
+        std::make_pair("2253KHz", "2253000"),
+        std::make_pair("2130KHz", "2130000"),
+        std::make_pair("1999KHz", "1999000"),
+        std::make_pair("1836KHz", "1836000"),
+        std::make_pair("1663KHz", "1663000"),
+        std::make_pair("1491KHz", "1491000"),
+        std::make_pair("1328KHz", "1328000"),
+        std::make_pair("1197KHz", "1197000"),
+        std::make_pair("1024KHz", "1024000"),
+        std::make_pair("910KHz", "910000"),
+        std::make_pair("799KHz", "799000"),
+        std::make_pair("696KHz", "696000"),
+        std::make_pair("533KHz", "533000"),
+        std::make_pair("400KHz", "400000"),
+        std::make_pair("0KHz", "0"),
+    }});
+
+    cfgs.push_back({"CL2", {
+        std::make_pair("2630KHz", "2630000"),
+        std::make_pair("2507KHz", "2507000"),
+        std::make_pair("2401KHz", "2401000"),
+        std::make_pair("2302KHz", "2302000"),
+        std::make_pair("2252KHz", "2252000"),
+        std::make_pair("2188KHz", "2188000"),
+        std::make_pair("2048KHz", "2048000"),
+        std::make_pair("1901KHz", "1901000"),
+        std::make_pair("1826KHz", "1826000"),
+        std::make_pair("1745KHz", "1745000"),
+        std::make_pair("1582KHz", "1582000"),
+        std::make_pair("1426KHz", "1426000"),
+        std::make_pair("1277KHz", "1277000"),
+        std::make_pair("1237KHz", "1237000"),
+        std::make_pair("1106KHz", "1106000"),
+        std::make_pair("984KHz", "984000"),
+        std::make_pair("851KHz", "851000"),
+        std::make_pair("848KHz", "848000"),
+        std::make_pair("500KHz", "500000"),
+        std::make_pair("0KHz", "0"),
+    }});
+
+    cfgs.push_back({"TPU", {
+        std::make_pair("1066MHz", "1066000000"),
+    }});
+
+    p->addStateResidencyDataProvider(std::make_shared<DvfsStateResidencyDataProvider>(
+            "/sys/devices/platform/1742048c.acpm_stats/fvp_stats", NS_TO_MS, cfgs));
 }
 
-void addDvfsStats(PowerStats *const service) {
-    sp<DvfsStateResidencyDataProvider> dvfsSdp = new DvfsStateResidencyDataProvider(
-            "/sys/devices/platform/1742048c.acpm_stats/fvp_stats", NS_TO_MS);
+void addSoC(std::shared_ptr<PowerStats> p) {
+    // A constant to represent the number of nanoseconds in one millisecond.
+    const int NS_TO_MS = 1000000;
 
-    dvfsSdp->addEntity(service->addPowerEntity("MIF-DVFS", PowerEntityType::SUBSYSTEM), "MIF",
-                       {
-                               std::make_pair("3172KHz", "3172000"),
-                               std::make_pair("2730KHz", "2730000"),
-                               std::make_pair("2535KHz", "2535000"),
-                               std::make_pair("2288KHz", "2288000"),
-                               std::make_pair("2028KHz", "2028000"),
-                               std::make_pair("1716KHz", "1716000"),
-                               std::make_pair("1539KHz", "1539000"),
-                               std::make_pair("1352KHz", "1352000"),
-                               std::make_pair("1014KHz", "1014000"),
-                               std::make_pair("845KHz", "845000"),
-                               std::make_pair("676KHz", "676000"),
-                               std::make_pair("546KHz", "546000"),
-                               std::make_pair("421KHz", "421000"),
-                               std::make_pair("0KHz", "0"),
-                       });
-
-    dvfsSdp->addEntity(service->addPowerEntity("CL0-DVFS", PowerEntityType::SUBSYSTEM), "CL0",
-                       {
-                               std::make_pair("2196KHz", "2196000"),
-                               std::make_pair("2098KHz", "2098000"),
-                               std::make_pair("2024KHz", "2024000"),
-                               std::make_pair("1950KHz", "1950000"),
-                               std::make_pair("1868KHz", "1868000"),
-                               std::make_pair("1745KHz", "1745000"),
-                               std::make_pair("1598KHz", "1598000"),
-                               std::make_pair("1459KHz", "1459000"),
-                               std::make_pair("1328KHz", "1328000"),
-                               std::make_pair("1197KHz", "1197000"),
-                               std::make_pair("1098KHz", "1098000"),
-                               std::make_pair("889KHz", "889000"),
-                               std::make_pair("738KHz", "738000"),
-                               std::make_pair("574KHz", "574000"),
-                               std::make_pair("300KHz", "300000"),
-                               std::make_pair("0KHz", "0"),
-                       });
-
-    dvfsSdp->addEntity(service->addPowerEntity("CL1-DVFS", PowerEntityType::SUBSYSTEM), "CL1",
-                       {
-                               std::make_pair("2466KHz", "2466000"),
-                               std::make_pair("2393KHz", "2393000"),
-                               std::make_pair("2348KHz", "2348000"),
-                               std::make_pair("2253KHz", "2253000"),
-                               std::make_pair("2130KHz", "2130000"),
-                               std::make_pair("1999KHz", "1999000"),
-                               std::make_pair("1836KHz", "1836000"),
-                               std::make_pair("1663KHz", "1663000"),
-                               std::make_pair("1491KHz", "1491000"),
-                               std::make_pair("1328KHz", "1328000"),
-                               std::make_pair("1197KHz", "1197000"),
-                               std::make_pair("1024KHz", "1024000"),
-                               std::make_pair("910KHz", "910000"),
-                               std::make_pair("799KHz", "799000"),
-                               std::make_pair("696KHz", "696000"),
-                               std::make_pair("533KHz", "533000"),
-                               std::make_pair("400KHz", "400000"),
-                               std::make_pair("0KHz", "0"),
-                       });
-
-    dvfsSdp->addEntity(service->addPowerEntity("CL2-DVFS", PowerEntityType::SUBSYSTEM), "CL2",
-                       {
-                               std::make_pair("3195KHz", "3195000"),
-                               std::make_pair("3097KHz", "3097000"),
-                               std::make_pair("2999KHz", "2999000"),
-                               std::make_pair("2900KHz", "2900000"),
-                               std::make_pair("2802KHz", "2802000"),
-                               std::make_pair("2704KHz", "2704000"),
-                               std::make_pair("2630KHz", "2630000"),
-                               std::make_pair("2507KHz", "2507000"),
-                               std::make_pair("2401KHz", "2401000"),
-                               std::make_pair("2302KHz", "2302000"),
-                               std::make_pair("2188KHz", "2188000"),
-                               std::make_pair("2048KHz", "2048000"),
-                               std::make_pair("1901KHz", "1901000"),
-                               std::make_pair("1745KHz", "1745000"),
-                               std::make_pair("1582KHz", "1582000"),
-                               std::make_pair("1426KHz", "1426000"),
-                               std::make_pair("1237KHz", "1237000"),
-                               std::make_pair("1106KHz", "1106000"),
-                               std::make_pair("984KHz", "984000"),
-                               std::make_pair("848KHz", "848000"),
-                               std::make_pair("500KHz", "500000"),
-                               std::make_pair("0KHz", "0"),
-                       });
-
-    // TODO(sujee): Complete frequency table for TPU.
-    dvfsSdp->addEntity(service->addPowerEntity("TPU-DVFS", PowerEntityType::SUBSYSTEM), "TPU",
-                       {
-                               std::make_pair("1066MHz", "1066000000"),
-                       });
-
-    service->addStateResidencyDataProvider(dvfsSdp);
-}
-
-void addGPUStats(PowerStats *const service) {
-    StateResidencyConfig gpuStateConfig = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "count = ",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "total_time = ",
-            .lastEntrySupported = true,
-            .lastEntryPrefix = "last_entry_time = ",
-    };
-
-    sp<GenericStateResidencyDataProvider> gpu = new GenericStateResidencyDataProvider(
-            "/sys/devices/platform/1c500000.mali/power_stats");
-
-    PowerEntityConfig onOffConfig("Summary stats: (times in ms)",
-                                  generateGenericStateResidencyConfigs(
-                                          gpuStateConfig, {{"DOWN", "OFF:"}, {"UP", "ON:"}}));
-    gpu->addEntity(service->addPowerEntity("GPU", PowerEntityType::SUBSYSTEM), onOffConfig);
-
-    PowerEntityConfig DVFSConfig(
-            "DVFS stats: (times in ms)",
-            generateGenericStateResidencyConfigs(gpuStateConfig, {{"996MHz", "996000:"},
-                                                                  {"885MHz", "885000:"},
-                                                                  {"750MHz", "750000:"},
-                                                                  {"434MHz", "434000:"},
-                                                                  {"302MHz", "302000:"},
-                                                                  {"151MHz", "151000:"}}));
-    gpu->addEntity(service->addPowerEntity("GPU-DVFS", PowerEntityType::SUBSYSTEM), DVFSConfig);
-    service->addStateResidencyDataProvider(gpu);
-}
-
-void addNFCStats(PowerStats *const service) {
-    StateResidencyConfig nfcStateConfig = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "Cumulative count:",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "Cumulative duration msec:",
-            .lastEntrySupported = true,
-            .lastEntryPrefix = "Last entry timestamp msec:",
-    };
-    std::vector<std::pair<std::string, std::string>> nfcStateHeaders = {
-            std::make_pair("IDLE", "Idle mode:"),
-            std::make_pair("ACTIVE", "Active mode:"),
-            std::make_pair("ACTIVE-RW", "Active Reader/Writer mode:"),
-    };
-
-    sp<GenericStateResidencyDataProvider> nfcSdp = new GenericStateResidencyDataProvider(
-            "/sys/devices/platform/10960000.hsi2c/i2c-4/4-0008/power_stats");
-    nfcSdp->addEntity(service->addPowerEntity("NFC", PowerEntityType::SUBSYSTEM),
-                      PowerEntityConfig("NFC subsystem", generateGenericStateResidencyConfigs(
-                                                                 nfcStateConfig, nfcStateHeaders)));
-    service->addStateResidencyDataProvider(nfcSdp);
-}
-
-void addPCIeStats(PowerStats *const service) {
-    // Add PCIe power entities for Modem and WiFi
-    StateResidencyConfig pcieStateConfig = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "Cumulative count:",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "Cumulative duration msec:",
-            .lastEntrySupported = true,
-            .lastEntryPrefix = "Last entry timestamp msec:",
-    };
-    std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
-            std::make_pair("UP", "Link up:"),
-            std::make_pair("DOWN", "Link down:"),
-    };
-
-    // Add PCIe - Modem
-    sp<GenericStateResidencyDataProvider> pcieModemSdp = new GenericStateResidencyDataProvider(
-            "/sys/devices/platform/11920000.pcie/power_stats");
-    uint32_t pcieModemId = service->addPowerEntity("PCIe-Modem", PowerEntityType::SUBSYSTEM);
-    pcieModemSdp->addEntity(
-            pcieModemId,
-            PowerEntityConfig("Version: 1", generateGenericStateResidencyConfigs(
-                                                    pcieStateConfig, pcieStateHeaders)));
-    service->addStateResidencyDataProvider(pcieModemSdp);
-
-    // Add PCIe - WiFi
-    sp<GenericStateResidencyDataProvider> pcieWifiSdp = new GenericStateResidencyDataProvider(
-            "/sys/devices/platform/14520000.pcie/power_stats");
-    uint32_t pcieWifiId = service->addPowerEntity("PCIe-WiFi", PowerEntityType::SUBSYSTEM);
-    pcieWifiSdp->addEntity(
-            pcieWifiId,
-            PowerEntityConfig("Version: 1", generateGenericStateResidencyConfigs(
-                                                    pcieStateConfig, pcieStateHeaders)));
-    service->addStateResidencyDataProvider(pcieWifiSdp);
-}
-
-void addSocStats(PowerStats *const service) {
     // ACPM stats are reported in nanoseconds. The transform function
     // converts nanoseconds to milliseconds.
     std::function<uint64_t(uint64_t)> acpmNsToMs = [](uint64_t a) { return a / NS_TO_MS; };
-    StateResidencyConfig lpmStateConfig = {
+    const GenericStateResidencyDataProvider::StateResidencyConfig lpmStateConfig = {
             .entryCountSupported = true,
             .entryCountPrefix = "success_count:",
             .totalTimeSupported = true,
@@ -330,7 +191,7 @@
             .lastEntryPrefix = "last_entry_time_ns:",
             .lastEntryTransform = acpmNsToMs,
     };
-    StateResidencyConfig downStateConfig = {
+    const GenericStateResidencyDataProvider::StateResidencyConfig downStateConfig = {
             .entryCountSupported = true,
             .entryCountPrefix = "down_count:",
             .totalTimeSupported = true,
@@ -340,7 +201,7 @@
             .lastEntryPrefix = "last_down_time_ns:",
             .lastEntryTransform = acpmNsToMs,
     };
-    StateResidencyConfig reqStateConfig = {
+    const GenericStateResidencyDataProvider::StateResidencyConfig reqStateConfig = {
             .entryCountSupported = true,
             .entryCountPrefix = "req_up_count:",
             .totalTimeSupported = true,
@@ -351,141 +212,312 @@
             .lastEntryTransform = acpmNsToMs,
 
     };
-    std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
+    const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
             std::make_pair("SICD", "SICD"),
             std::make_pair("SLEEP", "SLEEP"),
             std::make_pair("SLEEP_SLCMON", "SLEEP_SLCMON"),
             std::make_pair("STOP", "STOP"),
     };
-    std::vector<std::pair<std::string, std::string>> mifReqStateHeaders = {
+    const std::vector<std::pair<std::string, std::string>> mifReqStateHeaders = {
             std::make_pair("AOC", "AOC"),
             std::make_pair("GSA", "GSA"),
     };
-    std::vector<std::pair<std::string, std::string>> slcReqStateHeaders = {
+    const std::vector<std::pair<std::string, std::string>> slcReqStateHeaders = {
             std::make_pair("AOC", "AOC"),
     };
 
-    sp<GenericStateResidencyDataProvider> socSdp = new GenericStateResidencyDataProvider(
-            "/sys/devices/platform/1742048c.acpm_stats/soc_stats");
+    std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
+    cfgs.emplace_back(generateGenericStateResidencyConfigs(lpmStateConfig, powerStateHeaders),
+            "LPM", "LPM:");
+    cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
+            "MIF", "MIF:");
+    cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, mifReqStateHeaders),
+            "MIF-REQ", "MIF_REQ:");
+    cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
+            "SLC", "SLC:");
+    cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, slcReqStateHeaders),
+            "SLC-REQ", "SLC_REQ:");
 
-    socSdp->addEntity(service->addPowerEntity("LPM", PowerEntityType::SUBSYSTEM),
-                      PowerEntityConfig("LPM:", generateGenericStateResidencyConfigs(
-                                                        lpmStateConfig, powerStateHeaders)));
-    socSdp->addEntity(service->addPowerEntity("MIF", PowerEntityType::SUBSYSTEM),
-                      PowerEntityConfig("MIF:", generateGenericStateResidencyConfigs(
-                                                        downStateConfig, powerStateHeaders)));
-    socSdp->addEntity(service->addPowerEntity("MIF-REQ", PowerEntityType::SUBSYSTEM),
-                      PowerEntityConfig("MIF_REQ:", generateGenericStateResidencyConfigs(
-                                                            reqStateConfig, mifReqStateHeaders)));
-    socSdp->addEntity(service->addPowerEntity("SLC", PowerEntityType::SUBSYSTEM),
-                      PowerEntityConfig("SLC:", generateGenericStateResidencyConfigs(
-                                                        downStateConfig, powerStateHeaders)));
-    socSdp->addEntity(service->addPowerEntity("SLC-REQ", PowerEntityType::SUBSYSTEM),
-                      PowerEntityConfig("SLC_REQ:", generateGenericStateResidencyConfigs(
-                                                            reqStateConfig, slcReqStateHeaders)));
+    auto socSdp = std::make_shared<GenericStateResidencyDataProvider>(
+            "/sys/devices/platform/1742048c.acpm_stats/soc_stats", cfgs);
 
-    service->addStateResidencyDataProvider(socSdp);
+    p->addStateResidencyDataProvider(socSdp);
 }
 
-void addUfsStats(PowerStats *const service) {
-    sp<UfsStateResidencyDataProvider> ufsSdp = new UfsStateResidencyDataProvider(
-            service->addPowerEntity("UFS", PowerEntityType::SUBSYSTEM));
-    service->addStateResidencyDataProvider(ufsSdp);
+void setEnergyMeter(std::shared_ptr<PowerStats> p) {
+    std::vector<const std::string> deviceNames { "s2mpg10-odpm", "s2mpg11-odpm" };
+    p->setEnergyMeterDataProvider(std::make_unique<IioEnergyMeterDataProvider>(deviceNames, true));
 }
 
-void addWifiStats(PowerStats *const service) {
-    sp<GenericStateResidencyDataProvider> wifiSdp =
-            new GenericStateResidencyDataProvider("/sys/wifi/power_stats");
+void addDisplay(std::shared_ptr<PowerStats> p) {
+    // Add display residency stats
 
-    // The transform function converts microseconds to milliseconds.
-    std::function<uint64_t(uint64_t)> usecToMs = [](uint64_t a) { return a / 1000; };
-    StateResidencyConfig stateConfig = {
+    /*
+     * TODO(b/167216667): Add complete set of display states here. Must account
+     * for ALL devices built using this source
+     */
+    std::vector<std::string> states = {
+        "Off",
+        "LP: 1440x3040@30",
+        "On: 1440x3040@60",
+        "On: 1440x3040@90",
+        "HBM: 1440x3040@60",
+        "HBM: 1440x3040@90"};
+
+    auto displaySdp =
+        std::make_shared<DisplayStateResidencyDataProvider>("Display",
+            "/sys/class/backlight/panel0-backlight/state",
+            states);
+    p->addStateResidencyDataProvider(displaySdp);
+
+    // Add display energy consumer
+    /*
+     * TODO(b/167216667): Add correct display power model here. Must read from display rail
+     * and include proper coefficients for display states. Must account for ALL devices built
+     * using this source.
+     */
+    auto displayConsumer = PowerStatsEnergyConsumer::createMeterAndEntityConsumer(p,
+            EnergyConsumerType::DISPLAY, "display", {"PPVAR_VSYS_PWR_DISP"}, "Display",
+            {{"LP: 1440x3040@30", 1},
+             {"On: 1440x3040@60", 2},
+             {"On: 1440x3040@90", 3}});
+
+    p->addEnergyConsumer(displayConsumer);
+}
+
+void addCPUclusters(std::shared_ptr<PowerStats> p) {
+    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+            EnergyConsumerType::CPU_CLUSTER, "CPUCL0", {"S4M_VDD_CPUCL0"}));
+    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+            EnergyConsumerType::CPU_CLUSTER, "CPUCL1", {"S3M_VDD_CPUCL1"}));
+    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+            EnergyConsumerType::CPU_CLUSTER, "CPUCL2", {"S2M_VDD_CPUCL2"}));
+}
+
+void addGPU(std::shared_ptr<PowerStats> p) {
+    // Add gpu energy consumer
+    std::map<std::string, int32_t> stateCoeffs;
+    const int socRev = android::base::GetIntProperty(kBootHwSoCRev, 0);
+
+    // B0/B1 chips have different GPU DVFS operating points than A0/A1 SoC
+    if (socRev >= 2) {
+        stateCoeffs = {
+            {"151000",  10},
+            {"202000",  20},
+            {"251000",  30},
+            {"302000",  40},
+            {"351000",  50},
+            {"400000",  60},
+            {"471000",  70},
+            {"510000",  80},
+            {"572000",  90},
+            {"701000", 100},
+            {"762000", 110},
+            {"848000", 120}};
+    } else {
+        stateCoeffs = {
+            {"151000",  10},
+            {"302000",  20},
+            {"455000",  30},
+            {"572000",  40},
+            {"670000",  50}};
+    }
+
+    auto gpuConsumer = PowerStatsEnergyConsumer::createMeterAndAttrConsumer(p,
+            EnergyConsumerType::OTHER, "GPU", {"S2S_VDD_G3D"},
+            {{UID_TIME_IN_STATE, "/sys/devices/platform/1c500000.mali/uid_time_in_state"}},
+            stateCoeffs);
+
+    p->addEnergyConsumer(gpuConsumer);
+}
+
+void addMobileRadio(std::shared_ptr<PowerStats> p)
+{
+    // A constant to represent the number of microseconds in one millisecond.
+    const int US_TO_MS = 1000;
+
+    // modem power_stats are reported in microseconds. The transform function
+    // converts microseconds to milliseconds.
+    std::function<uint64_t(uint64_t)> modemUsToMs = [](uint64_t a) { return a / US_TO_MS; };
+    const GenericStateResidencyDataProvider::StateResidencyConfig powerStateConfig = {
             .entryCountSupported = true,
             .entryCountPrefix = "count:",
             .totalTimeSupported = true,
             .totalTimePrefix = "duration_usec:",
-            .totalTimeTransform = usecToMs,
+            .totalTimeTransform = modemUsToMs,
             .lastEntrySupported = true,
             .lastEntryPrefix = "last_entry_timestamp_usec:",
-            .lastEntryTransform = usecToMs,
+            .lastEntryTransform = modemUsToMs,
     };
-    StateResidencyConfig pcieStateConfig = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "count:",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "duration_usec:",
-            .totalTimeTransform = usecToMs,
+    const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
+            std::make_pair("SLEEP", "SLEEP:"),
     };
 
-    std::vector<std::pair<std::string, std::string>> stateHeaders = {
-            std::make_pair("AWAKE", "AWAKE:"),
-            std::make_pair("ASLEEP", "ASLEEP:"),
-    };
-    std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
-            std::make_pair("L0", "L0:"),     std::make_pair("L1", "L1:"),
-            std::make_pair("L1_1", "L1_1:"), std::make_pair("L1_2", "L1_2:"),
-            std::make_pair("L2", "L2:"),
-    };
+    std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
+    cfgs.emplace_back(generateGenericStateResidencyConfigs(powerStateConfig, powerStateHeaders),
+            "MODEM", "");
 
-    wifiSdp->addEntity(
-            service->addPowerEntity("WIFI", PowerEntityType::SUBSYSTEM),
-            PowerEntityConfig(generateGenericStateResidencyConfigs(stateConfig, stateHeaders)));
-    wifiSdp->addEntity(service->addPowerEntity("WIFI-PCIE", PowerEntityType::SUBSYSTEM),
-                       PowerEntityConfig(generateGenericStateResidencyConfigs(pcieStateConfig,
-                                                                              pcieStateHeaders)));
+    p->addStateResidencyDataProvider(std::make_shared<GenericStateResidencyDataProvider>(
+            "/sys/devices/platform/cpif/modem/power_stats", cfgs));
 
-    service->addStateResidencyDataProvider(wifiSdp);
+    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+            EnergyConsumerType::MOBILE_RADIO, "MODEM", {"VSYS_PWR_MODEM", "VSYS_PWR_RFFE"}));
 }
 
-int main(int /* argc */, char ** /* argv */) {
-    ALOGI("power.stats service 1.0 is starting.");
+void addGNSS(std::shared_ptr<PowerStats> p)
+{
+    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+            EnergyConsumerType::GNSS, "GPS", {"L9S_GNSS_CORE"}));
+}
 
-    PowerStats *service = new PowerStats();
+void addNFC(std::shared_ptr<PowerStats> p) {
+    const GenericStateResidencyDataProvider::StateResidencyConfig nfcStateConfig = {
+        .entryCountSupported = true,
+        .entryCountPrefix = "Cumulative count:",
+        .totalTimeSupported = true,
+        .totalTimePrefix = "Cumulative duration msec:",
+        .lastEntrySupported = true,
+        .lastEntryPrefix = "Last entry timestamp msec:",
+    };
+    const std::vector<std::pair<std::string, std::string>> nfcStateHeaders = {
+        std::make_pair("IDLE", "Idle mode:"),
+        std::make_pair("ACTIVE", "Active mode:"),
+        std::make_pair("ACTIVE-RW", "Active Reader/Writer mode:"),
+    };
 
-    // Add rail data provider
-    service->setRailDataProvider(std::make_unique<RailDataProvider>());
+    std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
+    cfgs.emplace_back(generateGenericStateResidencyConfigs(nfcStateConfig, nfcStateHeaders),
+            "NFC", "NFC subsystem");
 
-    addAoCStats(service);
-    addCpuCStateStats(service);
-    addDvfsStats(service);
-    addGPUStats(service);
-    addNFCStats(service);
-    addPCIeStats(service);
-    addSocStats(service);
-    addUfsStats(service);
-    addWifiStats(service);
+    auto nfcSdp = std::make_shared<GenericStateResidencyDataProvider>(
+            "/sys/devices/platform/10960000.hsi2c/i2c-3/3-0008/power_stats", cfgs);
 
-    // Add Power Entities that require the Aidl data provider
-    sp<AidlStateResidencyDataProvider> aidlSdp = new AidlStateResidencyDataProvider();
-    uint32_t bluetoothId = service->addPowerEntity("Bluetooth", PowerEntityType::SUBSYSTEM);
-    aidlSdp->addEntity(bluetoothId, "Bluetooth", {"Idle", "Active", "Tx", "Rx"});
-    uint32_t citadelId = service->addPowerEntity("Citadel", PowerEntityType::SUBSYSTEM);
-    aidlSdp->addEntity(citadelId, "Citadel", {"Last-Reset", "Active", "Deep-Sleep"});
-    service->addStateResidencyDataProvider(aidlSdp);
+    p->addStateResidencyDataProvider(nfcSdp);
+}
 
-    auto serviceStatus = android::defaultServiceManager()->addService(
-            android::String16("power.stats-vendor"), aidlSdp);
-    if (serviceStatus != android::OK) {
-        ALOGE("Unable to register power.stats-vendor service %d", serviceStatus);
-        return 1;
-    }
+void addPCIe(std::shared_ptr<PowerStats> p) {
+    // Add PCIe power entities for Modem and WiFi
+    const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
+        .entryCountSupported = true,
+        .entryCountPrefix = "Cumulative count:",
+        .totalTimeSupported = true,
+        .totalTimePrefix = "Cumulative duration msec:",
+        .lastEntrySupported = true,
+        .lastEntryPrefix = "Last entry timestamp msec:",
+    };
+    const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
+        std::make_pair("UP", "Link up:"),
+        std::make_pair("DOWN", "Link down:"),
+    };
 
-    sp<android::ProcessState> ps{android::ProcessState::self()};  // Create non-HW binder threadpool
-    ps->startThreadPool();
+    // Add PCIe - Modem
+    const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieModemCfgs = {
+        {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "PCIe-Modem",
+                "Version: 1"}
+    };
+    auto pcieModemSdp = std::make_shared<GenericStateResidencyDataProvider>(
+            "/sys/devices/platform/11920000.pcie/power_stats", pcieModemCfgs);
+    p->addStateResidencyDataProvider(pcieModemSdp);
 
-    // Configure the threadpool
-    configureRpcThreadpool(1, true /*callerWillJoin*/);
+    // Add PCIe - WiFi
+    const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieWifiCfgs = {
+        {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders),
+            "PCIe-WiFi", "Version: 1"}
+    };
+    auto pcieWifiSdp = std::make_shared<GenericStateResidencyDataProvider>(
+            "/sys/devices/platform/14520000.pcie/power_stats", pcieWifiCfgs);
+    p->addStateResidencyDataProvider(pcieWifiSdp);
+}
 
-    status_t status = service->registerAsService();
-    if (status != OK) {
-        ALOGE("Could not register service for power.stats HAL Iface (%d), exiting.", status);
-        return 1;
-    }
+void addWifi(std::shared_ptr<PowerStats> p) {
+    // The transform function converts microseconds to milliseconds.
+    std::function<uint64_t(uint64_t)> usecToMs = [](uint64_t a) { return a / 1000; };
+    const GenericStateResidencyDataProvider::StateResidencyConfig stateConfig = {
+        .entryCountSupported = true,
+        .entryCountPrefix = "count:",
+        .totalTimeSupported = true,
+        .totalTimePrefix = "duration_usec:",
+        .totalTimeTransform = usecToMs,
+        .lastEntrySupported = true,
+        .lastEntryPrefix = "last_entry_timestamp_usec:",
+        .lastEntryTransform = usecToMs,
+    };
+    const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
+        .entryCountSupported = true,
+        .entryCountPrefix = "count:",
+        .totalTimeSupported = true,
+        .totalTimePrefix = "duration_usec:",
+        .totalTimeTransform = usecToMs,
+        .lastEntrySupported = false,
+    };
 
-    ALOGI("power.stats service is ready");
-    joinRpcThreadpool();
+    const std::vector<std::pair<std::string, std::string>> stateHeaders = {
+        std::make_pair("AWAKE", "AWAKE:"),
+        std::make_pair("ASLEEP", "ASLEEP:"),
 
-    // In normal operation, we don't expect the thread pool to exit
-    ALOGE("power.stats service is shutting down");
-    return 1;
+    };
+    const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
+        std::make_pair("L0", "L0:"),
+        std::make_pair("L1", "L1:"),
+        std::make_pair("L1_1", "L1_1:"),
+        std::make_pair("L1_2", "L1_2:"),
+        std::make_pair("L2", "L2:"),
+    };
+
+    const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs = {
+        {generateGenericStateResidencyConfigs(stateConfig, stateHeaders), "WIFI", "WIFI"},
+        {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "WIFI-PCIE",
+                "WIFI-PCIE"}
+    };
+
+    auto wifiSdp = std::make_shared<GenericStateResidencyDataProvider>("/sys/wifi/power_stats",
+            cfgs);
+    p->addStateResidencyDataProvider(wifiSdp);
+}
+
+/**
+ * Unlike other data providers, which source power entity state residency data from the kernel,
+ * this data provider acts as a general-purpose channel for state residency data providers
+ * that live in user space. Entities are defined here and user space clients of this provider's
+ * vendor service register callbacks to provide state residency data for their given pwoer entity.
+ */
+void addPixelStateResidencyDataProvider(std::shared_ptr<PowerStats> p) {
+    std::shared_ptr<PixelStateResidencyDataProvider> pixelSdp =
+            ndk::SharedRefBase::make<PixelStateResidencyDataProvider>();
+
+    pixelSdp->addEntity("Bluetooth", {{0, "Idle"}, {1, "Active"}, {2, "Tx"}, {3, "Rx"}});
+
+    pixelSdp->start();
+    p->addStateResidencyDataProvider(pixelSdp);
+}
+
+int main() {
+    LOG(INFO) << "Pixel PowerStats HAL AIDL Service is starting.";
+
+    // single thread
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+    std::shared_ptr<PowerStats> p = ndk::SharedRefBase::make<PowerStats>();
+
+    setEnergyMeter(p);
+
+    addPixelStateResidencyDataProvider(p);
+    addAoC(p);
+    addDisplay(p);
+    addDvfsStats(p);
+    addSoC(p);
+    addCPUclusters(p);
+    addGPU(p);
+    addMobileRadio(p);
+    addGNSS(p);
+    addNFC(p);
+    addPCIe(p);
+    addWifi(p);
+
+    const std::string instance = std::string() + PowerStats::descriptor + "/default";
+    binder_status_t status = AServiceManager_addService(p->asBinder().get(), instance.c_str());
+    LOG_ALWAYS_FATAL_IF(status != STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
 }
diff --git a/powerstats/serviceaidl.cpp b/powerstats/serviceaidl.cpp
deleted file mode 100644
index 8c15775..0000000
--- a/powerstats/serviceaidl.cpp
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "android.hardware.power.stats-service.pixel"
-
-#include <PowerStatsAidl.h>
-#include "AocStateResidencyDataProviderAidl.h"
-#include "DvfsStateResidencyDataProviderAidl.h"
-#include <dataproviders/DisplayStateResidencyDataProvider.h>
-#include <dataproviders/GenericStateResidencyDataProvider.h>
-#include <dataproviders/IioEnergyMeterDataProvider.h>
-#include <dataproviders/PowerStatsEnergyConsumer.h>
-#include <dataproviders/PowerStatsEnergyAttribution.h>
-#include <dataproviders/PixelStateResidencyDataProvider.h>
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android/binder_manager.h>
-#include <android/binder_process.h>
-#include <log/log.h>
-
-using aidl::android::hardware::power::stats::AocStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::DisplayStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::DvfsStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::EnergyConsumerType;
-using aidl::android::hardware::power::stats::GenericStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::IioEnergyMeterDataProvider;
-using aidl::android::hardware::power::stats::PixelStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::PowerStats;
-using aidl::android::hardware::power::stats::PowerStatsEnergyConsumer;
-
-constexpr char kBootHwSoCRev[] = "ro.boot.hw.soc.rev";
-
-void addAoC(std::shared_ptr<PowerStats> p) {
-    std::string prefix = "/sys/devices/platform/19000000.aoc/control/";
-
-    // Add AoC cores (a32, ff1, hf0, and hf1)
-    std::vector<std::pair<std::string, std::string>> coreIds = {
-            {"AoC-A32", prefix + "a32_"},
-            {"AoC-FF1", prefix + "ff1_"},
-            {"AoC-HF1", prefix + "hf1_"},
-            {"AoC-HF0", prefix + "hf0_"},
-    };
-    std::vector<std::pair<std::string, std::string>> coreStates = {
-            {"DWN", "off"}, {"RET", "retention"}, {"WFI", "wfi"}};
-    p->addStateResidencyDataProvider(std::make_shared<AocStateResidencyDataProvider>(coreIds,
-            coreStates));
-
-    // Add AoC voltage stats
-    std::vector<std::pair<std::string, std::string>> voltageIds = {
-            {"AoC-Voltage", prefix + "voltage_"},
-    };
-    std::vector<std::pair<std::string, std::string>> voltageStates = {{"NOM", "nominal"},
-                                                                      {"SUD", "super_underdrive"},
-                                                                      {"UUD", "ultra_underdrive"},
-                                                                      {"UD", "underdrive"}};
-    p->addStateResidencyDataProvider(
-            std::make_shared<AocStateResidencyDataProvider>(voltageIds, voltageStates));
-
-    // Add AoC monitor mode
-    std::vector<std::pair<std::string, std::string>> monitorIds = {
-            {"AoC", prefix + "monitor_"},
-    };
-    std::vector<std::pair<std::string, std::string>> monitorStates = {
-            {"MON", "mode"},
-    };
-    p->addStateResidencyDataProvider(
-            std::make_shared<AocStateResidencyDataProvider>(monitorIds, monitorStates));
-}
-
-void addDvfsStats(std::shared_ptr<PowerStats> p) {
-    // A constant to represent the number of nanoseconds in one millisecond
-    const int NS_TO_MS = 1000000;
-
-    std::vector<DvfsStateResidencyDataProvider::Config> cfgs;
-
-    cfgs.push_back({"MIF", {
-        std::make_pair("3172KHz", "3172000"),
-        std::make_pair("2730KHz", "2730000"),
-        std::make_pair("2535KHz", "2535000"),
-        std::make_pair("2288KHz", "2288000"),
-        std::make_pair("2028KHz", "2028000"),
-        std::make_pair("1716KHz", "1716000"),
-        std::make_pair("1539KHz", "1539000"),
-        std::make_pair("1352KHz", "1352000"),
-        std::make_pair("1014KHz", "1014000"),
-        std::make_pair("845KHz", "845000"),
-        std::make_pair("676KHz", "676000"),
-        std::make_pair("546KHz", "546000"),
-        std::make_pair("421KHz", "421000"),
-        std::make_pair("0KHz", "0"),
-    }});
-
-    cfgs.push_back({"CL0", {
-        std::make_pair("2024KHz", "2024000"),
-        std::make_pair("1950KHz", "1950000"),
-        std::make_pair("1868KHz", "1868000"),
-        std::make_pair("1803KHz", "1803000"),
-        std::make_pair("1745KHz", "1745000"),
-        std::make_pair("1704KHz", "1704000"),
-        std::make_pair("1598KHz", "1598000"),
-        std::make_pair("1459KHz", "1459000"),
-        std::make_pair("1401KHz", "1401000"),
-        std::make_pair("1328KHz", "1328000"),
-        std::make_pair("1197KHz", "1197000"),
-        std::make_pair("1098KHz", "1098000"),
-        std::make_pair("930KHz", "930000"),
-        std::make_pair("889KHz", "889000"),
-        std::make_pair("738KHz", "738000"),
-        std::make_pair("574KHz", "574000"),
-        std::make_pair("300KHz", "300000"),
-        std::make_pair("0KHz", "0"),
-    }});
-
-    cfgs.push_back({"CL1", {
-        std::make_pair("2253KHz", "2253000"),
-        std::make_pair("2130KHz", "2130000"),
-        std::make_pair("1999KHz", "1999000"),
-        std::make_pair("1836KHz", "1836000"),
-        std::make_pair("1663KHz", "1663000"),
-        std::make_pair("1491KHz", "1491000"),
-        std::make_pair("1328KHz", "1328000"),
-        std::make_pair("1197KHz", "1197000"),
-        std::make_pair("1024KHz", "1024000"),
-        std::make_pair("910KHz", "910000"),
-        std::make_pair("799KHz", "799000"),
-        std::make_pair("696KHz", "696000"),
-        std::make_pair("533KHz", "533000"),
-        std::make_pair("400KHz", "400000"),
-        std::make_pair("0KHz", "0"),
-    }});
-
-    cfgs.push_back({"CL2", {
-        std::make_pair("2630KHz", "2630000"),
-        std::make_pair("2507KHz", "2507000"),
-        std::make_pair("2401KHz", "2401000"),
-        std::make_pair("2302KHz", "2302000"),
-        std::make_pair("2252KHz", "2252000"),
-        std::make_pair("2188KHz", "2188000"),
-        std::make_pair("2048KHz", "2048000"),
-        std::make_pair("1901KHz", "1901000"),
-        std::make_pair("1826KHz", "1826000"),
-        std::make_pair("1745KHz", "1745000"),
-        std::make_pair("1582KHz", "1582000"),
-        std::make_pair("1426KHz", "1426000"),
-        std::make_pair("1277KHz", "1277000"),
-        std::make_pair("1237KHz", "1237000"),
-        std::make_pair("1106KHz", "1106000"),
-        std::make_pair("984KHz", "984000"),
-        std::make_pair("851KHz", "851000"),
-        std::make_pair("848KHz", "848000"),
-        std::make_pair("500KHz", "500000"),
-        std::make_pair("0KHz", "0"),
-    }});
-
-    cfgs.push_back({"TPU", {
-        std::make_pair("1066MHz", "1066000000"),
-    }});
-
-    p->addStateResidencyDataProvider(std::make_shared<DvfsStateResidencyDataProvider>(
-            "/sys/devices/platform/1742048c.acpm_stats/fvp_stats", NS_TO_MS, cfgs));
-}
-
-void addSoC(std::shared_ptr<PowerStats> p) {
-    // A constant to represent the number of nanoseconds in one millisecond.
-    const int NS_TO_MS = 1000000;
-
-    // ACPM stats are reported in nanoseconds. The transform function
-    // converts nanoseconds to milliseconds.
-    std::function<uint64_t(uint64_t)> acpmNsToMs = [](uint64_t a) { return a / NS_TO_MS; };
-    const GenericStateResidencyDataProvider::StateResidencyConfig lpmStateConfig = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "success_count:",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "total_time_ns:",
-            .totalTimeTransform = acpmNsToMs,
-            .lastEntrySupported = true,
-            .lastEntryPrefix = "last_entry_time_ns:",
-            .lastEntryTransform = acpmNsToMs,
-    };
-    const GenericStateResidencyDataProvider::StateResidencyConfig downStateConfig = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "down_count:",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "total_down_time_ns:",
-            .totalTimeTransform = acpmNsToMs,
-            .lastEntrySupported = true,
-            .lastEntryPrefix = "last_down_time_ns:",
-            .lastEntryTransform = acpmNsToMs,
-    };
-    const GenericStateResidencyDataProvider::StateResidencyConfig reqStateConfig = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "req_up_count:",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "total_req_up_time_ns:",
-            .totalTimeTransform = acpmNsToMs,
-            .lastEntrySupported = true,
-            .lastEntryPrefix = "last_req_up_time_ns:",
-            .lastEntryTransform = acpmNsToMs,
-
-    };
-    const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
-            std::make_pair("SICD", "SICD"),
-            std::make_pair("SLEEP", "SLEEP"),
-            std::make_pair("SLEEP_SLCMON", "SLEEP_SLCMON"),
-            std::make_pair("STOP", "STOP"),
-    };
-    const std::vector<std::pair<std::string, std::string>> mifReqStateHeaders = {
-            std::make_pair("AOC", "AOC"),
-            std::make_pair("GSA", "GSA"),
-    };
-    const std::vector<std::pair<std::string, std::string>> slcReqStateHeaders = {
-            std::make_pair("AOC", "AOC"),
-    };
-
-    std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
-    cfgs.emplace_back(generateGenericStateResidencyConfigs(lpmStateConfig, powerStateHeaders),
-            "LPM", "LPM:");
-    cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
-            "MIF", "MIF:");
-    cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, mifReqStateHeaders),
-            "MIF-REQ", "MIF_REQ:");
-    cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
-            "SLC", "SLC:");
-    cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, slcReqStateHeaders),
-            "SLC-REQ", "SLC_REQ:");
-
-    auto socSdp = std::make_shared<GenericStateResidencyDataProvider>(
-            "/sys/devices/platform/1742048c.acpm_stats/soc_stats", cfgs);
-
-    p->addStateResidencyDataProvider(socSdp);
-}
-
-void setEnergyMeter(std::shared_ptr<PowerStats> p) {
-    std::vector<const std::string> deviceNames { "s2mpg10-odpm", "s2mpg11-odpm" };
-    p->setEnergyMeterDataProvider(std::make_unique<IioEnergyMeterDataProvider>(deviceNames, true));
-}
-
-void addDisplay(std::shared_ptr<PowerStats> p) {
-    // Add display residency stats
-
-    /*
-     * TODO(b/167216667): Add complete set of display states here. Must account
-     * for ALL devices built using this source
-     */
-    std::vector<std::string> states = {
-        "Off",
-        "LP: 1440x3040@30",
-        "On: 1440x3040@60",
-        "On: 1440x3040@90",
-        "HBM: 1440x3040@60",
-        "HBM: 1440x3040@90"};
-
-    auto displaySdp =
-        std::make_shared<DisplayStateResidencyDataProvider>("Display",
-            "/sys/class/backlight/panel0-backlight/state",
-            states);
-    p->addStateResidencyDataProvider(displaySdp);
-
-    // Add display energy consumer
-    /*
-     * TODO(b/167216667): Add correct display power model here. Must read from display rail
-     * and include proper coefficients for display states. Must account for ALL devices built
-     * using this source.
-     */
-    auto displayConsumer = PowerStatsEnergyConsumer::createMeterAndEntityConsumer(p,
-            EnergyConsumerType::DISPLAY, "display", {"PPVAR_VSYS_PWR_DISP"}, "Display",
-            {{"LP: 1440x3040@30", 1},
-             {"On: 1440x3040@60", 2},
-             {"On: 1440x3040@90", 3}});
-
-    p->addEnergyConsumer(displayConsumer);
-}
-
-void addCPUclusters(std::shared_ptr<PowerStats> p) {
-    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
-            EnergyConsumerType::CPU_CLUSTER, "CPUCL0", {"S4M_VDD_CPUCL0"}));
-    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
-            EnergyConsumerType::CPU_CLUSTER, "CPUCL1", {"S3M_VDD_CPUCL1"}));
-    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
-            EnergyConsumerType::CPU_CLUSTER, "CPUCL2", {"S2M_VDD_CPUCL2"}));
-}
-
-void addGPU(std::shared_ptr<PowerStats> p) {
-    // Add gpu energy consumer
-    std::map<std::string, int32_t> stateCoeffs;
-    const int socRev = android::base::GetIntProperty(kBootHwSoCRev, 0);
-
-    // B0/B1 chips have different GPU DVFS operating points than A0/A1 SoC
-    if (socRev >= 2) {
-        stateCoeffs = {
-            {"151000",  10},
-            {"202000",  20},
-            {"251000",  30},
-            {"302000",  40},
-            {"351000",  50},
-            {"400000",  60},
-            {"471000",  70},
-            {"510000",  80},
-            {"572000",  90},
-            {"701000", 100},
-            {"762000", 110},
-            {"848000", 120}};
-    } else {
-        stateCoeffs = {
-            {"151000",  10},
-            {"302000",  20},
-            {"455000",  30},
-            {"572000",  40},
-            {"670000",  50}};
-    }
-
-    auto gpuConsumer = PowerStatsEnergyConsumer::createMeterAndAttrConsumer(p,
-            EnergyConsumerType::OTHER, "GPU", {"S2S_VDD_G3D"},
-            {{UID_TIME_IN_STATE, "/sys/devices/platform/1c500000.mali/uid_time_in_state"}},
-            stateCoeffs);
-
-    p->addEnergyConsumer(gpuConsumer);
-}
-
-void addMobileRadio(std::shared_ptr<PowerStats> p)
-{
-    // A constant to represent the number of microseconds in one millisecond.
-    const int US_TO_MS = 1000;
-
-    // modem power_stats are reported in microseconds. The transform function
-    // converts microseconds to milliseconds.
-    std::function<uint64_t(uint64_t)> modemUsToMs = [](uint64_t a) { return a / US_TO_MS; };
-    const GenericStateResidencyDataProvider::StateResidencyConfig powerStateConfig = {
-            .entryCountSupported = true,
-            .entryCountPrefix = "count:",
-            .totalTimeSupported = true,
-            .totalTimePrefix = "duration_usec:",
-            .totalTimeTransform = modemUsToMs,
-            .lastEntrySupported = true,
-            .lastEntryPrefix = "last_entry_timestamp_usec:",
-            .lastEntryTransform = modemUsToMs,
-    };
-    const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
-            std::make_pair("SLEEP", "SLEEP:"),
-    };
-
-    std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
-    cfgs.emplace_back(generateGenericStateResidencyConfigs(powerStateConfig, powerStateHeaders),
-            "MODEM", "");
-
-    p->addStateResidencyDataProvider(std::make_shared<GenericStateResidencyDataProvider>(
-            "/sys/devices/platform/cpif/modem/power_stats", cfgs));
-
-    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
-            EnergyConsumerType::MOBILE_RADIO, "MODEM", {"VSYS_PWR_MODEM", "VSYS_PWR_RFFE"}));
-}
-
-void addGNSS(std::shared_ptr<PowerStats> p)
-{
-    p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
-            EnergyConsumerType::GNSS, "GPS", {"L9S_GNSS_CORE"}));
-}
-
-void addNFC(std::shared_ptr<PowerStats> p) {
-    const GenericStateResidencyDataProvider::StateResidencyConfig nfcStateConfig = {
-        .entryCountSupported = true,
-        .entryCountPrefix = "Cumulative count:",
-        .totalTimeSupported = true,
-        .totalTimePrefix = "Cumulative duration msec:",
-        .lastEntrySupported = true,
-        .lastEntryPrefix = "Last entry timestamp msec:",
-    };
-    const std::vector<std::pair<std::string, std::string>> nfcStateHeaders = {
-        std::make_pair("IDLE", "Idle mode:"),
-        std::make_pair("ACTIVE", "Active mode:"),
-        std::make_pair("ACTIVE-RW", "Active Reader/Writer mode:"),
-    };
-
-    std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
-    cfgs.emplace_back(generateGenericStateResidencyConfigs(nfcStateConfig, nfcStateHeaders),
-            "NFC", "NFC subsystem");
-
-    auto nfcSdp = std::make_shared<GenericStateResidencyDataProvider>(
-            "/sys/devices/platform/10960000.hsi2c/i2c-3/3-0008/power_stats", cfgs);
-
-    p->addStateResidencyDataProvider(nfcSdp);
-}
-
-void addPCIe(std::shared_ptr<PowerStats> p) {
-    // Add PCIe power entities for Modem and WiFi
-    const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
-        .entryCountSupported = true,
-        .entryCountPrefix = "Cumulative count:",
-        .totalTimeSupported = true,
-        .totalTimePrefix = "Cumulative duration msec:",
-        .lastEntrySupported = true,
-        .lastEntryPrefix = "Last entry timestamp msec:",
-    };
-    const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
-        std::make_pair("UP", "Link up:"),
-        std::make_pair("DOWN", "Link down:"),
-    };
-
-    // Add PCIe - Modem
-    const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieModemCfgs = {
-        {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "PCIe-Modem",
-                "Version: 1"}
-    };
-    auto pcieModemSdp = std::make_shared<GenericStateResidencyDataProvider>(
-            "/sys/devices/platform/11920000.pcie/power_stats", pcieModemCfgs);
-    p->addStateResidencyDataProvider(pcieModemSdp);
-
-    // Add PCIe - WiFi
-    const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieWifiCfgs = {
-        {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders),
-            "PCIe-WiFi", "Version: 1"}
-    };
-    auto pcieWifiSdp = std::make_shared<GenericStateResidencyDataProvider>(
-            "/sys/devices/platform/14520000.pcie/power_stats", pcieWifiCfgs);
-    p->addStateResidencyDataProvider(pcieWifiSdp);
-}
-
-void addWifi(std::shared_ptr<PowerStats> p) {
-    // The transform function converts microseconds to milliseconds.
-    std::function<uint64_t(uint64_t)> usecToMs = [](uint64_t a) { return a / 1000; };
-    const GenericStateResidencyDataProvider::StateResidencyConfig stateConfig = {
-        .entryCountSupported = true,
-        .entryCountPrefix = "count:",
-        .totalTimeSupported = true,
-        .totalTimePrefix = "duration_usec:",
-        .totalTimeTransform = usecToMs,
-        .lastEntrySupported = true,
-        .lastEntryPrefix = "last_entry_timestamp_usec:",
-        .lastEntryTransform = usecToMs,
-    };
-    const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
-        .entryCountSupported = true,
-        .entryCountPrefix = "count:",
-        .totalTimeSupported = true,
-        .totalTimePrefix = "duration_usec:",
-        .totalTimeTransform = usecToMs,
-        .lastEntrySupported = false,
-    };
-
-    const std::vector<std::pair<std::string, std::string>> stateHeaders = {
-        std::make_pair("AWAKE", "AWAKE:"),
-        std::make_pair("ASLEEP", "ASLEEP:"),
-
-    };
-    const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
-        std::make_pair("L0", "L0:"),
-        std::make_pair("L1", "L1:"),
-        std::make_pair("L1_1", "L1_1:"),
-        std::make_pair("L1_2", "L1_2:"),
-        std::make_pair("L2", "L2:"),
-    };
-
-    const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs = {
-        {generateGenericStateResidencyConfigs(stateConfig, stateHeaders), "WIFI", "WIFI"},
-        {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "WIFI-PCIE",
-                "WIFI-PCIE"}
-    };
-
-    auto wifiSdp = std::make_shared<GenericStateResidencyDataProvider>("/sys/wifi/power_stats",
-            cfgs);
-    p->addStateResidencyDataProvider(wifiSdp);
-}
-
-/**
- * Unlike other data providers, which source power entity state residency data from the kernel,
- * this data provider acts as a general-purpose channel for state residency data providers
- * that live in user space. Entities are defined here and user space clients of this provider's
- * vendor service register callbacks to provide state residency data for their given pwoer entity.
- */
-void addPixelStateResidencyDataProvider(std::shared_ptr<PowerStats> p) {
-    std::shared_ptr<PixelStateResidencyDataProvider> pixelSdp =
-            ndk::SharedRefBase::make<PixelStateResidencyDataProvider>();
-
-    pixelSdp->addEntity("Bluetooth", {{0, "Idle"}, {1, "Active"}, {2, "Tx"}, {3, "Rx"}});
-
-    pixelSdp->start();
-    p->addStateResidencyDataProvider(pixelSdp);
-}
-
-int main() {
-    LOG(INFO) << "Pixel PowerStats HAL AIDL Service is starting.";
-
-    // single thread
-    ABinderProcess_setThreadPoolMaxThreadCount(0);
-
-    std::shared_ptr<PowerStats> p = ndk::SharedRefBase::make<PowerStats>();
-
-    setEnergyMeter(p);
-
-    addPixelStateResidencyDataProvider(p);
-    addAoC(p);
-    addDisplay(p);
-    addDvfsStats(p);
-    addSoC(p);
-    addCPUclusters(p);
-    addGPU(p);
-    addMobileRadio(p);
-    addGNSS(p);
-    addNFC(p);
-    addPCIe(p);
-    addWifi(p);
-
-    const std::string instance = std::string() + PowerStats::descriptor + "/default";
-    binder_status_t status = AServiceManager_addService(p->asBinder().get(), instance.c_str());
-    LOG_ALWAYS_FATAL_IF(status != STATUS_OK);
-
-    ABinderProcess_joinThreadPool();
-    return EXIT_FAILURE;  // should not reach
-}
