blob: 38953f182586157a98d40336988d41b97e0a18ff [file] [log] [blame]
Chenjie Yu5305e1d2017-10-31 13:49:36 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define DEBUG true // STOPSHIP if true
18#include "Log.h"
19
20#include <android/hardware/power/1.0/IPower.h>
21#include <android/hardware/power/1.1/IPower.h>
22#include <fcntl.h>
23#include <hardware/power.h>
24#include <hardware_legacy/power.h>
25#include <inttypes.h>
26#include <semaphore.h>
27#include <stddef.h>
28#include <stdio.h>
29#include <string.h>
30#include <sys/stat.h>
31#include <sys/types.h>
32#include <unistd.h>
33#include "external/ResourcePowerManagerPuller.h"
34#include "external/StatsPuller.h"
35
36#include "logd/LogEvent.h"
37
38using android::hardware::hidl_vec;
39using android::hardware::power::V1_0::IPower;
40using android::hardware::power::V1_0::PowerStatePlatformSleepState;
41using android::hardware::power::V1_0::PowerStateVoter;
42using android::hardware::power::V1_0::Status;
43using android::hardware::power::V1_1::PowerStateSubsystem;
44using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
45using android::hardware::Return;
46using android::hardware::Void;
47
48using std::make_shared;
49using std::shared_ptr;
50
51namespace android {
52namespace os {
53namespace statsd {
54
55sp<android::hardware::power::V1_0::IPower> gPowerHalV1_0 = nullptr;
56sp<android::hardware::power::V1_1::IPower> gPowerHalV1_1 = nullptr;
57std::mutex gPowerHalMutex;
58bool gPowerHalExists = true;
59
60static const int power_state_platform_sleep_state_tag = 1011;
61static const int power_state_voter_tag = 1012;
62static const int power_state_subsystem_state_tag = 1013;
63
64bool getPowerHal() {
65 if (gPowerHalExists && gPowerHalV1_0 == nullptr) {
66 gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService();
67 if (gPowerHalV1_0 != nullptr) {
68 gPowerHalV1_1 = android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
69 ALOGI("Loaded power HAL service");
70 } else {
71 ALOGW("Couldn't load power HAL service");
72 gPowerHalExists = false;
73 }
74 }
75 return gPowerHalV1_0 != nullptr;
76}
77
78bool ResourcePowerManagerPuller::Pull(const int tagId, vector<shared_ptr<LogEvent>>* data) {
79 std::lock_guard<std::mutex> lock(gPowerHalMutex);
80
81 if (!getPowerHal()) {
82 ALOGE("Power Hal not loaded");
83 return false;
84 }
85
86 data->clear();
87 Return<void> ret = gPowerHalV1_0->getPlatformLowPowerStats(
88 [&data](hidl_vec<PowerStatePlatformSleepState> states, Status status) {
89
90 if (status != Status::SUCCESS) return;
91
92 for (size_t i = 0; i < states.size(); i++) {
93 const PowerStatePlatformSleepState& state = states[i];
94
95 auto statePtr = make_shared<LogEvent>(power_state_platform_sleep_state_tag);
96 auto elemList = statePtr->GetAndroidLogEventList();
97 *elemList << state.name;
98 *elemList << state.residencyInMsecSinceBoot;
99 *elemList << state.totalTransitions;
100 *elemList << state.supportedOnlyInSuspend;
101 data->push_back(statePtr);
102
103 VLOG("powerstate: %s, %lld, %lld, %d", state.name.c_str(),
104 (long long)state.residencyInMsecSinceBoot,
105 (long long)state.totalTransitions, state.supportedOnlyInSuspend ? 1 : 0);
106 for (auto voter : state.voters) {
107 auto voterPtr = make_shared<LogEvent>(power_state_voter_tag);
108 auto elemList = voterPtr->GetAndroidLogEventList();
109 *elemList << state.name;
110 *elemList << voter.name;
111 *elemList << voter.totalTimeInMsecVotedForSinceBoot;
112 *elemList << voter.totalNumberOfTimesVotedSinceBoot;
113 data->push_back(voterPtr);
114 VLOG("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(),
115 voter.name.c_str(), (long long)voter.totalTimeInMsecVotedForSinceBoot,
116 (long long)voter.totalNumberOfTimesVotedSinceBoot);
117 }
118 }
119 });
120 if (!ret.isOk()) {
121 ALOGE("getLowPowerStats() failed: power HAL service not available");
122 gPowerHalV1_0 = nullptr;
123 return false;
124 }
125
126 // Trying to cast to IPower 1.1, this will succeed only for devices supporting 1.1
127 sp<android::hardware::power::V1_1::IPower> gPowerHal_1_1 =
128 android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
129 if (gPowerHal_1_1 != nullptr) {
130 ret = gPowerHal_1_1->getSubsystemLowPowerStats(
131 [&data](hidl_vec<PowerStateSubsystem> subsystems, Status status) {
132
133 if (status != Status::SUCCESS) return;
134
135 if (subsystems.size() > 0) {
136 for (size_t i = 0; i < subsystems.size(); i++) {
137 const PowerStateSubsystem& subsystem = subsystems[i];
138 for (size_t j = 0; j < subsystem.states.size(); j++) {
139 const PowerStateSubsystemSleepState& state = subsystem.states[j];
140 auto subsystemStatePtr =
141 make_shared<LogEvent>(power_state_subsystem_state_tag);
142 auto elemList = subsystemStatePtr->GetAndroidLogEventList();
143 *elemList << subsystem.name;
144 *elemList << state.name;
145 *elemList << state.residencyInMsecSinceBoot;
146 *elemList << state.totalTransitions;
147 *elemList << state.lastEntryTimestampMs;
148 *elemList << state.supportedOnlyInSuspend;
149 data->push_back(subsystemStatePtr);
150 VLOG("subsystemstate: %s, %s, %lld, %lld, %lld",
151 subsystem.name.c_str(), state.name.c_str(),
152 (long long)state.residencyInMsecSinceBoot,
153 (long long)state.totalTransitions,
154 (long long)state.lastEntryTimestampMs);
155 }
156 }
157 }
158 });
159 }
160 return true;
161}
162
163} // namespace statsd
164} // namespace os
165} // namespace android