15305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu/*
25305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu * Copyright (C) 2017 The Android Open Source Project
35305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu *
45305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu * Licensed under the Apache License, Version 2.0 (the "License");
55305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu * you may not use this file except in compliance with the License.
65305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu * You may obtain a copy of the License at
75305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu *
85305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu *      http://www.apache.org/licenses/LICENSE-2.0
95305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu *
105305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu * Unless required by applicable law or agreed to in writing, software
115305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu * distributed under the License is distributed on an "AS IS" BASIS,
125305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu * See the License for the specific language governing permissions and
145305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu * limitations under the License.
155305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu */
165305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
17484524a246ffe453f8cd89b698a279c23b0bde1fTej Singh#define DEBUG false  // STOPSHIP if true
185305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include "Log.h"
195305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
205305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <android/hardware/power/1.0/IPower.h>
215305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <android/hardware/power/1.1/IPower.h>
225305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <fcntl.h>
235305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <hardware/power.h>
245305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <hardware_legacy/power.h>
255305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <inttypes.h>
265305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <semaphore.h>
275305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <stddef.h>
285305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <stdio.h>
295305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <string.h>
305305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <sys/stat.h>
315305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <sys/types.h>
325305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include <unistd.h>
33c8b7f2277c7d05dc0a1225dbed13ee85f18a6031Chenjie Yu#include "external/SubsystemSleepStatePuller.h"
345305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include "external/StatsPuller.h"
355305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
36c8b7f2277c7d05dc0a1225dbed13ee85f18a6031Chenjie Yu#include "SubsystemSleepStatePuller.h"
375305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu#include "logd/LogEvent.h"
38e33bc3b967aef6f10df82e5b374e4b701ce6ca69Chenjie Yu#include "statslog.h"
39330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac#include "stats_log_util.h"
405305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
415305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing android::hardware::hidl_vec;
425305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing android::hardware::power::V1_0::IPower;
435305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing android::hardware::power::V1_0::PowerStatePlatformSleepState;
445305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing android::hardware::power::V1_0::PowerStateVoter;
455305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing android::hardware::power::V1_0::Status;
465305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing android::hardware::power::V1_1::PowerStateSubsystem;
475305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing android::hardware::power::V1_1::PowerStateSubsystemSleepState;
485305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing android::hardware::Return;
495305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing android::hardware::Void;
505305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
515305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing std::make_shared;
525305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yuusing std::shared_ptr;
535305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
545305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yunamespace android {
555305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yunamespace os {
565305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yunamespace statsd {
575305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
585305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yusp<android::hardware::power::V1_0::IPower> gPowerHalV1_0 = nullptr;
595305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yusp<android::hardware::power::V1_1::IPower> gPowerHalV1_1 = nullptr;
605305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yustd::mutex gPowerHalMutex;
615305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yubool gPowerHalExists = true;
625305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
635305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yubool getPowerHal() {
645305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    if (gPowerHalExists && gPowerHalV1_0 == nullptr) {
655305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService();
665305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        if (gPowerHalV1_0 != nullptr) {
675305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu            gPowerHalV1_1 = android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
685305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu            ALOGI("Loaded power HAL service");
695305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        } else {
705305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu            ALOGW("Couldn't load power HAL service");
715305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu            gPowerHalExists = false;
725305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        }
735305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    }
745305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    return gPowerHalV1_0 != nullptr;
755305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu}
765305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
77c8b7f2277c7d05dc0a1225dbed13ee85f18a6031Chenjie YuSubsystemSleepStatePuller::SubsystemSleepStatePuller() : StatsPuller(android::util::SUBSYSTEM_SLEEP_STATE) {
78b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu}
79b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu
80c8b7f2277c7d05dc0a1225dbed13ee85f18a6031Chenjie Yubool SubsystemSleepStatePuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
815305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    std::lock_guard<std::mutex> lock(gPowerHalMutex);
825305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
835305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    if (!getPowerHal()) {
845305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        ALOGE("Power Hal not loaded");
855305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu        return false;
865305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    }
875305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
88330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac    int64_t wallClockTimestampNs = getWallClockNs();
89330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac    int64_t elapsedTimestampNs = getElapsedRealtimeNs();
9093fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen
915305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    data->clear();
925305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
93b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu    Return<void> ret;
94b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu        ret = gPowerHalV1_0->getPlatformLowPowerStats(
95330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                [&data, wallClockTimestampNs, elapsedTimestampNs](hidl_vec<PowerStatePlatformSleepState> states, Status status) {
965305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu                    if (status != Status::SUCCESS) return;
975305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
98b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                    for (size_t i = 0; i < states.size(); i++) {
99b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        const PowerStatePlatformSleepState& state = states[i];
100b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu
101330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                        auto statePtr = make_shared<LogEvent>(
102330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                            android::util::SUBSYSTEM_SLEEP_STATE,
103330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                            wallClockTimestampNs, elapsedTimestampNs);
104b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        statePtr->write(state.name);
105bbcbc605fc7507f5607e0fe4716b31c895436a77Chenjie Yu                        statePtr->write("");
106b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        statePtr->write(state.totalTransitions);
107c8b7f2277c7d05dc0a1225dbed13ee85f18a6031Chenjie Yu                        statePtr->write(state.residencyInMsecSinceBoot);
108b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        statePtr->init();
109b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        data->push_back(statePtr);
110b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        VLOG("powerstate: %s, %lld, %lld, %d", state.name.c_str(),
111b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                             (long long)state.residencyInMsecSinceBoot,
112b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                             (long long)state.totalTransitions,
113b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                             state.supportedOnlyInSuspend ? 1 : 0);
114b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        for (auto voter : state.voters) {
115330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                            auto voterPtr = make_shared<LogEvent>(
116330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                                android::util::SUBSYSTEM_SLEEP_STATE,
117330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                                wallClockTimestampNs, elapsedTimestampNs);
118bbcbc605fc7507f5607e0fe4716b31c895436a77Chenjie Yu                            voterPtr->write(state.name);
119bbcbc605fc7507f5607e0fe4716b31c895436a77Chenjie Yu                            voterPtr->write(voter.name);
120b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                            voterPtr->write(voter.totalNumberOfTimesVotedSinceBoot);
121c8b7f2277c7d05dc0a1225dbed13ee85f18a6031Chenjie Yu                            voterPtr->write(voter.totalTimeInMsecVotedForSinceBoot);
122b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                            voterPtr->init();
123b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                            data->push_back(voterPtr);
124b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                            VLOG("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(),
125b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                 voter.name.c_str(),
126b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                 (long long)voter.totalTimeInMsecVotedForSinceBoot,
127b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                 (long long)voter.totalNumberOfTimesVotedSinceBoot);
1285305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu                        }
1295305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu                    }
1305305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu                });
131b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu        if (!ret.isOk()) {
132b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu            ALOGE("getLowPowerStats() failed: power HAL service not available");
133b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu            gPowerHalV1_0 = nullptr;
134b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu            return false;
135b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu        }
136b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu
137b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu        // Trying to cast to IPower 1.1, this will succeed only for devices supporting 1.1
138b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu        sp<android::hardware::power::V1_1::IPower> gPowerHal_1_1 =
139b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
140b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu        if (gPowerHal_1_1 != nullptr) {
141b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu            ret = gPowerHal_1_1->getSubsystemLowPowerStats(
142330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                    [&data, wallClockTimestampNs, elapsedTimestampNs](hidl_vec<PowerStateSubsystem> subsystems, Status status) {
143b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        if (status != Status::SUCCESS) return;
144b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu
145b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        if (subsystems.size() > 0) {
146b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                            for (size_t i = 0; i < subsystems.size(); i++) {
147b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                const PowerStateSubsystem& subsystem = subsystems[i];
148b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                for (size_t j = 0; j < subsystem.states.size(); j++) {
149b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                    const PowerStateSubsystemSleepState& state =
150b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                            subsystem.states[j];
151b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                    auto subsystemStatePtr = make_shared<LogEvent>(
152330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                                        android::util::SUBSYSTEM_SLEEP_STATE,
153330af58f2b8582b855085655fae553cdfaf44e6cYangster-mac                                        wallClockTimestampNs, elapsedTimestampNs);
154bbcbc605fc7507f5607e0fe4716b31c895436a77Chenjie Yu                                    subsystemStatePtr->write(subsystem.name);
155bbcbc605fc7507f5607e0fe4716b31c895436a77Chenjie Yu                                    subsystemStatePtr->write(state.name);
156b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                    subsystemStatePtr->write(state.totalTransitions);
157c8b7f2277c7d05dc0a1225dbed13ee85f18a6031Chenjie Yu                                    subsystemStatePtr->write(state.residencyInMsecSinceBoot);
158b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                    subsystemStatePtr->init();
159b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                    data->push_back(subsystemStatePtr);
160b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                    VLOG("subsystemstate: %s, %s, %lld, %lld, %lld",
161b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                         subsystem.name.c_str(), state.name.c_str(),
162b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                         (long long)state.residencyInMsecSinceBoot,
163b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                         (long long)state.totalTransitions,
164b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                         (long long)state.lastEntryTimestampMs);
165b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                                }
166b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                            }
167b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                        }
168b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu                    });
169b038b709566c191164bd23539175df8aadeb2f94Chenjie Yu        }
1705305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu    return true;
1715305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu}
1725305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu
1735305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu}  // namespace statsd
1745305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu}  // namespace os
1755305e1ddc22bfe9ad941cb2550987aaba8de234cChenjie Yu}  // namespace android
176