src/external/StatsCompanionServicePuller.cpp \
src/external/SubsystemSleepStatePuller.cpp \
src/external/ResourceHealthManagerPuller.cpp \
+ src/external/ResourceThermalManagerPuller.cpp \
src/external/CpuTimePerUidPuller.cpp \
src/external/CpuTimePerUidFreqPuller.cpp \
src/external/KernelUidCpuActiveTimeReader.cpp \
android.hardware.health@2.0 \
android.hardware.power@1.0 \
android.hardware.power@1.1 \
+ android.hardware.thermal@1.0 \
libmemunreachable
# =========
BatteryLevelChanged battery_level_changed = 30;
ChargingStateChanged charging_state_changed = 31;
PluggedStateChanged plugged_state_changed = 32;
- DeviceTemperatureReported device_temperature_reported = 33;
+ // TODO: 33 is blank, but is available for use.
DeviceOnStatusChanged device_on_status_changed = 34;
WakeupAlarmOccurred wakeup_alarm_occurred = 35;
KernelWakeupReported kernel_wakeup_reported = 36;
}
// Pulled events will start at field 10000.
- // Next: 10021
+ // Next: 10022
oneof pulled {
WifiBytesTransfer wifi_bytes_transfer = 10000;
WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
DiskSpace disk_space = 10018;
RemainingBatteryCapacity remaining_battery_capacity = 10019;
FullBatteryCapacity full_battery_capacity = 10020;
+ Temperature temperature = 10021;
}
}
optional android.os.BatteryPluggedStateEnum state = 1;
}
-/**
- * Logs the temperature of the device, in tenths of a degree Celsius.
- *
- * Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message DeviceTemperatureReported {
- // Temperature in tenths of a degree C.
- optional int32 temperature = 1;
-}
-
// TODO: Define this more precisely.
// TODO: Log the ON state somewhere. It isn't currently logged anywhere.
/**
/**
* Pulls battery coulomb counter, which is the remaining battery charge in uAh.
- * Logged from: frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
+ * Pulled from:
+ * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
*/
message RemainingBatteryCapacity {
optional int32 charge_uAh = 1;
/**
* Pulls battery capacity, which is the battery capacity when full in uAh.
- * Logged from: frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
+ * Pulled from:
+ * frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
*/
message FullBatteryCapacity {
optional int32 capacity_uAh = 1;
+}
+
+/**
+ * Pulls the temperature of various parts of the device, in Celsius.
+ *
+ * Pulled from:
+ * frameworks/base/cmds/statsd/src/external/ResourceThermalManagerPuller.cpp
+ */
+message Temperature {
+ // The type of temperature being reported. Eg. CPU, GPU, SKIN, BATTERY.
+ optional android.os.TemperatureTypeEnum sensor_location = 1;
+
+ // The name of the temperature source. Eg. CPU0
+ optional string sensor_name = 2;
+
+ // Temperature in degrees C.
+ optional float temperature_C = 3;
}
\ No newline at end of file
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
* limitations under the License.
*/
-#define DEBUG true // STOPSHIP if true
+#define DEBUG false // STOPSHIP if true
#include "Log.h"
#include <android/hardware/health/2.0/IHealth.h>
bool getHealthHal() {
if (gHealthHal == nullptr) {
gHealthHal = get_health_service();
-
}
return gHealthHal != nullptr;
}
--- /dev/null
+/*
+ * 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 DEBUG false // STOPSHIP if true
+#include "Log.h"
+
+#include <android/hardware/thermal/1.0/IThermal.h>
+#include "external/ResourceThermalManagerPuller.h"
+#include "external/StatsPuller.h"
+
+#include "ResourceThermalManagerPuller.h"
+#include "logd/LogEvent.h"
+#include "statslog.h"
+#include "stats_log_util.h"
+
+#include <chrono>
+
+using android::hardware::hidl_death_recipient;
+using android::hardware::hidl_vec;
+using android::hidl::base::V1_0::IBase;
+using android::hardware::thermal::V1_0::IThermal;
+using android::hardware::thermal::V1_0::Temperature;
+using android::hardware::thermal::V1_0::ThermalStatus;
+using android::hardware::thermal::V1_0::ThermalStatusCode;
+using android::hardware::Return;
+using android::hardware::Void;
+
+using std::chrono::duration_cast;
+using std::chrono::nanoseconds;
+using std::chrono::system_clock;
+using std::make_shared;
+using std::shared_ptr;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+bool getThermalHalLocked();
+sp<android::hardware::thermal::V1_0::IThermal> gThermalHal = nullptr;
+std::mutex gThermalHalMutex;
+
+struct ThermalHalDeathRecipient : virtual public hidl_death_recipient {
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
+ std::lock_guard<std::mutex> lock(gThermalHalMutex);
+ ALOGE("ThermalHAL just died");
+ gThermalHal = nullptr;
+ getThermalHalLocked();
+ }
+};
+
+sp<ThermalHalDeathRecipient> gThermalHalDeathRecipient = nullptr;
+
+// The caller must be holding gThermalHalMutex.
+bool getThermalHalLocked() {
+ if (gThermalHal == nullptr) {
+ gThermalHal = IThermal::getService();
+ if (gThermalHal == nullptr) {
+ ALOGE("Unable to get Thermal service.");
+ } else {
+ if (gThermalHalDeathRecipient == nullptr) {
+ gThermalHalDeathRecipient = new ThermalHalDeathRecipient();
+ }
+ hardware::Return<bool> linked = gThermalHal->linkToDeath(
+ gThermalHalDeathRecipient, 0x451F /* cookie */);
+ if (!linked.isOk()) {
+ ALOGE("Transaction error in linking to ThermalHAL death: %s",
+ linked.description().c_str());
+ gThermalHal = nullptr;
+ } else if (!linked) {
+ ALOGW("Unable to link to ThermalHal death notifications");
+ gThermalHal = nullptr;
+ } else {
+ ALOGD("Link to death notification successful");
+ }
+ }
+ }
+ return gThermalHal != nullptr;
+}
+
+ResourceThermalManagerPuller::ResourceThermalManagerPuller() :
+ StatsPuller(android::util::TEMPERATURE) {
+}
+
+bool ResourceThermalManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
+ std::lock_guard<std::mutex> lock(gThermalHalMutex);
+ if (!getThermalHalLocked()) {
+ ALOGE("Thermal Hal not loaded");
+ return false;
+ }
+
+ int64_t wallClockTimestampNs = getWallClockNs();
+ int64_t elapsedTimestampNs = getElapsedRealtimeNs();
+
+ data->clear();
+ bool resultSuccess = true;
+
+ Return<void> ret = gThermalHal->getTemperatures(
+ [&](ThermalStatus status, const hidl_vec<Temperature>& temps) {
+ if (status.code != ThermalStatusCode::SUCCESS) {
+ ALOGE("Failed to get temperatures from ThermalHAL. Status: %d", status.code);
+ resultSuccess = false;
+ return;
+ }
+ if (mTagId == android::util::TEMPERATURE) {
+ for (size_t i = 0; i < temps.size(); ++i) {
+ auto ptr = make_shared<LogEvent>(android::util::TEMPERATURE,
+ wallClockTimestampNs, elapsedTimestampNs);
+ ptr->write((static_cast<int>(temps[i].type)));
+ ptr->write(temps[i].name);
+ ptr->write(temps[i].currentValue);
+ ptr->init();
+ data->push_back(ptr);
+ }
+ } else {
+ ALOGE("Unsupported tag in ResourceThermalManagerPuller: %d", mTagId);
+ }
+ });
+ if (!ret.isOk()) {
+ ALOGE("getThermalHalLocked() failed: thermal HAL service not available. Description: %s",
+ ret.description().c_str());
+ if (ret.isDeadObject()) {
+ gThermalHal = nullptr;
+ }
+ return false;
+ }
+ return resultSuccess;
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android
--- /dev/null
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <utils/String16.h>
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/**
+ * Reads IThermal.hal
+ */
+class ResourceThermalManagerPuller : public StatsPuller {
+public:
+ ResourceThermalManagerPuller();
+ bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
+};
+
+} // namespace statsd
+} // namespace os
+} // namespace android
\ No newline at end of file
#include <climits>
#include "CpuTimePerUidFreqPuller.h"
#include "CpuTimePerUidPuller.h"
-#include "ResourceHealthManagerPuller.h"
#include "KernelUidCpuActiveTimeReader.h"
#include "KernelUidCpuClusterTimeReader.h"
-#include "SubsystemSleepStatePuller.h"
+#include "ResourceHealthManagerPuller.h"
+#include "ResourceThermalManagerPuller.h"
#include "StatsCompanionServicePuller.h"
#include "StatsPullerManagerImpl.h"
#include "StatsService.h"
{{}, {}, 1, new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}},
// process_memory_state
{android::util::PROCESS_MEMORY_STATE,
- {{4,5,6,7,8}, {2,3}, 0, new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}};
+ {{4,5,6,7,8}, {2,3}, 0, new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
+ // temperature
+ {android::util::TEMPERATURE, {{}, {}, 1, new ResourceThermalManagerPuller()}}};
StatsPullerManagerImpl::StatsPullerManagerImpl()
: mCurrentPullingInterval(LONG_MAX) {
/**
* Device temperature types.
*/
+ // These constants are also defined in android/os/enums.proto.
+ // Any change to the types here or in the thermal hal should be made in the proto as well.
/** Temperature of CPUs in Celsius. */
public static final int DEVICE_TEMPERATURE_CPU = Constants.TemperatureType.CPU;
temp = Math.max(0, temp);
reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null,
- status, plugType, level, temp);
+ status, plugType, level);
final boolean onBattery = isOnBattery(plugType, status);
final long uptime = mClocks.uptimeMillis();
// Inform StatsLog of setBatteryState changes.
// If this is the first reporting, pass in recentPast == null.
private void reportChangesToStatsLog(HistoryItem recentPast,
- final int status, final int plugType, final int level, final int temp) {
+ final int status, final int plugType, final int level) {
if (recentPast == null || recentPast.batteryStatus != status) {
StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, status);
if (recentPast == null || recentPast.batteryLevel != level) {
StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, level);
}
- // Let's just always print the temperature, regardless of whether it changed.
- StatsLog.write(StatsLog.DEVICE_TEMPERATURE_REPORTED, temp);
}
public long getAwakeTimeBattery() {
BATTERY_STATUS_FULL = 5;
}
+// These constants are defined in hardware/interfaces/thermal/1.0/types.hal
+// They are primarily used by android/os/HardwarePropertiesManager.java.
+// Any change to the types in the thermal hal should be made here as well.
+enum TemperatureTypeEnum {
+ TEMPERATURE_TYPE_UKNOWN = -1;
+ TEMPERATURE_TYPE_CPU = 0;
+ TEMPERATURE_TYPE_GPU = 1;
+ TEMPERATURE_TYPE_BATTERY = 2;
+ TEMPERATURE_TYPE_SKIN = 3;
+}
+
// Wakelock types, primarily used by android/os/PowerManager.java.
enum WakeLockLevelEnum {
// NOTE: Wake lock levels were previously defined as a bit field, except