add CpuTimePerUidPuller and CpuTimePerUidFreqPuller
Note: these pullers return monotonically increasing numbers.
The uids could include isolated uids that needs further translation in
statsd.

Test: manually tested on device and check print outs
Change-Id: I7097aec0417a3ac567b9b86149b757ac27cd58d8
diff --git a/bin/Android.mk b/bin/Android.mk
index 929c3cc..a1f5bb1 100644
--- a/bin/Android.mk
+++ b/bin/Android.mk
@@ -31,6 +31,8 @@
     src/config/ConfigManager.cpp \
     src/external/StatsCompanionServicePuller.cpp \
     src/external/ResourcePowerManagerPuller.cpp \
+    src/external/CpuTimePerUidPuller.cpp \
+    src/external/CpuTimePerUidFreqPuller.cpp \
     src/external/StatsPullerManager.cpp \
     src/logd/LogEvent.cpp \
     src/logd/LogListener.cpp \
diff --git a/bin/src/external/CpuTimePerUidFreqPuller.cpp b/bin/src/external/CpuTimePerUidFreqPuller.cpp
new file mode 100644
index 0000000..e004d21
--- /dev/null
+++ b/bin/src/external/CpuTimePerUidFreqPuller.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define DEBUG true  // STOPSHIP if true
+#include "Log.h"
+
+#include <fstream>
+#include "external/CpuTimePerUidFreqPuller.h"
+
+#include "logd/LogEvent.h"
+#include "statslog.h"
+
+using std::make_shared;
+using std::shared_ptr;
+using std::ifstream;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+static const string sProcFile = "/proc/uid_cputime/show_uid_stat";
+static const int kLineBufferSize = 1024;
+
+/**
+ * Reads /proc/uid_time_in_state which has the format:
+ *
+ * uid: [freq1] [freq2] [freq3] ...
+ * [uid1]: [time in freq1] [time in freq2] [time in freq3] ...
+ * [uid2]: [time in freq1] [time in freq2] [time in freq3] ...
+ * ...
+ *
+ * This provides the times a UID's processes spent executing at each different cpu frequency.
+ * The file contains a monotonically increasing count of time for a single boot.
+ */
+bool CpuTimePerUidFreqPuller::Pull(const int tagId, vector<shared_ptr<LogEvent>>* data) {
+  data->clear();
+
+  ifstream fin;
+  fin.open(sProcFile);
+  if (!fin.good()) {
+    VLOG("Failed to read pseudo file %s", sProcFile.c_str());
+    return false;
+  }
+
+  uint64_t timestamp = time(nullptr) * NS_PER_SEC;
+  char buf[kLineBufferSize];
+  // first line prints the format and frequencies
+  fin.getline(buf, kLineBufferSize);
+  char * pch;
+  while(!fin.eof()){
+    fin.getline(buf, kLineBufferSize);
+    pch = strtok (buf, " :");
+    if (pch == NULL) break;
+    uint64_t uid = std::stoull(pch);
+    pch = strtok(NULL, " ");
+    uint64_t timeMs;
+    int idx = 0;
+    do {
+      timeMs = std::stoull(pch);
+      auto ptr = make_shared<LogEvent>(android::util::CPU_TIME_PER_UID_FREQ_PULLED, timestamp);
+      auto elemList = ptr->GetAndroidLogEventList();
+      *elemList << uid;
+      *elemList << idx;
+      *elemList << timeMs;
+      ptr->init();
+      data->push_back(ptr);
+      VLOG("uid %lld, freq idx %d, sys time %lld", (long long)uid, idx, (long long)timeMs);
+      idx ++;
+      pch = strtok(NULL, " ");
+    } while (pch != NULL);
+  }
+  return true;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/bin/src/external/CpuTimePerUidFreqPuller.h b/bin/src/external/CpuTimePerUidFreqPuller.h
new file mode 100644
index 0000000..839e5aa
--- /dev/null
+++ b/bin/src/external/CpuTimePerUidFreqPuller.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/String16.h>
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/**
+ * Reads /proc/uid_cputime/show_uid_stat which has the line format:
+ *
+ * uid: user_time_micro_seconds system_time_micro_seconds
+ *
+ * This provides the time a UID's processes spent executing in user-space and kernel-space.
+ * The file contains a monotonically increasing count of time for a single boot.
+ */
+class CpuTimePerUidFreqPuller : public StatsPuller {
+ public:
+  bool Pull(const int tagId, vector<std::shared_ptr<LogEvent>>* data) override;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/bin/src/external/CpuTimePerUidPuller.cpp b/bin/src/external/CpuTimePerUidPuller.cpp
new file mode 100644
index 0000000..b84b877
--- /dev/null
+++ b/bin/src/external/CpuTimePerUidPuller.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define DEBUG true  // STOPSHIP if true
+#include "Log.h"
+
+#include <fstream>
+#include "external/CpuTimePerUidPuller.h"
+
+#include "logd/LogEvent.h"
+#include "statslog.h"
+
+using std::make_shared;
+using std::shared_ptr;
+using std::ifstream;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+static const string sProcFile = "/proc/uid_cputime/show_uid_stat";
+static const int kLineBufferSize = 1024;
+
+/**
+ * Reads /proc/uid_cputime/show_uid_stat which has the line format:
+ *
+ * uid: user_time_micro_seconds system_time_micro_seconds power_in_milli-amp-micro_seconds
+ *
+ * This provides the time a UID's processes spent executing in user-space and kernel-space.
+ * The file contains a monotonically increasing count of time for a single boot.
+ */
+bool CpuTimePerUidPuller::Pull(const int tagId, vector<shared_ptr<LogEvent>>* data) {
+  data->clear();
+
+  ifstream fin;
+  fin.open(sProcFile);
+  if (!fin.good()) {
+    VLOG("Failed to read pseudo file %s", sProcFile.c_str());
+    return false;
+  }
+
+  uint64_t timestamp = time(nullptr) * NS_PER_SEC;
+  char buf[kLineBufferSize];
+  char * pch;
+  while(!fin.eof()){
+    fin.getline(buf, kLineBufferSize);
+    pch = strtok(buf, " :");
+    if (pch == NULL) break;
+    uint64_t uid = std::stoull(pch);
+    pch = strtok(buf, " ");
+    uint64_t userTimeMs = std::stoull(pch);
+    pch = strtok(buf, " ");
+    uint64_t sysTimeMs = std::stoull(pch);
+
+    auto ptr = make_shared<LogEvent>(android::util::CPU_TIME_PER_UID_PULLED, timestamp);
+    auto elemList = ptr->GetAndroidLogEventList();
+    *elemList << uid;
+    *elemList << userTimeMs;
+    *elemList << sysTimeMs;
+    ptr->init();
+    data->push_back(ptr);
+    VLOG("uid %lld, user time %lld, sys time %lld", (long long)uid, (long long)userTimeMs, (long long)sysTimeMs);
+  }
+  return true;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/bin/src/external/CpuTimePerUidPuller.h b/bin/src/external/CpuTimePerUidPuller.h
new file mode 100644
index 0000000..9bb8946
--- /dev/null
+++ b/bin/src/external/CpuTimePerUidPuller.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/String16.h>
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/**
+ * Reads /proc/uid_cputime/show_uid_stat which has the line format:
+ *
+ * uid: user_time_micro_seconds system_time_micro_seconds
+ *
+ * This provides the time a UID's processes spent executing in user-space and kernel-space.
+ * The file contains a monotonically increasing count of time for a single boot.
+ */
+class CpuTimePerUidPuller : public StatsPuller {
+ public:
+  bool Pull(const int tagId, vector<std::shared_ptr<LogEvent>>* data) override;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/bin/src/external/ResourcePowerManagerPuller.cpp b/bin/src/external/ResourcePowerManagerPuller.cpp
index 3608ee4..319feef 100644
--- a/bin/src/external/ResourcePowerManagerPuller.cpp
+++ b/bin/src/external/ResourcePowerManagerPuller.cpp
@@ -34,6 +34,7 @@
 #include "external/StatsPuller.h"
 
 #include "logd/LogEvent.h"
+#include "statslog.h"
 
 using android::hardware::hidl_vec;
 using android::hardware::power::V1_0::IPower;
@@ -57,10 +58,6 @@
 std::mutex gPowerHalMutex;
 bool gPowerHalExists = true;
 
-static const int power_state_platform_sleep_state_tag = 1011;
-static const int power_state_voter_tag = 1012;
-static const int power_state_subsystem_state_tag = 1013;
-
 bool getPowerHal() {
     if (gPowerHalExists && gPowerHalV1_0 == nullptr) {
         gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService();
@@ -94,8 +91,8 @@
                 for (size_t i = 0; i < states.size(); i++) {
                     const PowerStatePlatformSleepState& state = states[i];
 
-                    auto statePtr =
-                            make_shared<LogEvent>(power_state_platform_sleep_state_tag, timestamp);
+                    auto statePtr = make_shared<LogEvent>(
+                            android::util::POWER_STATE_PLATFORM_SLEEP_STATE_PULLED, timestamp);
                     auto elemList = statePtr->GetAndroidLogEventList();
                     *elemList << state.name;
                     *elemList << state.residencyInMsecSinceBoot;
@@ -107,12 +104,14 @@
                          (long long)state.residencyInMsecSinceBoot,
                          (long long)state.totalTransitions, state.supportedOnlyInSuspend ? 1 : 0);
                     for (auto voter : state.voters) {
-                        auto voterPtr = make_shared<LogEvent>(power_state_voter_tag, timestamp);
+                        auto voterPtr =
+                                make_shared<LogEvent>(android::util::POWER_STATE_VOTER_PULLED, timestamp);
                         auto elemList = voterPtr->GetAndroidLogEventList();
                         *elemList << state.name;
                         *elemList << voter.name;
                         *elemList << voter.totalTimeInMsecVotedForSinceBoot;
                         *elemList << voter.totalNumberOfTimesVotedSinceBoot;
+                        voterPtr->init();
                         data->push_back(voterPtr);
                         VLOG("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(),
                              voter.name.c_str(), (long long)voter.totalTimeInMsecVotedForSinceBoot,
@@ -141,7 +140,7 @@
                             for (size_t j = 0; j < subsystem.states.size(); j++) {
                                 const PowerStateSubsystemSleepState& state = subsystem.states[j];
                                 auto subsystemStatePtr = make_shared<LogEvent>(
-                                        power_state_subsystem_state_tag, timestamp);
+                                        android::util::POWER_STATE_SUBSYSTEM_SLEEP_STATE_PULLED, timestamp);
                                 auto elemList = subsystemStatePtr->GetAndroidLogEventList();
                                 *elemList << subsystem.name;
                                 *elemList << state.name;
diff --git a/bin/src/external/StatsPullerManager.cpp b/bin/src/external/StatsPullerManager.cpp
index 43543cc..5a05b45 100644
--- a/bin/src/external/StatsPullerManager.cpp
+++ b/bin/src/external/StatsPullerManager.cpp
@@ -21,6 +21,8 @@
 #include <cutils/log.h>
 #include <algorithm>
 #include <climits>
+#include "CpuTimePerUidFreqPuller.h"
+#include "CpuTimePerUidPuller.h"
 #include "ResourcePowerManagerPuller.h"
 #include "StatsCompanionServicePuller.h"
 #include "StatsPullerManager.h"
@@ -42,21 +44,29 @@
 
 StatsPullerManager::StatsPullerManager()
     : mCurrentPullingInterval(LONG_MAX), mPullStartTimeMs(get_pull_start_time_ms()) {
-    shared_ptr<StatsPuller> statsCompanionServicePuller =
-            make_shared<StatsCompanionServicePuller>();
+    shared_ptr<StatsPuller> statsCompanionServicePuller = make_shared<StatsCompanionServicePuller>();
     shared_ptr<StatsPuller> resourcePowerManagerPuller = make_shared<ResourcePowerManagerPuller>();
+    shared_ptr<StatsPuller> cpuTimePerUidPuller = make_shared<CpuTimePerUidPuller>();
+    shared_ptr<StatsPuller> cpuTimePerUidFreqPuller = make_shared<CpuTimePerUidFreqPuller>();
 
-    mPullers.insert({android::util::KERNEL_WAKELOCK_PULLED, statsCompanionServicePuller});
-    mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED, statsCompanionServicePuller});
-    mPullers.insert({android::util::MOBILE_BYTES_TRANSFERRED, statsCompanionServicePuller});
-    mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED_BY_FG_BG, statsCompanionServicePuller});
-    mPullers.insert(
-            {android::util::MOBILE_BYTES_TRANSFERRED_BY_FG_BG, statsCompanionServicePuller});
-    mPullers.insert(
-            {android::util::POWER_STATE_PLATFORM_SLEEP_STATE_PULLED, resourcePowerManagerPuller});
-    mPullers.insert({android::util::POWER_STATE_VOTER_PULLED, resourcePowerManagerPuller});
-    mPullers.insert(
-            {android::util::POWER_STATE_SUBSYSTEM_SLEEP_STATE_PULLED, resourcePowerManagerPuller});
+    mPullers.insert({android::util::KERNEL_WAKELOCK_PULLED,
+                     statsCompanionServicePuller});
+    mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED,
+                     statsCompanionServicePuller});
+    mPullers.insert({android::util::MOBILE_BYTES_TRANSFERRED,
+                     statsCompanionServicePuller});
+    mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED_BY_FG_BG,
+                     statsCompanionServicePuller});
+    mPullers.insert({android::util::MOBILE_BYTES_TRANSFERRED_BY_FG_BG,
+                     statsCompanionServicePuller});
+    mPullers.insert({android::util::POWER_STATE_PLATFORM_SLEEP_STATE_PULLED,
+                     resourcePowerManagerPuller});
+    mPullers.insert({android::util::POWER_STATE_VOTER_PULLED,
+                     resourcePowerManagerPuller});
+    mPullers.insert({android::util::POWER_STATE_SUBSYSTEM_SLEEP_STATE_PULLED,
+                     resourcePowerManagerPuller});
+    mPullers.insert({android::util::CPU_TIME_PER_UID_PULLED, cpuTimePerUidPuller});
+    mPullers.insert({android::util::CPU_TIME_PER_UID_FREQ_PULLED, cpuTimePerUidFreqPuller});
 
     mStatsCompanionService = StatsService::getStatsCompanionService();
 }
