blob: 33a17deabc5a42e909e0f5d55cb48e461485f011 [file] [log] [blame]
Tej Singh40298312018-02-16 00:15:09 -08001/*
2 * Copyright (C) 2018 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 false // STOPSHIP if true
18#include "Log.h"
19
20#include <android/hardware/thermal/1.0/IThermal.h>
21#include "external/ResourceThermalManagerPuller.h"
22#include "external/StatsPuller.h"
23
24#include "ResourceThermalManagerPuller.h"
25#include "logd/LogEvent.h"
26#include "statslog.h"
27#include "stats_log_util.h"
28
29#include <chrono>
30
31using android::hardware::hidl_death_recipient;
32using android::hardware::hidl_vec;
33using android::hidl::base::V1_0::IBase;
34using android::hardware::thermal::V1_0::IThermal;
35using android::hardware::thermal::V1_0::Temperature;
36using android::hardware::thermal::V1_0::ThermalStatus;
37using android::hardware::thermal::V1_0::ThermalStatusCode;
38using android::hardware::Return;
39using android::hardware::Void;
40
41using std::chrono::duration_cast;
42using std::chrono::nanoseconds;
43using std::chrono::system_clock;
44using std::make_shared;
45using std::shared_ptr;
46
47namespace android {
48namespace os {
49namespace statsd {
50
51bool getThermalHalLocked();
52sp<android::hardware::thermal::V1_0::IThermal> gThermalHal = nullptr;
53std::mutex gThermalHalMutex;
54
55struct ThermalHalDeathRecipient : virtual public hidl_death_recipient {
56 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
57 std::lock_guard<std::mutex> lock(gThermalHalMutex);
58 ALOGE("ThermalHAL just died");
59 gThermalHal = nullptr;
60 getThermalHalLocked();
61 }
62};
63
64sp<ThermalHalDeathRecipient> gThermalHalDeathRecipient = nullptr;
65
66// The caller must be holding gThermalHalMutex.
67bool getThermalHalLocked() {
68 if (gThermalHal == nullptr) {
69 gThermalHal = IThermal::getService();
70 if (gThermalHal == nullptr) {
71 ALOGE("Unable to get Thermal service.");
72 } else {
73 if (gThermalHalDeathRecipient == nullptr) {
74 gThermalHalDeathRecipient = new ThermalHalDeathRecipient();
75 }
76 hardware::Return<bool> linked = gThermalHal->linkToDeath(
77 gThermalHalDeathRecipient, 0x451F /* cookie */);
78 if (!linked.isOk()) {
79 ALOGE("Transaction error in linking to ThermalHAL death: %s",
80 linked.description().c_str());
81 gThermalHal = nullptr;
82 } else if (!linked) {
83 ALOGW("Unable to link to ThermalHal death notifications");
84 gThermalHal = nullptr;
85 } else {
86 ALOGD("Link to death notification successful");
87 }
88 }
89 }
90 return gThermalHal != nullptr;
91}
92
93ResourceThermalManagerPuller::ResourceThermalManagerPuller() :
94 StatsPuller(android::util::TEMPERATURE) {
95}
96
97bool ResourceThermalManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
98 std::lock_guard<std::mutex> lock(gThermalHalMutex);
99 if (!getThermalHalLocked()) {
100 ALOGE("Thermal Hal not loaded");
101 return false;
102 }
103
104 int64_t wallClockTimestampNs = getWallClockNs();
105 int64_t elapsedTimestampNs = getElapsedRealtimeNs();
106
107 data->clear();
108 bool resultSuccess = true;
109
110 Return<void> ret = gThermalHal->getTemperatures(
111 [&](ThermalStatus status, const hidl_vec<Temperature>& temps) {
112 if (status.code != ThermalStatusCode::SUCCESS) {
113 ALOGE("Failed to get temperatures from ThermalHAL. Status: %d", status.code);
114 resultSuccess = false;
115 return;
116 }
117 if (mTagId == android::util::TEMPERATURE) {
118 for (size_t i = 0; i < temps.size(); ++i) {
119 auto ptr = make_shared<LogEvent>(android::util::TEMPERATURE,
120 wallClockTimestampNs, elapsedTimestampNs);
121 ptr->write((static_cast<int>(temps[i].type)));
122 ptr->write(temps[i].name);
Tej Singhd89137e2018-03-26 14:51:40 -0700123 // Convert the temperature to an int.
124 int32_t temp = static_cast<int>(temps[i].currentValue * 10);
125 ptr->write(temp);
Tej Singh40298312018-02-16 00:15:09 -0800126 ptr->init();
127 data->push_back(ptr);
128 }
129 } else {
130 ALOGE("Unsupported tag in ResourceThermalManagerPuller: %d", mTagId);
131 }
132 });
133 if (!ret.isOk()) {
134 ALOGE("getThermalHalLocked() failed: thermal HAL service not available. Description: %s",
135 ret.description().c_str());
136 if (ret.isDeadObject()) {
137 gThermalHal = nullptr;
138 }
139 return false;
140 }
141 return resultSuccess;
142}
143
144} // namespace statsd
145} // namespace os
146} // namespace android