diff --git a/bin/src/stats_events.proto b/bin/src/stats_events.proto
index a516ca3..9ab07de 100644
--- a/bin/src/stats_events.proto
+++ b/bin/src/stats_events.proto
@@ -87,6 +87,8 @@
         PowerStateVoterPulled power_state_voter_pulled = 1006;
         PowerStateSubsystemSleepStatePulled power_state_subsystem_sleep_state_pulled = 1007;
         CpuTimePerFreqPulled cpu_time_per_freq_pulled = 1008;
+        CpuTimePerUidPulled cpu_time_per_uid_pulled = 1009;
+        CpuTimePerUidFreqPulled cpu_time_per_uid_freq_pulled = 1010;
     }
 }
 
@@ -870,6 +872,7 @@
 }
 
 /*
+<<<<<<< HEAD
  * Pulls Cpu time per frequency.
  * Note: this should be pulled for gauge metric only, without condition.
  * The puller keeps internal state of last values. It should not be pulled by
@@ -885,3 +888,24 @@
     optional uint32 freq_index = 2;
     optional uint64 time = 3;
 }
+
+/*
+ * Pulls Cpu Time Per Uid.
+ * Note that isolated process uid time should be attributed to host uids.
+ */
+message CpuTimePerUidPulled {
+    optional uint64 uid = 1;
+    optional uint64 user_time_ms = 2;
+    optional uint64 sys_time_ms = 3;
+}
+
+/**
+ * Pulls Cpu Time Per Uid per frequency.
+ * Note that isolated process uid time should be attributed to host uids.
+ * For each uid, we order the time by descending frequencies.
+ */
+message CpuTimePerUidFreqPulled {
+    optional uint64 uid = 1;
+    optional uint64 freq_idx = 2;
+    optional uint64 time_ms = 3;
+}