Snap for 8426163 from c1bdd1e20dab2bcf81f743a7a2e952e939238960 to mainline-tzdata2-release
Change-Id: I5d08fcc39bc17670e122502e1c876b9df8d5612f
diff --git a/Android.bp b/Android.bp
index 284a095..e91352c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,31 +1,3 @@
soong_namespace {
imports: ["hardware/google/interfaces"],
}
-
-package {
- default_applicable_licenses: ["hardware_google_pixel_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-// See: http://go/android-license-faq
-license {
- name: "hardware_google_pixel_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-Apache-2.0",
- "SPDX-license-identifier-BSD",
- ],
- // large-scale-change unable to identify any license_text files
-}
diff --git a/METADATA b/METADATA
deleted file mode 100644
index d97975c..0000000
--- a/METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-third_party {
- license_type: NOTICE
-}
diff --git a/PixelLogger/PixelLogger.mk b/PixelLogger/PixelLogger.mk
deleted file mode 100644
index cfd5b00..0000000
--- a/PixelLogger/PixelLogger.mk
+++ /dev/null
@@ -1,2 +0,0 @@
-PRODUCT_PACKAGES_DEBUG += PixelLogger
-BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/logger_app
diff --git a/atrace/Android.bp b/atrace/Android.bp
index 08ca125..8ddb7c8 100644
--- a/atrace/Android.bp
+++ b/atrace/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_binary {
name: "android.hardware.atrace@1.0-service.pixel",
defaults: ["hidl_defaults"],
diff --git a/atrace/AtraceDevice.cpp b/atrace/AtraceDevice.cpp
index 5f8b9cd..c673275 100644
--- a/atrace/AtraceDevice.cpp
+++ b/atrace/AtraceDevice.cpp
@@ -16,7 +16,6 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
#include "AtraceDevice.h"
@@ -35,39 +34,30 @@
std::vector<std::pair<std::string, bool>> paths;
};
-// This is a map stores categories and their tracefs event name with required flags
+// This is a map stores categories and their sysfs paths with required flags
const std::map<std::string, TracingConfig> kTracingMap = {
{
"gfx",
{"Graphics",
- {{"mdss", false},
- {"sde", false},
- {"dpu", false},
- {"g2d", false},
- {"mali", false}}},
- },
- {
- "memory",
- {"Memory", {{"fastrpc/fastrpc_dma_stat", false}, {"dmabuf_heap", false}}},
+ {{"/sys/kernel/debug/tracing/events/mdss/enable", false},
+ {"/sys/kernel/debug/tracing/events/sde/enable", false},
+ {"/sys/kernel/debug/tracing/events/mali_systrace/enable", false}}},
},
{
"ion",
- {"ION Allocation", {{"kmem/ion_alloc_buffer_start", false}}},
+ {"ION Allocation",
+ {{"/sys/kernel/debug/tracing/events/kmem/ion_alloc_buffer_start/enable", false}}},
},
{
"sched",
- {"CPU Scheduling and Trustzone", {{"scm", false}, {"systrace", false}}},
+ {"CPU Scheduling and Trustzone",
+ {{"/sys/kernel/debug/tracing/events/scm/enable", false},
+ {"/sys/kernel/debug/tracing/events/systrace/enable", false}}},
},
{
"freq",
- {"CPU Frequency and System Clock", {{"msm_bus", false}}},
- },
- {
- "thermal_tj",
- {"Tj power limits and frequency",
- {{"lmh/lmh_dcvs_freq", false},
- {"thermal_exynos", false},
- {"thermal_exynos_gpu", false}}},
+ {"CPU Frequency and System Clock",
+ {{"/sys/kernel/debug/tracing/events/msm_bus/enable", false}}},
},
};
@@ -85,31 +75,16 @@
return Void();
}
-AtraceDevice::AtraceDevice() {
- struct stat st;
-
- mTracefsEventRoot = "/sys/kernel/tracing/events/";
- if (stat(mTracefsEventRoot.c_str(), &st) != 0) {
- mTracefsEventRoot = "/sys/kernel/debug/tracing/events/";
- CHECK(stat(mTracefsEventRoot.c_str(), &st) == 0) << "tracefs must be mounted at either"
- "/sys/kernel/tracing or "
- "/sys/kernel/debug/tracing";
- }
-}
-
Return<::android::hardware::atrace::V1_0::Status> AtraceDevice::enableCategories(
const hidl_vec<hidl_string> &categories) {
if (!categories.size()) {
return Status::ERROR_INVALID_ARGUMENT;
}
-
for (auto &c : categories) {
if (kTracingMap.count(c)) {
for (auto &p : kTracingMap.at(c).paths) {
- std::string tracefs_event_enable_path = android::base::StringPrintf(
- "%s%s/enable", mTracefsEventRoot.c_str(), p.first.c_str());
- if (!android::base::WriteStringToFile("1", tracefs_event_enable_path)) {
- LOG(ERROR) << "Failed to enable tracing on: " << tracefs_event_enable_path;
+ if (!android::base::WriteStringToFile("1", p.first)) {
+ LOG(ERROR) << "Failed to enable tracing on: " << p.first;
if (p.second) {
// disable before return
disableAllCategories();
@@ -126,13 +101,10 @@
Return<::android::hardware::atrace::V1_0::Status> AtraceDevice::disableAllCategories() {
auto ret = Status::SUCCESS;
-
for (auto &c : kTracingMap) {
for (auto &p : c.second.paths) {
- std::string tracefs_event_enable_path = android::base::StringPrintf(
- "%s%s/enable", mTracefsEventRoot.c_str(), p.first.c_str());
- if (!android::base::WriteStringToFile("0", tracefs_event_enable_path)) {
- LOG(ERROR) << "Failed to disable tracing on: " << tracefs_event_enable_path;
+ if (!android::base::WriteStringToFile("0", p.first)) {
+ LOG(ERROR) << "Failed to disable tracing on: " << p.first;
if (p.second) {
ret = Status::ERROR_TRACING_POINT;
}
diff --git a/atrace/AtraceDevice.h b/atrace/AtraceDevice.h
index 2863cd3..a15cd6c 100644
--- a/atrace/AtraceDevice.h
+++ b/atrace/AtraceDevice.h
@@ -34,15 +34,12 @@
using ::android::hardware::Void;
struct AtraceDevice : public IAtraceDevice {
- AtraceDevice();
// Methods from ::android::hardware::atrace::V1_0::IAtraceDevice follow.
Return<void> listCategories(listCategories_cb _hidl_cb) override;
Return<::android::hardware::atrace::V1_0::Status> enableCategories(
const hidl_vec<hidl_string> &categories) override;
Return<::android::hardware::atrace::V1_0::Status> disableAllCategories() override;
- private:
- std::string mTracefsEventRoot;
// Methods from ::android::hidl::base::V1_0::IBase follow.
};
diff --git a/atrace/android.hardware.atrace@1.0-service.pixel.rc b/atrace/android.hardware.atrace@1.0-service.pixel.rc
index 353c073..b26296d 100644
--- a/atrace/android.hardware.atrace@1.0-service.pixel.rc
+++ b/atrace/android.hardware.atrace@1.0-service.pixel.rc
@@ -1,41 +1,16 @@
on late-init
# vendor graphics trace points
chmod 0666 /sys/kernel/debug/tracing/events/sde/enable
- chmod 0666 /sys/kernel/tracing/events/sde/enable
chmod 0666 /sys/kernel/debug/tracing/events/mdss/enable
- chmod 0666 /sys/kernel/tracing/events/mdss/enable
- chmod 0666 /sys/kernel/debug/tracing/events/dpu/enable
- chmod 0666 /sys/kernel/tracing/events/dpu/enable
- chmod 0666 /sys/kernel/debug/tracing/events/g2d/enable
- chmod 0666 /sys/kernel/tracing/events/g2d/enable
- chmod 0666 /sys/kernel/debug/tracing/events/mali/enable
- chmod 0666 /sys/kernel/tracing/events/mali/enable
-
+ chmod 0666 /sys/kernel/debug/tracing/events/mali_systrace/enable
# ion allocation trace point
chmod 0666 /sys/kernel/debug/tracing/events/kmem/ion_alloc_buffer_start/enable
- chmod 0666 /sys/kernel/tracing/events/kmem/ion_alloc_buffer_start/enable
# scm trace point
chmod 0666 /sys/kernel/debug/tracing/events/scm/enable
- chmod 0666 /sys/kernel/tracing/events/scm/enable
# system bus clk trace point
chmod 0666 /sys/kernel/debug/tracing/events/msm_bus/enable
- chmod 0666 /sys/kernel/tracing/events/msm_bus/enable
# legacy systrace point
chmod 0666 /sys/kernel/debug/tracing/events/systrace/enable
- chmod 0666 /sys/kernel/tracing/events/systrace/enable
- # qct hw lmh-dcvs
- chmod 0666 /sys/kernel/debug/tracing/events/lmh/lmh_dcvs_freq/enable
- chmod 0666 /sys/kernel/tracing/events/lmh/lmh_dcvs_freq/enable
- # qct fastrpc dma buffers
- chmod 0666 /sys/kernel/debug/tracing/events/fastrpc/fastrpc_dma_stat/enable
- chmod 0666 /sys/kernel/tracing/events/fastrpc/fastrpc_dma_stat/enable
- # dmabuf heap stats
- chmod 0666 /sys/kernel/tracing/events/dmabuf_heap/enable
- # Tj pid control loop trace points
- chmod 0666 /sys/kernel/debug/tracing/events/thermal_exynos/enable
- chmod 0666 /sys/kernel/tracing/events/thermal_exynos/enable
- chmod 0666 /sys/kernel/debug/tracing/events/thermal_exynos_gpu/enable
- chmod 0666 /sys/kernel/tracing/events/thermal_exynos_gpu/enable
service vendor.atrace-hal-1-0 /vendor/bin/hw/android.hardware.atrace@1.0-service.pixel
interface android.hardware.atrace@1.0::IAtraceDevice default
diff --git a/bootctrl/Android.bp b/bootctrl/Android.bp
index 27f8af1..852800e 100644
--- a/bootctrl/Android.bp
+++ b/bootctrl/Android.bp
@@ -1,10 +1,6 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library {
- name: "android.hardware.boot@1.2-impl-pixel-legacy",
- stem: "android.hardware.boot@1.0-impl-1.2-pixel-legacy",
+ name: "android.hardware.boot@1.1-impl-pixel-legacy",
+ stem: "android.hardware.boot@1.0-impl-1.1-pixel-legacy",
vendor: true,
recovery_available: true,
srcs: [
@@ -24,7 +20,6 @@
"libutils",
"android.hardware.boot@1.0",
"android.hardware.boot@1.1",
- "android.hardware.boot@1.2",
],
static_libs: [
"libboot_control",
diff --git a/bootctrl/BootControlShared.cpp b/bootctrl/BootControlShared.cpp
index e5b9797..125bec4 100644
--- a/bootctrl/BootControlShared.cpp
+++ b/bootctrl/BootControlShared.cpp
@@ -27,7 +27,7 @@
namespace android {
namespace hardware {
namespace boot {
-namespace V1_2 {
+namespace V1_1 {
namespace implementation {
using android::bootable::GetMiscVirtualAbMergeStatus;
@@ -54,7 +54,7 @@
}
} // namespace implementation
-} // namespace V1_2
+} // namespace V1_1
} // namespace boot
} // namespace hardware
} // namespace android
diff --git a/bootctrl/BootControlShared.h b/bootctrl/BootControlShared.h
index 43aedba..ff49e3e 100644
--- a/bootctrl/BootControlShared.h
+++ b/bootctrl/BootControlShared.h
@@ -16,18 +16,17 @@
#pragma once
-#include <android/hardware/boot/1.2/IBootControl.h>
+#include <android/hardware/boot/1.1/IBootControl.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace boot {
-namespace V1_2 {
+namespace V1_1 {
namespace implementation {
using ::android::hardware::Return;
-using ::android::hardware::boot::V1_1::MergeStatus;
struct BootControlShared : public IBootControl {
BootControlShared();
@@ -41,7 +40,7 @@
extern "C" IBootControl *HIDL_FETCH_IBootControl(const char *name);
} // namespace implementation
-} // namespace V1_2
+} // namespace V1_1
} // namespace boot
} // namespace hardware
} // namespace android
diff --git a/bootctrl/LegacyBootControl.cpp b/bootctrl/LegacyBootControl.cpp
index 1287c8e..83254e9 100644
--- a/bootctrl/LegacyBootControl.cpp
+++ b/bootctrl/LegacyBootControl.cpp
@@ -28,7 +28,7 @@
namespace android {
namespace hardware {
namespace boot {
-namespace V1_2 {
+namespace V1_1 {
namespace implementation {
using ::android::hardware::boot::V1_0::CommandResult;
@@ -97,17 +97,6 @@
return Void();
}
-// Methods from ::android::hardware::boot::V1_2::IBootControl follow.
-Return<uint32_t> BootControl::getActiveBootSlot() {
- auto get_active_slot = mModule->getActiveBootSlot;
- if (!get_active_slot) {
- ALOGE("Failed to find the implementation of getActiveBootSlot in boot"
- " control HAL.");
- return 0;
- }
- return get_active_slot(mModule);
-}
-
IBootControl *HIDL_FETCH_IBootControl(const char * /* hal */) {
int ret = 0;
boot_control_module_t *module = NULL;
@@ -127,7 +116,7 @@
}
} // namespace implementation
-} // namespace V1_2
+} // namespace V1_1
} // namespace boot
} // namespace hardware
} // namespace android
diff --git a/bootctrl/LegacyBootControl.h b/bootctrl/LegacyBootControl.h
index 75548b0..0653cbd 100644
--- a/bootctrl/LegacyBootControl.h
+++ b/bootctrl/LegacyBootControl.h
@@ -24,7 +24,7 @@
namespace android {
namespace hardware {
namespace boot {
-namespace V1_2 {
+namespace V1_1 {
namespace implementation {
using ::android::hardware::Return;
@@ -43,9 +43,6 @@
Return<BoolResult> isSlotMarkedSuccessful(uint32_t slot) override;
Return<void> getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) override;
- // Methods from ::android::hardware::boot::V1_2::IBootControl follow.
- Return<uint32_t> getActiveBootSlot() override;
-
private:
boot_control_module_t *mModule;
};
@@ -53,7 +50,7 @@
extern "C" IBootControl *HIDL_FETCH_IBootControl(const char *name);
} // namespace implementation
-} // namespace V1_2
+} // namespace V1_1
} // namespace boot
} // namespace hardware
} // namespace android
diff --git a/citadel/citadel.mk b/citadel/citadel.mk
deleted file mode 100644
index c66fc1f..0000000
--- a/citadel/citadel.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Citadel
-PRODUCT_PACKAGES += \
- citadeld \
- citadel_updater \
- android.hardware.authsecret@1.0-service.citadel \
- android.hardware.oemlock@1.0-service.citadel \
- android.hardware.weaver@1.0-service.citadel \
- android.hardware.keymaster@4.1-service.citadel \
- android.hardware.identity@1.0-service.citadel \
- android.hardware.fastboot@1.1-impl.pixel \
- wait_for_strongbox
-
-# Citadel debug stuff
-PRODUCT_PACKAGES_DEBUG += \
- test_citadel
-
-# Resume on Reboot support
-PRODUCT_PACKAGES += \
- android.hardware.rebootescrow-service.citadel
-
-# init scripts (won't be in AOSP)
--include vendor/google_nos/init/citadel/init.mk
-
-ifneq ($(wildcard vendor/google_nos/provision),)
-PRODUCT_PACKAGES_DEBUG += CitadelProvision
-
-# Set CITADEL_LAZY_PSK_SYNC to true on projects with faceauth, otherwise false.
-#
-# EVT devices left the factory without being provisioned,
-# and thus the shared authtoken key is yet to be established.
-# Since faceauth HAT enforcement fails without the preshared
-# authtoken, auto-sync it in the field for userdebug/eng.
-# Please refer to b/135295587 for more detail.
-#
-CITADEL_LAZY_PSK_SYNC := false
-endif
-
-# Sepolicy
-BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/citadel
diff --git a/common/fstab.firmware b/common/fstab.firmware
new file mode 100644
index 0000000..5968dcc
--- /dev/null
+++ b/common/fstab.firmware
@@ -0,0 +1,4 @@
+# Android fstab file.
+
+#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
+/dev/block/bootdevice/by-name/modem /vendor/firmware_mnt vfat ro,shortname=lower,uid=0,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0 wait,slotselect
diff --git a/common/fstab.persist b/common/fstab.persist
new file mode 100644
index 0000000..f3840b1
--- /dev/null
+++ b/common/fstab.persist
@@ -0,0 +1,4 @@
+# Keep persist in an fstab file, since we need to run fsck on it after abnormal shutdown.
+
+#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
+/dev/block/platform/soc/1d84000.ufshc/by-name/persist /mnt/vendor/persist ext4 nosuid,nodev,noatime,barrier=1 wait
diff --git a/common/init.insmod.sh b/common/init.insmod.sh
new file mode 100755
index 0000000..29e04c8
--- /dev/null
+++ b/common/init.insmod.sh
@@ -0,0 +1,38 @@
+#!/vendor/bin/sh
+
+########################################################
+### init.insmod.cfg format: ###
+### ----------------------------------------------- ###
+### [insmod|setprop|enable/moprobe] [path|prop name] ###
+### ... ###
+########################################################
+
+if [ $# -eq 1 ]; then
+ cfg_file=$1
+else
+ exit 1
+fi
+
+if [ -f $cfg_file ]; then
+ while IFS="|" read -r action arg
+ do
+ case $action in
+ "insmod") insmod $arg ;;
+ "setprop") setprop $arg 1 ;;
+ "enable") echo 1 > $arg ;;
+ "modprobe")
+ case ${arg} in
+ "-b *" | "-b")
+ arg="-b $(cat /vendor/lib/modules/modules.load)" ;;
+ "*" | "")
+ arg="$(cat /vendor/lib/modules/modules.load)" ;;
+ esac
+ modprobe -a -d /vendor/lib/modules $arg ;;
+ esac
+ done < $cfg_file
+fi
+
+# set property even if there is no insmod config
+# as property value "1" is expected in early-boot trigger
+setprop vendor.all.modules.ready 1
+setprop vendor.all.devices.ready 1
diff --git a/common/init.pixel.rc b/common/init.pixel.rc
index 25b14fe..9c4d223 100644
--- a/common/init.pixel.rc
+++ b/common/init.pixel.rc
@@ -1,26 +1,34 @@
+on early-init
+ mount_all /vendor/etc/fstab.persist --early
+
+on fs
+ mount_all /vendor/etc/fstab.firmware --early
+
+on late-fs
+ mount_all /vendor/etc/fstab.firmware --late
+
+on property:sys.boot_completed=1
+ swapon_all /vendor/etc/fstab.firmware
+
# Write the dark theme magic to /misc partition.
service vendor.theme_set /vendor/bin/misc_writer --set-dark-theme
disabled
oneshot
-# Set dark boot flag when the device is provisioned.
-on property:persist.sys.device_provisioned=1
+# Clear the dark theme magic in /misc partition.
+service vendor.theme_clear /vendor/bin/misc_writer --clear-dark-theme
+ disabled
+ oneshot
+
+# Set dark boot flag on dark mode (UiModeManager.MODE_NIGHT_YES == 2).
+on property:persist.sys.theme=2
start vendor.theme_set
-# Set or clear the warm reset flag upon the change of system property. The flag itself is set
-on init && property:ro.boot.slot_successful=no
- write /sys/module/msm_poweroff/parameters/warm_reset 1
+# Clear the dark boot flag on light mode (UiModeManager.MODE_NIGHT_NO == 1) or auto mode
+# (UiModeManager.MODE_NIGHT_AUTO == 0).
+on property:persist.sys.theme=1
+ start vendor.theme_clear
-# by writing a sysfs file; and the file will be read by kernel.
-on property:ota.warm_reset=1
- write /sys/module/msm_poweroff/parameters/warm_reset 1
+on property:persist.sys.theme=0
+ start vendor.theme_clear
-on property:ota.warm_reset=0
- write /sys/module/msm_poweroff/parameters/warm_reset 0
-
-on init
- copy_per_line /dev/cpuctl/tasks /dev/cpuctl/system/tasks
-
-# Migrate tasks again in case kernel threads are created during boot
-on property:sys.boot_completed=1
- copy_per_line /dev/cpuctl/tasks /dev/cpuctl/system/tasks
diff --git a/common/pixel-common-device.mk b/common/pixel-common-device.mk
index b8c7784..0f7f6af 100644
--- a/common/pixel-common-device.mk
+++ b/common/pixel-common-device.mk
@@ -1,21 +1,11 @@
PRODUCT_COPY_FILES += \
- hardware/google/pixel/common/init.pixel.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.pixel.rc
+ hardware/google/pixel/common/fstab.firmware:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.firmware \
+ hardware/google/pixel/common/fstab.persist:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.persist \
+ hardware/google/pixel/common/init.pixel.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.pixel.rc \
+ hardware/google/pixel/common/init.insmod.sh:$(TARGET_COPY_OUT_VENDOR)/bin/init.insmod.sh
BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/common
# Write flags to the vendor space in /misc partition.
PRODUCT_PACKAGES += \
misc_writer
-
-# Enable atrace hal and tools for pixel devices
-PRODUCT_PACKAGES += \
- android.hardware.atrace@1.0-service.pixel \
- dmabuf_dump
-
-
-# fastbootd
-PRODUCT_PACKAGES += \
- fastbootd
-
-# Common ramdump file type.
-BOARD_VENDOR_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/ramdump/common
diff --git a/dauntless/android.hardware.strongbox_keystore.xml b/dauntless/android.hardware.strongbox_keystore.xml
deleted file mode 100644
index 949cfcf..0000000
--- a/dauntless/android.hardware.strongbox_keystore.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-
-<!-- Feature for devices with StrongBox-backed keystore. -->
-<permissions>
- <feature name="android.hardware.strongbox_keystore" version="100"/>
-</permissions>
diff --git a/dauntless/dauntless.mk b/dauntless/dauntless.mk
deleted file mode 100644
index d083500..0000000
--- a/dauntless/dauntless.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Dauntless
-PRODUCT_PACKAGES += \
- citadeld \
- citadel_updater \
- android.hardware.weaver@1.0-service.citadel \
- android.hardware.identity@1.0-service.citadel
-
-# AIDL
-PRODUCT_PACKAGES += \
- android.hardware.security.keymint-service.citadel
-
-PRODUCT_COPY_FILES += \
- hardware/google/pixel/dauntless/android.hardware.strongbox_keystore.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.strongbox_keystore.xml
-
-# init scripts (won't be in AOSP)
--include vendor/google_nos/init/dauntless/init.mk
-
-ifneq ($(wildcard vendor/google_nos/provision),)
-PRODUCT_PACKAGES_DEBUG += CitadelProvision
-endif
diff --git a/dynamic_partitions/Android.bp b/dynamic_partitions/Android.bp
index a5e54a9..ba0557f 100644
--- a/dynamic_partitions/Android.bp
+++ b/dynamic_partitions/Android.bp
@@ -14,10 +14,6 @@
// limitations under the License.
//
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
sh_binary {
name: "check_dynamic_partitions",
src: "check_dynamic_partitions",
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index c40b69f..646c0a9 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -13,12 +13,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library {
- name: "android.hardware.fastboot@1.1-impl.pixel",
+ name: "android.hardware.fastboot@1.0-impl.pixel",
recovery: true,
srcs: [
"Fastboot.cpp",
@@ -26,17 +22,10 @@
relative_install_path: "hw",
export_include_dirs: ["include"],
shared_libs: [
- "liblog",
"libbase",
"libhidlbase",
"libutils",
"libcutils",
"android.hardware.fastboot@1.0",
- "android.hardware.fastboot@1.1",
- ],
- static_libs: [
- "libnos_for_fastboot",
- "libnos_citadel_for_fastboot",
- "libfstab",
],
}
diff --git a/fastboot/Fastboot.cpp b/fastboot/Fastboot.cpp
index 93435d6..f68c7c3 100644
--- a/fastboot/Fastboot.cpp
+++ b/fastboot/Fastboot.cpp
@@ -24,14 +24,11 @@
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
-#include <app_nugget.h>
-#include <nos/NuggetClient.h>
-#include <nos/debug.h>
namespace android {
namespace hardware {
namespace fastboot {
-namespace V1_1 {
+namespace V1_0 {
namespace implementation {
constexpr const char* BRIGHTNESS_FILE = "/sys/class/backlight/panel0-backlight/brightness";
@@ -122,33 +119,6 @@
return Void();
}
-Return<void> Fastboot::doOemSpecificErase(V1_1::IFastboot::doOemSpecificErase_cb _hidl_cb) {
- // Connect to Titan M
- ::nos::NuggetClient client;
- client.Open();
- if (!client.IsOpen()) {
- _hidl_cb({ Status::FAILURE_UNKNOWN, "open Titan M fail" });
- return Void();
- }
-
- // Tell Titan M to wipe user data
- const uint32_t magicValue = htole32(ERASE_CONFIRMATION);
- std::vector<uint8_t> magic(sizeof(magicValue));
- memcpy(magic.data(), &magicValue, sizeof(magicValue));
- const uint8_t retry_count = 5;
- for(uint8_t i = 0; i < retry_count; i++) {
- const uint32_t status
- = client.CallApp(APP_ID_NUGGET, NUGGET_PARAM_NUKE_FROM_ORBIT, magic, nullptr);
- if (status == APP_SUCCESS) {
- _hidl_cb({ Status::SUCCESS, "" });
- return Void();
- }
- }
-
- _hidl_cb({ Status::FAILURE_UNKNOWN, "Titan M user data wipe failed" });
- return Void();
-}
-
Fastboot::Fastboot() {}
// Methods from ::android::hidl::base::V1_0::IBase follow.
@@ -158,7 +128,7 @@
}
} // namespace implementation
-} // namespace V1_1
+} // namespace V1_0
} // namespace fastboot
} // namespace hardware
} // namespace android
diff --git a/fastboot/include/fastboot/Fastboot.h b/fastboot/include/fastboot/Fastboot.h
index 2e3afb1..e5c0a11 100644
--- a/fastboot/include/fastboot/Fastboot.h
+++ b/fastboot/include/fastboot/Fastboot.h
@@ -16,14 +16,14 @@
#pragma once
-#include <android/hardware/fastboot/1.1/IFastboot.h>
+#include <android/hardware/fastboot/1.0/IFastboot.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace fastboot {
-namespace V1_1 {
+namespace V1_0 {
namespace implementation {
#define FB_OEM_SET_BRIGHTNESS "setbrightness"
@@ -31,9 +31,6 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using ::android::hardware::fastboot::V1_0::FileSystemType;
-using ::android::hardware::fastboot::V1_0::Status;
-using ::android::hardware::fastboot::V1_0::Result;
struct Fastboot : public IFastboot {
Fastboot();
@@ -46,15 +43,12 @@
Return<void> getVariant(getVariant_cb _hidl_cb) override;
Return<void> getOffModeChargeState(getOffModeChargeState_cb _hidl_cb) override;
Return<void> getBatteryVoltageFlashingThreshold(getBatteryVoltageFlashingThreshold_cb _hidl_cb) override;
-
- // Methods from ::android::hardware::fastboot::V1_1::IFastboot follow.
- Return<void> doOemSpecificErase(V1_1::IFastboot::doOemSpecificErase_cb _hidl_cb) override;
};
extern "C" IFastboot* HIDL_FETCH_IFastboot(const char* name);
} // namespace implementation
-} // namespace V1_1
+} // namespace V1_0
} // namespace fastboot
} // namespace hardware
} // namespace android
diff --git a/health/Android.bp b/health/Android.bp
index f06c633..b563b43 100644
--- a/health/Android.bp
+++ b/health/Android.bp
@@ -1,21 +1,15 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library {
name: "libpixelhealth",
vendor: true,
export_include_dirs: ["include"],
srcs: [
- "BatteryDefender.cpp",
"BatteryMetricsLogger.cpp",
"BatteryThermalControl.cpp",
- "ChargerDetect.cpp",
"CycleCountBackupRestore.cpp",
"DeviceHealth.cpp",
"LowBatteryShutdownMetrics.cpp",
- "StatsHelper.cpp"
+ "BatteryDefender.cpp",
],
cflags: [
@@ -28,17 +22,15 @@
],
export_shared_lib_headers: [
- "android.frameworks.stats-V1-ndk_platform",
- "pixelatoms-cpp",
+ "android.frameworks.stats@1.0",
],
shared_libs: [
- "android.frameworks.stats-V1-ndk_platform",
+ "android.frameworks.stats@1.0",
"libbase",
- "libbinder_ndk",
"libcutils",
+ "libhidlbase",
"libutils",
- "pixelatoms-cpp",
],
}
@@ -66,7 +58,6 @@
static_libs: [
"libgmock",
"libpixelhealth",
- "libbatterymonitor",
],
shared_libs: [
diff --git a/health/BatteryDefender.cpp b/health/BatteryDefender.cpp
index 94ca031..37283da 100644
--- a/health/BatteryDefender.cpp
+++ b/health/BatteryDefender.cpp
@@ -34,14 +34,10 @@
namespace pixel {
namespace health {
-BatteryDefender::BatteryDefender(const std::string pathWirelessPresent,
- const std::string pathChargeLevelStart,
- const std::string pathChargeLevelStop,
+BatteryDefender::BatteryDefender(const char *pathChargeLevelStart, const char *pathChargeLevelStop,
const int32_t timeToActivateSecs,
const int32_t timeToClearTimerSecs)
-
- : mPathWirelessPresent(pathWirelessPresent),
- kPathChargeLevelStart(pathChargeLevelStart),
+ : kPathChargeLevelStart(pathChargeLevelStart),
kPathChargeLevelStop(pathChargeLevelStop),
kTimeToActivateSecs(timeToActivateSecs),
kTimeToClearTimerSecs(timeToClearTimerSecs) {
@@ -55,10 +51,6 @@
mTimeChargerPresentSecs = 0;
}
-void BatteryDefender::setWirelessNotSupported(void) {
- mPathWirelessPresent = PATH_NOT_SUPPORTED;
-}
-
void BatteryDefender::loadPersistentStorage(void) {
if (mIsPowerAvailable) {
// Load accumulated time from persisted storage
@@ -83,19 +75,14 @@
str->erase(std::remove(str->begin(), str->end(), '\r'), str->end());
}
-int BatteryDefender::readFileToInt(const std::string &path) {
+int BatteryDefender::readFileToInt(const char *path) {
std::string buffer;
int value = 0; // default
-
- if (path == PATH_NOT_SUPPORTED) {
- return value;
- }
-
if (!android::base::ReadFileToString(path, &buffer)) {
LOG(ERROR) << "Failed to read " << path;
} else {
removeLineEndings(&buffer);
- if (!android::base::ParseInt(buffer, &value)) {
+ if (!android::base::ParseInt(buffer.c_str(), &value)) {
LOG(ERROR) << "Failed to parse " << path;
}
}
@@ -103,7 +90,7 @@
return value;
}
-bool BatteryDefender::writeIntToFile(const std::string &path, const int value) {
+bool BatteryDefender::writeIntToFile(const char *path, const int value) {
bool success = android::base::WriteStringToFile(std::to_string(value), path);
if (!success) {
LOG(ERROR) << "Failed to write " << path;
@@ -112,11 +99,10 @@
return success;
}
-void BatteryDefender::writeTimeToFile(const std::string &path, const int value, int64_t *previous) {
- // Some number of seconds delay before repeated writes
- const bool hasTimeChangedSignificantly =
- ((value == 0) || (*previous == -1) || (value > (*previous + kWriteDelaySecs)) ||
- (value < (*previous - kWriteDelaySecs)));
+void BatteryDefender::writeTimeToFile(const char *path, const int value, int64_t *previous) {
+ // 30 second delay before repeated writes
+ const bool hasTimeChangedSignificantly = ((value == 0) || (*previous == -1) ||
+ (value > *previous + 30) || (value < *previous - 30));
if ((value != *previous) && hasTimeChangedSignificantly) {
writeIntToFile(path, value);
*previous = value;
@@ -127,20 +113,8 @@
int chargeLevelStart = vendorStart;
int chargeLevelStop = vendorStop;
if (mCurrentState == STATE_ACTIVE) {
- const int newDefenderLevelStart = android::base::GetIntProperty(
- kPropBatteryDefenderCtrlStartSOC, kChargeLevelDefenderStart, 0, 100);
- const int newDefenderLevelStop = android::base::GetIntProperty(
- kPropBatteryDefenderCtrlStopSOC, kChargeLevelDefenderStop, 0, 100);
- const bool overrideLevelsValid =
- (newDefenderLevelStart <= newDefenderLevelStop) && (newDefenderLevelStop != 0);
-
- if (overrideLevelsValid) {
- chargeLevelStart = newDefenderLevelStart;
- chargeLevelStop = newDefenderLevelStop;
- } else {
- chargeLevelStart = kChargeLevelDefenderStart;
- chargeLevelStop = kChargeLevelDefenderStop;
- }
+ chargeLevelStart = kChargeLevelDefenderStart;
+ chargeLevelStop = kChargeLevelDefenderStop;
}
// Disable battery defender effects in charger mode until
@@ -160,13 +134,13 @@
}
bool BatteryDefender::isChargePowerAvailable(void) {
- // USB presence is an indicator of power availability
- const bool chargerPresentWired = readFileToInt(kPathUSBChargerPresent) != 0;
- const bool chargerPresentWireless = readFileToInt(mPathWirelessPresent) != 0;
- mIsUsbPresent = chargerPresentWired;
- mIsWirelessPresent = chargerPresentWireless;
+ // USB presence is an indicator of connectivity
+ const bool chargerPresentWired = readFileToInt(kPathWiredChargerPresent) != 0;
- return chargerPresentWired || chargerPresentWireless;
+ // Wireless online is an indicator of a device having charge power
+ const bool chargerOnlineWireless = readFileToInt(kPathWirelessChargerOnline) != 0;
+
+ return chargerPresentWired || chargerOnlineWireless;
}
bool BatteryDefender::isDefaultChargeLevel(const int start, const int stop) {
@@ -175,12 +149,11 @@
bool BatteryDefender::isBatteryDefenderDisabled(const int vendorStart, const int vendorStop) {
const bool isDefaultVendorChargeLevel = isDefaultChargeLevel(vendorStart, vendorStop);
- const bool isOverrideDisabled =
+ const bool isExplicitlyDisabled =
android::base::GetBoolProperty(kPropBatteryDefenderDisable, false);
- const bool isCtrlEnabled =
- android::base::GetBoolProperty(kPropBatteryDefenderCtrlEnable, kDefaultEnable);
+ const bool isDebuggable = android::base::GetBoolProperty(kPropDebuggable, false);
- return isOverrideDisabled || (isDefaultVendorChargeLevel == false) || (isCtrlEnabled == false);
+ return isExplicitlyDisabled || (isDefaultVendorChargeLevel == false) || (isDebuggable == false);
}
void BatteryDefender::addTimeToChargeTimers(void) {
@@ -197,31 +170,14 @@
int32_t BatteryDefender::getTimeToActivate(void) {
// Use the default constructor value if the modified property is not between 60 and INT_MAX
// (seconds)
- const int32_t timeToActivateOverride =
- android::base::GetIntProperty(kPropBatteryDefenderThreshold, kTimeToActivateSecs,
- (int32_t)ONE_MIN_IN_SECONDS, INT32_MAX);
-
- const bool overrideActive = timeToActivateOverride != kTimeToActivateSecs;
- if (overrideActive) {
- return timeToActivateOverride;
- } else {
- // No overrides taken; apply ctrl time to activate...
- // Note; do not allow less than 1 day trigger time
- return android::base::GetIntProperty(kPropBatteryDefenderCtrlActivateTime,
- kTimeToActivateSecs, (int32_t)ONE_DAY_IN_SECONDS,
- INT32_MAX);
- }
+ return android::base::GetIntProperty(kPropBatteryDefenderThreshold, kTimeToActivateSecs,
+ (int32_t)ONE_MIN_IN_SECONDS, INT32_MAX);
}
-void BatteryDefender::stateMachine_runAction(const state_E state,
- const struct android::BatteryProperties *props) {
+void BatteryDefender::stateMachine_runAction(const state_E state) {
switch (state) {
case STATE_INIT:
loadPersistentStorage();
- if (props->chargerUsbOnline || props->chargerAcOnline) {
- mWasAcOnline = props->chargerAcOnline;
- mWasUsbOnline = props->chargerUsbOnline;
- }
break;
case STATE_DISABLED:
@@ -229,15 +185,12 @@
clearStateData();
break;
- case STATE_CONNECTED: {
+ case STATE_CONNECTED:
addTimeToChargeTimers();
-
- const int triggerLevel = android::base::GetIntProperty(
- kPropBatteryDefenderCtrlTriggerSOC, kChargeHighCapacityLevel, 0, 100);
- if (props->batteryLevel >= triggerLevel) {
+ if (readFileToInt(kPathBatteryCapacity) == kChargeHighCapacityLevel) {
mHasReachedHighCapacityLevel = true;
}
- } break;
+ break;
case STATE_ACTIVE:
addTimeToChargeTimers();
@@ -284,26 +237,13 @@
case STATE_CONNECTED:
if (mTimeChargerPresentSecs > mTimeToActivateSecsModified) {
nextState = STATE_ACTIVE;
- }
- FALLTHROUGH_INTENDED;
-
- case STATE_ACTIVE: {
- const int timeToClear = android::base::GetIntProperty(
- kPropBatteryDefenderCtrlResumeTime, kTimeToClearTimerSecs, 0, INT32_MAX);
-
- const int bdClear = android::base::GetIntProperty(kPropBatteryDefenderCtrlClear, 0);
-
- if (bdClear > 0) {
- android::base::SetProperty(kPropBatteryDefenderCtrlClear, "0");
+ } else if (mTimeChargerNotPresentSecs > kTimeToClearTimerSecs) {
nextState = STATE_DISCONNECTED;
}
+ break;
- /* Check for mIsPowerAvailable in case timeToClear is 0 */
- if ((mTimeChargerNotPresentSecs >= timeToClear) && (mIsPowerAvailable == false)) {
- nextState = STATE_DISCONNECTED;
- }
- } break;
-
+ case STATE_ACTIVE:
+ // Latch unless disabled or unless the health module has restarted (ie. reboot)
default:
break;
}
@@ -317,8 +257,9 @@
void BatteryDefender::stateMachine_firstAction(const state_E state) {
switch (state) {
case STATE_DISABLED:
+ clearStateData();
LOG(INFO) << "Disabled!";
- FALLTHROUGH_INTENDED;
+ break;
case STATE_DISCONNECTED:
clearStateData();
@@ -345,50 +286,7 @@
}
}
-void BatteryDefender::updateDefenderProperties(struct android::BatteryProperties *props) {
- /**
- * Override the OVERHEAT flag for UI updates to settings.
- * Also, force AC/USB online if active and still connected to power.
- */
- if (mCurrentState == STATE_ACTIVE) {
- props->batteryHealth = android::BATTERY_HEALTH_OVERHEAT;
- }
-
- /**
- * If the kernel is forcing the input current limit to 0, then the online status may
- * need to be overwritten. Also, setting a charge limit below the current charge level
- * may disable the adapter.
- * Note; only override "online" if necessary (all "online"s are false).
- */
- if (props->chargerUsbOnline == false && props->chargerAcOnline == false) {
- /* Override if the USB is connected and a battery defender is active */
- if (mIsUsbPresent && props->batteryHealth == android::BATTERY_HEALTH_OVERHEAT) {
- if (mWasAcOnline) {
- props->chargerAcOnline = true;
- }
- if (mWasUsbOnline) {
- props->chargerUsbOnline = true;
- }
- }
- } else {
- /* One of these booleans will always be true if updated here */
- mWasAcOnline = props->chargerAcOnline;
- mWasUsbOnline = props->chargerUsbOnline;
- }
-
- /* Do the same as above for wireless adapters */
- if (props->chargerWirelessOnline == false) {
- if (mIsWirelessPresent && props->batteryHealth == android::BATTERY_HEALTH_OVERHEAT) {
- props->chargerWirelessOnline = true;
- }
- }
-}
-
-void BatteryDefender::update(struct android::BatteryProperties *props) {
- if (!props) {
- return;
- }
-
+void BatteryDefender::update(void) {
// Update module inputs
const int chargeLevelVendorStart =
android::base::GetIntProperty(kPropChargeLevelVendorStart, kChargeLevelDefaultStart);
@@ -399,22 +297,19 @@
mTimeBetweenUpdateCalls = getDeltaTimeSeconds(&mTimePreviousSecs);
// Run state machine
- stateMachine_runAction(mCurrentState, props);
+ stateMachine_runAction(mCurrentState);
const state_E nextState = stateMachine_getNextState(mCurrentState);
if (nextState != mCurrentState) {
stateMachine_firstAction(nextState);
}
mCurrentState = nextState;
- // Verify/update battery defender battery properties
- updateDefenderProperties(props); /* May override battery properties */
-
// Store outputs
writeTimeToFile(kPathPersistChargerPresentTime, mTimeChargerPresentSecs,
&mTimeChargerPresentSecsPrevious);
writeTimeToFile(kPathPersistDefenderActiveTime, mTimeActiveSecs, &mTimeActiveSecsPrevious);
writeChargeLevelsToFile(chargeLevelVendorStart, chargeLevelVendorStop);
- android::base::SetProperty(kPropBatteryDefenderState, kStateStringMap[mCurrentState]);
+ android::base::SetProperty(kPropBatteryDefenderState, stateStringMap[mCurrentState]);
}
} // namespace health
diff --git a/health/BatteryMetricsLogger.cpp b/health/BatteryMetricsLogger.cpp
index bd58028..58c6b58 100644
--- a/health/BatteryMetricsLogger.cpp
+++ b/health/BatteryMetricsLogger.cpp
@@ -15,17 +15,17 @@
* limitations under the License.
*/
+#include <android/frameworks/stats/1.0/IStats.h>
#include <pixelhealth/BatteryMetricsLogger.h>
-#include <pixelhealth/StatsHelper.h>
namespace hardware {
namespace google {
namespace pixel {
namespace health {
-VendorBatteryHealthSnapshot::BatterySnapshotType toBatterySnapshotType(int type) {
- return static_cast<VendorBatteryHealthSnapshot::BatterySnapshotType>(type);
-}
+using android::sp;
+using android::frameworks::stats::V1_0::BatteryHealthSnapshotArgs;
+using android::frameworks::stats::V1_0::IStats;
BatteryMetricsLogger::BatteryMetricsLogger(const char *const batt_res, const char *const batt_ocv,
const char *const batt_avg_res, int sample_period,
@@ -48,37 +48,37 @@
return nanoseconds_to_seconds(systemTime(SYSTEM_TIME_BOOTTIME));
}
-bool BatteryMetricsLogger::uploadOutlierMetric(const std::shared_ptr<IStats> &stats_client,
- sampleType type) {
+bool BatteryMetricsLogger::uploadOutlierMetric(sp<IStats> stats_client, sampleType type) {
+ BatteryHealthSnapshotArgs min_stats_ss = {
+ .type = static_cast<BatteryHealthSnapshotArgs::BatterySnapshotType>(0),
+ .temperatureDeciC = min_[type][TEMP],
+ .voltageMicroV = min_[type][VOLT],
+ .currentMicroA = min_[type][CURR],
+ .openCircuitVoltageMicroV = min_[type][OCV],
+ .resistanceMicroOhm = min_[type][RES],
+ .levelPercent = min_[type][SOC]};
+ BatteryHealthSnapshotArgs max_stats_ss = {
+ .type = static_cast<BatteryHealthSnapshotArgs::BatterySnapshotType>(0),
+ .temperatureDeciC = max_[type][TEMP],
+ .voltageMicroV = max_[type][VOLT],
+ .currentMicroA = max_[type][CURR],
+ .openCircuitVoltageMicroV = max_[type][OCV],
+ .resistanceMicroOhm = max_[type][RES],
+ .levelPercent = max_[type][SOC]};
if (kStatsSnapshotType[type] < 0)
return false;
- VendorBatteryHealthSnapshot min_stats_ss;
- min_stats_ss.set_type(toBatterySnapshotType(kStatsSnapshotType[type]));
- min_stats_ss.set_temperature_deci_celsius(min_[type][TEMP]);
- min_stats_ss.set_voltage_micro_volt(min_[type][VOLT]);
- min_stats_ss.set_current_micro_amps(min_[type][CURR]);
- min_stats_ss.set_open_circuit_micro_volt(min_[type][OCV]);
- min_stats_ss.set_resistance_micro_ohm(min_[type][RES]);
- min_stats_ss.set_level_percent(min_[type][SOC]);
+ min_stats_ss.type = (BatteryHealthSnapshotArgs::BatterySnapshotType)kStatsSnapshotType[type];
+ max_stats_ss.type =
+ (BatteryHealthSnapshotArgs::BatterySnapshotType)(kStatsSnapshotType[type] + 1);
- VendorBatteryHealthSnapshot max_stats_ss;
- max_stats_ss.set_type(toBatterySnapshotType(kStatsSnapshotType[type] + 1));
- max_stats_ss.set_temperature_deci_celsius(max_[type][TEMP]);
- max_stats_ss.set_voltage_micro_volt(max_[type][VOLT]);
- max_stats_ss.set_current_micro_amps(max_[type][CURR]);
- max_stats_ss.set_open_circuit_micro_volt(max_[type][OCV]);
- max_stats_ss.set_resistance_micro_ohm(max_[type][RES]);
- max_stats_ss.set_level_percent(max_[type][SOC]);
-
- reportBatteryHealthSnapshot(stats_client, min_stats_ss);
- reportBatteryHealthSnapshot(stats_client, max_stats_ss);
+ stats_client->reportBatteryHealthSnapshot(min_stats_ss);
+ stats_client->reportBatteryHealthSnapshot(max_stats_ss);
return true;
}
-bool BatteryMetricsLogger::uploadAverageBatteryResistance(
- const std::shared_ptr<IStats> &stats_client) {
+bool BatteryMetricsLogger::uploadAverageBatteryResistance(sp<IStats> stats_client) {
if (strlen(kBatteryAvgResistance) == 0) {
LOG(INFO) << "Sysfs path for average battery resistance not specified";
return true;
@@ -97,16 +97,15 @@
return false;
}
// Upload average metric
- VendorBatteryHealthSnapshot avg_res_ss_stats;
- avg_res_ss_stats.set_type(VendorBatteryHealthSnapshot::BATTERY_SNAPSHOT_TYPE_AVG_RESISTANCE);
- avg_res_ss_stats.set_temperature_deci_celsius(0);
- avg_res_ss_stats.set_voltage_micro_volt(0);
- avg_res_ss_stats.set_current_micro_amps(0);
- avg_res_ss_stats.set_open_circuit_micro_volt(0);
- avg_res_ss_stats.set_resistance_micro_ohm(batt_avg_res);
- avg_res_ss_stats.set_level_percent(0);
-
- reportBatteryHealthSnapshot(stats_client, avg_res_ss_stats);
+ BatteryHealthSnapshotArgs avg_res_ss_stats = {
+ .type = BatteryHealthSnapshotArgs::BatterySnapshotType::AVG_RESISTANCE,
+ .temperatureDeciC = 0,
+ .voltageMicroV = 0,
+ .currentMicroA = 0,
+ .openCircuitVoltageMicroV = 0,
+ .resistanceMicroOhm = batt_avg_res,
+ .levelPercent = 0};
+ stats_client->reportBatteryHealthSnapshot(avg_res_ss_stats);
return true;
}
@@ -119,7 +118,7 @@
LOG(INFO) << "Uploading metrics at time " << std::to_string(time) << " w/ "
<< std::to_string(num_samples_) << " samples";
- std::shared_ptr<IStats> stats_client = getStatsService();
+ sp<IStats> stats_client = IStats::tryGetService();
if (!stats_client) {
LOG(ERROR) << "Unable to connect to Stats service";
return false;
diff --git a/health/BatteryThermalControl.cpp b/health/BatteryThermalControl.cpp
index 47762c4..d119b34 100644
--- a/health/BatteryThermalControl.cpp
+++ b/health/BatteryThermalControl.cpp
@@ -21,8 +21,6 @@
namespace pixel {
namespace health {
-using android::base::GetIntProperty;
-
BatteryThermalControl::BatteryThermalControl(const std::string &path) : mThermalSocMode(path) {
mStatus = true;
}
@@ -43,14 +41,9 @@
}
void BatteryThermalControl::updateThermalState(const struct android::BatteryProperties *props) {
- int bcl_disable = GetIntProperty("persist.vendor.disable.bcl.control", 0);
-
- if (bcl_disable)
- setThermalMode(false, true);
- else
- setThermalMode(props->batteryStatus != android::BATTERY_STATUS_CHARGING &&
- props->batteryStatus != android::BATTERY_STATUS_FULL,
- props->maxChargingCurrent * props->maxChargingVoltage < 37500000);
+ setThermalMode(props->batteryStatus != android::BATTERY_STATUS_CHARGING &&
+ props->batteryStatus != android::BATTERY_STATUS_FULL,
+ props->maxChargingCurrent * props->maxChargingVoltage < 37500000);
}
} // namespace health
diff --git a/health/ChargerDetect.cpp b/health/ChargerDetect.cpp
deleted file mode 100644
index 1de7e95..0000000
--- a/health/ChargerDetect.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2020 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 LOG_TAG "dChargerDetect"
-
-#include <android-base/file.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-#include <cutils/klog.h>
-#include <dirent.h>
-#include <pixelhealth/ChargerDetect.h>
-#include <string>
-
-constexpr char kPowerSupplySysfsPath[]{"/sys/class/power_supply/"};
-constexpr char kUsbOnlinePath[]{"/sys/class/power_supply/usb/online"};
-constexpr char kUsbPowerSupplySysfsPath[]{"/sys/class/power_supply/usb/usb_type"};
-constexpr char kTcpmPsyFilter[]{"tcpm"};
-using android::BatteryMonitor;
-
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace health {
-
-int ChargerDetect::readFromFile(const std::string& path, std::string* buf) {
- if (android::base::ReadFileToString(path.c_str(), buf)) {
- *buf = android::base::Trim(*buf);
- }
- return buf->length();
-}
-
-int ChargerDetect::getIntField(const std::string& path) {
- std::string buf;
- int value = 0;
-
- if (readFromFile(path, &buf) > 0)
- android::base::ParseInt(buf, &value);
-
- return value;
-}
-
-/*
- * Traverses through /sys/class/power_supply/ to identify TCPM(Type-C/PD) power supply.
- * TCPM power supply's name follows the format "tcpm-source-psy-6-0025" with i2c/i3c bus id
- * and client id(SID) baked in.
- */
-void ChargerDetect::populateTcpmPsyName(std::string* tcpmPsyName) {
- std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(kPowerSupplySysfsPath), closedir);
- if (dir == NULL) {
- KLOG_ERROR(LOG_TAG, "Could not open %s\n", kPowerSupplySysfsPath);
- } else {
- struct dirent* entry;
-
- while ((entry = readdir(dir.get()))) {
- const char* name = entry->d_name;
-
- KLOG_INFO(LOG_TAG, "Psy name:%s", name);
- if (strstr(name, kTcpmPsyFilter)) {
- *tcpmPsyName = name;
- }
- }
- }
-}
-
-/*
- * The contents of /sys/class/power_supply/<Power supply name>/usb_type follows the format:
- * Unknown [SDP] CDP DCP
- * with the current selected value encloses within square braces.
- * This functions extracts the current selected value and returns it back to the caller.
- */
-int ChargerDetect::getPsyUsbType(const std::string& path, std::string* type) {
- size_t start;
- std::string usbType;
- int ret;
-
- ret = readFromFile(path, &usbType);
- if (ret <= 0) {
- KLOG_ERROR(LOG_TAG, "Error reading %s: %d\n", path.c_str(), ret);
- return -EINVAL;
- }
-
- start = usbType.find('[');
- if (start == std::string::npos) {
- KLOG_ERROR(LOG_TAG, "'[' not found in %s: %s\n", path.c_str(), usbType.c_str());
- return -EINVAL;
- }
-
- *type = usbType.substr(start + 1, usbType.find(']') - start - 1);
- return 0;
-}
-
-/*
- * Reads the usb power_supply's usb_type and the tcpm power_supply's usb_type to infer
- * HealthInfo(hardware/interfaces/health/1.0/types.hal) online property.
- */
-void ChargerDetect::onlineUpdate(struct android::BatteryProperties *props) {
- std::string tcpmOnlinePath, usbPsyType;
- static std::string tcpmPsyName;
- int ret;
-
- props->chargerAcOnline = false;
- props->chargerUsbOnline = false;
-
- if (tcpmPsyName.empty()) {
- populateTcpmPsyName(&tcpmPsyName);
- KLOG_INFO(LOG_TAG, "TcpmPsyName:%s\n", tcpmPsyName.c_str());
- }
-
- if (!getIntField(kUsbOnlinePath)) {
- return;
- }
-
- ret = getPsyUsbType(kUsbPowerSupplySysfsPath, &usbPsyType);
- if (!ret) {
- if (usbPsyType == "CDP" || usbPsyType == "DCP") {
- props->chargerAcOnline = true;
- return;
- } else if (usbPsyType == "SDP") {
- props->chargerUsbOnline = true;
- return;
- }
- }
-
- /* Safe to assume AC charger here if BC1.2 non compliant */
- props->chargerAcOnline = true;
-
- if (tcpmPsyName.empty()) {
- return;
- }
-
- ret = getPsyUsbType(std::string(kPowerSupplySysfsPath) + tcpmPsyName + "/usb_type" ,
- &usbPsyType);
- if (ret < 0) {
- return;
- }
-
- KLOG_INFO(LOG_TAG, "TcpmPsy Usbtype:%s\n", usbPsyType.c_str());
-
- return;
-}
-
-} // namespace health
-} // namespace pixel
-} // namespace google
-} // namespace hardware
diff --git a/health/LowBatteryShutdownMetrics.cpp b/health/LowBatteryShutdownMetrics.cpp
index 09fd45d..2dd07d1 100644
--- a/health/LowBatteryShutdownMetrics.cpp
+++ b/health/LowBatteryShutdownMetrics.cpp
@@ -15,8 +15,8 @@
* limitations under the License.
*/
+#include <android/frameworks/stats/1.0/IStats.h>
#include <pixelhealth/LowBatteryShutdownMetrics.h>
-#include <pixelhealth/StatsHelper.h>
namespace hardware {
namespace google {
@@ -24,9 +24,12 @@
namespace health {
using android::BATTERY_STATUS_DISCHARGING;
+using android::sp;
using android::base::GetProperty;
using android::base::ReadFileToString;
using android::base::SetProperty;
+using android::frameworks::stats::V1_0::BatteryCausedShutdown;
+using android::frameworks::stats::V1_0::IStats;
LowBatteryShutdownMetrics::LowBatteryShutdownMetrics(const char *const voltage_avg,
const char *const persist_prop)
@@ -43,14 +46,13 @@
return false;
}
- std::shared_ptr<IStats> stats_client = getStatsService();
+ sp<IStats> stats_client = IStats::tryGetService();
if (!stats_client) {
- LOG(ERROR) << "Unable to connect to IStats service";
+ LOG(ERROR) << "Unable to connect to Stats service";
return false;
}
// Process and upload comma-delimited last voltage values
- VendorBatteryCausedShutdown shutdown;
int32_t voltage_avg;
for (const auto &item : android::base::Split(prop_contents, ",")) {
if (!(voltage_avg = stoi(item))) {
@@ -58,8 +60,8 @@
continue;
}
LOG(INFO) << "Uploading voltage_avg: " << std::to_string(voltage_avg);
- shutdown.set_last_recorded_micro_volt(voltage_avg);
- reportBatteryCausedShutdown(stats_client, shutdown);
+ BatteryCausedShutdown shutdown = {.voltageMicroV = voltage_avg};
+ stats_client->reportBatteryCausedShutdown(shutdown);
}
// Clear property now that we've uploaded its contents
diff --git a/health/StatsHelper.cpp b/health/StatsHelper.cpp
deleted file mode 100644
index 6986d6a..0000000
--- a/health/StatsHelper.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include <android-base/logging.h>
-#include <android/binder_manager.h>
-#include <pixelhealth/StatsHelper.h>
-
-#define LOG_TAG "pixelhealth-vendor"
-
-#include <utils/Log.h>
-
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace health {
-
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
-namespace PixelAtoms = android::hardware::google::pixel::PixelAtoms;
-
-std::shared_ptr<IStats> getStatsService() {
- const std::string instance = std::string() + IStats::descriptor + "/default";
- static bool isStatsDeclared = false;
- if (!isStatsDeclared) {
- // It is good to cache the result - it would not be changed
- isStatsDeclared = AServiceManager_isDeclared(instance.c_str());
- if (!isStatsDeclared) {
- LOG(ERROR) << "Stats service is not registered.";
- return nullptr;
- }
- }
- /* TODO stayfan@: b/187221893 Review implementing separate thread to log atoms
- * to prevent data loss at device boot stage, while IStats might not be ready
- */
- return IStats::fromBinder(ndk::SpAIBinder(AServiceManager_getService(instance.c_str())));
-}
-
-void reportBatteryHealthSnapshot(const std::shared_ptr<IStats> &stats_client,
- const VendorBatteryHealthSnapshot &batteryHealthSnapshot) {
- // Load values array
- std::vector<VendorAtomValue> values(7);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(batteryHealthSnapshot.type());
- values[0] = tmp;
- tmp.set<VendorAtomValue::intValue>(batteryHealthSnapshot.temperature_deci_celsius());
- values[1] = tmp;
- tmp.set<VendorAtomValue::intValue>(batteryHealthSnapshot.voltage_micro_volt());
- values[2] = tmp;
- tmp.set<VendorAtomValue::intValue>(batteryHealthSnapshot.current_micro_amps());
- values[3] = tmp;
- tmp.set<VendorAtomValue::intValue>(batteryHealthSnapshot.open_circuit_micro_volt());
- values[4] = tmp;
- tmp.set<VendorAtomValue::intValue>(batteryHealthSnapshot.resistance_micro_ohm());
- values[5] = tmp;
- tmp.set<VendorAtomValue::intValue>(batteryHealthSnapshot.level_percent());
- values[6] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVendorBatteryHealthSnapshot,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- LOG(ERROR) << "Unable to report VendorBatteryHealthSnapshot to IStats service";
-}
-
-void reportBatteryCausedShutdown(const std::shared_ptr<IStats> &stats_client,
- const VendorBatteryCausedShutdown &batteryCausedShutdown) {
- // Load values array
- std::vector<VendorAtomValue> values(1);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(batteryCausedShutdown.last_recorded_micro_volt());
- values[0] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVendorBatteryCausedShutdown,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- LOG(ERROR) << "Unable to report VendorBatteryHealthSnapshot to IStats service";
-}
-
-} // namespace health
-} // namespace pixel
-} // namespace google
-} // namespace hardware
diff --git a/health/include/pixelhealth/BatteryDefender.h b/health/include/pixelhealth/BatteryDefender.h
index 59f69e2..30512c2 100644
--- a/health/include/pixelhealth/BatteryDefender.h
+++ b/health/include/pixelhealth/BatteryDefender.h
@@ -17,8 +17,6 @@
#ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_BATTERYDEFENDER_H
#define HARDWARE_GOOGLE_PIXEL_HEALTH_BATTERYDEFENDER_H
-#include <batteryservice/BatteryService.h>
-
#include <stdbool.h>
#include <time.h>
#include <string>
@@ -33,33 +31,26 @@
const uint32_t ONE_DAY_IN_HOURS = 24;
const uint32_t ONE_DAY_IN_SECONDS = ONE_DAY_IN_HOURS * ONE_HOUR_IN_MINUTES * ONE_MIN_IN_SECONDS;
-const uint32_t DEFAULT_TIME_TO_ACTIVATE_SECONDS = (4 * ONE_DAY_IN_SECONDS);
+const uint32_t DEFAULT_TIME_TO_ACTIVATE_SECONDS = (14 * ONE_DAY_IN_SECONDS);
const uint32_t DEFAULT_TIME_TO_CLEAR_SECONDS = (5 * ONE_MIN_IN_SECONDS);
const int DEFAULT_CHARGE_LEVEL_START = 0;
const int DEFAULT_CHARGE_LEVEL_STOP = 100;
-const int DEFAULT_CHARGE_LEVEL_DEFENDER_START = 70;
-const int DEFAULT_CHARGE_LEVEL_DEFENDER_STOP = 80;
+const int DEFAULT_CHARGE_LEVEL_DEFENDER_START = 60;
+const int DEFAULT_CHARGE_LEVEL_DEFENDER_STOP = 70;
const int DEFAULT_CAPACITY_LEVEL = 100;
-const int WRITE_DELAY_SECS = 2 * ONE_MIN_IN_SECONDS;
-
-const char *const PATH_NOT_SUPPORTED = "";
class BatteryDefender {
public:
// Set default google charger paths - can be overridden for other devices
- BatteryDefender(const std::string pathWirelessPresent = PATH_NOT_SUPPORTED,
- const std::string pathChargeLevelStart =
+ BatteryDefender(const char *pathChargeLevelStart =
"/sys/devices/platform/soc/soc:google,charger/charge_start_level",
- const std::string pathChargeLevelStop =
+ const char *pathChargeLevelStop =
"/sys/devices/platform/soc/soc:google,charger/charge_stop_level",
const int32_t timeToActivateSecs = DEFAULT_TIME_TO_ACTIVATE_SECONDS,
const int32_t timeToClearTimerSecs = DEFAULT_TIME_TO_CLEAR_SECONDS);
// This function shall be called periodically in HealthService
- void update(struct android::BatteryProperties *props);
-
- // Set wireless not supported if this is not a device with a wireless charger
- void setWirelessNotSupported(void);
+ void update(void);
private:
enum state_E {
@@ -70,7 +61,7 @@
STATE_ACTIVE,
STATE_COUNT,
};
- const char *const kStateStringMap[STATE_COUNT] = {
+ const char *const stateStringMap[STATE_COUNT] = {
[STATE_INIT] = "INIT",
[STATE_DISABLED] = "DISABLED",
[STATE_DISCONNECTED] = "DISCONNECTED",
@@ -78,17 +69,18 @@
[STATE_ACTIVE] = "ACTIVE",
};
- std::string mPathWirelessPresent;
- const std::string kPathChargeLevelStart;
- const std::string kPathChargeLevelStop;
+ const char *const kPathChargeLevelStart;
+ const char *const kPathChargeLevelStop;
const int32_t kTimeToActivateSecs;
const int32_t kTimeToClearTimerSecs;
// Sysfs
- const std::string kPathUSBChargerPresent = "/sys/class/power_supply/usb/present";
- const std::string kPathPersistChargerPresentTime =
+ const char *const kPathWirelessChargerOnline = "/sys/class/power_supply/wireless/online";
+ const char *const kPathWiredChargerPresent = "/sys/class/power_supply/usb/present";
+ const char *const kPathBatteryCapacity = "/sys/class/power_supply/battery/capacity";
+ const char *const kPathPersistChargerPresentTime =
"/mnt/vendor/persist/battery/defender_charger_time";
- const std::string kPathPersistDefenderActiveTime =
+ const char *const kPathPersistDefenderActiveTime =
"/mnt/vendor/persist/battery/defender_active_time";
// Properties
@@ -97,35 +89,19 @@
const char *const kPropBatteryDefenderState = "vendor.battery.defender.state";
const char *const kPropBatteryDefenderDisable = "vendor.battery.defender.disable";
const char *const kPropBatteryDefenderThreshold = "vendor.battery.defender.threshold";
+ const char *const kPropDebuggable = "ro.debuggable";
const char *const kPropBootmode = "ro.bootmode";
- const char *const kPropBatteryDefenderCtrlEnable = "vendor.battery.defender.ctrl.enable";
- const char *const kPropBatteryDefenderCtrlActivateTime =
- "vendor.battery.defender.ctrl.trigger_time";
- const char *const kPropBatteryDefenderCtrlResumeTime =
- "vendor.battery.defender.ctrl.resume_time";
- const char *const kPropBatteryDefenderCtrlStartSOC =
- "vendor.battery.defender.ctrl.recharge_soc_start";
- const char *const kPropBatteryDefenderCtrlStopSOC =
- "vendor.battery.defender.ctrl.recharge_soc_stop";
- const char *const kPropBatteryDefenderCtrlTriggerSOC =
- "vendor.battery.defender.ctrl.trigger_soc";
- const char *const kPropBatteryDefenderCtrlClear = "vendor.battery.defender.ctrl.clear";
-
// Default thresholds
- const bool kDefaultEnable = true;
const int kChargeLevelDefaultStart = DEFAULT_CHARGE_LEVEL_START;
const int kChargeLevelDefaultStop = DEFAULT_CHARGE_LEVEL_STOP;
const int kChargeLevelDefenderStart = DEFAULT_CHARGE_LEVEL_DEFENDER_START;
const int kChargeLevelDefenderStop = DEFAULT_CHARGE_LEVEL_DEFENDER_STOP;
const int kChargeHighCapacityLevel = DEFAULT_CAPACITY_LEVEL;
- const int kWriteDelaySecs = WRITE_DELAY_SECS;
// Inputs
int64_t mTimeBetweenUpdateCalls = 0;
int64_t mTimePreviousSecs;
- bool mIsUsbPresent = false;
- bool mIsWirelessPresent = false;
bool mIsPowerAvailable = false;
bool mIsDefenderDisabled = false;
int32_t mTimeToActivateSecsModified;
@@ -140,29 +116,20 @@
int mChargeLevelStartPrevious = DEFAULT_CHARGE_LEVEL_START;
int mChargeLevelStopPrevious = DEFAULT_CHARGE_LEVEL_STOP;
bool mHasReachedHighCapacityLevel = false;
- bool mWasAcOnline = false;
- bool mWasUsbOnline = true; /* Default; in case neither AC/USB online becomes 1 */
- // Process state actions
- void stateMachine_runAction(const state_E state,
- const struct android::BatteryProperties *props);
+ void stateMachine_runAction(const state_E state); // Process state actions
+ state_E stateMachine_getNextState(const state_E state); // Check transitions
+ void stateMachine_firstAction(const state_E state); // Process entry actions
- // Check state transitions
- state_E stateMachine_getNextState(const state_E state);
-
- // Process state entry actions
- void stateMachine_firstAction(const state_E state);
-
- void updateDefenderProperties(struct android::BatteryProperties *props);
void clearStateData(void);
void loadPersistentStorage(void);
int64_t getTime(void);
int64_t getDeltaTimeSeconds(int64_t *timeStartSecs);
int32_t getTimeToActivate(void);
void removeLineEndings(std::string *str);
- int readFileToInt(const std::string &path);
- bool writeIntToFile(const std::string &path, const int value);
- void writeTimeToFile(const std::string &path, const int value, int64_t *previous);
+ int readFileToInt(const char *path);
+ bool writeIntToFile(const char *path, const int value);
+ void writeTimeToFile(const char *path, const int value, int64_t *previous);
void writeChargeLevelsToFile(const int vendorStart, const int vendorStop);
bool isChargePowerAvailable(void);
bool isDefaultChargeLevel(const int start, const int stop);
diff --git a/health/include/pixelhealth/BatteryMetricsLogger.h b/health/include/pixelhealth/BatteryMetricsLogger.h
index 82257e2..790a6ed 100644
--- a/health/include/pixelhealth/BatteryMetricsLogger.h
+++ b/health/include/pixelhealth/BatteryMetricsLogger.h
@@ -17,12 +17,11 @@
#ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_BATTERYMETRICSLOGGER_H
#define HARDWARE_GOOGLE_PIXEL_HEALTH_BATTERYMETRICSLOGGER_H
-#include <aidl/android/frameworks/stats/IStats.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
+#include <android/frameworks/stats/1.0/IStats.h>
#include <batteryservice/BatteryService.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
#include <math.h>
#include <time.h>
#include <utils/Timers.h>
@@ -34,8 +33,9 @@
namespace pixel {
namespace health {
-using aidl::android::frameworks::stats::IStats;
-using android::hardware::google::pixel::PixelAtoms::VendorBatteryHealthSnapshot;
+using android::sp;
+using android::frameworks::stats::V1_0::BatteryHealthSnapshotArgs;
+using android::frameworks::stats::V1_0::IStats;
class BatteryMetricsLogger {
public:
@@ -58,11 +58,11 @@
const int kStatsSnapshotType[NUM_FIELDS] = {
-1,
- VendorBatteryHealthSnapshot::BATTERY_SNAPSHOT_TYPE_MIN_CURRENT,
- VendorBatteryHealthSnapshot::BATTERY_SNAPSHOT_TYPE_MIN_VOLTAGE,
- VendorBatteryHealthSnapshot::BATTERY_SNAPSHOT_TYPE_MIN_TEMP,
- VendorBatteryHealthSnapshot::BATTERY_SNAPSHOT_TYPE_MIN_BATT_LEVEL,
- VendorBatteryHealthSnapshot::BATTERY_SNAPSHOT_TYPE_MIN_RESISTANCE,
+ (int)BatteryHealthSnapshotArgs::BatterySnapshotType::MIN_CURRENT,
+ (int)BatteryHealthSnapshotArgs::BatterySnapshotType::MIN_VOLTAGE,
+ (int)BatteryHealthSnapshotArgs::BatterySnapshotType::MIN_TEMP,
+ (int)BatteryHealthSnapshotArgs::BatterySnapshotType::MIN_BATT_LEVEL,
+ (int)BatteryHealthSnapshotArgs::BatterySnapshotType::MIN_RESISTANCE,
-1,
};
@@ -88,8 +88,8 @@
int64_t getTime();
bool recordSample(struct android::BatteryProperties *props);
bool uploadMetrics();
- bool uploadOutlierMetric(const std::shared_ptr<IStats> &stats_client, sampleType type);
- bool uploadAverageBatteryResistance(const std::shared_ptr<IStats> &stats_client);
+ bool uploadOutlierMetric(sp<IStats> stats_client, sampleType type);
+ bool uploadAverageBatteryResistance(sp<IStats> stats_client);
};
} // namespace health
diff --git a/health/include/pixelhealth/BatteryThermalControl.h b/health/include/pixelhealth/BatteryThermalControl.h
index 9b8790a..4b15220 100644
--- a/health/include/pixelhealth/BatteryThermalControl.h
+++ b/health/include/pixelhealth/BatteryThermalControl.h
@@ -18,7 +18,6 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/properties.h>
#include <android-base/strings.h>
#include <batteryservice/BatteryService.h>
diff --git a/health/include/pixelhealth/ChargerDetect.h b/health/include/pixelhealth/ChargerDetect.h
deleted file mode 100644
index ee8b496..0000000
--- a/health/include/pixelhealth/ChargerDetect.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_CHARGER_DETECT_H
-
-#include <android-base/strings.h>
-#include <healthd/BatteryMonitor.h>
-
-using android::BatteryMonitor;
-
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace health {
-
-class ChargerDetect {
- public:
- static void onlineUpdate(struct android::BatteryProperties *props);
- static void populateTcpmPsyName(std::string* tcpmPsyName);
- private:
- static int getPsyUsbType(const std::string& path, std::string* type);
- static int readFromFile(const std::string& path, std::string* buf);
- static int getIntField(const std::string& path);
-};
-
-} // namespace health
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-
-#endif
diff --git a/health/include/pixelhealth/StatsHelper.h b/health/include/pixelhealth/StatsHelper.h
deleted file mode 100644
index 90bf985..0000000
--- a/health/include/pixelhealth/StatsHelper.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_HEALTH_STATSHELPER_H
-#define HARDWARE_GOOGLE_PIXEL_HEALTH_STATSHELPER_H
-
-#include <aidl/android/frameworks/stats/IStats.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace health {
-
-using aidl::android::frameworks::stats::IStats;
-using android::hardware::google::pixel::PixelAtoms::VendorBatteryCausedShutdown;
-using android::hardware::google::pixel::PixelAtoms::VendorBatteryHealthSnapshot;
-
-std::shared_ptr<IStats> getStatsService();
-
-void reportBatteryHealthSnapshot(const std::shared_ptr<IStats> &stats_client,
- const VendorBatteryHealthSnapshot &batteryHealthSnapshot);
-
-void reportBatteryCausedShutdown(const std::shared_ptr<IStats> &stats_client,
- const VendorBatteryCausedShutdown &batteryCausedShutdown);
-
-} // namespace health
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-
-#endif // HARDWARE_GOOGLE_PIXEL_HEALTH_STATSHELPER_H
diff --git a/health/test/TestBatteryDefender.cpp b/health/test/TestBatteryDefender.cpp
index 378b9c6..50656c6 100644
--- a/health/test/TestBatteryDefender.cpp
+++ b/health/test/TestBatteryDefender.cpp
@@ -24,8 +24,6 @@
#include <android-base/file.h>
#include <android-base/properties.h>
-#define MIN_TIME_BETWEEN_FILE_UPDATES (WRITE_DELAY_SECS + 1)
-
class HealthInterface {
public:
virtual ~HealthInterface() {}
@@ -104,39 +102,13 @@
using ::testing::Return;
using ::testing::SetArgPointee;
-struct android::BatteryProperties props;
-BatteryDefender *battDefender;
-
-const char *kPathWiredChargerPresent = "/sys/class/power_supply/usb/present";
-const char *kPathWirelessChargerPresent = "/sys/class/power_supply/wireless/present";
-const char *kPathPersistChargerPresentTime = "/mnt/vendor/persist/battery/defender_charger_time";
-const char *kPathPersistDefenderActiveTime = "/mnt/vendor/persist/battery/defender_active_time";
-const char *kPathStartLevel = "/sys/devices/platform/soc/soc:google,charger/charge_start_level";
-const char *kPathStopLevel = "/sys/devices/platform/soc/soc:google,charger/charge_stop_level";
-
-const char *kPropChargeLevelVendorStart = "persist.vendor.charge.start.level";
-const char *kPropChargeLevelVendorStop = "persist.vendor.charge.stop.level";
-const char *kPropBatteryDefenderState = "vendor.battery.defender.state";
-const char *kPropBatteryDefenderDisable = "vendor.battery.defender.disable";
-const char *kPropBatteryDefenderThreshold = "vendor.battery.defender.threshold";
-
-const char *kPropBatteryDefenderCtrlEnable = "vendor.battery.defender.ctrl.enable";
-const char *kPropBatteryDefenderCtrlActivateTime = "vendor.battery.defender.ctrl.trigger_time";
-const char *kPropBatteryDefenderCtrlResumeTime = "vendor.battery.defender.ctrl.resume_time";
-const char *kPropBatteryDefenderCtrlStartSOC = "vendor.battery.defender.ctrl.recharge_soc_start";
-const char *kPropBatteryDefenderCtrlStopSOC = "vendor.battery.defender.ctrl.recharge_soc_stop";
-const char *kPropBatteryDefenderCtrlTriggerSOC = "vendor.battery.defender.ctrl.trigger_soc";
-
class BatteryDefenderTest : public ::testing::Test {
public:
- BatteryDefenderTest() : defender(kPathWirelessChargerPresent) {}
+ BatteryDefenderTest() {}
void SetUp() {
mock = &mockFixture;
- props = {};
- battDefender = &defender;
-
EXPECT_CALL(*mock, SetProperty(_, _)).Times(AnyNumber());
EXPECT_CALL(*mock, ReadFileToString(_, _, _)).Times(AnyNumber());
EXPECT_CALL(*mock, GetIntProperty(_, _, _, _)).Times(AnyNumber());
@@ -153,60 +125,48 @@
private:
HealthInterfaceMock mockFixture;
- BatteryDefender defender;
};
+const char *kPathWirelessChargerOnline = "/sys/class/power_supply/wireless/online";
+const char *kPathWiredChargerPresent = "/sys/class/power_supply/usb/present";
+const char *kPathBatteryCapacity = "/sys/class/power_supply/battery/capacity";
+const char *kPathPersistChargerPresentTime = "/mnt/vendor/persist/battery/defender_charger_time";
+const char *kPathPersistDefenderActiveTime = "/mnt/vendor/persist/battery/defender_active_time";
+const char *kPathStartLevel = "/sys/devices/platform/soc/soc:google,charger/charge_start_level";
+const char *kPathStopLevel = "/sys/devices/platform/soc/soc:google,charger/charge_stop_level";
+
+const char *kPropChargeLevelVendorStart = "persist.vendor.charge.start.level";
+const char *kPropChargeLevelVendorStop = "persist.vendor.charge.stop.level";
+const char *kPropBatteryDefenderState = "vendor.battery.defender.state";
+const char *kPropBatteryDefenderDisable = "vendor.battery.defender.disable";
+const char *kPropBatteryDefenderThreshold = "vendor.battery.defender.threshold";
+const char *kPropDebuggable = "ro.debuggable";
+
static void enableDefender(void) {
ON_CALL(*mock, GetIntProperty(kPropChargeLevelVendorStart, _, _, _)).WillByDefault(Return(0));
ON_CALL(*mock, GetIntProperty(kPropChargeLevelVendorStop, _, _, _)).WillByDefault(Return(100));
ON_CALL(*mock, GetBoolProperty(kPropBatteryDefenderDisable, _)).WillByDefault(Return(false));
-
- ON_CALL(*mock, GetBoolProperty(kPropBatteryDefenderCtrlEnable, _)).WillByDefault(Return(true));
+ ON_CALL(*mock, GetBoolProperty(kPropDebuggable, _)).WillByDefault(Return(true));
}
-static void usbPresent(void) {
+static void powerAvailable(void) {
+ ON_CALL(*mock, ReadFileToString(kPathWirelessChargerOnline, _, _))
+ .WillByDefault(DoAll(SetArgPointee<1>(std::string("1")), Return(true)));
ON_CALL(*mock, ReadFileToString(kPathWiredChargerPresent, _, _))
.WillByDefault(DoAll(SetArgPointee<1>(std::string("1")), Return(true)));
}
-static void wirelessPresent(void) {
- ON_CALL(*mock, ReadFileToString(kPathWirelessChargerPresent, _, _))
- .WillByDefault(DoAll(SetArgPointee<1>(std::string("1")), Return(true)));
-}
-
-static void wirelessNotPresent(void) {
- ON_CALL(*mock, ReadFileToString(kPathWirelessChargerPresent, _, _))
- .WillByDefault(DoAll(SetArgPointee<1>(std::string("0")), Return(true)));
-}
-
-static void powerAvailable(void) {
- wirelessPresent();
- usbPresent();
-}
-
-static void defaultThresholds(void) {
+static void defaultThreshold(void) {
ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderThreshold, _, _, _))
.WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
-
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlActivateTime, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlResumeTime, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_CLEAR_SECONDS));
-
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStartSOC, _, _, _))
- .WillByDefault(Return(70));
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStopSOC, _, _, _))
- .WillByDefault(Return(80));
-
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlTriggerSOC, _, _, _))
- .WillByDefault(Return(100));
}
static void capacityReached(void) {
- props.batteryLevel = 100;
+ ON_CALL(*mock, ReadFileToString(kPathBatteryCapacity, _, _))
+ .WillByDefault(DoAll(SetArgPointee<1>(std::to_string(100)), Return(true)));
}
-static void initTo1000sConnectedCapacityReached(void) {
+static void initToConnectedCapacityReached(void) {
ON_CALL(*mock, ReadFileToString(kPathPersistChargerPresentTime, _, _))
.WillByDefault(DoAll(SetArgPointee<1>(std::to_string(1000)), Return(true)));
}
@@ -219,556 +179,235 @@
}
TEST_F(BatteryDefenderTest, EnableAndDisconnected) {
+ BatteryDefender battDefender;
+
enableDefender();
// No power
- InSequence s;
-
// Enable Battery Defender
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISCONNECTED"));
- battDefender->update(&props);
+ battDefender.update();
}
TEST_F(BatteryDefenderTest, DisableNonDefaultLevels) {
- InSequence s;
+ BatteryDefender battDefender;
// Enable Battery Defender
EXPECT_CALL(*mock, GetIntProperty(kPropChargeLevelVendorStart, _, _, _)).WillOnce(Return(30));
EXPECT_CALL(*mock, GetIntProperty(kPropChargeLevelVendorStop, _, _, _)).WillOnce(Return(35));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISABLED"));
- battDefender->update(&props);
+ battDefender.update();
+}
+
+TEST_F(BatteryDefenderTest, DisableDebuggable) {
+ BatteryDefender battDefender;
+
+ // Enable Battery Defender
+ EXPECT_CALL(*mock, GetBoolProperty(kPropDebuggable, _)).WillOnce(Return(false));
+
+ EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISABLED"));
+ battDefender.update();
}
TEST_F(BatteryDefenderTest, DisableExplicit) {
- InSequence s;
+ BatteryDefender battDefender;
// Enable Battery Defender
EXPECT_CALL(*mock, GetBoolProperty(kPropBatteryDefenderDisable, _)).WillOnce(Return(true));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISABLED"));
- battDefender->update(&props);
+ battDefender.update();
}
TEST_F(BatteryDefenderTest, InitActive) {
+ BatteryDefender battDefender;
+
enableDefender();
powerAvailable();
- defaultThresholds();
-
- InSequence s;
+ defaultThreshold();
EXPECT_CALL(*mock, ReadFileToString(kPathPersistChargerPresentTime, _, _))
.WillOnce(DoAll(SetArgPointee<1>(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1)),
Return(true)));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
- battDefender->update(&props);
+ battDefender.update();
}
TEST_F(BatteryDefenderTest, InitConnectedCapacityReached) {
+ BatteryDefender battDefender;
+
enableDefender();
powerAvailable();
- defaultThresholds();
+ defaultThreshold();
InSequence s;
- int time_expected = DEFAULT_TIME_TO_ACTIVATE_SECONDS - 1;
EXPECT_CALL(*mock, ReadFileToString(kPathPersistChargerPresentTime, _, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::to_string(time_expected)), Return(true)));
+ .WillOnce(DoAll(SetArgPointee<1>(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS - 1)),
+ Return(true)));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- battDefender->update(&props);
+ battDefender.update();
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- time_expected += MIN_TIME_BETWEEN_FILE_UPDATES;
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(time_expected),
+ testvar_systemTimeSecs++;
+ EXPECT_CALL(*mock, WriteStringToFile(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS),
kPathPersistChargerPresentTime, _));
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
- battDefender->update(&props);
+ EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
+ battDefender.update();
}
TEST_F(BatteryDefenderTest, InitConnected) {
+ BatteryDefender battDefender;
+
enableDefender();
powerAvailable();
- defaultThresholds();
+ defaultThreshold();
InSequence s;
EXPECT_CALL(*mock, ReadFileToString(kPathPersistChargerPresentTime, _, _))
.WillOnce(DoAll(SetArgPointee<1>(std::to_string(0)), Return(true)));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- battDefender->update(&props);
+ battDefender.update();
// mHasReachedHighCapacityLevel shall be false
testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- battDefender->update(&props);
-
- // Would be active if mHasReachedHighCapacityLevel was true
- testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- battDefender->update(&props);
+ battDefender.update();
}
TEST_F(BatteryDefenderTest, TriggerTime) {
+ BatteryDefender battDefender;
+
enableDefender();
powerAvailable();
- defaultThresholds();
+ defaultThreshold();
InSequence s;
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 1;
+ battDefender.update();
// Reached 100% capacity at least once
- capacityReached();
+ EXPECT_CALL(*mock, ReadFileToString(kPathBatteryCapacity, _, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::to_string(100)), Return(true)));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 1;
+ battDefender.update();
EXPECT_CALL(*mock, WriteStringToFile(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS),
kPathPersistChargerPresentTime, _));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS;
- battDefender->update(&props);
+ battDefender.update();
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS +
- MIN_TIME_BETWEEN_FILE_UPDATES),
+ EXPECT_CALL(*mock, WriteStringToFile(std::to_string(DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1),
kPathPersistChargerPresentTime, _));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 1;
+ battDefender.update();
}
TEST_F(BatteryDefenderTest, ChargeLevels) {
+ BatteryDefender battDefender;
+
enableDefender();
powerAvailable();
- defaultThresholds();
- initTo1000sConnectedCapacityReached();
+ defaultThreshold();
+ initToConnectedCapacityReached();
InSequence s;
// No expectations needed; default values already set
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
testvar_systemTimeSecs += 0;
- battDefender->update(&props);
+ battDefender.update();
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(70), kPathStartLevel, _));
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(80), kPathStopLevel, _));
+ EXPECT_CALL(*mock, WriteStringToFile(std::to_string(60), kPathStartLevel, _));
+ EXPECT_CALL(*mock, WriteStringToFile(std::to_string(70), kPathStopLevel, _));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
- battDefender->update(&props);
+ battDefender.update();
}
TEST_F(BatteryDefenderTest, ActiveTime) {
+ BatteryDefender battDefender;
+
enableDefender();
powerAvailable();
- defaultThresholds();
+ defaultThreshold();
initToActive();
InSequence s;
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(70), kPathStartLevel, _));
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(80), kPathStopLevel, _));
+ EXPECT_CALL(*mock, WriteStringToFile(std::to_string(60), kPathStartLevel, _));
+ EXPECT_CALL(*mock, WriteStringToFile(std::to_string(70), kPathStopLevel, _));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
- battDefender->update(&props);
-}
-
-TEST_F(BatteryDefenderTest, ActiveTime_NonDefaultLevels) {
- enableDefender();
- powerAvailable();
- initToActive();
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderThreshold, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlActivateTime, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlResumeTime, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_CLEAR_SECONDS));
-
- // Non-default
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStartSOC, _, _, _))
- .WillByDefault(Return(50));
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStopSOC, _, _, _))
- .WillByDefault(Return(60));
-
- InSequence s;
-
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(50), kPathStartLevel, _));
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(60), kPathStopLevel, _));
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
- battDefender->update(&props);
-}
-
-TEST_F(BatteryDefenderTest, ActiveTime_NonDefaultLevels_invalid) {
- enableDefender();
- powerAvailable();
- initToActive();
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderThreshold, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlActivateTime, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlResumeTime, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_CLEAR_SECONDS));
-
- // Non-default
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStartSOC, _, _, _))
- .WillByDefault(Return(30));
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlStopSOC, _, _, _))
- .WillByDefault(Return(10));
-
- InSequence s;
-
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(70), kPathStartLevel, _));
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(80), kPathStopLevel, _));
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
- battDefender->update(&props);
+ battDefender.update();
}
TEST_F(BatteryDefenderTest, ConnectDisconnectCycle) {
+ BatteryDefender battDefender;
+
enableDefender();
- defaultThresholds();
- initTo1000sConnectedCapacityReached();
+ defaultThreshold();
+ initToConnectedCapacityReached();
InSequence s;
// Power ON
- wirelessPresent();
+ ON_CALL(*mock, ReadFileToString(kPathWirelessChargerOnline, _, _))
+ .WillByDefault(DoAll(SetArgPointee<1>(std::string("1")), Return(true)));
EXPECT_CALL(*mock, WriteStringToFile(std::to_string(1000), kPathPersistChargerPresentTime, _));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 60;
+ battDefender.update();
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(1000 + MIN_TIME_BETWEEN_FILE_UPDATES),
- kPathPersistChargerPresentTime, _));
+ EXPECT_CALL(*mock, WriteStringToFile(std::to_string(1060), kPathPersistChargerPresentTime, _));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 60;
+ battDefender.update();
// Power OFF
- wirelessNotPresent();
+ ON_CALL(*mock, ReadFileToString(kPathWirelessChargerOnline, _, _))
+ .WillByDefault(DoAll(SetArgPointee<1>(std::string("0")), Return(true)));
- // Maintain kPathPersistChargerPresentTime = 1000 + MIN_TIME_BETWEEN_FILE_UPDATES
+ // Maintain kPathPersistChargerPresentTime = 1060
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 60;
+ battDefender.update();
- // Maintain kPathPersistChargerPresentTime = 1000 + MIN_TIME_BETWEEN_FILE_UPDATES
+ // Maintain kPathPersistChargerPresentTime = 1060
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += DEFAULT_TIME_TO_CLEAR_SECONDS - MIN_TIME_BETWEEN_FILE_UPDATES - 1;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 60 * 4;
+ battDefender.update();
- testvar_systemTimeSecs += 1;
EXPECT_CALL(*mock, WriteStringToFile(std::to_string(0), kPathPersistChargerPresentTime, _));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISCONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 1;
+ battDefender.update();
// Power ON
- wirelessPresent();
+ ON_CALL(*mock, ReadFileToString(kPathWirelessChargerOnline, _, _))
+ .WillByDefault(DoAll(SetArgPointee<1>(std::string("1")), Return(true)));
// Maintain kPathPersistChargerPresentTime = 0
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 60;
+ battDefender.update();
capacityReached();
// Maintain kPathPersistChargerPresentTime = 0
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
+ testvar_systemTimeSecs += 60;
+ battDefender.update();
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(MIN_TIME_BETWEEN_FILE_UPDATES),
- kPathPersistChargerPresentTime, _));
+ EXPECT_CALL(*mock, WriteStringToFile(std::to_string(60), kPathPersistChargerPresentTime, _));
EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
-}
-
-TEST_F(BatteryDefenderTest, ConnectDisconnectResumeTimeThreshold) {
- enableDefender();
- initTo1000sConnectedCapacityReached();
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderThreshold, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlActivateTime, _, _, _))
- .WillByDefault(Return(DEFAULT_TIME_TO_ACTIVATE_SECONDS));
-
- // Non-default thresholds
- ON_CALL(*mock, GetIntProperty(kPropBatteryDefenderCtrlResumeTime, _, _, _))
- .WillByDefault(Return(0));
-
- InSequence s;
-
- // Power ON
- wirelessPresent();
-
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(1000), kPathPersistChargerPresentTime, _));
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
-
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(1000 + MIN_TIME_BETWEEN_FILE_UPDATES),
- kPathPersistChargerPresentTime, _));
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
-
- // Power OFF
- wirelessNotPresent();
-
- EXPECT_CALL(*mock, WriteStringToFile(std::to_string(0), kPathPersistChargerPresentTime, _));
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISCONNECTED"));
- testvar_systemTimeSecs += MIN_TIME_BETWEEN_FILE_UPDATES;
- battDefender->update(&props);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitActive_allOnlineFalse) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initToActive();
-
- InSequence s;
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, false);
- ASSERT_EQ(props.chargerUsbOnline, true);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, false);
- ASSERT_EQ(props.chargerUsbOnline, true);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitActive_usbOnline) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initToActive();
-
- InSequence s;
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = true;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, false);
- ASSERT_EQ(props.chargerUsbOnline, true);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, false);
- ASSERT_EQ(props.chargerUsbOnline, true);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitActive_acOnline) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initToActive();
-
- InSequence s;
-
- props.chargerAcOnline = true;
- props.chargerUsbOnline = false;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, false);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, false);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitActive_allOnline) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initToActive();
-
- InSequence s;
-
- props.chargerAcOnline = true;
- props.chargerUsbOnline = true;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, true);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, true);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_allOnlineFalse) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initTo1000sConnectedCapacityReached();
-
- InSequence s;
-
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- battDefender->update(&props);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, false);
- ASSERT_EQ(props.chargerUsbOnline, true);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, false);
- ASSERT_EQ(props.chargerUsbOnline, true);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_usbOnline) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initTo1000sConnectedCapacityReached();
-
- InSequence s;
-
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- battDefender->update(&props);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = true;
- testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, false);
- ASSERT_EQ(props.chargerUsbOnline, true);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, false);
- ASSERT_EQ(props.chargerUsbOnline, true);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_acOnline) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initTo1000sConnectedCapacityReached();
-
- InSequence s;
-
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- battDefender->update(&props);
-
- props.chargerAcOnline = true;
- props.chargerUsbOnline = false;
- testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, false);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, false);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_allOnline) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initTo1000sConnectedCapacityReached();
-
- InSequence s;
-
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- battDefender->update(&props);
-
- props.chargerAcOnline = true;
- props.chargerUsbOnline = true;
- testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE")).Times(2);
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, true);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, true);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_overrideHealth) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initTo1000sConnectedCapacityReached();
-
- InSequence s;
-
- props.batteryHealth = android::BATTERY_HEALTH_UNKNOWN;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED"));
- battDefender->update(&props);
- ASSERT_EQ(props.batteryHealth, android::BATTERY_HEALTH_UNKNOWN);
-
- props.batteryHealth = android::BATTERY_HEALTH_UNKNOWN;
- testvar_systemTimeSecs += DEFAULT_TIME_TO_ACTIVATE_SECONDS + 1;
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "ACTIVE"));
- battDefender->update(&props);
- ASSERT_EQ(props.batteryHealth, android::BATTERY_HEALTH_OVERHEAT);
-}
-
-TEST_F(BatteryDefenderTest, PropsOverride_InitConnected_kernelDefend) {
- enableDefender();
- usbPresent();
- defaultThresholds();
- initTo1000sConnectedCapacityReached();
-
- InSequence s;
-
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "CONNECTED")).Times(3);
- battDefender->update(&props);
-
- props.chargerAcOnline = true;
- props.chargerUsbOnline = true;
- props.batteryHealth = android::BATTERY_HEALTH_OVERHEAT;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, true);
-
- props.chargerAcOnline = false;
- props.chargerUsbOnline = false;
- battDefender->update(&props);
- ASSERT_EQ(props.chargerAcOnline, true);
- ASSERT_EQ(props.chargerUsbOnline, true);
-}
-
-TEST_F(BatteryDefenderTest, WirelessPathUnsupported) {
- enableDefender();
- wirelessPresent();
- defaultThresholds();
-
- InSequence s;
-
- battDefender->setWirelessNotSupported();
-
- EXPECT_CALL(*mock, SetProperty(kPropBatteryDefenderState, "DISCONNECTED"));
- battDefender->update(&props);
+ testvar_systemTimeSecs += 60;
+ battDefender.update();
}
} // namespace health
diff --git a/kernel_headers/Android.bp b/kernel_headers/Android.bp
deleted file mode 100644
index 660a592..0000000
--- a/kernel_headers/Android.bp
+++ /dev/null
@@ -1,9 +0,0 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-kernel_headers {
- name: "qti_kernel_headers",
- vendor: true,
- recovery_available: true,
-}
diff --git a/misc_writer/Android.bp b/misc_writer/Android.bp
index 6ad523a..73c44d2 100644
--- a/misc_writer/Android.bp
+++ b/misc_writer/Android.bp
@@ -14,10 +14,6 @@
// limitations under the License.
//
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_defaults {
name: "misc_writer_defaults",
vendor: true,
diff --git a/mm/Android.bp b/mm/Android.bp
index b00d7fd..f733d7e 100644
--- a/mm/Android.bp
+++ b/mm/Android.bp
@@ -1,7 +1,3 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
sh_binary {
name: "mm_logd",
src: "init.mm.logging.sh",
diff --git a/mm/device.mk b/mm/device.mk
index 656ecb4..150410e 100644
--- a/mm/device.mk
+++ b/mm/device.mk
@@ -6,10 +6,4 @@
mm_logd
endif
-# ZRAM writeback
-PRODUCT_PROPERTY_OVERRIDES += \
- ro.zram.mark_idle_delay_mins=60 \
- ro.zram.first_wb_delay_mins=1440 \
- ro.zram.periodic_wb_delay_hours=24
-
BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/mm
diff --git a/mm/device_gki.mk b/mm/device_gki.mk
deleted file mode 100644
index 5d068e6..0000000
--- a/mm/device_gki.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-PRODUCT_COPY_FILES += \
- hardware/google/pixel/mm/pixel-mm-gki.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/pixel-mm-gki.rc
-
-ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
-PRODUCT_PACKAGES += \
- mm_logd
-endif
-
-# ZRAM writeback
-PRODUCT_PROPERTY_OVERRIDES += \
- ro.zram.mark_idle_delay_mins=60 \
- ro.zram.first_wb_delay_mins=1440 \
- ro.zram.periodic_wb_delay_hours=24
-
-# LMK tuning
-PRODUCT_PROPERTY_OVERRIDES += \
- ro.lmk.filecache_min_kb=153600
-
-BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/mm/gki
diff --git a/mm/device_legacy.mk b/mm/device_legacy.mk
index d32648a..140fb85 100644
--- a/mm/device_legacy.mk
+++ b/mm/device_legacy.mk
@@ -6,10 +6,4 @@
mm_logd
endif
-# ZRAM writeback
-PRODUCT_PROPERTY_OVERRIDES += \
- ro.zram.mark_idle_delay_mins=60 \
- ro.zram.first_wb_delay_mins=1440 \
- ro.zram.periodic_wb_delay_hours=24
-
BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/mm
diff --git a/mm/pixel-mm-gki.rc b/mm/pixel-mm-gki.rc
deleted file mode 100644
index 06684ff..0000000
--- a/mm/pixel-mm-gki.rc
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2021 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.
-
-on init
- # memory reserve tuning
- write /proc/sys/vm/watermark_boost_factor 0
- write /proc/sys/vm/min_free_kbytes 27386
- write /proc/sys/vm/lowmem_reserve_ratio "0 0 0"
- # khugepaged tuning
- write /sys/kernel/mm/transparent_hugepage/khugepaged/scan_sleep_millisecs 60000
-
-on property:sys.boot_completed=1
- chmod 444 /sys/kernel/debug/page_owner
diff --git a/mm/pixel-mm-legacy.rc b/mm/pixel-mm-legacy.rc
index 069eedb..67b619a 100644
--- a/mm/pixel-mm-legacy.rc
+++ b/mm/pixel-mm-legacy.rc
@@ -27,8 +27,6 @@
write /sys/kernel/debug/tracing/instances/pixel-trace/events/mm_event/enable 1
write /sys/kernel/debug/tracing/instances/pixel-trace/events/f2fs/f2fs_iostat/enable 1
write /sys/kernel/debug/tracing/instances/pixel-trace/events/ufs/ufs_stats/enable 1
- write /sys/kernel/debug/tracing/instances/pixel-trace/events/ufs_pixel/ufs_stats/enable 1
- chmod 444 /sys/kernel/debug/page_owner
# turns off tracing right before bugreporting to keep more traces
on property:init.svc.dumpstatez=running
@@ -42,9 +40,3 @@
on property:init.svc.bugreport=stopped
write /d/tracing/instances/pixel-trace/tracing_on 1
-
-on property:init.svc.bugreportd=running
- write /d/tracing/instances/pixel-trace/tracing_on 0
-
-on property:init.svc.bugreportd=stopped
- write /d/tracing/instances/pixel-trace/tracing_on 1
diff --git a/mm/pixel-mm.rc b/mm/pixel-mm.rc
index b2b1cd5..8523fc1 100644
--- a/mm/pixel-mm.rc
+++ b/mm/pixel-mm.rc
@@ -26,8 +26,6 @@
write /sys/kernel/tracing/instances/pixel-trace/events/mm_event/enable 1
write /sys/kernel/tracing/instances/pixel-trace/events/f2fs/f2fs_iostat/enable 1
write /sys/kernel/tracing/instances/pixel-trace/events/ufs/ufs_stats/enable 1
- write /sys/kernel/tracing/instances/pixel-trace/events/ufs_pixel/ufs_stats/enable 1
- chmod 444 /sys/kernel/debug/page_owner
# turns off tracing right before bugreporting to keep more traces
on property:init.svc.dumpstatez=running
@@ -41,9 +39,3 @@
on property:init.svc.bugreport=stopped
write /sys/kernel/tracing/instances/pixel-trace/tracing_on 1
-
-on property:init.svc.bugreportd=running
- write /sys/kernel/tracing/instances/pixel-trace/tracing_on 0
-
-on property:init.svc.bugreportd=stopped
- write /sys/kernel/tracing/instances/pixel-trace/tracing_on 1
diff --git a/perfstatsd/Android.bp b/perfstatsd/Android.bp
index 9c7228a..541aff7 100644
--- a/perfstatsd/Android.bp
+++ b/perfstatsd/Android.bp
@@ -14,10 +14,6 @@
* limitations under the License.
*/
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_defaults {
name: "perfstatsd_defaults",
diff --git a/pixelstats/Android.bp b/pixelstats/Android.bp
index 21bb6d8..7f2ee61 100644
--- a/pixelstats/Android.bp
+++ b/pixelstats/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library {
name: "pixelatoms-cpp",
vendor: true,
@@ -41,43 +37,27 @@
sdk_version: "current",
}
-java_library_host {
- name: "pixelatoms-java_host",
- proto: {
- type: "full",
- },
- srcs: [
- "pixelatoms.proto",
- ],
-}
-
cc_library {
name: "libpixelstats",
vendor: true,
export_include_dirs: ["include"],
srcs: [
- "BatteryCapacityReporter.cpp",
- "BatteryEEPROMReporter.cpp",
"DropDetect.cpp",
- "MmMetricsReporter.cpp",
- "MitigationStatsReporter.cpp",
"OrientationCollector.cpp",
- "PcaChargeStats.cpp",
- "StatsHelper.cpp",
"SysfsCollector.cpp",
"UeventListener.cpp",
- "WirelessChargeStats.cpp",
"WlcReporter.cpp",
+ "BatteryCapacityReporter.cpp",
],
cflags: [
"-Wall",
"-Werror",
],
shared_libs: [
- "android.frameworks.stats-V1-ndk_platform",
+ "android.frameworks.stats@1.0",
"libbase",
- "libbinder_ndk",
+ "libbinder",
"libcutils",
"libhidlbase",
"liblog",
@@ -86,11 +66,11 @@
"pixelatoms-cpp",
],
export_shared_lib_headers: [
- "android.frameworks.stats-V1-ndk_platform",
- "pixelatoms-cpp",
+ "android.frameworks.stats@1.0",
],
static_libs: [
"chre_client",
],
header_libs: ["chre_api"],
}
+
diff --git a/pixelstats/BatteryCapacityReporter.cpp b/pixelstats/BatteryCapacityReporter.cpp
index bd9ee01..9b2995f 100644
--- a/pixelstats/BatteryCapacityReporter.cpp
+++ b/pixelstats/BatteryCapacityReporter.cpp
@@ -23,8 +23,8 @@
#include <android-base/file.h>
+#include <android/frameworks/stats/1.0/IStats.h>
#include <pixelstats/BatteryCapacityReporter.h>
-#include <pixelstats/StatsHelper.h>
#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
@@ -33,14 +33,11 @@
namespace google {
namespace pixel {
-using aidl::android::frameworks::stats::IStats;
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
using android::base::ReadFileToString;
+using android::frameworks::stats::V1_0::IStats;
+using android::frameworks::stats::V1_0::VendorAtom;
using android::hardware::google::pixel::PixelAtoms::BatteryCapacityFG;
-#define ONE_HOUR_SECS (60 * 60)
-
BatteryCapacityReporter::BatteryCapacityReporter() {
// Remove the need for a translation function/table, while removing the dependency on the
// generated <pixelatoms.pb.h> in BatteryCapacityReporter.h.
@@ -58,11 +55,10 @@
static_cast<int>(BatteryCapacityFG::LOG_REASON_DIVERGING_FG));
}
-void BatteryCapacityReporter::checkAndReport(const std::shared_ptr<IStats> &stats_client,
- const std::string &path) {
+void BatteryCapacityReporter::checkAndReport(const std::string &path) {
if (parse(path)) {
- if (checkLogEvent()) {
- reportEvent(stats_client);
+ if (check()) {
+ report();
}
}
}
@@ -95,42 +91,18 @@
return true;
}
-bool BatteryCapacityReporter::shouldReportEvent(void) {
- const int64_t current_time = getTimeSecs();
- if (current_time == 0) {
- ALOGE("Current boot time is zero!");
- return false;
+bool BatteryCapacityReporter::check(void) {
+ if (unexpected_event_timer_active_) {
+ // A 30 minute timer with a boolean gate helps prevent uninitialized timers and potential
+ // overflows.
+ // - Active when the timer is less than 30 minutes, thus continues checking the elapsed
+ // time.
+ // - Once expired (> 30 min), active becomes false and the timer no longer needs to check
+ // the elapsed time.
+ unexpected_event_timer_active_ =
+ (getTimeSecs() - unexpected_event_timer_secs_) <= (30 * 60);
}
- /* Perform cleanup of events that are older than 1 hour */
- for (int i = 0; i < MAX_LOG_EVENTS_PER_HOUR; i++) {
- if (log_event_time_secs_[i] != 0 && /* Non-empty */
- log_event_time_secs_[i] + ONE_HOUR_SECS < current_time) {
- log_event_time_secs_[i] = 0;
- num_events_in_last_hour_--;
- }
- }
-
- /* Log event if there hasn't been many events in the past hour */
- if (num_events_in_last_hour_ < MAX_LOG_EVENTS_PER_HOUR) {
- for (int i = 0; i < MAX_LOG_EVENTS_PER_HOUR; i++) {
- if (log_event_time_secs_[i] == 0) { /* Empty */
- log_event_time_secs_[i] = current_time;
- num_events_in_last_hour_++;
- return true;
- }
- }
- } else {
- ALOGD("Too many log events in past hour; event ignored.");
- }
-
- return false;
-}
-
-/**
- * @return true if a log should be reported, else false
- */
-bool BatteryCapacityReporter::checkLogEvent(void) {
LogReason log_reason = LOG_REASON_UNKNOWN;
if (status_previous_ != status_) {
// Handle nominal events
@@ -147,54 +119,59 @@
status_previous_ = status_;
- } else {
- // Handle abnormal events
+ } else if (unexpected_event_timer_active_ == false) {
+ // Handle abnormal events at a minimum period
+
const float diff = fabsf(ssoc_ - gdf_);
if (fabsf(ssoc_ - ssoc_previous_) >= 2.0f) {
+ unexpected_event_timer_secs_ = getTimeSecs();
+ unexpected_event_timer_active_ = true;
log_reason = LOG_REASON_PERCENT_SKIP;
// Every +- 1% when above a 4% SOC difference (w/ timer)
} else if (static_cast<int>(round(ssoc_gdf_diff_previous_)) !=
static_cast<int>(round(diff)) &&
diff >= 4.0f) {
+ unexpected_event_timer_secs_ = getTimeSecs();
+ unexpected_event_timer_active_ = true;
log_reason = LOG_REASON_DIVERGING_FG;
ssoc_gdf_diff_previous_ = diff;
}
}
ssoc_previous_ = ssoc_;
+
log_reason_ = log_reason;
-
- if (log_reason != LOG_REASON_UNKNOWN) {
- /* Found new log event! */
- /* Check if we should actually report the event */
- return shouldReportEvent();
- }
-
- return false;
+ return (log_reason != LOG_REASON_UNKNOWN);
}
-void BatteryCapacityReporter::reportEvent(const std::shared_ptr<IStats> &stats_client) {
+void BatteryCapacityReporter::report(void) {
+ sp<IStats> stats_client = IStats::tryGetService();
+ if (!stats_client) {
+ ALOGD("Couldn't connect to IStats service");
+ return;
+ }
+
// Load values array
- std::vector<VendorAtomValue> values(5);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(log_reason_);
+ std::vector<VendorAtom::Value> values(5);
+ VendorAtom::Value tmp;
+ tmp.intValue(log_reason_);
values[BatteryCapacityFG::kCapacityLogReasonFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::floatValue>(gdf_);
+ tmp.floatValue(gdf_);
values[BatteryCapacityFG::kCapacityGdfFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::floatValue>(ssoc_);
+ tmp.floatValue(ssoc_);
values[BatteryCapacityFG::kCapacitySsocFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::floatValue>(gdf_curve_);
+ tmp.floatValue(gdf_curve_);
values[BatteryCapacityFG::kCapacityGdfCurveFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::floatValue>(ssoc_curve_);
+ tmp.floatValue(ssoc_curve_);
values[BatteryCapacityFG::kCapacitySsocCurveFieldNumber - kVendorAtomOffset] = tmp;
// Send vendor atom to IStats HAL
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kFgCapacity,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ .atomId = PixelAtoms::Ids::FG_CAPACITY,
+ .values = values};
+ Return<void> ret = stats_client->reportVendorAtom(event);
if (!ret.isOk())
ALOGE("Unable to report to IStats service");
}
diff --git a/pixelstats/BatteryEEPROMReporter.cpp b/pixelstats/BatteryEEPROMReporter.cpp
deleted file mode 100644
index 80140fa..0000000
--- a/pixelstats/BatteryEEPROMReporter.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2020 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 LOG_TAG "pixelstats: BatteryEEPROM"
-
-#include <log/log.h>
-#include <time.h>
-#include <utils/Timers.h>
-#include <cinttypes>
-#include <cmath>
-
-#include <android-base/file.h>
-#include <pixelstats/BatteryEEPROMReporter.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
-using android::base::ReadFileToString;
-using android::hardware::google::pixel::PixelAtoms::BatteryEEPROM;
-
-#define LINESIZE 71
-
-BatteryEEPROMReporter::BatteryEEPROMReporter() {}
-
-void BatteryEEPROMReporter::checkAndReport(const std::shared_ptr<IStats> &stats_client,
- const std::string &path) {
- std::string file_contents;
- std::string history_each;
-
- const int kSecondsPerMonth = 60 * 60 * 24 * 30;
- int64_t now = getTimeSecs();
-
- if ((report_time_ != 0) && (now - report_time_ < kSecondsPerMonth)) {
- ALOGD("Not upload time. now: %" PRId64 ", pre: %" PRId64, now, report_time_);
- return;
- }
-
- if (!ReadFileToString(path.c_str(), &file_contents)) {
- ALOGE("Unable to read %s - %s", path.c_str(), strerror(errno));
- return;
- }
- ALOGD("checkAndReport: %s", file_contents.c_str());
-
- int16_t i, num;
- struct BatteryHistory hist;
- const int kHistTotalLen = strlen(file_contents.c_str());
-
- for (i = 0; i < (LINESIZE * BATT_HIST_NUM_MAX); i = i + LINESIZE) {
- if (i + LINESIZE > kHistTotalLen)
- break;
- history_each = file_contents.substr(i, LINESIZE);
- num = sscanf(history_each.c_str(),
- "%4" SCNx16 "%4" SCNx16 "%4" SCNx16 "%4" SCNx16
- "%2" SCNx8 "%2" SCNx8 " %2" SCNx8 "%2" SCNx8
- "%2" SCNx8 "%2" SCNx8 " %2" SCNx8 "%2" SCNx8
- "%2" SCNx8 "%2" SCNx8 " %4" SCNx16 "%4" SCNx16
- "%4" SCNx16 "%4" SCNx16 "%4" SCNx16,
- &hist.cycle_cnt, &hist.full_cap, &hist.esr,
- &hist.rslow, &hist.batt_temp, &hist.soh,
- &hist.cc_soc, &hist.cutoff_soc, &hist.msoc,
- &hist.sys_soc, &hist.reserve, &hist.batt_soc,
- &hist.min_temp, &hist.max_temp, &hist.max_vbatt,
- &hist.min_vbatt, &hist.max_ibatt, &hist.min_ibatt,
- &hist.checksum);
-
- if (num != kNumBatteryHistoryFields) {
- ALOGE("Couldn't process %s", history_each.c_str());
- continue;
- }
-
- if (checkLogEvent(hist)) {
- reportEvent(stats_client, hist);
- report_time_ = getTimeSecs();
- }
- }
-}
-
-int64_t BatteryEEPROMReporter::getTimeSecs(void) {
- return nanoseconds_to_seconds(systemTime(SYSTEM_TIME_BOOTTIME));
-}
-
-/**
- * @return true if a log should be reported, else false.
- * Here we use checksum to confirm the data is usable or not.
- * The checksum mismatch when storage data overflow or corrupt.
- * We don't need data in such cases.
- */
-bool BatteryEEPROMReporter::checkLogEvent(struct BatteryHistory hist) {
- int checksum = 0;
-
- checksum = hist.cycle_cnt + hist.full_cap + hist.esr + hist.rslow
- + hist.soh + hist.batt_temp + hist.cutoff_soc + hist.cc_soc
- + hist.sys_soc + hist.msoc + hist.batt_soc + hist.reserve
- + hist.max_temp + hist.min_temp + hist.max_vbatt
- + hist.min_vbatt + hist.max_ibatt + hist.min_ibatt;
- /* Compare with checksum data */
- if (checksum == hist.checksum) {
- return true;
- } else {
- return false;
- }
-}
-
-void BatteryEEPROMReporter::reportEvent(const std::shared_ptr<IStats> &stats_client,
- const struct BatteryHistory &hist) {
- // upload atom
- const std::vector<int> eeprom_history_fields = {
- BatteryEEPROM::kCycleCntFieldNumber, BatteryEEPROM::kFullCapFieldNumber,
- BatteryEEPROM::kEsrFieldNumber, BatteryEEPROM::kRslowFieldNumber,
- BatteryEEPROM::kSohFieldNumber, BatteryEEPROM::kBattTempFieldNumber,
- BatteryEEPROM::kCutoffSocFieldNumber, BatteryEEPROM::kCcSocFieldNumber,
- BatteryEEPROM::kSysSocFieldNumber, BatteryEEPROM::kMsocFieldNumber,
- BatteryEEPROM::kBattSocFieldNumber, BatteryEEPROM::kReserveFieldNumber,
- BatteryEEPROM::kMaxTempFieldNumber, BatteryEEPROM::kMinTempFieldNumber,
- BatteryEEPROM::kMaxVbattFieldNumber, BatteryEEPROM::kMinVbattFieldNumber,
- BatteryEEPROM::kMaxIbattFieldNumber, BatteryEEPROM::kMinIbattFieldNumber,
- BatteryEEPROM::kChecksumFieldNumber};
-
- ALOGD("reportEvent: cycle_cnt:%d, full_cap:%d, esr:%d, rslow:%d, soh:%d, "
- "batt_temp:%d, cutoff_soc:%d, cc_soc:%d, sys_soc:%d, msoc:%d, "
- "batt_soc:%d, reserve:%d, max_temp:%d, min_temp:%d, max_vbatt:%d, "
- "min_vbatt:%d, max_ibatt:%d, min_ibatt:%d, checksum:%d",
- hist.cycle_cnt, hist.full_cap, hist.esr, hist.rslow, hist.soh, hist.batt_temp,
- hist.cutoff_soc, hist.cc_soc, hist.sys_soc, hist.msoc, hist.batt_soc, hist.reserve,
- hist.max_temp, hist.min_temp, hist.max_vbatt, hist.min_vbatt, hist.max_ibatt,
- hist.min_ibatt, hist.checksum);
-
- std::vector<VendorAtomValue> values(eeprom_history_fields.size());
- VendorAtomValue val;
-
- val.set<VendorAtomValue::intValue>(hist.cycle_cnt);
- values[BatteryEEPROM::kCycleCntFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.full_cap);
- values[BatteryEEPROM::kFullCapFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.esr);
- values[BatteryEEPROM::kEsrFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.rslow);
- values[BatteryEEPROM::kRslowFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.soh);
- values[BatteryEEPROM::kSohFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.batt_temp);
- values[BatteryEEPROM::kBattTempFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.cutoff_soc);
- values[BatteryEEPROM::kCutoffSocFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.cc_soc);
- values[BatteryEEPROM::kCcSocFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.sys_soc);
- values[BatteryEEPROM::kSysSocFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.msoc);
- values[BatteryEEPROM::kMsocFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.batt_soc);
- values[BatteryEEPROM::kBattSocFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.reserve);
- values[BatteryEEPROM::kReserveFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.max_temp);
- values[BatteryEEPROM::kMaxTempFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.min_temp);
- values[BatteryEEPROM::kMinTempFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.max_vbatt);
- values[BatteryEEPROM::kMaxVbattFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.min_vbatt);
- values[BatteryEEPROM::kMinVbattFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.max_ibatt);
- values[BatteryEEPROM::kMaxIbattFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.min_ibatt);
- values[BatteryEEPROM::kMinIbattFieldNumber - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::intValue>(hist.checksum);
- values[BatteryEEPROM::kChecksumFieldNumber - kVendorAtomOffset] = val;
-
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kBatteryEeprom,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- ALOGE("Unable to report BatteryEEPROM to Stats service");
-}
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/pixelstats/DropDetect.cpp b/pixelstats/DropDetect.cpp
index cfac324..1b1bb1c 100644
--- a/pixelstats/DropDetect.cpp
+++ b/pixelstats/DropDetect.cpp
@@ -19,23 +19,19 @@
#include <chre_host/host_protocol_host.h>
#include <chre_host/socket_client.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-#include <pixelstats/StatsHelper.h>
-
+#include <android/frameworks/stats/1.0/IStats.h>
#define LOG_TAG "pixelstats-vendor"
#include <log/log.h>
#include <inttypes.h>
#include <math.h>
-using aidl::android::frameworks::stats::IStats;
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
using android::sp;
using android::chre::HostProtocolHost;
using android::chre::IChreMessageHandlers;
using android::chre::SocketClient;
-using android::hardware::google::pixel::PixelAtoms::VendorPhysicalDropDetected;
+using android::frameworks::stats::V1_0::IStats;
+using android::frameworks::stats::V1_0::PhysicalDropDetected;
// following convention of CHRE code.
namespace fbs = ::chre::fbs;
@@ -73,14 +69,12 @@
kDropEventDetectionV2 = 6,
};
-void requestNanoappList(SocketClient *client) {
- if (client != nullptr) {
- flatbuffers::FlatBufferBuilder builder(64);
- HostProtocolHost::encodeNanoappListRequest(builder);
+void requestNanoappList(SocketClient &client) {
+ flatbuffers::FlatBufferBuilder builder(64);
+ HostProtocolHost::encodeNanoappListRequest(builder);
- if (!client->sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
- ALOGE("Failed to send NanoappList request");
- }
+ if (!client.sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
+ ALOGE("Failed to send NanoappList request");
}
}
@@ -98,7 +92,7 @@
}
void DropDetect::onConnected() {
- requestNanoappList(this);
+ requestNanoappList(*this);
}
/**
@@ -128,7 +122,7 @@
ALOGE("Drop Detect app not found");
}
-static VendorPhysicalDropDetected dropEventFromNanoappPayload(const struct DropEventPayload *p) {
+static PhysicalDropDetected dropEventFromNanoappPayload(const struct DropEventPayload *p) {
ALOGI("Received drop detect message! Confidence %f Peak %f Duration %g",
p->confidence, p->accel_magnitude_peak, p->free_fall_duration_ns / 1e9);
@@ -138,14 +132,12 @@
int32_t accel_magnitude_peak_1000ths_g = p->accel_magnitude_peak * 1000.0;
int32_t free_fall_duration_ms = p->free_fall_duration_ns / 1000000;
- VendorPhysicalDropDetected drop_info;
- drop_info.set_confidence_pctg(confidence);
- drop_info.set_accel_peak_thousandths_g(accel_magnitude_peak_1000ths_g);
- drop_info.set_freefall_time_millis(free_fall_duration_ms);
- return drop_info;
+ return PhysicalDropDetected{ confidence,
+ accel_magnitude_peak_1000ths_g,
+ free_fall_duration_ms };
}
-static VendorPhysicalDropDetected dropEventFromNanoappPayload(const struct DropEventPayloadV2 *p) {
+static PhysicalDropDetected dropEventFromNanoappPayload(const struct DropEventPayloadV2 *p) {
ALOGI("Received drop detect message: "
"duration %g ms, impact acceleration: x = %f, y = %f, z = %f",
p->free_fall_duration_ns / 1e6,
@@ -167,21 +159,22 @@
int32_t free_fall_duration_ms = static_cast<int32_t>(p->free_fall_duration_ns / 1000000);
- VendorPhysicalDropDetected drop_info;
- drop_info.set_confidence_pctg(confidence_percentage);
- drop_info.set_accel_peak_thousandths_g(static_cast<int32_t>(impact_magnitude * 1000));
- drop_info.set_freefall_time_millis(free_fall_duration_ms);
- return drop_info;
+ return PhysicalDropDetected{
+ .confidencePctg = confidence_percentage,
+ .accelPeak = static_cast<int32_t>(impact_magnitude * 1000),
+ .freefallDuration = free_fall_duration_ms,
+ };
}
-static void reportDropEventToStatsd(const VendorPhysicalDropDetected &drop) {
- const std::shared_ptr<IStats> stats_client = getStatsService();
+static void reportDropEventToStatsd(const PhysicalDropDetected& drop) {
+ sp<IStats> stats_client = IStats::tryGetService();
if (!stats_client) {
- ALOGE("Unable to get AIDL Stats service");
- return;
+ ALOGE("Unable to connect to Stats service");
+ } else {
+ Return<void> ret = stats_client->reportPhysicalDropDetected(drop);
+ if (!ret.isOk())
+ ALOGE("Unable to report physical drop to Stats service");
}
-
- reportPhysicalDropDetected(stats_client, drop);
}
/**
diff --git a/pixelstats/MitigationStatsReporter.cpp b/pixelstats/MitigationStatsReporter.cpp
deleted file mode 100644
index 82ad15f..0000000
--- a/pixelstats/MitigationStatsReporter.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2021 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 LOG_TAG "pixelstats: PowerMitigationStats"
-
-#include <aidl/android/frameworks/stats/IStats.h>
-#include <android-base/file.h>
-#include <android-base/parseint.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android/binder_manager.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-#include <pixelstats/MitigationStatsReporter.h>
-#include <utils/Log.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using aidl::android::frameworks::stats::IStats;
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
-using android::base::ReadFileToString;
-using android::hardware::google::pixel::PixelAtoms::PowerMitigationStats;
-
-MitigationStatsReporter::MitigationStatsReporter() {}
-
-bool MitigationStatsReporter::ReadFileToInt(const std::string &path, int *val) {
- std::string file_contents;
-
- if (!ReadFileToString(path.c_str(), &file_contents)) {
- ALOGI("Unable to read %s - %s", path.c_str(), strerror(errno));
- return false;
- } else {
- file_contents = android::base::Trim(file_contents);
- if (!android::base::ParseInt(file_contents, val)) {
- ALOGI("Unable to convert %s to int - %s", path.c_str(), strerror(errno));
- return false;
- }
- }
- return true;
-}
-
-void MitigationStatsReporter::logMitigationStatsPerHour(const std::shared_ptr<IStats> &stats_client,
- const std::string &path) {
- struct MitigationCount last_count = {};
- struct MitigationCap last_cap = {};
-
- if (!logMitigationCount(path, &last_count))
- return;
- logMitigationCap(path, &last_cap);
-
- VendorAtomValue tmp;
- std::vector<VendorAtomValue> values(24);
- tmp.set<VendorAtomValue::intValue>(last_count.batoilo_count - prev_count.batoilo_count);
- values[PowerMitigationStats::kBatoiloCountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.vdroop1_count - prev_count.vdroop1_count);
- values[PowerMitigationStats::kVdroop1CountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.vdroop2_count - prev_count.vdroop2_count);
- values[PowerMitigationStats::kVdroop2CountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.smpl_warn_count - prev_count.smpl_warn_count);
- values[PowerMitigationStats::kSmplWarnCountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.ocp_cpu1_count - prev_count.ocp_cpu1_count);
- values[PowerMitigationStats::kOcpCpu1CountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.ocp_cpu2_count - prev_count.ocp_cpu2_count);
- values[PowerMitigationStats::kOcpCpu2CountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.ocp_gpu_count - prev_count.ocp_gpu_count);
- values[PowerMitigationStats::kOcpGpuCountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.ocp_tpu_count - prev_count.ocp_tpu_count);
- values[PowerMitigationStats::kOcpTpuCountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_cpu1_count -
- prev_count.soft_ocp_cpu1_count);
- values[PowerMitigationStats::kSoftOcpCpu1CountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_cpu2_count -
- prev_count.soft_ocp_cpu2_count);
- values[PowerMitigationStats::kSoftOcpCpu2CountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_gpu_count -
- prev_count.soft_ocp_gpu_count);
- values[PowerMitigationStats::kSoftOcpGpuCountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_tpu_count -
- prev_count.soft_ocp_tpu_count);
- values[PowerMitigationStats::kSoftOcpTpuCountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.batoilo_cap);
- values[PowerMitigationStats::kBatoiloCapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.vdroop1_cap);
- values[PowerMitigationStats::kVdroop1CapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.vdroop2_cap);
- values[PowerMitigationStats::kVdroop2CapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.smpl_warn_cap);
- values[PowerMitigationStats::kSmplWarnCapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.ocp_cpu1_cap);
- values[PowerMitigationStats::kOcpCpu1CapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.ocp_cpu2_cap);
- values[PowerMitigationStats::kOcpCpu2CapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.ocp_gpu_cap);
- values[PowerMitigationStats::kOcpGpuCapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.ocp_tpu_cap);
- values[PowerMitigationStats::kOcpTpuCapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_cpu1_cap);
- values[PowerMitigationStats::kSoftOcpCpu1CapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_cpu2_cap);
- values[PowerMitigationStats::kSoftOcpCpu2CapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_gpu_cap);
- values[PowerMitigationStats::kSoftOcpGpuCapFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_tpu_cap);
- values[PowerMitigationStats::kSoftOcpTpuCapFieldNumber - kVendorAtomOffset] = tmp;
-
- prev_count = last_count;
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kMitigationStats,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- ALOGE("Unable to report to Stats service");
-}
-
-void MitigationStatsReporter::logMitigationCap(const std::string kMitigationDir,
- struct MitigationCap *last_cap) {
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/batoilo_cap",
- &(last_cap->batoilo_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_cpu1_cap",
- &(last_cap->ocp_cpu1_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_cpu2_cap",
- &(last_cap->ocp_cpu2_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_gpu_cap",
- &(last_cap->ocp_gpu_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_tpu_cap",
- &(last_cap->ocp_tpu_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/smpl_warn_cap",
- &(last_cap->smpl_warn_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_cpu1_cap",
- &(last_cap->soft_ocp_cpu1_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_cpu2_cap",
- &(last_cap->soft_ocp_cpu2_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_gpu_cap",
- &(last_cap->soft_ocp_gpu_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_tpu_cap",
- &(last_cap->soft_ocp_tpu_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/vdroop1_cap",
- &(last_cap->vdroop1_cap));
- ReadFileToInt(kMitigationDir + "/last_triggered_capacity/vdroop2_cap",
- &(last_cap->vdroop2_cap));
-}
-
-bool MitigationStatsReporter::logMitigationCount(const std::string kMitigationDir,
- struct MitigationCount *last_count) {
- bool send_stats = false;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/batoilo_count",
- &(last_count->batoilo_count)))
- return false;
- send_stats |= (last_count->batoilo_count - prev_count.batoilo_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_cpu1_count",
- &(last_count->ocp_cpu1_count)))
- return false;
- send_stats |= (last_count->ocp_cpu1_count - prev_count.ocp_cpu1_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_cpu2_count",
- &(last_count->ocp_cpu2_count)))
- return false;
- send_stats |= (last_count->ocp_cpu2_count - prev_count.ocp_cpu2_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_gpu_count",
- &(last_count->ocp_gpu_count)))
- return false;
- send_stats |= (last_count->ocp_gpu_count - prev_count.ocp_gpu_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_tpu_count",
- &(last_count->ocp_tpu_count)))
- return false;
- send_stats |= (last_count->ocp_tpu_count - prev_count.ocp_tpu_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/smpl_warn_count",
- &(last_count->smpl_warn_count)))
- return false;
- send_stats |= (last_count->smpl_warn_count - prev_count.smpl_warn_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_cpu1_count",
- &(last_count->soft_ocp_cpu1_count)))
- return false;
- send_stats |= (last_count->soft_ocp_cpu1_count - prev_count.soft_ocp_cpu1_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_cpu2_count",
- &(last_count->soft_ocp_cpu2_count)))
- return false;
- send_stats |= (last_count->soft_ocp_cpu2_count - prev_count.soft_ocp_cpu2_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_gpu_count",
- &(last_count->soft_ocp_gpu_count)))
- return false;
- send_stats |= (last_count->soft_ocp_gpu_count - prev_count.soft_ocp_gpu_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_tpu_count",
- &(last_count->soft_ocp_tpu_count)))
- return false;
- send_stats |= (last_count->soft_ocp_tpu_count - prev_count.soft_ocp_tpu_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/vdroop1_count",
- &(last_count->vdroop1_count)))
- return false;
- send_stats |= (last_count->vdroop1_count - prev_count.vdroop1_count) > 0;
- if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/vdroop2_count",
- &(last_count->vdroop2_count)))
- return false;
- send_stats |= (last_count->vdroop2_count - prev_count.vdroop2_count) > 0;
- return send_stats;
-}
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/pixelstats/MmMetricsReporter.cpp b/pixelstats/MmMetricsReporter.cpp
deleted file mode 100644
index 29d3dfe..0000000
--- a/pixelstats/MmMetricsReporter.cpp
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * Copyright (C) 2021 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 LOG_TAG "pixelstats: MmMetrics"
-
-#include <aidl/android/frameworks/stats/IStats.h>
-#include <android-base/file.h>
-#include <android-base/parseint.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android/binder_manager.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-#include <pixelstats/MmMetricsReporter.h>
-#include <utils/Log.h>
-
-#define SZ_4K 0x00001000
-#define SZ_2M 0x00200000
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using aidl::android::frameworks::stats::IStats;
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
-using android::base::ReadFileToString;
-using android::base::StartsWith;
-using android::hardware::google::pixel::PixelAtoms::CmaStatus;
-using android::hardware::google::pixel::PixelAtoms::CmaStatusExt;
-using android::hardware::google::pixel::PixelAtoms::PixelMmMetricsPerDay;
-using android::hardware::google::pixel::PixelAtoms::PixelMmMetricsPerHour;
-
-const std::vector<MmMetricsReporter::MmMetricsInfo> MmMetricsReporter::kMmMetricsPerHourInfo = {
- {"nr_free_pages", PixelMmMetricsPerHour::kFreePagesFieldNumber, false},
- {"nr_anon_pages", PixelMmMetricsPerHour::kAnonPagesFieldNumber, false},
- {"nr_file_pages", PixelMmMetricsPerHour::kFilePagesFieldNumber, false},
- {"nr_slab_reclaimable", PixelMmMetricsPerHour::kSlabReclaimableFieldNumber, false},
- {"nr_zspages", PixelMmMetricsPerHour::kZspagesFieldNumber, false},
- {"nr_unevictable", PixelMmMetricsPerHour::kUnevictableFieldNumber, false},
-};
-
-const std::vector<MmMetricsReporter::MmMetricsInfo> MmMetricsReporter::kMmMetricsPerDayInfo = {
- {"workingset_refault", PixelMmMetricsPerDay::kWorkingsetRefaultFieldNumber, true},
- {"workingset_refault_file", PixelMmMetricsPerDay::kWorkingsetRefaultFieldNumber, true},
- {"pswpin", PixelMmMetricsPerDay::kPswpinFieldNumber, true},
- {"pswpout", PixelMmMetricsPerDay::kPswpoutFieldNumber, true},
- {"allocstall_dma", PixelMmMetricsPerDay::kAllocstallDmaFieldNumber, true},
- {"allocstall_dma32", PixelMmMetricsPerDay::kAllocstallDma32FieldNumber, true},
- {"allocstall_normal", PixelMmMetricsPerDay::kAllocstallNormalFieldNumber, true},
- {"allocstall_movable", PixelMmMetricsPerDay::kAllocstallMovableFieldNumber, true},
- {"pgalloc_dma", PixelMmMetricsPerDay::kPgallocDmaFieldNumber, true},
- {"pgalloc_dma32", PixelMmMetricsPerDay::kPgallocDma32FieldNumber, true},
- {"pgalloc_normal", PixelMmMetricsPerDay::kPgallocNormalFieldNumber, true},
- {"pgalloc_movable", PixelMmMetricsPerDay::kPgallocMovableFieldNumber, true},
- {"pgsteal_kswapd", PixelMmMetricsPerDay::kPgstealKswapdFieldNumber, true},
- {"pgsteal_direct", PixelMmMetricsPerDay::kPgstealDirectFieldNumber, true},
- {"pgscan_kswapd", PixelMmMetricsPerDay::kPgscanKswapdFieldNumber, true},
- {"pgscan_direct", PixelMmMetricsPerDay::kPgscanDirectFieldNumber, true},
- {"oom_kill", PixelMmMetricsPerDay::kOomKillFieldNumber, true},
- {"pgalloc_costly_order", PixelMmMetricsPerDay::kPgallocHighFieldNumber, true},
- {"pgcache_hit", PixelMmMetricsPerDay::kPgcacheHitFieldNumber, true},
- {"pgcache_miss", PixelMmMetricsPerDay::kPgcacheMissFieldNumber, true},
-};
-
-const std::vector<MmMetricsReporter::MmMetricsInfo> MmMetricsReporter::kCmaStatusInfo = {
- {"alloc_pages_attempts", CmaStatus::kCmaAllocPagesAttemptsFieldNumber, true},
- {"alloc_pages_failfast_attempts", CmaStatus::kCmaAllocPagesSoftAttemptsFieldNumber, true},
- {"fail_pages", CmaStatus::kCmaFailPagesFieldNumber, true},
- {"fail_failfast_pages", CmaStatus::kCmaFailSoftPagesFieldNumber, true},
- {"migrated_pages", CmaStatus::kMigratedPagesFieldNumber, true},
-};
-
-const std::vector<MmMetricsReporter::MmMetricsInfo> MmMetricsReporter::kCmaStatusExtInfo = {
- {"latency_low", CmaStatusExt::kCmaAllocLatencyLowFieldNumber, false},
- {"latency_mid", CmaStatusExt::kCmaAllocLatencyMidFieldNumber, false},
- {"latency_high", CmaStatusExt::kCmaAllocLatencyHighFieldNumber, false},
-};
-
-const std::map<std::string, MmMetricsReporter::CmaType> MmMetricsReporter::kCmaTypeInfo = {
- {"farawimg", MmMetricsReporter::FARAWIMG}, {"faimg", MmMetricsReporter::FAIMG},
- {"faceauth_tpu", MmMetricsReporter::FATPU}, {"faprev", MmMetricsReporter::FAPREV},
- {"vframe", MmMetricsReporter::VFRAME}, {"vstream", MmMetricsReporter::VSTREAM},
-};
-
-MmMetricsReporter::MmMetricsReporter()
- : kVmstatPath("/proc/vmstat"),
- kIonTotalPoolsPath("/sys/kernel/dma_heap/total_pools_kb"),
- kIonTotalPoolsPathForLegacy("/sys/kernel/ion/total_pools_kb"),
- kGpuTotalPages("/sys/kernel/pixel_stat/gpu/mem/total_page_count"),
- kPixelStatMm("/sys/kernel/pixel_stat/mm") {}
-
-bool MmMetricsReporter::ReadFileToUint(const char *const path, uint64_t *val) {
- std::string file_contents;
-
- if (!ReadFileToString(path, &file_contents)) {
- ALOGI("Unable to read %s - %s", path, strerror(errno));
- return false;
- } else {
- file_contents = android::base::Trim(file_contents);
- if (!android::base::ParseUint(file_contents, val)) {
- ALOGI("Unable to convert %s to uint - %s", path, strerror(errno));
- return false;
- }
- }
- return true;
-}
-
-bool MmMetricsReporter::reportVendorAtom(const std::shared_ptr<IStats> &stats_client, int atom_id,
- const std::vector<VendorAtomValue> &values,
- const std::string &atom_name) {
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = atom_id,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk()) {
- ALOGE("Unable to report %s to Stats service", atom_name.c_str());
- return false;
- }
- return true;
-}
-
-/**
- * Parse the output of /proc/vmstat or the sysfs having the same output format.
- * The map containing pairs of {field_string, data} will be returned.
- */
-std::map<std::string, uint64_t> MmMetricsReporter::readVmStat(const char *path) {
- std::string file_contents;
- std::map<std::string, uint64_t> vmstat_data;
-
- if (path == nullptr) {
- ALOGI("vmstat path is not specified");
- return vmstat_data;
- }
-
- if (!ReadFileToString(path, &file_contents)) {
- ALOGE("Unable to read vmstat from %s, err: %s", path, strerror(errno));
- return vmstat_data;
- }
-
- std::istringstream data(file_contents);
- std::string line;
- while (std::getline(data, line)) {
- std::vector<std::string> words = android::base::Split(line, " ");
- if (words.size() != 2)
- continue;
-
- uint64_t i;
- if (!android::base::ParseUint(words[1], &i))
- continue;
-
- vmstat_data[words[0]] = i;
- }
- return vmstat_data;
-}
-
-uint64_t MmMetricsReporter::getIonTotalPools() {
- uint64_t res;
-
- if (!ReadFileToUint(kIonTotalPoolsPathForLegacy, &res) || (res == 0)) {
- if (!ReadFileToUint(kIonTotalPoolsPath, &res)) {
- return 0;
- }
- }
-
- return res;
-}
-
-/**
- * Collect GPU memory from kGpuTotalPages and return the total number of 4K page.
- */
-uint64_t MmMetricsReporter::getGpuMemory() {
- uint64_t gpu_size = 0;
-
- if (!ReadFileToUint(kGpuTotalPages, &gpu_size)) {
- return 0;
- }
- return gpu_size;
-}
-
-/**
- * fillAtomValues() is used to copy Mm metrics to values
- * metrics_info: This is a vector of MmMetricsInfo {field_string, atom_key, update_diff}
- * field_string is used to get the data from mm_metrics.
- * atom_key is the position where the data should be put into values.
- * update_diff will be true if this is an accumulated data.
- * metrics_info may have multiple entries with the same atom_key,
- * e.g. workingset_refault and workingset_refault_file.
- * mm_metrics: This map contains pairs of {field_string, cur_value} collected
- * from /proc/vmstat or the sysfs for the pixel specific metrics.
- * e.g. {"nr_free_pages", 200000}
- * Some data in mm_metrics are accumulated, e.g. pswpin.
- * We upload the difference instead of the accumulated value
- * when update_diff of the field is true.
- * prev_mm_metrics: The pointer to the metrics we collected last time.
- * atom_values: The atom values that will be reported later.
- */
-void MmMetricsReporter::fillAtomValues(const std::vector<MmMetricsInfo> &metrics_info,
- const std::map<std::string, uint64_t> &mm_metrics,
- std::map<std::string, uint64_t> *prev_mm_metrics,
- std::vector<VendorAtomValue> *atom_values) {
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::longValue>(0);
- // resize atom_values to add all fields defined in metrics_info
- int max_idx = 0;
- for (auto &entry : metrics_info) {
- if (max_idx < entry.atom_key)
- max_idx = entry.atom_key;
- }
- int size = max_idx - kVendorAtomOffset + 1;
- if (atom_values->size() < size)
- atom_values->resize(size, tmp);
-
- for (auto &entry : metrics_info) {
- int atom_idx = entry.atom_key - kVendorAtomOffset;
-
- auto data = mm_metrics.find(entry.name);
- if (data == mm_metrics.end())
- continue;
-
- uint64_t cur_value = data->second;
- uint64_t prev_value = 0;
- if (prev_mm_metrics->size() != 0) {
- auto prev_data = prev_mm_metrics->find(entry.name);
- if (prev_data != prev_mm_metrics->end())
- prev_value = prev_data->second;
- }
-
- if (entry.update_diff) {
- tmp.set<VendorAtomValue::longValue>(cur_value - prev_value);
- } else {
- tmp.set<VendorAtomValue::longValue>(cur_value);
- }
- (*atom_values)[atom_idx] = tmp;
- }
- (*prev_mm_metrics) = mm_metrics;
-}
-
-void MmMetricsReporter::logPixelMmMetricsPerHour(const std::shared_ptr<IStats> &stats_client) {
- // Currently, we collect these metrics and report this atom only for userdebug_or_eng
- // We only grant permissions to access sysfs for userdebug_or_eng.
- // Add a check to avoid unnecessary access.
- if (android::base::GetProperty("ro.build.type", "") == "user")
- return;
-
- std::map<std::string, uint64_t> vmstat = readVmStat(kVmstatPath);
- if (vmstat.size() == 0)
- return;
-
- uint64_t ion_total_pools = getIonTotalPools();
- uint64_t gpu_memory = getGpuMemory();
-
- std::vector<VendorAtomValue> values;
- bool is_first_atom = (prev_hour_vmstat_.size() == 0) ? true : false;
- fillAtomValues(kMmMetricsPerHourInfo, vmstat, &prev_hour_vmstat_, &values);
-
- // resize values to add the following fields
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::longValue>(0);
- int size = PixelMmMetricsPerHour::kGpuMemoryFieldNumber - kVendorAtomOffset + 1;
- if (values.size() < size) {
- values.resize(size, tmp);
- }
- tmp.set<VendorAtomValue::longValue>(ion_total_pools);
- values[PixelMmMetricsPerHour::kIonTotalPoolsFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::longValue>(gpu_memory);
- values[PixelMmMetricsPerHour::kGpuMemoryFieldNumber - kVendorAtomOffset] = tmp;
-
- // Don't report the first atom to avoid big spike in accumulated values.
- if (!is_first_atom) {
- // Send vendor atom to IStats HAL
- reportVendorAtom(stats_client, PixelAtoms::Atom::kPixelMmMetricsPerHour, values,
- "PixelMmMetricsPerHour");
- }
-}
-
-void MmMetricsReporter::logPixelMmMetricsPerDay(const std::shared_ptr<IStats> &stats_client) {
- // Currently, we collect these metrics and report this atom only for userdebug_or_eng
- // We only grant permissions to access sysfs for userdebug_or_eng.
- // Add a check to avoid unnecessary access.
- if (android::base::GetProperty("ro.build.type", "") == "user")
- return;
-
- std::map<std::string, uint64_t> vmstat = readVmStat(kVmstatPath);
- if (vmstat.size() == 0)
- return;
-
- std::vector<VendorAtomValue> values;
- bool is_first_atom = (prev_day_vmstat_.size() == 0) ? true : false;
- fillAtomValues(kMmMetricsPerDayInfo, vmstat, &prev_day_vmstat_, &values);
-
- std::map<std::string, uint64_t> pixel_vmstat =
- readVmStat(android::base::StringPrintf("%s/vmstat", kPixelStatMm).c_str());
- fillAtomValues(kMmMetricsPerDayInfo, pixel_vmstat, &prev_day_pixel_vmstat_, &values);
- fillProcessStime(PixelMmMetricsPerDay::kKswapdStimeClksFieldNumber, "kswapd0", &kswapd_pid_,
- &prev_kswapd_stime_, &values);
- fillProcessStime(PixelMmMetricsPerDay::kKcompactdStimeClksFieldNumber, "kcompactd0",
- &kcompactd_pid_, &prev_kcompactd_stime_, &values);
-
- // Don't report the first atom to avoid big spike in accumulated values.
- if (!is_first_atom) {
- // Send vendor atom to IStats HAL
- reportVendorAtom(stats_client, PixelAtoms::Atom::kPixelMmMetricsPerDay, values,
- "PixelMmMetricsPerDay");
- }
-}
-
-/**
- * Check if /proc/<pid>/comm is equal to name.
- */
-bool MmMetricsReporter::isValidPid(int pid, const char *name) {
- if (pid <= 0)
- return false;
-
- std::string file_contents;
- std::string path = android::base::StringPrintf("/proc/%d/comm", pid);
- if (!ReadFileToString(path, &file_contents)) {
- ALOGI("Unable to read %s, err: %s", path.c_str(), strerror(errno));
- return false;
- }
-
- file_contents = android::base::Trim(file_contents);
- return !file_contents.compare(name);
-}
-
-/**
- * Return pid if /proc/<pid>/comm is equal to name, or -1 if not found.
- */
-int MmMetricsReporter::findPidByProcessName(const char *name) {
- std::unique_ptr<DIR, int (*)(DIR *)> dir(opendir("/proc"), closedir);
- if (!dir)
- return -1;
-
- int pid;
- while (struct dirent *dp = readdir(dir.get())) {
- if (dp->d_type != DT_DIR)
- continue;
-
- if (!android::base::ParseInt(dp->d_name, &pid))
- continue;
-
- // Avoid avc denial since pixelstats-vendor doesn't have the permission to access /proc/1
- if (pid == 1)
- continue;
-
- std::string file_contents;
- std::string path = android::base::StringPrintf("/proc/%s/comm", dp->d_name);
- if (!ReadFileToString(path, &file_contents))
- continue;
-
- file_contents = android::base::Trim(file_contents);
- if (file_contents.compare(name))
- continue;
-
- return pid;
- }
- return -1;
-}
-
-/**
- * Get stime of a process from /proc/<pid>/stat
- * stime is the 15th field.
- */
-uint64_t MmMetricsReporter::getStimeByPid(int pid) {
- const int stime_idx = 15;
- uint64_t stime;
- std::string file_contents;
- std::string path = android::base::StringPrintf("/proc/%d/stat", pid);
- if (!ReadFileToString(path, &file_contents)) {
- ALOGI("Unable to read %s, err: %s", path.c_str(), strerror(errno));
- return false;
- }
-
- std::vector<std::string> data = android::base::Split(file_contents, " ");
- if (data.size() < stime_idx) {
- ALOGI("Unable to find stime from %s. size: %lu", path.c_str(), data.size());
- return false;
- }
-
- if (android::base::ParseUint(data[stime_idx - 1], &stime))
- return stime;
- else
- return 0;
-}
-
-/**
- * Find stime of the process and copy it into atom_values
- * atom_key: Currently, it can only be kKswapdTimeFieldNumber or kKcompactdTimeFieldNumber
- * name: process name
- * pid: The pid of the process. It would be the pid we found last time,
- * or -1 if not found.
- * prev_stime: The stime of the process collected last time.
- * atom_values: The atom we will report later.
- */
-void MmMetricsReporter::fillProcessStime(int atom_key, const char *name, int *pid,
- uint64_t *prev_stime,
- std::vector<VendorAtomValue> *atom_values) {
- // resize atom_values if there is no space for this stime field.
- int atom_idx = atom_key - kVendorAtomOffset;
- int size = atom_idx + 1;
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::longValue>(0);
- if (atom_values->size() < size)
- atom_values->resize(size, tmp);
-
- if (!isValidPid(*pid, name)) {
- (*pid) = findPidByProcessName(name);
- if ((*pid) <= 0) {
- ALOGI("Unable to find pid of %s, err: %s", name, strerror(errno));
- return;
- }
- }
-
- uint64_t stime = getStimeByPid(*pid);
- tmp.set<VendorAtomValue::longValue>(stime - *prev_stime);
- (*atom_values)[atom_idx] = tmp;
- (*prev_stime) = stime;
-}
-
-/**
- * Collect CMA metrics from kPixelStatMm/cma/<cma_type>/<metric>
- * cma_type: CMA heap name
- * metrics_info: This is a vector of MmMetricsInfo {metric, atom_key, update_diff}.
- * Currently, we only collect CMA metrics defined in metrics_info
- */
-std::map<std::string, uint64_t> MmMetricsReporter::readCmaStat(
- const std::string &cma_type,
- const std::vector<MmMetricsReporter::MmMetricsInfo> &metrics_info) {
- uint64_t file_contents;
- std::map<std::string, uint64_t> cma_stat;
- for (auto &entry : metrics_info) {
- std::string path = android::base::StringPrintf("%s/cma/%s/%s", kPixelStatMm,
- cma_type.c_str(), entry.name.c_str());
- if (!ReadFileToUint(path.c_str(), &file_contents))
- continue;
- cma_stat[entry.name] = file_contents;
- }
- return cma_stat;
-}
-
-/**
- * This function is to collect CMA metrics and upload them.
- * The CMA metrics are collected by readCmaStat(), copied into atom values
- * by fillAtomValues(), and then uploaded by reportVendorAtom(). The collected
- * metrics will be stored in prev_cma_stat_ and prev_cma_stat_ext_ according
- * to its CmaType.
- *
- * stats_client: The Stats service
- * atom_id: The id of atom. It can be PixelAtoms::Atom::kCmaStatus or kCmaStatusExt
- * cma_type: The name of CMA heap. We only collect metrics from CMA heaps defined
- * in kCmaTypeInfo.
- * type_idx: The id of the CMA heap. We add this id in atom values to identify
- * the CMA status data.
- * metrics_info: This is a vector of MmMetricsInfo {metric, atom_key, update_diff}.
- * We only collect metrics defined in metrics_info from CMA heap path.
- * all_prev_cma_stat: This is the CMA status collected last time.
- * It is a map containing pairs of {type_idx, cma_stat}, and cma_stat is
- * a map contains pairs of {metric, cur_value}.
- * e.g. {CmaType::FARAWIMG, {"alloc_pages_attempts", 100000}, {...}, ....}
- * is collected from kPixelStatMm/cma/farawimg/alloc_pages_attempts
- */
-void MmMetricsReporter::reportCmaStatusAtom(
- const std::shared_ptr<IStats> &stats_client, int atom_id, const std::string &cma_type,
- CmaType type_idx, const std::vector<MmMetricsInfo> &metrics_info,
- std::map<CmaType, std::map<std::string, uint64_t>> *all_prev_cma_stat) {
- std::map<std::string, uint64_t> cma_stat = readCmaStat(cma_type, metrics_info);
- if (!cma_stat.empty()) {
- std::vector<VendorAtomValue> values;
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(type_idx);
- values.push_back(tmp);
-
- std::map<std::string, uint64_t> prev_cma_stat;
- auto entry = all_prev_cma_stat->find(type_idx);
- if (entry != all_prev_cma_stat->end())
- prev_cma_stat = entry->second;
-
- bool is_first_atom = (prev_cma_stat.size() == 0) ? true : false;
- fillAtomValues(metrics_info, cma_stat, &prev_cma_stat, &values);
- (*all_prev_cma_stat)[type_idx] = prev_cma_stat;
- if (!is_first_atom)
- reportVendorAtom(stats_client, atom_id, values, "CmaStatus");
- }
-}
-
-/**
- * Find the CMA heap defined in kCmaTypeInfo, and then call reportCmaStatusAtom()
- * to collect the CMA metrics from kPixelStatMm/cma/<cma_type> and upload them.
- */
-void MmMetricsReporter::logCmaStatus(const std::shared_ptr<IStats> &stats_client) {
- std::string cma_root = android::base::StringPrintf("%s/cma", kPixelStatMm);
- std::unique_ptr<DIR, int (*)(DIR *)> dir(opendir(cma_root.c_str()), closedir);
- if (!dir)
- return;
-
- while (struct dirent *dp = readdir(dir.get())) {
- if (dp->d_type != DT_DIR)
- continue;
-
- std::string cma_type(dp->d_name);
- auto type = kCmaTypeInfo.find(cma_type);
- if (type == kCmaTypeInfo.end())
- continue;
-
- reportCmaStatusAtom(stats_client, PixelAtoms::Atom::kCmaStatus, cma_type, type->second,
- kCmaStatusInfo, &prev_cma_stat_);
- reportCmaStatusAtom(stats_client, PixelAtoms::Atom::kCmaStatusExt, cma_type, type->second,
- kCmaStatusExtInfo, &prev_cma_stat_ext_);
- }
-}
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/pixelstats/OrientationCollector.cpp b/pixelstats/OrientationCollector.cpp
index b33d3c6..2647a06 100644
--- a/pixelstats/OrientationCollector.cpp
+++ b/pixelstats/OrientationCollector.cpp
@@ -129,9 +129,7 @@
void OrientationCollector::disableOrientationSensor() {
if (mSensorManager != nullptr && mQueue != nullptr) {
- if (mOrientationSensor != nullptr) {
- ASensorEventQueue_disableSensor(mQueue, mOrientationSensor);
- }
+ ASensorEventQueue_disableSensor(mQueue, mOrientationSensor);
ASensorManager_destroyEventQueue(mSensorManager, mQueue);
}
}
diff --git a/pixelstats/PcaChargeStats.cpp b/pixelstats/PcaChargeStats.cpp
deleted file mode 100644
index b81e423..0000000
--- a/pixelstats/PcaChargeStats.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2021 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 LOG_TAG "pixelstats-uevent"
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-#include <log/log.h>
-#include <pixelstats/PcaChargeStats.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using android::base::ReadFileToString;
-using android::base::WriteStringToFile;
-
-bool PcaChargeStats::CheckPcaContentsAndAck(std::string *file_contents) {
- std::string line;
- std::istringstream ss;
-
- if (!ReadFileToString(kPcaChargeMetricsPath.c_str(), file_contents)) {
- return false;
- }
-
- ss.str(*file_contents);
-
- if (!std::getline(ss, line)) {
- ALOGE("Unable to read first line %s - %s", kPcaChargeMetricsPath.c_str(), strerror(errno));
- return false;
- }
- if (!WriteStringToFile(std::to_string(0), kPcaChargeMetricsPath.c_str())) {
- ALOGE("Couldn't clear %s - %s", kPcaChargeMetricsPath.c_str(), strerror(errno));
- return false;
- }
- return true;
-}
-
-PcaChargeStats::PcaChargeStats(const std::string pca_charge_metrics_path)
- : kPcaChargeMetricsPath(pca_charge_metrics_path) {}
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/pixelstats/StatsHelper.cpp b/pixelstats/StatsHelper.cpp
deleted file mode 100644
index e41ef8a..0000000
--- a/pixelstats/StatsHelper.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include <android/binder_manager.h>
-#include <pixelstats/StatsHelper.h>
-
-#define LOG_TAG "pixelstats-vendor"
-
-#include <utils/Log.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
-
-// Proto messages are 1-indexed and VendorAtom field numbers start at 2, so
-// store everything in the values array at the index of the field number
-// -2.
-const int kVendorAtomOffset = 2;
-
-std::shared_ptr<IStats> getStatsService() {
- const std::string instance = std::string() + IStats::descriptor + "/default";
- static bool isStatsDeclared = false;
- if (!isStatsDeclared) {
- // It is good to cache the result - it would not be changed
- isStatsDeclared = AServiceManager_isDeclared(instance.c_str());
- if (!isStatsDeclared) {
- ALOGE("Stats service is not registered.");
- return nullptr;
- }
- }
- return IStats::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str())));
-}
-
-void reportSpeakerImpedance(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorSpeakerImpedance &speakerImpedance) {
- // Load values array
- std::vector<VendorAtomValue> values(2);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(speakerImpedance.speaker_location());
- values[0] = tmp;
- tmp.set<VendorAtomValue::intValue>(speakerImpedance.impedance());
- values[1] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVendorSpeakerImpedance,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- ALOGE("Unable to report VendorSpeakerImpedance to Stats service");
-}
-
-void reportSlowIo(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorSlowIo &slowIo) {
- // Load values array
- std::vector<VendorAtomValue> values(2);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(slowIo.operation());
- values[0] = tmp;
- tmp.set<VendorAtomValue::intValue>(slowIo.count());
- values[1] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVendorSlowIo,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- ALOGE("Unable to report VendorSlowIo to Stats service");
-}
-
-void reportChargeCycles(const std::shared_ptr<IStats> &stats_client,
- const std::vector<int32_t> &chargeCycles) {
- // Load values array
- const int32_t kChargeCyclesBucketsCount =
- PixelAtoms::VendorChargeCycles::kCycleBucket10FieldNumber - kVendorAtomOffset + 1;
- std::vector<VendorAtomValue> values(kChargeCyclesBucketsCount);
- VendorAtomValue tmp;
- for (int32_t bucketIdx = 0; bucketIdx < kChargeCyclesBucketsCount; ++bucketIdx) {
- tmp.set<VendorAtomValue::intValue>(chargeCycles[bucketIdx]);
- values[bucketIdx] = tmp;
- }
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVendorChargeCycles,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- ALOGE("Unable to report VendorChargeCycles to Stats service");
-}
-
-void reportHardwareFailed(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorHardwareFailed &failure) {
- // Load values array
- std::vector<VendorAtomValue> values(3);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(failure.hardware_type());
- values[0] = tmp;
- tmp.set<VendorAtomValue::intValue>(failure.hardware_location());
- values[1] = tmp;
- tmp.set<VendorAtomValue::intValue>(failure.failure_code());
- values[2] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVendorHardwareFailed,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- ALOGE("Unable to report VendorHardwareFailed to Stats service");
-}
-
-void reportSpeechDspStat(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorSpeechDspStat &dsp_stats) {
- // Load values array
- std::vector<VendorAtomValue> values(4);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(dsp_stats.total_uptime_millis());
- values[0] = tmp;
- tmp.set<VendorAtomValue::intValue>(dsp_stats.total_downtime_millis());
- values[1] = tmp;
- tmp.set<VendorAtomValue::intValue>(dsp_stats.total_crash_count());
- values[2] = tmp;
- tmp.set<VendorAtomValue::intValue>(dsp_stats.total_recover_count());
- values[3] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVendorSpeechDspStat,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- ALOGE("Unable to report VendorSpeechDspStat to Stats service");
-}
-
-void reportPhysicalDropDetected(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorPhysicalDropDetected &dropDetected) {
- // Load values array
- std::vector<VendorAtomValue> values(3);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(dropDetected.confidence_pctg());
- values[0] = tmp;
- tmp.set<VendorAtomValue::intValue>(dropDetected.accel_peak_thousandths_g());
- values[1] = tmp;
- tmp.set<VendorAtomValue::intValue>(dropDetected.freefall_time_millis());
- values[2] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVendorPhysicalDropDetected,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- ALOGE("Unable to report VendorPhysicalDropDetected to Stats service");
-}
-
-void reportUsbPortOverheat(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorUsbPortOverheat &overheat_info) {
- // Load values array
- std::vector<VendorAtomValue> values(5);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(overheat_info.plug_temperature_deci_c());
- values[0] = tmp;
- tmp.set<VendorAtomValue::intValue>(overheat_info.max_temperature_deci_c());
- values[1] = tmp;
- tmp.set<VendorAtomValue::intValue>(overheat_info.time_to_overheat_secs());
- values[2] = tmp;
- tmp.set<VendorAtomValue::intValue>(overheat_info.time_to_hysteresis_secs());
- values[3] = tmp;
- tmp.set<VendorAtomValue::intValue>(overheat_info.time_to_inactive_secs());
- values[4] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVendorUsbPortOverheat,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk())
- ALOGE("Unable to report VendorUsbPortOverheat to Stats service");
-}
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/pixelstats/SysfsCollector.cpp b/pixelstats/SysfsCollector.cpp
index 8b002d0..bf1e3d5 100644
--- a/pixelstats/SysfsCollector.cpp
+++ b/pixelstats/SysfsCollector.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <pixelstats/StatsHelper.h>
#include <pixelstats/SysfsCollector.h>
#define LOG_TAG "pixelstats-vendor"
@@ -23,13 +22,14 @@
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
-#include <android/binder_manager.h>
+#include <android/frameworks/stats/1.0/IStats.h>
+#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
#include <utils/Log.h>
+#include <utils/StrongPointer.h>
#include <utils/Timers.h>
-#include <mntent.h>
#include <sys/timerfd.h>
-#include <cinttypes>
+#include <mntent.h>
#include <string>
namespace android {
@@ -37,25 +37,22 @@
namespace google {
namespace pixel {
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
+using android::sp;
using android::base::ReadFileToString;
using android::base::StartsWith;
-using android::base::WriteStringToFile;
+using android::frameworks::stats::V1_0::ChargeCycles;
+using android::frameworks::stats::V1_0::HardwareFailed;
+using android::frameworks::stats::V1_0::IStats;
+using android::frameworks::stats::V1_0::SlowIo;
+using android::frameworks::stats::V1_0::SpeakerImpedance;
+using android::frameworks::stats::V1_0::SpeechDspStat;
+using android::frameworks::stats::V1_0::VendorAtom;
using android::hardware::google::pixel::PixelAtoms::BatteryCapacity;
-using android::hardware::google::pixel::PixelAtoms::BootStatsInfo;
-using android::hardware::google::pixel::PixelAtoms::F2fsCompressionInfo;
-using android::hardware::google::pixel::PixelAtoms::F2fsStatsInfo;
-using android::hardware::google::pixel::PixelAtoms::F2fsGcSegmentInfo;
using android::hardware::google::pixel::PixelAtoms::StorageUfsHealth;
-using android::hardware::google::pixel::PixelAtoms::StorageUfsResetCount;
-using android::hardware::google::pixel::PixelAtoms::VendorChargeCycles;
-using android::hardware::google::pixel::PixelAtoms::VendorHardwareFailed;
-using android::hardware::google::pixel::PixelAtoms::VendorSlowIo;
-using android::hardware::google::pixel::PixelAtoms::VendorSpeakerImpedance;
-using android::hardware::google::pixel::PixelAtoms::VendorSpeechDspStat;
-using android::hardware::google::pixel::PixelAtoms::ZramBdStat;
+using android::hardware::google::pixel::PixelAtoms::F2fsStatsInfo;
using android::hardware::google::pixel::PixelAtoms::ZramMmStat;
+using android::hardware::google::pixel::PixelAtoms::ZramBdStat;
+using android::hardware::google::pixel::PixelAtoms::BootStatsInfo;
SysfsCollector::SysfsCollector(const struct SysfsPaths &sysfs_paths)
: kSlowioReadCntPath(sysfs_paths.SlowioReadCntPath),
@@ -72,12 +69,10 @@
kUFSLifetimeA(sysfs_paths.UFSLifetimeA),
kUFSLifetimeB(sysfs_paths.UFSLifetimeB),
kUFSLifetimeC(sysfs_paths.UFSLifetimeC),
- kUFSHostResetPath(sysfs_paths.UFSHostResetPath),
kF2fsStatsPath(sysfs_paths.F2fsStatsPath),
+ kUserdataBlockProp(sysfs_paths.UserdataBlockProp),
kZramMmStatPath("/sys/block/zram0/mm_stat"),
- kZramBdStatPath("/sys/block/zram0/bd_stat"),
- kEEPROMPath(sysfs_paths.EEPROMPath),
- kPowerMitigationStatsPath(sysfs_paths.MitigationPath) {}
+ kZramBdStatPath("/sys/block/zram0/bd_stat") {}
bool SysfsCollector::ReadFileToInt(const std::string &path, int *val) {
return ReadFileToInt(path.c_str(), val);
@@ -106,9 +101,10 @@
* The contents are expected to be N buckets total, the nth of which indicates the
* number of times battery %-full has been increased with the n/N% full bucket.
*/
-void SysfsCollector::logBatteryChargeCycles(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::logBatteryChargeCycles() {
std::string file_contents;
int val;
+ std::vector<int> charge_cycles;
if (kCycleCountBinsPath == nullptr || strlen(kCycleCountBinsPath) == 0) {
ALOGV("Battery charge cycle path not specified");
return;
@@ -118,44 +114,21 @@
return;
}
- const int32_t kChargeCyclesBucketsCount =
- VendorChargeCycles::kCycleBucket10FieldNumber - kVendorAtomOffset + 1;
- std::vector<int32_t> charge_cycles;
std::stringstream stream(file_contents);
while (stream >> val) {
charge_cycles.push_back(val);
}
- if (charge_cycles.size() > kChargeCyclesBucketsCount) {
- ALOGW("Got excessive battery charge cycles count %" PRIu64,
- static_cast<uint64_t>(charge_cycles.size()));
- } else {
- // Push 0 for buckets that do not exist.
- for (int bucketIdx = charge_cycles.size(); bucketIdx < kChargeCyclesBucketsCount;
- ++bucketIdx) {
- charge_cycles.push_back(0);
- }
- }
+ ChargeCycles cycles;
+ cycles.cycleBucket = charge_cycles;
std::replace(file_contents.begin(), file_contents.end(), ' ', ',');
- reportChargeCycles(stats_client, charge_cycles);
-}
-
-/**
- * Read the contents of kEEPROMPath and report them.
- */
-void SysfsCollector::logBatteryEEPROM(const std::shared_ptr<IStats> &stats_client) {
- if (kEEPROMPath == nullptr || strlen(kEEPROMPath) == 0) {
- ALOGV("Battery EEPROM path not specified");
- return;
- }
-
- battery_EEPROM_reporter_.checkAndReport(stats_client, kEEPROMPath);
+ stats_->reportChargeCycles(cycles);
}
/**
* Check the codec for failures over the past 24hr.
*/
-void SysfsCollector::logCodecFailed(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::logCodecFailed() {
std::string file_contents;
if (kCodecPath == nullptr || strlen(kCodecPath) == 0) {
ALOGV("Audio codec path not specified");
@@ -168,18 +141,17 @@
if (file_contents == "0") {
return;
} else {
- VendorHardwareFailed failure;
- failure.set_hardware_type(VendorHardwareFailed::HARDWARE_FAILED_CODEC);
- failure.set_hardware_location(0);
- failure.set_failure_code(VendorHardwareFailed::COMPLETE);
- reportHardwareFailed(stats_client, failure);
+ HardwareFailed failed = {.hardwareType = HardwareFailed::HardwareType::CODEC,
+ .hardwareLocation = 0,
+ .errorCode = HardwareFailed::HardwareErrorCode::COMPLETE};
+ stats_->reportHardwareFailed(failed);
}
}
/**
* Check the codec1 for failures over the past 24hr.
*/
-void SysfsCollector::logCodec1Failed(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::logCodec1Failed() {
std::string file_contents;
if (kCodec1Path == nullptr || strlen(kCodec1Path) == 0) {
ALOGV("Audio codec1 path not specified");
@@ -193,17 +165,15 @@
return;
} else {
ALOGE("%s report hardware fail", kCodec1Path);
- VendorHardwareFailed failure;
- failure.set_hardware_type(VendorHardwareFailed::HARDWARE_FAILED_CODEC);
- failure.set_hardware_location(1);
- failure.set_failure_code(VendorHardwareFailed::COMPLETE);
- reportHardwareFailed(stats_client, failure);
+ HardwareFailed failed = {.hardwareType = HardwareFailed::HardwareType::CODEC,
+ .hardwareLocation = 1,
+ .errorCode = HardwareFailed::HardwareErrorCode::COMPLETE};
+ stats_->reportHardwareFailed(failed);
}
}
-void SysfsCollector::reportSlowIoFromFile(const std::shared_ptr<IStats> &stats_client,
- const char *path,
- const VendorSlowIo::IoOperation &operation_s) {
+void SysfsCollector::reportSlowIoFromFile(const char *path,
+ const SlowIo::IoOperation &operation_s) {
std::string file_contents;
if (path == nullptr || strlen(path) == 0) {
ALOGV("slow_io path not specified");
@@ -217,10 +187,8 @@
if (sscanf(file_contents.c_str(), "%d", &slow_io_count) != 1) {
ALOGE("Unable to parse %s from file %s to int.", file_contents.c_str(), path);
} else if (slow_io_count > 0) {
- VendorSlowIo slow_io;
- slow_io.set_operation(operation_s);
- slow_io.set_count(slow_io_count);
- reportSlowIo(stats_client, slow_io);
+ SlowIo slowio = {.operation = operation_s, .count = slow_io_count};
+ stats_->reportSlowIo(slowio);
}
// Clear the stats
if (!android::base::WriteStringToFile("0", path, true)) {
@@ -232,17 +200,17 @@
/**
* Check for slow IO operations.
*/
-void SysfsCollector::logSlowIO(const std::shared_ptr<IStats> &stats_client) {
- reportSlowIoFromFile(stats_client, kSlowioReadCntPath, VendorSlowIo::READ);
- reportSlowIoFromFile(stats_client, kSlowioWriteCntPath, VendorSlowIo::WRITE);
- reportSlowIoFromFile(stats_client, kSlowioUnmapCntPath, VendorSlowIo::UNMAP);
- reportSlowIoFromFile(stats_client, kSlowioSyncCntPath, VendorSlowIo::SYNC);
+void SysfsCollector::logSlowIO() {
+ reportSlowIoFromFile(kSlowioReadCntPath, SlowIo::IoOperation::READ);
+ reportSlowIoFromFile(kSlowioWriteCntPath, SlowIo::IoOperation::WRITE);
+ reportSlowIoFromFile(kSlowioUnmapCntPath, SlowIo::IoOperation::UNMAP);
+ reportSlowIoFromFile(kSlowioSyncCntPath, SlowIo::IoOperation::SYNC);
}
/**
* Report the last-detected impedance of left & right speakers.
*/
-void SysfsCollector::logSpeakerImpedance(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::logSpeakerImpedance() {
std::string file_contents;
if (kImpedancePath == nullptr || strlen(kImpedancePath) == 0) {
ALOGV("Audio impedance path not specified");
@@ -258,22 +226,18 @@
ALOGE("Unable to parse speaker impedance %s", file_contents.c_str());
return;
}
- VendorSpeakerImpedance left_obj;
- left_obj.set_speaker_location(0);
- left_obj.set_impedance(static_cast<int32_t>(left * 1000));
-
- VendorSpeakerImpedance right_obj;
- right_obj.set_speaker_location(1);
- right_obj.set_impedance(static_cast<int32_t>(right * 1000));
-
- reportSpeakerImpedance(stats_client, left_obj);
- reportSpeakerImpedance(stats_client, right_obj);
+ SpeakerImpedance left_obj = {.speakerLocation = 0,
+ .milliOhms = static_cast<int32_t>(left * 1000)};
+ SpeakerImpedance right_obj = {.speakerLocation = 1,
+ .milliOhms = static_cast<int32_t>(right * 1000)};
+ stats_->reportSpeakerImpedance(left_obj);
+ stats_->reportSpeakerImpedance(right_obj);
}
/**
* Report the Speech DSP state.
*/
-void SysfsCollector::logSpeechDspStat(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::logSpeechDspStat() {
std::string file_contents;
if (kSpeechDspPath == nullptr || strlen(kSpeechDspPath) == 0) {
ALOGV("Speech DSP path not specified");
@@ -284,25 +248,24 @@
return;
}
- int32_t up_time = 0, down_time = 0, crash_count = 0, recover_count = 0;
- if (sscanf(file_contents.c_str(), "%d,%d,%d,%d", &up_time, &down_time, &crash_count,
- &recover_count) != 4) {
+ int32_t uptime = 0, downtime = 0, crashcount = 0, recovercount = 0;
+ if (sscanf(file_contents.c_str(), "%d,%d,%d,%d", &uptime, &downtime, &crashcount,
+ &recovercount) != 4) {
ALOGE("Unable to parse speech dsp stat %s", file_contents.c_str());
return;
}
- ALOGD("SpeechDSP uptime %d downtime %d crashcount %d recovercount %d", up_time, down_time,
- crash_count, recover_count);
- VendorSpeechDspStat dsp_stat;
- dsp_stat.set_total_uptime_millis(up_time);
- dsp_stat.set_total_downtime_millis(down_time);
- dsp_stat.set_total_crash_count(crash_count);
- dsp_stat.set_total_recover_count(recover_count);
+ ALOGD("SpeechDSP uptime %d downtime %d crashcount %d recovercount %d", uptime, downtime,
+ crashcount, recovercount);
+ SpeechDspStat dspstat = {.totalUptimeMillis = uptime,
+ .totalDowntimeMillis = downtime,
+ .totalCrashCount = crashcount,
+ .totalRecoverCount = recovercount};
- reportSpeechDspStat(stats_client, dsp_stat);
+ stats_->reportSpeechDspStat(dspstat);
}
-void SysfsCollector::logBatteryCapacity(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::logBatteryCapacity() {
std::string file_contents;
if (kBatteryCapacityCC == nullptr || strlen(kBatteryCapacityCC) == 0) {
ALOGV("Battery Capacity CC path not specified");
@@ -314,27 +277,27 @@
}
int delta_cc_sum, delta_vfsoc_sum;
if (!ReadFileToInt(kBatteryCapacityCC, &delta_cc_sum) ||
- !ReadFileToInt(kBatteryCapacityVFSOC, &delta_vfsoc_sum))
- return;
+ !ReadFileToInt(kBatteryCapacityVFSOC, &delta_vfsoc_sum))
+ return;
// Load values array
- std::vector<VendorAtomValue> values(2);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(delta_cc_sum);
+ std::vector<VendorAtom::Value> values(2);
+ VendorAtom::Value tmp;
+ tmp.intValue(delta_cc_sum);
values[BatteryCapacity::kDeltaCcSumFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(delta_vfsoc_sum);
+ tmp.intValue(delta_vfsoc_sum);
values[BatteryCapacity::kDeltaVfsocSumFieldNumber - kVendorAtomOffset] = tmp;
// Send vendor atom to IStats HAL
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kBatteryCapacity,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ .atomId = PixelAtoms::Ids::BATTERY_CAPACITY,
+ .values = values};
+ Return<void> ret = stats_->reportVendorAtom(event);
if (!ret.isOk())
ALOGE("Unable to report ChargeStats to Stats service");
}
-void SysfsCollector::logUFSLifetime(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::logUFSLifetime() {
std::string file_contents;
if (kUFSLifetimeA == nullptr || strlen(kUFSLifetimeA) == 0) {
ALOGV("UFS lifetimeA path not specified");
@@ -358,54 +321,26 @@
}
// Load values array
- std::vector<VendorAtomValue> values(3);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(lifetimeA);
+ std::vector<VendorAtom::Value> values(3);
+ VendorAtom::Value tmp;
+ tmp.intValue(lifetimeA);
values[StorageUfsHealth::kLifetimeAFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(lifetimeB);
+ tmp.intValue(lifetimeB);
values[StorageUfsHealth::kLifetimeBFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(lifetimeC);
+ tmp.intValue(lifetimeC);
values[StorageUfsHealth::kLifetimeCFieldNumber - kVendorAtomOffset] = tmp;
+
// Send vendor atom to IStats HAL
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kStorageUfsHealth,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ .atomId = PixelAtoms::Ids::STORAGE_UFS_HEALTH,
+ .values = values};
+ Return<void> ret = stats_->reportVendorAtom(event);
if (!ret.isOk()) {
ALOGE("Unable to report UfsHealthStat to Stats service");
}
}
-void SysfsCollector::logUFSErrorStats(const std::shared_ptr<IStats> &stats_client) {
- int host_reset_count;
-
- if (kUFSHostResetPath == nullptr || strlen(kUFSHostResetPath) == 0) {
- ALOGV("UFS host reset count specified");
- return;
- }
-
- if (!ReadFileToInt(kUFSHostResetPath, &host_reset_count)) {
- ALOGE("Unable to read host reset count");
- return;
- }
-
- // Load values array
- std::vector<VendorAtomValue> values(1);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(host_reset_count);
- values[StorageUfsResetCount::kHostResetCountFieldNumber - kVendorAtomOffset] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kUfsResetCount,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk()) {
- ALOGE("Unable to report UFS host reset count to Stats service");
- }
-}
-
static std::string getUserDataBlock() {
std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "re"), endmntent);
if (fp == nullptr) {
@@ -422,7 +357,7 @@
return "";
}
-void SysfsCollector::logF2fsStats(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::logF2fsStats() {
int dirty, free, cp_calls_fg, gc_calls_fg, moved_block_fg, vblocks;
int cp_calls_bg, gc_calls_bg, moved_block_bg;
@@ -431,198 +366,77 @@
return;
}
- const std::string userdataBlock = getUserDataBlock();
- const std::string kF2fsStatsDir = kF2fsStatsPath + userdataBlock;
+ std::string userdataBlock = getUserDataBlock();
- if (!ReadFileToInt(kF2fsStatsDir + "/dirty_segments", &dirty)) {
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/dirty_segments"), &dirty)) {
ALOGV("Unable to read dirty segments");
}
- if (!ReadFileToInt(kF2fsStatsDir + "/free_segments", &free)) {
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/free_segments"), &free)) {
ALOGV("Unable to read free segments");
}
- if (!ReadFileToInt(kF2fsStatsDir + "/cp_foreground_calls", &cp_calls_fg)) {
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/cp_foreground_calls"), &cp_calls_fg)) {
ALOGV("Unable to read cp_foreground_calls");
}
- if (!ReadFileToInt(kF2fsStatsDir + "/cp_background_calls", &cp_calls_bg)) {
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/cp_background_calls"), &cp_calls_bg)) {
ALOGV("Unable to read cp_background_calls");
}
- if (!ReadFileToInt(kF2fsStatsDir + "/gc_foreground_calls", &gc_calls_fg)) {
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/gc_foreground_calls"), &gc_calls_fg)) {
ALOGV("Unable to read gc_foreground_calls");
}
- if (!ReadFileToInt(kF2fsStatsDir + "/gc_background_calls", &gc_calls_bg)) {
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/gc_background_calls"), &gc_calls_bg)) {
ALOGV("Unable to read gc_background_calls");
}
- if (!ReadFileToInt(kF2fsStatsDir + "/moved_blocks_foreground", &moved_block_fg)) {
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/moved_blocks_foreground"), &moved_block_fg)) {
ALOGV("Unable to read moved_blocks_foreground");
}
- if (!ReadFileToInt(kF2fsStatsDir + "/moved_blocks_background", &moved_block_bg)) {
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/moved_blocks_background"), &moved_block_bg)) {
ALOGV("Unable to read moved_blocks_background");
}
- if (!ReadFileToInt(kF2fsStatsDir + "/avg_vblocks", &vblocks)) {
+ if (!ReadFileToInt(kF2fsStatsPath + (userdataBlock + "/avg_vblocks"), &vblocks)) {
ALOGV("Unable to read avg_vblocks");
}
// Load values array
- std::vector<VendorAtomValue> values(9);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(dirty);
+ std::vector<VendorAtom::Value> values(9);
+ VendorAtom::Value tmp;
+ tmp.intValue(dirty);
values[F2fsStatsInfo::kDirtySegmentsFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(free);
+ tmp.intValue(free);
values[F2fsStatsInfo::kFreeSegmentsFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(cp_calls_fg);
+ tmp.intValue(cp_calls_fg);
values[F2fsStatsInfo::kCpCallsFgFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(cp_calls_bg);
+ tmp.intValue(cp_calls_bg);
values[F2fsStatsInfo::kCpCallsBgFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(gc_calls_fg);
+ tmp.intValue(gc_calls_fg);
values[F2fsStatsInfo::kGcCallsFgFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(gc_calls_bg);
+ tmp.intValue(gc_calls_bg);
values[F2fsStatsInfo::kGcCallsBgFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(moved_block_fg);
+ tmp.intValue(moved_block_fg);
values[F2fsStatsInfo::kMovedBlocksFgFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(moved_block_bg);
+ tmp.intValue(moved_block_bg);
values[F2fsStatsInfo::kMovedBlocksBgFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(vblocks);
+ tmp.intValue(vblocks);
values[F2fsStatsInfo::kValidBlocksFieldNumber - kVendorAtomOffset] = tmp;
// Send vendor atom to IStats HAL
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kF2FsStats,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ .atomId = PixelAtoms::Ids::F2FS_STATS,
+ .values = values};
+ Return<void> ret = stats_->reportVendorAtom(event);
if (!ret.isOk()) {
ALOGE("Unable to report F2fs stats to Stats service");
}
}
-void SysfsCollector::logF2fsCompressionInfo(const std::shared_ptr<IStats> &stats_client) {
- int compr_written_blocks, compr_saved_blocks, compr_new_inodes;
-
- if (kF2fsStatsPath == nullptr) {
- ALOGV("F2fs stats path not specified");
- return;
- }
-
- std::string userdataBlock = getUserDataBlock();
-
- std::string path = kF2fsStatsPath + (userdataBlock + "/compr_written_block");
- if (!ReadFileToInt(path, &compr_written_blocks)) {
- ALOGE("Unable to read compression written blocks");
- return;
- }
-
- path = kF2fsStatsPath + (userdataBlock + "/compr_saved_block");
- if (!ReadFileToInt(path, &compr_saved_blocks)) {
- ALOGE("Unable to read compression saved blocks");
- return;
- } else {
- if (!WriteStringToFile(std::to_string(0), path)) {
- ALOGE("Failed to write to file %s", path.c_str());
- return;
- }
- }
-
- path = kF2fsStatsPath + (userdataBlock + "/compr_new_inode");
- if (!ReadFileToInt(path, &compr_new_inodes)) {
- ALOGE("Unable to read compression new inodes");
- return;
- } else {
- if (!WriteStringToFile(std::to_string(0), path)) {
- ALOGE("Failed to write to file %s", path.c_str());
- return;
- }
- }
-
- // Load values array
- std::vector<VendorAtomValue> values(3);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(compr_written_blocks);
- values[F2fsCompressionInfo::kComprWrittenBlocksFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(compr_saved_blocks);
- values[F2fsCompressionInfo::kComprSavedBlocksFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(compr_new_inodes);
- values[F2fsCompressionInfo::kComprNewInodesFieldNumber - kVendorAtomOffset] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kF2FsCompressionInfo,
- .values = values};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk()) {
- ALOGE("Unable to report F2fs compression info to Stats service");
- }
-}
-
-int SysfsCollector::getReclaimedSegments(const std::string &mode) {
- std::string userDataStatsPath = kF2fsStatsPath + getUserDataBlock();
- std::string gcSegmentModePath = userDataStatsPath + "/gc_segment_mode";
- std::string gcReclaimedSegmentsPath = userDataStatsPath + "/gc_reclaimed_segments";
- int reclaimed_segments;
-
- if (!WriteStringToFile(mode, gcSegmentModePath)) {
- ALOGE("Failed to change gc_segment_mode to %s", mode.c_str());
- return -1;
- }
-
- if (!ReadFileToInt(gcReclaimedSegmentsPath, &reclaimed_segments)) {
- ALOGE("GC mode(%s): Unable to read gc_reclaimed_segments", mode.c_str());
- return -1;
- }
-
- if (!WriteStringToFile(std::to_string(0), gcReclaimedSegmentsPath)) {
- ALOGE("GC mode(%s): Failed to reset gc_reclaimed_segments", mode.c_str());
- return -1;
- }
-
- return reclaimed_segments;
-}
-
-void SysfsCollector::logF2fsGcSegmentInfo(const std::shared_ptr<IStats> &stats_client) {
- int reclaimed_segments_normal, reclaimed_segments_urgent_high, reclaimed_segments_urgent_low;
- std::string gc_normal_mode = std::to_string(0); // GC normal mode
- std::string gc_urgent_high_mode = std::to_string(4); // GC urgent high mode
- std::string gc_urgent_low_mode = std::to_string(5); // GC urgent low mode
-
- if (kF2fsStatsPath == nullptr) {
- ALOGV("F2fs stats path not specified");
- return;
- }
-
- reclaimed_segments_normal = getReclaimedSegments(gc_normal_mode);
- if (reclaimed_segments_normal == -1) return;
- reclaimed_segments_urgent_high = getReclaimedSegments(gc_urgent_high_mode);
- if (reclaimed_segments_urgent_high == -1) return;
- reclaimed_segments_urgent_low = getReclaimedSegments(gc_urgent_low_mode);
- if (reclaimed_segments_urgent_low == -1) return;
-
- // Load values array
- std::vector<VendorAtomValue> values(3);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(reclaimed_segments_normal);
- values[F2fsGcSegmentInfo::kReclaimedSegmentsNormalFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(reclaimed_segments_urgent_high);
- values[F2fsGcSegmentInfo::kReclaimedSegmentsUrgentHighFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(reclaimed_segments_urgent_low);
- values[F2fsGcSegmentInfo::kReclaimedSegmentsUrgentLowFieldNumber - kVendorAtomOffset] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kF2FsGcSegmentInfo,
- .values = values};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk()) {
- ALOGE("Unable to report F2fs GC Segment info to Stats service");
- }
-}
-
-void SysfsCollector::reportZramMmStat(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::reportZramMmStat() {
std::string file_contents;
if (!kZramMmStatPath) {
ALOGV("ZramMmStat path not specified");
@@ -641,54 +455,39 @@
int64_t same_pages = 0;
int64_t pages_compacted = 0;
int64_t huge_pages = 0;
- int64_t huge_pages_since_boot = 0;
- // huge_pages_since_boot may not exist according to kernel version.
- // only check if the number of collected data is equal or larger then 8
- if (sscanf(file_contents.c_str(),
- "%" SCNd64 " %" SCNd64 " %" SCNd64 " %" SCNd64 " %" SCNd64 " %" SCNd64
- " %" SCNd64 " %" SCNd64 " %" SCNd64,
- &orig_data_size, &compr_data_size, &mem_used_total, &mem_limit, &max_used_total,
- &same_pages, &pages_compacted, &huge_pages, &huge_pages_since_boot) < 8) {
+ if (sscanf(file_contents.c_str(), "%lu %lu %lu %lu %lu %lu %lu %lu",
+ &orig_data_size, &compr_data_size, &mem_used_total, &mem_limit,
+ &max_used_total, &same_pages, &pages_compacted, &huge_pages) != 8) {
ALOGE("Unable to parse ZramMmStat %s from file %s to int.",
file_contents.c_str(), kZramMmStatPath);
}
- // Load values array.
- // The size should be the same as the number of fields in ZramMmStat
- std::vector<VendorAtomValue> values(6);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(orig_data_size);
+ // Load values array
+ std::vector<VendorAtom::Value> values(5);
+ VendorAtom::Value tmp;
+ tmp.intValue(orig_data_size);
values[ZramMmStat::kOrigDataSizeFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(compr_data_size);
+ tmp.intValue(compr_data_size);
values[ZramMmStat::kComprDataSizeFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(mem_used_total);
+ tmp.intValue(mem_used_total);
values[ZramMmStat::kMemUsedTotalFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(same_pages);
+ tmp.intValue(same_pages);
values[ZramMmStat::kSamePagesFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(huge_pages);
+ tmp.intValue(huge_pages);
values[ZramMmStat::kHugePagesFieldNumber - kVendorAtomOffset] = tmp;
- // Skip the first data to avoid a big spike in this accumulated value.
- if (prev_huge_pages_since_boot_ == -1)
- tmp.set<VendorAtomValue::intValue>(0);
- else
- tmp.set<VendorAtomValue::intValue>(huge_pages_since_boot - prev_huge_pages_since_boot_);
-
- values[ZramMmStat::kHugePagesSinceBootFieldNumber - kVendorAtomOffset] = tmp;
- prev_huge_pages_since_boot_ = huge_pages_since_boot;
-
// Send vendor atom to IStats HAL
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kZramMmStat,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ .atomId = PixelAtoms::Ids::ZRAM_MM_STAT,
+ .values = values};
+ Return<void> ret = stats_->reportVendorAtom(event);
if (!ret.isOk())
ALOGE("Zram Unable to report ZramMmStat to Stats service");
}
}
-void SysfsCollector::reportZramBdStat(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::reportZramBdStat() {
std::string file_contents;
if (!kZramBdStatPath) {
ALOGV("ZramBdStat path not specified");
@@ -703,38 +502,38 @@
int64_t bd_reads = 0;
int64_t bd_writes = 0;
- if (sscanf(file_contents.c_str(), "%" SCNd64 " %" SCNd64 " %" SCNd64,
+ if (sscanf(file_contents.c_str(), "%lu %lu %lu",
&bd_count, &bd_reads, &bd_writes) != 3) {
ALOGE("Unable to parse ZramBdStat %s from file %s to int.",
file_contents.c_str(), kZramBdStatPath);
}
// Load values array
- std::vector<VendorAtomValue> values(3);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(bd_count);
+ std::vector<VendorAtom::Value> values(3);
+ VendorAtom::Value tmp;
+ tmp.intValue(bd_count);
values[ZramBdStat::kBdCountFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(bd_reads);
+ tmp.intValue(bd_reads);
values[ZramBdStat::kBdReadsFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(bd_writes);
+ tmp.intValue(bd_writes);
values[ZramBdStat::kBdWritesFieldNumber - kVendorAtomOffset] = tmp;
// Send vendor atom to IStats HAL
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kZramBdStat,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ .atomId = PixelAtoms::Ids::ZRAM_BD_STAT,
+ .values = values};
+ Return<void> ret = stats_->reportVendorAtom(event);
if (!ret.isOk())
ALOGE("Zram Unable to report ZramBdStat to Stats service");
}
}
-void SysfsCollector::logZramStats(const std::shared_ptr<IStats> &stats_client) {
- reportZramMmStat(stats_client);
- reportZramBdStat(stats_client);
+void SysfsCollector::logZramStats() {
+ reportZramMmStat();
+ reportZramBdStat();
}
-void SysfsCollector::logBootStats(const std::shared_ptr<IStats> &stats_client) {
+void SysfsCollector::logBootStats() {
int mounted_time_sec = 0;
if (kF2fsStatsPath == nullptr) {
@@ -758,20 +557,20 @@
}
// Load values array
- std::vector<VendorAtomValue> values(3);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(mounted_time_sec);
+ std::vector<VendorAtom::Value> values(3);
+ VendorAtom::Value tmp;
+ tmp.intValue(mounted_time_sec);
values[BootStatsInfo::kMountedTimeSecFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(fsck_time_ms / 1000);
+ tmp.intValue(fsck_time_ms / 1000);
values[BootStatsInfo::kFsckTimeSecFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(checkpoint_time_ms / 1000);
+ tmp.intValue(checkpoint_time_ms / 1000);
values[BootStatsInfo::kCheckpointTimeSecFieldNumber - kVendorAtomOffset] = tmp;
// Send vendor atom to IStats HAL
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kBootStats,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ .atomId = PixelAtoms::Ids::BOOT_STATS,
+ .values = values};
+ Return<void> ret = stats_->reportVendorAtom(event);
if (!ret.isOk()) {
ALOGE("Unable to report Boot stats to Stats service");
} else {
@@ -779,44 +578,29 @@
}
}
-void SysfsCollector::logPerDay() {
- const std::shared_ptr<IStats> stats_client = getStatsService();
- if (!stats_client) {
- ALOGE("Unable to get AIDL Stats service");
+void SysfsCollector::logAll() {
+ stats_ = IStats::tryGetService();
+ if (!stats_) {
+ ALOGE("Unable to connect to Stats service");
return;
}
+
// Collect once per service init; can be multiple due to service reinit
if (!log_once_reported) {
- logBootStats(stats_client);
+ logBootStats();
}
- logBatteryCapacity(stats_client);
- logBatteryChargeCycles(stats_client);
- logBatteryEEPROM(stats_client);
- logCodec1Failed(stats_client);
- logCodecFailed(stats_client);
- logF2fsStats(stats_client);
- logF2fsCompressionInfo(stats_client);
- logF2fsGcSegmentInfo(stats_client);
- logSlowIO(stats_client);
- logSpeakerImpedance(stats_client);
- logSpeechDspStat(stats_client);
- logUFSLifetime(stats_client);
- logUFSErrorStats(stats_client);
- logZramStats(stats_client);
- mm_metrics_reporter_.logCmaStatus(stats_client);
- mm_metrics_reporter_.logPixelMmMetricsPerDay(stats_client);
-}
+ logBatteryChargeCycles();
+ logCodecFailed();
+ logCodec1Failed();
+ logSlowIO();
+ logSpeakerImpedance();
+ logSpeechDspStat();
+ logBatteryCapacity();
+ logUFSLifetime();
+ logF2fsStats();
+ logZramStats();
-void SysfsCollector::logPerHour() {
- const std::shared_ptr<IStats> stats_client = getStatsService();
- if (!stats_client) {
- ALOGE("Unable to get AIDL Stats service");
- return;
- }
- mm_metrics_reporter_.logPixelMmMetricsPerHour(stats_client);
- if (kPowerMitigationStatsPath != nullptr && strlen(kPowerMitigationStatsPath) > 0)
- mitigation_stats_reporter_.logMitigationStatsPerHour(stats_client,
- kPowerMitigationStatsPath);
+ stats_.clear();
}
/**
@@ -834,20 +618,18 @@
sleep(30);
// Collect first set of stats on boot.
- logPerHour();
- logPerDay();
+ logAll();
- // Set an one-hour timer.
+ // Collect stats every 24hrs after.
struct itimerspec period;
- const int kSecondsPerHour = 60 * 60;
- int hours = 0;
- period.it_interval.tv_sec = kSecondsPerHour;
+ const int kSecondsPerDay = 60 * 60 * 24;
+ period.it_interval.tv_sec = kSecondsPerDay;
period.it_interval.tv_nsec = 0;
- period.it_value.tv_sec = kSecondsPerHour;
+ period.it_value.tv_sec = kSecondsPerDay;
period.it_value.tv_nsec = 0;
if (timerfd_settime(timerfd, 0, &period, NULL)) {
- ALOGE("Unable to set one hour timer - %s", strerror(errno));
+ ALOGE("Unable to set 24hr timer - %s", strerror(errno));
return;
}
@@ -862,14 +644,7 @@
ALOGE("Timerfd error - %s\n", strerror(errno));
return;
}
-
- hours++;
- logPerHour();
- if (hours == 24) {
- // Collect stats every 24hrs after.
- logPerDay();
- hours = 0;
- }
+ logAll();
}
}
diff --git a/pixelstats/UeventListener.cpp b/pixelstats/UeventListener.cpp
index 0528301..f7b3c54 100644
--- a/pixelstats/UeventListener.cpp
+++ b/pixelstats/UeventListener.cpp
@@ -14,74 +14,39 @@
* limitations under the License.
*/
-/* If you are watching for a new uevent, uncomment the following define.
- * After flashing your test build, run:
- * adb root && adb shell
- * stop vendor.pixelstats_vendor
- * touch /data/local/tmp/uevents
- * /vendor/bin/pixelstats-vendor &
- *
- * then trigger any events.
- * If you leave adb connected, you can watch them with
- * tail -f /data/local/tmp/uevents
- *
- * Once you are done,
- *
- * adb pull /data/local/tmp/uevents
- * adb rm /data/local/tmp/uevents
- * adb reboot
- *
- * provide this log in the bug as support for your feature.
- */
-// #define LOG_UEVENTS_TO_FILE_ONLY_FOR_DEVEL "/data/local/tmp/uevents"
-
#define LOG_TAG "pixelstats-uevent"
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
-#include <android/binder_manager.h>
+#include <android/frameworks/stats/1.0/IStats.h>
#include <cutils/uevent.h>
-#include <fcntl.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
#include <log/log.h>
-#include <pixelstats/StatsHelper.h>
#include <pixelstats/UeventListener.h>
#include <pixelstats/WlcReporter.h>
-#include <sys/stat.h>
-#include <sys/types.h>
#include <unistd.h>
#include <utils/StrongPointer.h>
-#include <string>
#include <thread>
+using android::sp;
+using android::base::ReadFileToString;
+using android::base::WriteStringToFile;
+using android::frameworks::stats::V1_0::HardwareFailed;
+using android::frameworks::stats::V1_0::IStats;
+using android::frameworks::stats::V1_0::UsbPortOverheatEvent;
+using android::frameworks::stats::V1_0::VendorAtom;
+using android::hardware::google::pixel::WlcReporter;
+using android::hardware::google::pixel::PixelAtoms::ChargeStats;
+using android::hardware::google::pixel::PixelAtoms::VoltageTierStats;
+
namespace android {
namespace hardware {
namespace google {
namespace pixel {
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
-using android::sp;
-using android::base::ReadFileToString;
-using android::base::WriteStringToFile;
-using android::hardware::google::pixel::WlcReporter;
-using android::hardware::google::pixel::PixelAtoms::ChargeStats;
-using android::hardware::google::pixel::PixelAtoms::PdVidPid;
-using android::hardware::google::pixel::PixelAtoms::VendorHardwareFailed;
-using android::hardware::google::pixel::PixelAtoms::VendorUsbPortOverheat;
-using android::hardware::google::pixel::PixelAtoms::VoltageTierStats;
-
constexpr int32_t UEVENT_MSG_LEN = 2048; // it's 2048 in all other users.
-constexpr int32_t PRODUCT_TYPE_OFFSET = 23;
-constexpr int32_t PRODUCT_TYPE_MASK = 7;
-constexpr int32_t PRODUCT_TYPE_CHARGER = 3;
-constexpr int32_t VID_MASK = 0xffff;
-constexpr int32_t VID_GOOGLE = 0x18d1;
-constexpr int32_t PID_OFFSET = 2;
-constexpr int32_t PID_LENGTH = 4;
bool UeventListener::ReadFileToInt(const std::string &path, int *val) {
return ReadFileToInt(path.c_str(), val);
@@ -100,18 +65,24 @@
return true;
}
-void UeventListener::ReportMicBrokenOrDegraded(const std::shared_ptr<IStats> &stats_client,
- const int mic, const bool isbroken) {
- VendorHardwareFailed failure;
- failure.set_hardware_type(VendorHardwareFailed::HARDWARE_FAILED_MICROPHONE);
- failure.set_hardware_location(mic);
- failure.set_failure_code(isbroken ? VendorHardwareFailed::COMPLETE
- : VendorHardwareFailed::DEGRADE);
- reportHardwareFailed(stats_client, failure);
+void UeventListener::ReportMicBrokenOrDegraded(const int mic, const bool isbroken) {
+ sp<IStats> stats_client = IStats::tryGetService();
+
+ if (stats_client) {
+ HardwareFailed failure = {
+ .hardwareType = HardwareFailed::HardwareType::MICROPHONE,
+ .hardwareLocation = mic,
+ .errorCode = isbroken ? HardwareFailed::HardwareErrorCode::COMPLETE
+ : HardwareFailed::HardwareErrorCode::DEGRADE};
+ Return<void> ret = stats_client->reportHardwareFailed(failure);
+ if (!ret.isOk())
+ ALOGE("Unable to report physical drop to Stats service");
+ } else {
+ ALOGE("Unable to connect to Stats service");
+ }
}
-void UeventListener::ReportMicStatusUevents(const std::shared_ptr<IStats> &stats_client,
- const char *devpath, const char *mic_status) {
+void UeventListener::ReportMicStatusUevents(const char *devpath, const char *mic_status) {
if (!devpath || !mic_status)
return;
if (!strcmp(devpath, ("DEVPATH=" + kAudioUevent).c_str())) {
@@ -127,14 +98,14 @@
return;
if (!value[1].compare("true")) {
- ReportMicBrokenOrDegraded(stats_client, 0, isbroken);
+ ReportMicBrokenOrDegraded(0, isbroken);
} else {
int mic_status = atoi(value[1].c_str());
if (mic_status > 0 && mic_status <= 7) {
for (int mic_bit = 0; mic_bit < 3; mic_bit++)
if (mic_status & (0x1 << mic_bit))
- ReportMicBrokenOrDegraded(stats_client, mic_bit, isbroken);
+ ReportMicBrokenOrDegraded(mic_bit, isbroken);
} else if (mic_status == 0) {
// mic is ok
return;
@@ -148,201 +119,114 @@
}
}
-void UeventListener::ReportUsbPortOverheatEvent(const std::shared_ptr<IStats> &stats_client,
- const char *driver) {
+void UeventListener::ReportUsbPortOverheatEvent(const char *driver) {
+ UsbPortOverheatEvent event = {};
+ std::string file_contents;
+
if (!driver || strcmp(driver, "DRIVER=google,overheat_mitigation")) {
return;
}
- int32_t plug_temperature_deci_c = 0;
- int32_t max_temperature_deci_c = 0;
- int32_t time_to_overheat_secs = 0;
- int32_t time_to_hysteresis_secs = 0;
- int32_t time_to_inactive_secs = 0;
+ ReadFileToInt((kUsbPortOverheatPath + "/plug_temp"), &event.plugTemperatureDeciC);
+ ReadFileToInt((kUsbPortOverheatPath + "/max_temp"), &event.maxTemperatureDeciC);
+ ReadFileToInt((kUsbPortOverheatPath + "/trip_time"), &event.timeToOverheat);
+ ReadFileToInt((kUsbPortOverheatPath + "/hysteresis_time"), &event.timeToHysteresis);
+ ReadFileToInt((kUsbPortOverheatPath + "/cleared_time"), &event.timeToInactive);
- // TODO(achant b/182941868): test return value and skip reporting in case of an error
- ReadFileToInt((kUsbPortOverheatPath + "/plug_temp"), &plug_temperature_deci_c);
- ReadFileToInt((kUsbPortOverheatPath + "/max_temp"), &max_temperature_deci_c);
- ReadFileToInt((kUsbPortOverheatPath + "/trip_time"), &time_to_overheat_secs);
- ReadFileToInt((kUsbPortOverheatPath + "/hysteresis_time"), &time_to_hysteresis_secs);
- ReadFileToInt((kUsbPortOverheatPath + "/cleared_time"), &time_to_inactive_secs);
+ sp<IStats> stats_client = IStats::tryGetService();
- VendorUsbPortOverheat overheat_info;
- overheat_info.set_plug_temperature_deci_c(plug_temperature_deci_c);
- overheat_info.set_max_temperature_deci_c(max_temperature_deci_c);
- overheat_info.set_time_to_overheat_secs(time_to_overheat_secs);
- overheat_info.set_time_to_hysteresis_secs(time_to_hysteresis_secs);
- overheat_info.set_time_to_inactive_secs(time_to_inactive_secs);
-
- reportUsbPortOverheat(stats_client, overheat_info);
+ if (stats_client) {
+ stats_client->reportUsbPortOverheatEvent(event);
+ }
}
-void UeventListener::ReportChargeStats(const std::shared_ptr<IStats> &stats_client,
- const std::string line, const std::string wline_at,
- const std::string wline_ac, const std::string pca_line) {
- int charge_stats_fields[] = {ChargeStats::kAdapterTypeFieldNumber,
- ChargeStats::kAdapterVoltageFieldNumber,
- ChargeStats::kAdapterAmperageFieldNumber,
- ChargeStats::kSsocInFieldNumber,
- ChargeStats::kVoltageInFieldNumber,
- ChargeStats::kSsocOutFieldNumber,
- ChargeStats::kVoltageOutFieldNumber,
- ChargeStats::kAdapterCapabilities0FieldNumber,
- ChargeStats::kAdapterCapabilities1FieldNumber,
- ChargeStats::kAdapterCapabilities2FieldNumber,
- ChargeStats::kAdapterCapabilities3FieldNumber,
- ChargeStats::kAdapterCapabilities4FieldNumber,
- ChargeStats::kReceiverState0FieldNumber,
- ChargeStats::kReceiverState1FieldNumber};
- const int32_t chg_fields_size = std::size(charge_stats_fields);
- static_assert(chg_fields_size == 14, "Unexpected charge stats fields size");
- const int32_t wlc_fields_size = 7;
- std::vector<VendorAtomValue> values(chg_fields_size);
- VendorAtomValue val;
- int32_t i = 0, tmp[chg_fields_size] = {0}, fields_size = (chg_fields_size - wlc_fields_size);
- int32_t pca_ac[2] = {0}, pca_rs[5] = {0};
+void UeventListener::ReportChargeStats(const sp<IStats> &stats_client, const char *line) {
+ std::vector<int> charge_stats_fields = {
+ ChargeStats::kAdapterTypeFieldNumber, ChargeStats::kAdapterVoltageFieldNumber,
+ ChargeStats::kAdapterAmperageFieldNumber, ChargeStats::kSsocInFieldNumber,
+ ChargeStats::kVoltageInFieldNumber, ChargeStats::kSsocOutFieldNumber,
+ ChargeStats::kVoltageOutFieldNumber};
+ std::vector<VendorAtom::Value> values(charge_stats_fields.size());
+ VendorAtom::Value val;
+ int32_t i = 0, tmp[7] = {0};
- ALOGD("ChargeStats: processing %s", line.c_str());
- if (sscanf(line.c_str(), "%d,%d,%d, %d,%d,%d,%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4],
- &tmp[5], &tmp[6]) != 7) {
- ALOGE("Couldn't process %s", line.c_str());
+ ALOGD("ChargeStats: processing %s", line);
+ if (sscanf(line, "%d,%d,%d, %d,%d,%d,%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5],
+ &tmp[6]) != 7) {
+ ALOGE("Couldn't process %s", line);
return;
}
-
- if (!wline_at.empty()) {
- int32_t ssoc_tmp = 0;
- ALOGD("ChargeStats(wlc): processing %s", wline_at.c_str());
- if (sscanf(wline_at.c_str(), "A:%d", &ssoc_tmp) != 1) {
- ALOGE("Couldn't process %s", wline_at.c_str());
- } else {
- tmp[0] = wireless_charge_stats_.TranslateSysModeToAtomValue(ssoc_tmp);
- ALOGD("ChargeStats(wlc): processing %s", wline_ac.c_str());
- if (sscanf(wline_ac.c_str(), "D:%x,%x,%x,%x,%x, %x,%x", &tmp[7], &tmp[8], &tmp[9],
- &tmp[10], &tmp[11], &tmp[12], &tmp[13]) != 7)
- ALOGE("Couldn't process %s", wline_ac.c_str());
- else
- fields_size = chg_fields_size; /* include wlc stats */
- }
- }
-
- if (!pca_line.empty()) {
- ALOGD("ChargeStats(pca): processing %s", pca_line.c_str());
- if (sscanf(pca_line.c_str(), "D:%x,%x %x,%x,%x,%x,%x", &pca_ac[0], &pca_ac[1], &pca_rs[0],
- &pca_rs[1], &pca_rs[2], &pca_rs[3], &pca_rs[4]) != 7) {
- ALOGE("Couldn't process %s", pca_line.c_str());
- } else {
- fields_size = chg_fields_size; /* include pca stats */
- tmp[9] = pca_rs[2];
- tmp[10] = pca_rs[3];
- tmp[11] = pca_rs[4];
- tmp[13] = pca_rs[1];
- if (wline_at.empty()) {
- tmp[7] = pca_ac[0];
- tmp[8] = pca_ac[1];
- tmp[12] = pca_rs[0];
- }
- }
- }
-
- for (i = 0; i < fields_size; i++) {
- val.set<VendorAtomValue::intValue>(tmp[i]);
+ for (i = 0; i < charge_stats_fields.size(); i++) {
+ val.intValue(tmp[i]);
values[charge_stats_fields[i] - kVendorAtomOffset] = val;
}
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kChargeStats,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ .atomId = PixelAtoms::Ids::CHARGE_STATS,
+ .values = values};
+ Return<void> ret = stats_client->reportVendorAtom(event);
if (!ret.isOk())
ALOGE("Unable to report ChargeStats to Stats service");
}
-void UeventListener::ReportVoltageTierStats(const std::shared_ptr<IStats> &stats_client,
- const char *line, const bool has_wireless,
- const std::string wfile_contents) {
- int voltage_tier_stats_fields[] = {
- VoltageTierStats::kVoltageTierFieldNumber,
- VoltageTierStats::kSocInFieldNumber, /* retrieved via ssoc_tmp */
- VoltageTierStats::kCcInFieldNumber,
- VoltageTierStats::kTempInFieldNumber,
- VoltageTierStats::kTimeFastSecsFieldNumber,
- VoltageTierStats::kTimeTaperSecsFieldNumber,
- VoltageTierStats::kTimeOtherSecsFieldNumber,
- VoltageTierStats::kTempMinFieldNumber,
- VoltageTierStats::kTempAvgFieldNumber,
- VoltageTierStats::kTempMaxFieldNumber,
- VoltageTierStats::kIbattMinFieldNumber,
- VoltageTierStats::kIbattAvgFieldNumber,
- VoltageTierStats::kIbattMaxFieldNumber,
- VoltageTierStats::kIclMinFieldNumber,
- VoltageTierStats::kIclAvgFieldNumber,
- VoltageTierStats::kIclMaxFieldNumber,
- VoltageTierStats::kMinAdapterPowerOutFieldNumber,
- VoltageTierStats::kTimeAvgAdapterPowerOutFieldNumber,
- VoltageTierStats::kMaxAdapterPowerOutFieldNumber,
- VoltageTierStats::kChargingOperatingPointFieldNumber};
-
- const int32_t vtier_fields_size = std::size(voltage_tier_stats_fields);
- static_assert(vtier_fields_size == 20, "Unexpected voltage tier stats fields size");
- const int32_t wlc_fields_size = 4;
- std::vector<VendorAtomValue> values(vtier_fields_size);
- VendorAtomValue val;
+void UeventListener::ReportVoltageTierStats(const sp<IStats> &stats_client, const char *line) {
+ std::vector<int> voltage_tier_stats_fields = {VoltageTierStats::kVoltageTierFieldNumber,
+ VoltageTierStats::kSocInFieldNumber,
+ VoltageTierStats::kCcInFieldNumber,
+ VoltageTierStats::kTempInFieldNumber,
+ VoltageTierStats::kTimeFastSecsFieldNumber,
+ VoltageTierStats::kTimeTaperSecsFieldNumber,
+ VoltageTierStats::kTimeOtherSecsFieldNumber,
+ VoltageTierStats::kTempMinFieldNumber,
+ VoltageTierStats::kTempAvgFieldNumber,
+ VoltageTierStats::kTempMaxFieldNumber,
+ VoltageTierStats::kIbattMinFieldNumber,
+ VoltageTierStats::kIbattAvgFieldNumber,
+ VoltageTierStats::kIbattMaxFieldNumber,
+ VoltageTierStats::kIclMinFieldNumber,
+ VoltageTierStats::kIclAvgFieldNumber,
+ VoltageTierStats::kIclMaxFieldNumber};
+ std::vector<VendorAtom::Value> values(voltage_tier_stats_fields.size());
+ VendorAtom::Value val;
float ssoc_tmp;
- int32_t i = 0, tmp[vtier_fields_size - 1] = {0}, /* ssoc_tmp is not saved in this array */
- fields_size = (vtier_fields_size - wlc_fields_size);
+ int32_t i = 0, tmp[15] = {0};
+ ALOGD("VoltageTierStats: processing %s", line);
if (sscanf(line, "%d, %f,%d,%d, %d,%d,%d, %d,%d,%d, %d,%d,%d, %d,%d,%d", &tmp[0], &ssoc_tmp,
&tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5], &tmp[6], &tmp[7], &tmp[8], &tmp[9],
&tmp[10], &tmp[11], &tmp[12], &tmp[13], &tmp[14]) != 16) {
- /* If format isn't as expected, then ignore line on purpose */
+ ALOGE("Couldn't process %s", line);
return;
}
-
- if (has_wireless) {
- wireless_charge_stats_.CalculateWirelessChargeStats(static_cast<int>(ssoc_tmp),
- wfile_contents);
- tmp[15] = wireless_charge_stats_.pout_min_;
- tmp[16] = wireless_charge_stats_.pout_avg_;
- tmp[17] = wireless_charge_stats_.pout_max_;
- tmp[18] = wireless_charge_stats_.of_freq_;
- fields_size = vtier_fields_size; /* include wlc stats */
- }
-
- ALOGD("VoltageTierStats: processed %s", line);
- val.set<VendorAtomValue::intValue>(tmp[0]);
+ val.intValue(tmp[0]);
values[voltage_tier_stats_fields[0] - kVendorAtomOffset] = val;
- val.set<VendorAtomValue::floatValue>(ssoc_tmp);
+ val.floatValue(ssoc_tmp);
values[voltage_tier_stats_fields[1] - kVendorAtomOffset] = val;
- for (i = 2; i < fields_size; i++) {
- val.set<VendorAtomValue::intValue>(tmp[i - 1]);
+ for (i = 2; i < voltage_tier_stats_fields.size(); i++) {
+ val.intValue(tmp[i - 1]);
values[voltage_tier_stats_fields[i] - kVendorAtomOffset] = val;
}
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kVoltageTierStats,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ .atomId = PixelAtoms::Ids::VOLTAGE_TIER_STATS,
+ .values = values};
+ Return<void> ret = stats_client->reportVendorAtom(event);
if (!ret.isOk())
ALOGE("Unable to report VoltageTierStats to Stats service");
}
-void UeventListener::ReportChargeMetricsEvent(const std::shared_ptr<IStats> &stats_client,
- const char *driver) {
+void UeventListener::ReportChargeMetricsEvent(const char *driver) {
if (!driver || strcmp(driver, "DRIVER=google,battery")) {
return;
}
- std::string file_contents, line, wfile_contents, wline_at, wline_ac, pca_file_contents,
- pca_line;
+ std::string file_contents, line;
std::istringstream ss;
- bool has_wireless = wireless_charge_stats_.CheckWirelessContentsAndAck(&wfile_contents);
- bool has_pca = pca_charge_stats_.CheckPcaContentsAndAck(&pca_file_contents);
if (!ReadFileToString(kChargeMetricsPath.c_str(), &file_contents)) {
ALOGE("Unable to read %s - %s", kChargeMetricsPath.c_str(), strerror(errno));
return;
}
-
ss.str(file_contents);
if (!std::getline(ss, line)) {
@@ -350,47 +234,39 @@
return;
}
- if (!WriteStringToFile(std::to_string(0), kChargeMetricsPath.c_str())) {
- ALOGE("Couldn't clear %s - %s", kChargeMetricsPath.c_str(), strerror(errno));
+ if (!WriteStringToFile(kChargeMetricsPath.c_str(), std::to_string(0))) {
+ ALOGE("Couldn't clear %s", kChargeMetricsPath.c_str());
}
- if (has_pca) {
- std::istringstream pca_ss;
-
- pca_ss.str(pca_file_contents);
- std::getline(pca_ss, pca_line);
+ sp<IStats> stats_client = IStats::tryGetService();
+ if (!stats_client) {
+ ALOGE("Couldn't connect to IStats service");
+ return;
}
- if (has_wireless) {
- std::istringstream wss;
-
- /* there are two lines in the head, A: ...(Adapter Type) and D: ...(Adapter Capabilities) */
- wss.str(wfile_contents);
- std::getline(wss, wline_at);
- std::getline(wss, wline_ac);
-
- /* reset initial tier soc */
- wireless_charge_stats_.tier_soc_ = 0;
- }
-
- ReportChargeStats(stats_client, line, wline_at, wline_ac, pca_line);
+ ReportChargeStats(stats_client, line.c_str());
while (std::getline(ss, line)) {
- ReportVoltageTierStats(stats_client, line.c_str(), has_wireless, wfile_contents);
+ ReportVoltageTierStats(stats_client, line.c_str());
}
}
/* ReportWlc
* Report wireless relate metrics when wireless charging start
*/
-void UeventListener::ReportWlc(const std::shared_ptr<IStats> &stats_client, const bool pow_wireless,
- const bool online, const char *ptmc) {
- if (!pow_wireless) {
+void UeventListener::ReportWlc(const char *driver) {
+ if (!driver || strncmp(driver, "POWER_SUPPLY_PRESENT=", strlen("POWER_SUPPLY_PRESENT="))) {
return;
}
-
- wlc_reporter_.checkAndReport(stats_client, online, ptmc);
+ if (wireless_charging_supported_) {
+ sp<WlcReporter> wlc_reporter = new WlcReporter();
+ if (wlc_reporter != nullptr) {
+ wireless_charging_state_ =
+ wlc_reporter->checkAndReport(wireless_charging_state_);
+ }
+ }
}
+
/**
* Report raw battery capacity, system battery capacity and associated
* battery capacity curves. This data is collected to verify the filter
@@ -408,8 +284,7 @@
* 5. When there is a difference of >= 4 percent between the raw hardware
* battery capacity and the system reported battery capacity.
*/
-void UeventListener::ReportBatteryCapacityFGEvent(const std::shared_ptr<IStats> &stats_client,
- const char *subsystem) {
+void UeventListener::ReportBatteryCapacityFGEvent(const char *subsystem) {
if (!subsystem || strcmp(subsystem, "SUBSYSTEM=power_supply")) {
return;
}
@@ -419,62 +294,7 @@
return;
}
- battery_capacity_reporter_.checkAndReport(stats_client, kBatterySSOCPath);
-}
-
-void UeventListener::ReportTypeCPartnerId(const std::shared_ptr<IStats> &stats_client) {
- std::string file_contents_vid, file_contents_pid;
- uint32_t pid, vid;
-
- if (!ReadFileToString(kTypeCPartnerVidPath.c_str(), &file_contents_vid)) {
- ALOGE("Unable to read %s - %s", kTypeCPartnerVidPath.c_str(), strerror(errno));
- return;
- }
-
- if (sscanf(file_contents_vid.c_str(), "%x", &vid) != 1) {
- ALOGE("Unable to parse vid %s from file %s to int.", file_contents_vid.c_str(),
- kTypeCPartnerVidPath.c_str());
- return;
- }
-
- if (!ReadFileToString(kTypeCPartnerPidPath.c_str(), &file_contents_pid)) {
- ALOGE("Unable to read %s - %s", kTypeCPartnerPidPath.c_str(), strerror(errno));
- return;
- }
-
- if (sscanf(file_contents_pid.substr(PID_OFFSET, PID_LENGTH).c_str(), "%x", &pid) != 1) {
- ALOGE("Unable to parse pid %s from file %s to int.",
- file_contents_pid.substr(PID_OFFSET, PID_LENGTH).c_str(),
- kTypeCPartnerPidPath.c_str());
- return;
- }
-
- // Upload data only for chargers
- if (((vid >> PRODUCT_TYPE_OFFSET) & PRODUCT_TYPE_MASK) != PRODUCT_TYPE_CHARGER) {
- return;
- }
-
- // Upload data only for Google VID
- if ((VID_MASK & vid) != VID_GOOGLE) {
- return;
- }
-
- std::vector<VendorAtomValue> values(2);
- VendorAtomValue tmp;
-
- tmp.set<VendorAtomValue::intValue>(vid & VID_MASK);
- values[PdVidPid::kVidFieldNumber - kVendorAtomOffset] = tmp;
- tmp.set<VendorAtomValue::intValue>(pid);
- values[PdVidPid::kPidFieldNumber - kVendorAtomOffset] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kPdVidPid,
- .values = std::move(values)};
- const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
- if (!ret.isOk()) {
- ALOGE("Unable to report PD VID/PID to Stats service");
- }
+ battery_capacity_reporter_.checkAndReport(kBatterySSOCPath);
}
bool UeventListener::ProcessUevent() {
@@ -483,10 +303,7 @@
const char *driver, *product, *subsystem;
const char *mic_break_status, *mic_degrade_status;
const char *devpath;
- bool collect_partner_id = false;
- bool pow_online;
- bool pow_wireless;
- const char *pow_ptmc;
+ const char *powpresent;
int n;
if (uevent_fd_ < 0) {
@@ -497,15 +314,6 @@
}
}
-#ifdef LOG_UEVENTS_TO_FILE_ONLY_FOR_DEVEL
- if (log_fd_ < 0) {
- /* Intentionally no O_CREAT so no logging will happen
- * unless the user intentionally 'touch's the file.
- */
- log_fd_ = open(LOG_UEVENTS_TO_FILE_ONLY_FOR_DEVEL, O_WRONLY);
- }
-#endif
-
n = uevent_kernel_multicast_recv(uevent_fd_, msg, UEVENT_MSG_LEN);
if (n <= 0 || n >= UEVENT_MSG_LEN)
return false;
@@ -515,8 +323,7 @@
msg[n + 1] = '\0';
driver = product = subsystem = NULL;
- mic_break_status = mic_degrade_status = devpath = pow_ptmc = NULL;
- pow_online = pow_wireless = false;
+ mic_break_status = mic_degrade_status = devpath = powpresent = NULL;
/**
* msg is a sequence of null-terminated strings.
@@ -525,10 +332,6 @@
*/
cp = msg;
while (*cp) {
- if (log_fd_ > 0) {
- write(log_fd_, cp, strlen(cp));
- write(log_fd_, "\n", 1);
- }
if (!strncmp(cp, "DRIVER=", strlen("DRIVER="))) {
driver = cp;
} else if (!strncmp(cp, "PRODUCT=", strlen("PRODUCT="))) {
@@ -539,92 +342,51 @@
mic_degrade_status = cp;
} else if (!strncmp(cp, "DEVPATH=", strlen("DEVPATH="))) {
devpath = cp;
+ } else if (!strncmp(cp, "POWER_SUPPLY_PRESENT=",
+ strlen("POWER_SUPPLY_PRESENT="))) {
+ powpresent = cp;
} else if (!strncmp(cp, "SUBSYSTEM=", strlen("SUBSYSTEM="))) {
subsystem = cp;
- } else if (!strncmp(cp, "DEVTYPE=typec_partner", strlen("DEVTYPE=typec_partner"))) {
- collect_partner_id = true;
- } else if (!strncmp(cp, "POWER_SUPPLY_NAME=wireless",
- strlen("POWER_SUPPLY_NAME=wireless"))) {
- pow_wireless = true;
- } else if (!strncmp(cp, "POWER_SUPPLY_ONLINE=1", strlen("POWER_SUPPLY_ONLINE=1"))) {
- pow_online = true;
- } else if (!kWirelessChargerPtmcUevent.empty() &&
- !strncmp(cp, kWirelessChargerPtmcUevent.c_str(),
- strlen(kWirelessChargerPtmcUevent.c_str()))) {
- pow_ptmc = cp + strlen(kWirelessChargerPtmcUevent.c_str());
}
+
/* advance to after the next \0 */
while (*cp++) {
}
}
- std::shared_ptr<IStats> stats_client = getStatsService();
- if (!stats_client) {
- ALOGE("Unable to get Stats service instance.");
- } else {
- /* Process the strings recorded. */
- ReportMicStatusUevents(stats_client, devpath, mic_break_status);
- ReportMicStatusUevents(stats_client, devpath, mic_degrade_status);
- ReportUsbPortOverheatEvent(stats_client, driver);
- ReportChargeMetricsEvent(stats_client, driver);
- ReportWlc(stats_client, pow_wireless, pow_online, pow_ptmc);
- ReportBatteryCapacityFGEvent(stats_client, subsystem);
- if (collect_partner_id) {
- ReportTypeCPartnerId(stats_client);
- }
- }
+ /* Process the strings recorded. */
+ ReportMicStatusUevents(devpath, mic_break_status);
+ ReportMicStatusUevents(devpath, mic_degrade_status);
+ ReportUsbPortOverheatEvent(driver);
+ ReportChargeMetricsEvent(driver);
+ ReportWlc(powpresent);
+ ReportBatteryCapacityFGEvent(subsystem);
- if (log_fd_ > 0) {
- write(log_fd_, "\n", 1);
- }
return true;
}
UeventListener::UeventListener(const std::string audio_uevent, const std::string ssoc_details_path,
const std::string overheat_path,
- const std::string charge_metrics_path,
- const std::string typec_partner_vid_path,
- const std::string typec_partner_pid_path)
+ const std::string charge_metrics_path)
: kAudioUevent(audio_uevent),
kBatterySSOCPath(ssoc_details_path),
kUsbPortOverheatPath(overheat_path),
kChargeMetricsPath(charge_metrics_path),
- kTypeCPartnerVidPath(typec_partner_vid_path),
- kTypeCPartnerPidPath(typec_partner_pid_path),
- kWirelessChargerPtmcUevent(""),
- kWirelessChargerPtmcPath(""),
uevent_fd_(-1),
- log_fd_(-1) {}
-
-UeventListener::UeventListener(const struct UeventPaths &uevents_paths)
- : kAudioUevent((uevents_paths.AudioUevent == nullptr) ? "" : uevents_paths.AudioUevent),
- kBatterySSOCPath((uevents_paths.SsocDetailsPath == nullptr) ? ssoc_details_path
- : uevents_paths.SsocDetailsPath),
- kUsbPortOverheatPath((uevents_paths.OverheatPath == nullptr) ? overheat_path_default
- : uevents_paths.OverheatPath),
- kChargeMetricsPath((uevents_paths.ChargeMetricsPath == nullptr)
- ? charge_metrics_path_default
- : uevents_paths.ChargeMetricsPath),
- kTypeCPartnerVidPath((uevents_paths.TypeCPartnerVidPath == nullptr)
- ? typec_partner_vid_path_default
- : uevents_paths.TypeCPartnerVidPath),
- kTypeCPartnerPidPath((uevents_paths.TypeCPartnerPidPath == nullptr)
- ? typec_partner_pid_path_default
- : uevents_paths.TypeCPartnerPidPath),
- kWirelessChargerPtmcUevent((uevents_paths.WirelessChargerPtmcUevent == nullptr)
- ? ""
- : uevents_paths.WirelessChargerPtmcUevent),
- kWirelessChargerPtmcPath((uevents_paths.WirelessChargerPtmcPath == nullptr)
- ? ""
- : uevents_paths.WirelessChargerPtmcPath),
- uevent_fd_(-1),
- log_fd_(-1) {}
+ wireless_charging_state_(false) {}
/* Thread function to continuously monitor uevents.
* Exit after kMaxConsecutiveErrors to prevent spinning. */
void UeventListener::ListenForever() {
constexpr int kMaxConsecutiveErrors = 10;
int consecutive_errors = 0;
+ sp<WlcReporter> wlc_reporter = new WlcReporter();
+ if (wlc_reporter != nullptr) {
+ wireless_charging_supported_ = wlc_reporter->isWlcSupported();
+ } else {
+ ALOGE("Fail to create WlcReporter.");
+ wireless_charging_supported_ = false;
+ }
while (1) {
if (ProcessUevent()) {
diff --git a/pixelstats/WirelessChargeStats.cpp b/pixelstats/WirelessChargeStats.cpp
deleted file mode 100644
index 6fd34c4..0000000
--- a/pixelstats/WirelessChargeStats.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2021 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 LOG_TAG "pixelstats-uevent"
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-#include <log/log.h>
-#include <pixelstats/WirelessChargeStats.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using android::base::ReadFileToString;
-using android::base::WriteStringToFile;
-
-/* Reference to <kernel>/private/google-modules/bms/p9221_charger.h
- * translate sys_mode value to enum define in pixelatoms.proto
- */
-int WirelessChargeStats::TranslateSysModeToAtomValue(const int sys_mode) {
- switch (sys_mode) {
- case 1:
- return PixelAtoms::ChargeStats::ADAPTER_TYPE_WPC_BPP;
- case 2:
- return PixelAtoms::ChargeStats::ADAPTER_TYPE_WPC_EPP;
- case 3:
- return PixelAtoms::ChargeStats::ADAPTER_TYPE_WPC_L7;
- default:
- return PixelAtoms::ChargeStats::ADAPTER_TYPE_WLC;
- }
-}
-
-bool WirelessChargeStats::CheckWirelessContentsAndAck(std::string *file_contents) {
- std::string line;
- std::istringstream ss;
-
- if (!ReadFileToString(kWirelessChargeMetricsPath.c_str(), file_contents))
- return false;
-
- ss.str(*file_contents);
-
- if (!std::getline(ss, line)) {
- ALOGE("Unable to read first line %s - %s", kWirelessChargeMetricsPath.c_str(),
- strerror(errno));
- return false;
- }
- if (!WriteStringToFile(std::to_string(0), kWirelessChargeMetricsPath.c_str())) {
- ALOGE("Couldn't clear %s - %s", kWirelessChargeMetricsPath.c_str(), strerror(errno));
- return false;
- }
- return true;
-}
-
-void WirelessChargeStats::ResetChargeMetrics() {
- pout_min_ = 0;
- pout_avg_ = 0;
- pout_max_ = 0;
- of_freq_ = 0;
- alignment_ = 0;
- count_ = 0;
-}
-
-void WirelessChargeStats::CalculateWirelessChargeMetrics(const int pout_min, const int pout_avg,
- const int pout_max, const int of_freq,
- const int alignment) {
- if ((pout_min_ == 0) || (pout_min_ > pout_min))
- pout_min_ = pout_min;
-
- pout_avg_ += pout_avg;
- count_++;
-
- if ((pout_max_ == 0) || (pout_max_ < pout_max))
- pout_max_ = pout_max;
-
- if (alignment_ == 0 || ((alignment >= 0) && (alignment_ > alignment))) {
- of_freq_ = of_freq;
- alignment_ = alignment;
- }
-}
-
-void WirelessChargeStats::CalculateWirelessChargeStats(const int ssoc_tmp,
- const std::string file_contents) {
- std::string line;
- std::istringstream ss;
-
- ResetChargeMetrics();
- ss.str(file_contents);
-
- while (std::getline(ss, line)) {
- int32_t buf[11] = {0};
- if (sscanf(line.c_str(), "%d:%d, %d,%d,%d, %d,%d, %d,%d,%d,%d", &buf[0], &buf[1], &buf[2],
- &buf[3], &buf[4], &buf[5], &buf[6], &buf[7], &buf[8], &buf[9], &buf[10]) == 11) {
- const int32_t soc = buf[0];
-
- /* calculate wireless charge stats of next voltage tier */
- if (soc > tier_soc_) {
- const int32_t alignment = buf[6];
-
- if (alignment >= 0 && alignment < 100)
- ALOGD("WirelessChargeStats: misalignment %s", line.c_str());
-
- CalculateWirelessChargeMetrics(buf[2], buf[3], buf[4], buf[5], buf[6]);
- if (soc >= ssoc_tmp) {
- /* reach next voltage tier, restore final results before sending out*/
- pout_avg_ = (pout_avg_ / count_);
- tier_soc_ = soc;
- ALOGD("WirelessChargeStats: atoms %d %d %d %d", pout_min_, pout_avg_, pout_max_,
- of_freq_);
- return;
- }
- }
- }
- }
-}
-
-WirelessChargeStats::WirelessChargeStats(const std::string wireless_charge_metrics_path)
- : kWirelessChargeMetricsPath(wireless_charge_metrics_path) {}
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/pixelstats/WlcReporter.cpp b/pixelstats/WlcReporter.cpp
index fc72aae..7c9a93f 100644
--- a/pixelstats/WlcReporter.cpp
+++ b/pixelstats/WlcReporter.cpp
@@ -17,200 +17,51 @@
#define LOG_TAG "pixelstats-wlc"
#include <android-base/file.h>
-#include <android-base/strings.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
#include <log/log.h>
#include <pixelstats/OrientationCollector.h>
#include <pixelstats/WlcReporter.h>
-#include <sys/timerfd.h>
-#include <time.h>
-#include <utils/Timers.h>
-#include <thread>
+#define POWER_SUPPLY_SYSFS_PATH "/sys/class/power_supply/wireless/online"
+#define POWER_SUPPLY_PTMC_PATH "/sys/class/power_supply/wireless/ptmc_id"
+#define GOOGLE_PTMC_ID 72
-/* I set a higher rare limit ti orientation, beacuae user might try to adjust
- * orientation when start charge
- **/
-#define GOOGLE_PTMC_ID (0x72)
-#define ID_UNKNOWN (0)
-#define WLC_VENDOR_REPORT_RATE_LIMIT_MIN_SEC (60 * 60)
-#define WLC_VENDOR_REPORT_RATE_LIMIT_MAX_COUNT_PER_DAY (10)
-#define ORIENTATION_REPORT_RATE_LIMIT_MIN_SEC (0)
-#define ORIENTATION_REPORT_RATE_LIMIT_MAX_COUNT_PER_DAY (10)
-#define DAY_SECOND (86400)
+using android::base::ReadFileToString;
+using android::frameworks::stats::V1_0::IStats;
+using android::frameworks::stats::V1_0::VendorAtom;
namespace android {
namespace hardware {
namespace google {
namespace pixel {
-using aidl::android::frameworks::stats::IStats;
-using aidl::android::frameworks::stats::VendorAtom;
-using aidl::android::frameworks::stats::VendorAtomValue;
-using android::base::ReadFileToString;
-
-WlcReporter::WlcStatus::WlcStatus()
- : is_charging(false),
- check_charger_vendor_id(false),
- check_charger_vendor_id_scheduled(false),
- check_vendor_id_attempts(0) {}
-
-WlcReporter::ReportRecord::ReportRecord(char const *name_)
- : name(name_),
- last_reported_time_in_sec_today(0),
- last_reported_time_in_sec(0),
- count_today(0) {}
-
-WlcReporter::WlcReporter(const char *ptmc_path) : kWirelessChargerPtmcPath(ptmc_path) {}
-void WlcReporter::checkAndReport(const std::shared_ptr<IStats> &stats_client, bool online,
- const char *ptmc_uevent) {
- bool wireless_charging = online;
- bool started_wireless_charging = wireless_charging && !wlc_status_.is_charging;
- wlc_status_.is_charging = wireless_charging;
- ALOGV("reportVendorId is_charging: %s, started_wireless_charging: %s",
- (wireless_charging) ? "true" : "false", (started_wireless_charging) ? "true" : "false");
-
- if (started_wireless_charging) {
- reportOrientation(stats_client);
- wlc_status_.check_vendor_id_attempts = 0;
- if (checkRateLimit(WLC_VENDOR_REPORT_RATE_LIMIT_MIN_SEC,
- WLC_VENDOR_REPORT_RATE_LIMIT_MAX_COUNT_PER_DAY, &rec_wlc_vendor_)) {
- wlc_status_.check_charger_vendor_id = true;
- if (kWirelessChargerPtmcPath != nullptr && strlen(kWirelessChargerPtmcPath) != 0) {
- scheduleReportVendorId(stats_client);
- } else {
- ALOGV("ptmc_path not set");
- }
- }
+bool WlcReporter::checkAndReport(bool isWirelessChargingLast) {
+ bool wireless_charging = isWlcOnline();
+ if (wireless_charging && !isWirelessChargingLast) {
+ doLog();
}
- if (!wireless_charging) {
- wlc_status_.check_charger_vendor_id = false;
- }
- if (wireless_charging) {
- checkVendorId(stats_client, ptmc_uevent);
- }
+ return wireless_charging;
}
-void WlcReporter::checkVendorId(const std::shared_ptr<IStats> &stats_client,
- const char *ptmc_uevent) {
- if (!ptmc_uevent || !wlc_status_.check_charger_vendor_id) {
- return;
- }
- if (reportVendorMayRetry(stats_client, ptmc_uevent)) {
- wlc_status_.check_charger_vendor_id = false;
- }
-}
+bool WlcReporter::readFileToInt(const char *const path, int *val) {
+ std::string file_contents;
-bool WlcReporter::reportVendorMayRetry(const std::shared_ptr<IStats> &stats_client,
- const char *ptmc_uevent) {
- int ptmcId = readPtmcId(ptmc_uevent);
- if (ptmcId == ID_UNKNOWN) {
- if (++(wlc_status_.check_vendor_id_attempts) < kMaxVendorIdAttempts) {
- return false;
- } /* else if ptmc not ready after retry assume ptmc not supported by charger */
+ if (!ReadFileToString(path, &file_contents)) {
+ ALOGE("Unable to read %s - %s", path, strerror(errno));
+ return false;
+ } else if (sscanf(file_contents.c_str(), "%d", val) != 1) {
+ ALOGE("Unable to convert %s (%s) to int - %s", path, file_contents.c_str(),
+ strerror(errno));
+ return false;
}
- ALOGV("reportVendorId from Uevent");
- reportVendor(stats_client, ptmcId);
return true;
}
-void WlcReporter::reportVendor(const std::shared_ptr<IStats> &stats_client, const int ptmcId) {
- int vendorCharger = (ptmcId == GOOGLE_PTMC_ID)
- ? PixelAtoms::WirelessChargingStats::VENDOR_GOOGLE
- : PixelAtoms::WirelessChargingStats::VENDOR_UNKNOWN;
- ALOGV("ptmcId: 0x%x; vendorCharger: %d", ptmcId, vendorCharger);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(vendorCharger);
- std::vector<VendorAtomValue> values(1);
- values[PixelAtoms::WirelessChargingStats::kChargerVendorFieldNumber - kVendorAtomOffset] = tmp;
-
- // Send vendor atom to IStats HAL
- VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kWirelessChargingStats,
- .values = std::move(values)};
- const ndk::ScopedAStatus retStat = stats_client->reportVendorAtom(event);
- if (!retStat.isOk()) {
- ALOGE("Unable to report WLC_STATS to Stats service");
- }
- return;
-}
-
-int WlcReporter::readPtmcId(const char *ptmc_str) {
- int id;
- if (sscanf(ptmc_str, "%x", &id) != 1) {
- return ID_UNKNOWN;
- }
+int WlcReporter::readPtmcId() {
+ int id = 0;
+ readFileToInt(POWER_SUPPLY_PTMC_PATH, &id);
return id;
}
-void WlcReporter::scheduleReportVendorId(const std::shared_ptr<IStats> &stats_client) {
- if (wlc_status_.check_charger_vendor_id_scheduled) {
- return;
- }
-
- wlc_status_.check_charger_vendor_id_scheduled = true;
- std::thread taskThread(&WlcReporter::reportInBackground, this, stats_client,
- kWirelessChargerPtmcPath);
- taskThread.detach();
-}
-
-bool WlcReporter::ptmcWaitTimer(int timerfd) {
- const int kDelaytimeBeforeReadPtmcId = 60;
- struct itimerspec period;
- period.it_interval.tv_sec = 0;
- period.it_interval.tv_nsec = 0;
- period.it_value.tv_sec = kDelaytimeBeforeReadPtmcId;
- period.it_value.tv_nsec = 0;
-
- if (timerfd_settime(timerfd, 0, &period, nullptr)) {
- ALOGE("Unable to set timer - %s", strerror(errno));
- return false;
- }
- int readval;
- do {
- char buf[8];
- errno = 0;
- readval = read(timerfd, buf, sizeof(buf));
- } while (readval < 0 && errno == EINTR);
- if (readval < 0) {
- ALOGE("Timerfd error - %s", strerror(errno));
- return false;
- }
- return true;
-}
-
-/*
- * PTMC path use to sore wireless charger vendor id,
- * and it take some time to get ready after wireless chagre start,
- * to prevnt busy wait, I use timer and background thread to check PTMC ID
- **/
-void WlcReporter::reportInBackground(const std::shared_ptr<IStats> &stats_client,
- const char *ptmc_path) {
- int timerfd = timerfd_create(CLOCK_BOOTTIME, 0);
- if (timerfd < 0) {
- ALOGE("Unable to create timerfd - %s", strerror(errno));
- return;
- }
- if (ptmcWaitTimer(timerfd)) {
- if (!wlc_status_.is_charging) {
- ALOGV("Not charging, skip report vender id");
- } else if (!wlc_status_.check_charger_vendor_id) {
- ALOGV("id reported by uevnt, skip report vender id");
- } else {
- std::string file_contents;
- if (!ReadFileToString(ptmc_path, &file_contents)) {
- ALOGE("ReadFileToString %s fail", ptmc_path);
- } else {
- int ptmcId = readPtmcId(file_contents.c_str());
- ALOGV("reportVendorId from file");
- reportVendor(stats_client, ptmcId);
- }
- }
- }
- wlc_status_.check_charger_vendor_id_scheduled = false;
- close(timerfd);
-}
-
/* Reference to frameworks/native/libs/ui/include/ui/DisplayInfo.h
* translate orientation value from sensor to enum define in
* pixelatoms.proto
@@ -230,61 +81,71 @@
}
}
-void WlcReporter::reportOrientation(const std::shared_ptr<IStats> &stats_client) {
- ALOGV("reportOrientation");
- if (!checkRateLimit(ORIENTATION_REPORT_RATE_LIMIT_MIN_SEC,
- ORIENTATION_REPORT_RATE_LIMIT_MAX_COUNT_PER_DAY, &rec_orientation_)) {
+void WlcReporter::doLog() {
+ sp<IStats> stats_client = IStats::tryGetService();
+
+ if (stats_client == nullptr) {
+ ALOGE("logWlc get IStats fail.");
return;
}
- sp<OrientationCollector> orientationCollector =
- OrientationCollector::createOrientationCollector();
- if (orientationCollector != nullptr) {
- int orientationFromSensor = -1;
- orientationCollector->pollOrientation(&orientationFromSensor);
- VendorAtomValue tmp;
- tmp.set<VendorAtomValue::intValue>(
- translateDeviceOrientationToAtomValue(orientationFromSensor));
+ std::vector<VendorAtom::Value> values(1);
- std::vector<VendorAtomValue> values(1);
+ int vendoriCharger = (readPtmcId() == GOOGLE_PTMC_ID)
+ ? PixelAtoms::WirelessChargingStats::VENDOR_GOOGLE
+ : PixelAtoms::WirelessChargingStats::VENDOR_UNKNOWN;
+ VendorAtom::Value tmp;
+ tmp.intValue(vendoriCharger);
+ values[PixelAtoms::WirelessChargingStats::kChargerVendorFieldNumber - kVendorAtomOffset] = tmp;
+
+ // Send vendor atom to IStats HAL
+ VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
+ .atomId = PixelAtoms::Ids::WIRELESS_CHARGING_STATS,
+ .values = values};
+ Return<void> retStat = stats_client->reportVendorAtom(event);
+ if (!retStat.isOk())
+ ALOGE("Unable to report WLC_STATS to Stats service");
+
+ int orientationFromSensor;
+ sp<OrientationCollector> orientationCollector;
+ orientationCollector = OrientationCollector::createOrientationCollector();
+ if (orientationCollector != nullptr) {
+ orientationCollector->pollOrientation(&orientationFromSensor);
+ VendorAtom::Value tmp;
+ tmp.intValue(translateDeviceOrientationToAtomValue(orientationFromSensor));
values[PixelAtoms::DeviceOrientation::kOrientationFieldNumber - kVendorAtomOffset] = tmp;
VendorAtom event = {.reverseDomainName = PixelAtoms::ReverseDomainNames().pixel(),
- .atomId = PixelAtoms::Atom::kDeviceOrientation,
- .values = std::move(values)};
- const ndk::ScopedAStatus retStat = stats_client->reportVendorAtom(event);
- if (!retStat.isOk()) {
+ .atomId = PixelAtoms::Ids::DEVICE_ORIENTATION,
+ .values = values};
+ Return<void> retOrientation = stats_client->reportVendorAtom(event);
+ if (!retOrientation.isOk())
ALOGE("Unable to report Orientation to Stats service");
- }
orientationCollector->disableOrientationSensor();
}
}
-bool WlcReporter::checkRateLimit(int64_t minSecond, int maxCount, ReportRecord *rec) {
- if (rec == nullptr) {
- ALOGE("ReportRecord should not be NULL");
+bool WlcReporter::isWlcSupported() {
+ std::string file_contents;
+
+ if (!ReadFileToString(POWER_SUPPLY_SYSFS_PATH, &file_contents)) {
+ ALOGV("Unable to read %s - %s", POWER_SUPPLY_SYSFS_PATH, strerror(errno));
return false;
+ } else {
+ return true;
}
- int64_t now = nanoseconds_to_seconds(systemTime(SYSTEM_TIME_BOOTTIME));
- if (rec->last_reported_time_in_sec > 0 && now - rec->last_reported_time_in_sec < minSecond) {
- ALOGV("%s: Rate limit, min period: %ld", rec->name, minSecond);
- return false;
- }
- if (rec->last_reported_time_in_sec_today == 0) {
- rec->last_reported_time_in_sec_today = now;
- ALOGV("%s: reset day time (init)", rec->name);
- } else if (now - rec->last_reported_time_in_sec_today > DAY_SECOND) {
- rec->last_reported_time_in_sec_today = now;
- rec->count_today = 0;
- ALOGV("%s: reset day time", rec->name);
- } else if (rec->count_today >= maxCount) {
- ALOGV("%s: Rate limit, max count: %d", rec->name, maxCount);
- return false;
- }
- (rec->count_today)++;
- ALOGV("%s: checkRateLimit count: %d", rec->name, rec->count_today);
- rec->last_reported_time_in_sec = now;
- return true;
}
+
+bool WlcReporter::isWlcOnline() {
+ std::string file_contents;
+
+ if (!ReadFileToString(POWER_SUPPLY_SYSFS_PATH, &file_contents)) {
+ ALOGE("Unable to read %s - %s", POWER_SUPPLY_SYSFS_PATH, strerror(errno));
+ return false;
+ }
+ ALOGV("isWlcOnline value: %s", file_contents.c_str());
+ return file_contents == "1\n";
+}
+
} // namespace pixel
} // namespace google
} // namespace hardware
diff --git a/pixelstats/include/pixelstats/BatteryCapacityReporter.h b/pixelstats/include/pixelstats/BatteryCapacityReporter.h
index 07e69e7..eb0effe 100644
--- a/pixelstats/include/pixelstats/BatteryCapacityReporter.h
+++ b/pixelstats/include/pixelstats/BatteryCapacityReporter.h
@@ -17,32 +17,25 @@
#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_BATTERYCAPACITYREPORTER_H
#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_BATTERYCAPACITYREPORTER_H
-#include <aidl/android/frameworks/stats/IStats.h>
-
namespace android {
namespace hardware {
namespace google {
namespace pixel {
-using aidl::android::frameworks::stats::IStats;
-
-#define MAX_LOG_EVENTS_PER_HOUR 4
-
/**
* A class to upload battery capacity metrics
*/
class BatteryCapacityReporter {
public:
BatteryCapacityReporter();
- void checkAndReport(const std::shared_ptr<IStats> &stats_client, const std::string &path);
+ void checkAndReport(const std::string &path);
private:
int64_t getTimeSecs();
bool parse(const std::string &path);
- bool checkLogEvent(void);
- bool shouldReportEvent(void);
- void reportEvent(const std::shared_ptr<IStats> &stats_client);
+ bool check(void);
+ void report(void);
/**
* SOC status translation from sysfs node
@@ -71,11 +64,10 @@
float ssoc_curve_ = 0.0f;
float ssoc_previous_ = -1.0f;
float ssoc_gdf_diff_previous_ = 0.0f;
+ int64_t unexpected_event_timer_secs_ = 0;
+ bool unexpected_event_timer_active_ = false;
LogReason log_reason_ = LOG_REASON_UNKNOWN;
- int num_events_in_last_hour_ = 0;
- int64_t log_event_time_secs_[MAX_LOG_EVENTS_PER_HOUR] = {0};
-
// Proto messages are 1-indexed and VendorAtom field numbers start at 2, so
// store everything in the values array at the index of the field number
// -2.
diff --git a/pixelstats/include/pixelstats/BatteryEEPROMReporter.h b/pixelstats/include/pixelstats/BatteryEEPROMReporter.h
deleted file mode 100644
index 5019731..0000000
--- a/pixelstats/include/pixelstats/BatteryEEPROMReporter.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_BATTERYEEPROMREPORTER_H
-#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_BATTERYEEPROMREPORTER_H
-
-#include <cstdint>
-#include <string>
-
-#include <aidl/android/frameworks/stats/IStats.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using aidl::android::frameworks::stats::IStats;
-
-// The storage for save whole history is 928 byte
-// each history contains 19 items with total size 28 byte
-// hence the history number is 928/28~33
-#define BATT_HIST_NUM_MAX 33
-
-/**
- * A class to upload battery EEPROM metrics
- */
-class BatteryEEPROMReporter {
- public:
- BatteryEEPROMReporter();
- void checkAndReport(const std::shared_ptr<IStats> &stats_client, const std::string &path);
-
- private:
- // Proto messages are 1-indexed and VendorAtom field numbers start at 2, so
- // store everything in the values array at the index of the field number
- // -2.
- const int kVendorAtomOffset = 2;
-
- struct BatteryHistory {
- /* The cycle count number; record of charge/discharge times */
- uint16_t cycle_cnt;
- /* The current full capacity of the battery under nominal conditions */
- uint16_t full_cap;
- /* The battery equivalent series resistance */
- uint16_t esr;
- /* Battery resistance related to temperature change */
- uint16_t rslow;
- /* Battery health indicator reflecting the battery age state */
- uint8_t soh;
- /* The battery temperature */
- int8_t batt_temp;
- /* Battery state of charge (SOC) shutdown point */
- uint8_t cutoff_soc;
- /* Raw battery state of charge (SOC), based on battery current (CC = Coulomb Counter) */
- uint8_t cc_soc;
- /* Estimated battery state of charge (SOC) from batt_soc with endpoint limiting
- * (0% and 100%)
- */
- uint8_t sys_soc;
- /* Filtered monotonic SOC, handles situations where the cutoff_soc is increased and
- * then decreased from the battery physical properties
- */
- uint8_t msoc;
- /* Estimated SOC derived from cc_soc that provides voltage loop feedback correction using
- * battery voltage, current, and status values
- */
- uint8_t batt_soc;
-
- /* Field used for data padding in the EEPROM data */
- uint8_t reserve;
-
- /* The maximum battery temperature ever seen */
- int8_t max_temp;
- /* The minimum battery temperature ever seen */
- int8_t min_temp;
- /* The maximum battery voltage ever seen */
- uint16_t max_vbatt;
- /* The minimum battery voltage ever seen */
- uint16_t min_vbatt;
- /* The maximum battery current ever seen */
- int16_t max_ibatt;
- /* The minimum battery current ever seen */
- int16_t min_ibatt;
- /* Field used to verify the integrity of the EEPROM data */
- uint16_t checksum;
- };
- /* The number of elements in struct BatteryHistory */
- const int kNumBatteryHistoryFields = 19;
-
- int64_t report_time_ = 0;
- int64_t getTimeSecs();
-
- bool checkLogEvent(struct BatteryHistory hist);
- void reportEvent(const std::shared_ptr<IStats> &stats_client,
- const struct BatteryHistory &hist);
-};
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_BATTERYEEPROMREPORTER_H
diff --git a/pixelstats/include/pixelstats/MitigationStatsReporter.h b/pixelstats/include/pixelstats/MitigationStatsReporter.h
deleted file mode 100644
index 219cfa8..0000000
--- a/pixelstats/include/pixelstats/MitigationStatsReporter.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_MITIGATIONSTATSREPORTER_H
-#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_MITIGATIONSTATSREPORTER_H
-
-#include <map>
-#include <string>
-
-#include <aidl/android/frameworks/stats/IStats.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using aidl::android::frameworks::stats::IStats;
-using aidl::android::frameworks::stats::VendorAtomValue;
-
-/**
- * A class to upload Pixel Mitigation Stats metrics
- */
-class MitigationStatsReporter {
- public:
- MitigationStatsReporter();
- void logMitigationStatsPerHour(const std::shared_ptr<IStats> &stats_client,
- const std::string &path);
-
- private:
- struct MitigationCount {
- int batoilo_count;
- int vdroop1_count;
- int vdroop2_count;
- int smpl_warn_count;
- int ocp_cpu1_count;
- int ocp_cpu2_count;
- int ocp_tpu_count;
- int ocp_gpu_count;
- int soft_ocp_cpu1_count;
- int soft_ocp_cpu2_count;
- int soft_ocp_tpu_count;
- int soft_ocp_gpu_count;
- };
-
- struct MitigationCap {
- int batoilo_cap;
- int vdroop1_cap;
- int vdroop2_cap;
- int smpl_warn_cap;
- int ocp_cpu1_cap;
- int ocp_cpu2_cap;
- int ocp_tpu_cap;
- int ocp_gpu_cap;
- int soft_ocp_cpu1_cap;
- int soft_ocp_cpu2_cap;
- int soft_ocp_tpu_cap;
- int soft_ocp_gpu_cap;
- };
-
- // Proto messages are 1-indexed and VendorAtom field numbers start at 2, so
- // store everything in the values array at the index of the field number
- // -2.
- const int kVendorAtomOffset = 2;
- struct MitigationCount prev_count;
-
- bool logMitigationCount(const std::string kMitigationDir, struct MitigationCount *last_count);
- void logMitigationCap(const std::string kMitigationDir, struct MitigationCap *last_cap);
- bool ReadFileToInt(const std::string &path, int *val);
-};
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_MITIGATIONSTATSREPORTER_H
diff --git a/pixelstats/include/pixelstats/MmMetricsReporter.h b/pixelstats/include/pixelstats/MmMetricsReporter.h
deleted file mode 100644
index 1af6fe2..0000000
--- a/pixelstats/include/pixelstats/MmMetricsReporter.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_MMMETRICSREPORTER_H
-#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_MMMETRICSREPORTER_H
-
-#include <map>
-#include <string>
-
-#include <aidl/android/frameworks/stats/IStats.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using aidl::android::frameworks::stats::IStats;
-using aidl::android::frameworks::stats::VendorAtomValue;
-
-/**
- * A class to upload Pixel MM health metrics
- */
-class MmMetricsReporter {
- public:
- MmMetricsReporter();
- void logPixelMmMetricsPerHour(const std::shared_ptr<IStats> &stats_client);
- void logPixelMmMetricsPerDay(const std::shared_ptr<IStats> &stats_client);
- void logCmaStatus(const std::shared_ptr<IStats> &stats_client);
-
- private:
- struct MmMetricsInfo {
- std::string name;
- int atom_key;
- bool update_diff;
- };
-
- enum CmaType {
- FARAWIMG = 0,
- FAIMG = 1,
- FATPU = 2,
- FAPREV = 3,
- VFRAME = 4,
- VSTREAM = 5,
- };
-
- static const std::vector<MmMetricsInfo> kMmMetricsPerHourInfo;
- static const std::vector<MmMetricsInfo> kMmMetricsPerDayInfo;
- static const std::vector<MmMetricsInfo> kCmaStatusInfo;
- static const std::vector<MmMetricsInfo> kCmaStatusExtInfo;
- static const std::map<std::string, CmaType> kCmaTypeInfo;
-
- bool ReadFileToUint(const char *const path, uint64_t *val);
- bool reportVendorAtom(const std::shared_ptr<IStats> &stats_client, int atom_id,
- const std::vector<VendorAtomValue> &values, const std::string &atom_name);
- std::map<std::string, uint64_t> readVmStat(const char *path);
- uint64_t getIonTotalPools();
- uint64_t getGpuMemory();
- void fillAtomValues(const std::vector<MmMetricsInfo> &metrics_info,
- const std::map<std::string, uint64_t> &mm_metrics,
- std::map<std::string, uint64_t> *prev_mm_metrics,
- std::vector<VendorAtomValue> *atom_values);
- bool isValidPid(int pid, const char *name);
- int findPidByProcessName(const char *name);
- uint64_t getStimeByPid(int pid);
- void fillProcessStime(int atom_key, const char *name, int *pid, uint64_t *prev_stime,
- std::vector<VendorAtomValue> *atom_values);
- std::map<std::string, uint64_t> readCmaStat(const std::string &cma_type,
- const std::vector<MmMetricsInfo> &metrics_info);
- void reportCmaStatusAtom(const std::shared_ptr<IStats> &stats_client, int atom_id,
- const std::string &cma_type, CmaType type_idx,
- const std::vector<MmMetricsInfo> &metrics_info,
- std::map<CmaType, std::map<std::string, uint64_t>> *all_prev_cma_stat);
-
- const char *const kVmstatPath;
- const char *const kIonTotalPoolsPath;
- const char *const kIonTotalPoolsPathForLegacy;
- const char *const kGpuTotalPages;
- const char *const kPixelStatMm;
- // Proto messages are 1-indexed and VendorAtom field numbers start at 2, so
- // store everything in the values array at the index of the field number
- // -2.
- const int kVendorAtomOffset = 2;
-
- std::map<std::string, uint64_t> prev_hour_vmstat_;
- std::map<std::string, uint64_t> prev_day_vmstat_;
- std::map<std::string, uint64_t> prev_day_pixel_vmstat_;
- std::map<CmaType, std::map<std::string, uint64_t>> prev_cma_stat_;
- std::map<CmaType, std::map<std::string, uint64_t>> prev_cma_stat_ext_;
- int kswapd_pid_ = -1;
- int kcompactd_pid_ = -1;
- uint64_t prev_kswapd_stime_ = 0;
- uint64_t prev_kcompactd_stime_ = 0;
-};
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_BATTERYCAPACITYREPORTER_H
diff --git a/pixelstats/include/pixelstats/PcaChargeStats.h b/pixelstats/include/pixelstats/PcaChargeStats.h
deleted file mode 100644
index 90a6c3e..0000000
--- a/pixelstats/include/pixelstats/PcaChargeStats.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_PCACHARGESTATS_H
-#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_PCACHARGESTATS_H
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-class PcaChargeStats {
- public:
- PcaChargeStats(const std::string pca_charge_metrics_path =
- "/sys/class/power_supply/pca9468-mains/device/chg_stats");
-
- bool CheckPcaContentsAndAck(std::string *file_contents);
-
- private:
- const std::string kPcaChargeMetricsPath;
-};
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_PCACHARGESTATS_H
diff --git a/pixelstats/include/pixelstats/StatsHelper.h b/pixelstats/include/pixelstats/StatsHelper.h
deleted file mode 100644
index b8a2390..0000000
--- a/pixelstats/include/pixelstats/StatsHelper.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_STATSHELPER_H
-#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_STATSHELPER_H
-
-#include <aidl/android/frameworks/stats/IStats.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-using aidl::android::frameworks::stats::IStats;
-
-std::shared_ptr<IStats> getStatsService();
-
-void reportSpeakerImpedance(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorSpeakerImpedance &speakerImpedance);
-
-void reportSlowIo(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorSlowIo &slowIo);
-
-void reportChargeCycles(const std::shared_ptr<IStats> &stats_client,
- const std::vector<int32_t> &chargeCycles);
-
-void reportHardwareFailed(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorHardwareFailed &failure);
-
-void reportSpeechDspStat(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorSpeechDspStat &dsp_stats);
-
-void reportPhysicalDropDetected(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorPhysicalDropDetected &dropDetected);
-
-void reportUsbPortOverheat(const std::shared_ptr<IStats> &stats_client,
- const PixelAtoms::VendorUsbPortOverheat &overheat_info);
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_STATSHELPER_H
diff --git a/pixelstats/include/pixelstats/SysfsCollector.h b/pixelstats/include/pixelstats/SysfsCollector.h
index 8045d4a..c6cc608 100644
--- a/pixelstats/include/pixelstats/SysfsCollector.h
+++ b/pixelstats/include/pixelstats/SysfsCollector.h
@@ -17,20 +17,18 @@
#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_SYSFSCOLLECTOR_H
#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_SYSFSCOLLECTOR_H
-#include <aidl/android/frameworks/stats/IStats.h>
-#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-#include "BatteryEEPROMReporter.h"
-#include "MitigationStatsReporter.h"
-#include "MmMetricsReporter.h"
+#include <android/frameworks/stats/1.0/IStats.h>
+#include <utils/StrongPointer.h>
+
+using android::sp;
+using android::frameworks::stats::V1_0::IStats;
+using android::frameworks::stats::V1_0::SlowIo;
namespace android {
namespace hardware {
namespace google {
namespace pixel {
-using aidl::android::frameworks::stats::IStats;
-using android::hardware::google::pixel::PixelAtoms::VendorSlowIo;
-
class SysfsCollector {
public:
struct SysfsPaths {
@@ -48,13 +46,10 @@
const char *const UFSLifetimeA;
const char *const UFSLifetimeB;
const char *const UFSLifetimeC;
- const char *const UFSHostResetPath;
const char *const F2fsStatsPath;
const char *const UserdataBlockProp;
const char *const ZramMmStatPath;
const char *const ZramBdStatPath;
- const char *const EEPROMPath;
- const char *const MitigationPath;
};
SysfsCollector(const struct SysfsPaths &paths);
@@ -63,30 +58,25 @@
private:
bool ReadFileToInt(const std::string &path, int *val);
bool ReadFileToInt(const char *path, int *val);
- void logPerDay();
- void logPerHour();
+ void logAll();
- void logBatteryChargeCycles(const std::shared_ptr<IStats> &stats_client);
- void logCodecFailed(const std::shared_ptr<IStats> &stats_client);
- void logCodec1Failed(const std::shared_ptr<IStats> &stats_client);
- void logSlowIO(const std::shared_ptr<IStats> &stats_client);
- void logSpeakerImpedance(const std::shared_ptr<IStats> &stats_client);
- void logSpeechDspStat(const std::shared_ptr<IStats> &stats_client);
- void logBatteryCapacity(const std::shared_ptr<IStats> &stats_client);
- void logUFSLifetime(const std::shared_ptr<IStats> &stats_client);
- void logUFSErrorStats(const std::shared_ptr<IStats> &stats_client);
- void logF2fsStats(const std::shared_ptr<IStats> &stats_client);
- void logF2fsCompressionInfo(const std::shared_ptr<IStats> &stats_client);
- void logF2fsGcSegmentInfo(const std::shared_ptr<IStats> &stats_client);
- void logZramStats(const std::shared_ptr<IStats> &stats_client);
- void logBootStats(const std::shared_ptr<IStats> &stats_client);
- void logBatteryEEPROM(const std::shared_ptr<IStats> &stats_client);
+ void logBatteryChargeCycles();
+ void logCodecFailed();
+ void logCodec1Failed();
+ void logSlowIO();
+ void logSpeakerImpedance();
+ void logSpeechDspStat();
+ void logBatteryCapacity();
+ void logUFSLifetime();
+ void logF2fsStats();
+ void logZramStats();
+ void logBootStats();
- void reportSlowIoFromFile(const std::shared_ptr<IStats> &stats_client, const char *path,
- const VendorSlowIo::IoOperation &operation_s);
- void reportZramMmStat(const std::shared_ptr<IStats> &stats_client);
- void reportZramBdStat(const std::shared_ptr<IStats> &stats_client);
- int getReclaimedSegments(const std::string &mode);
+ void reportSlowIoFromFile(const char *path, const SlowIo::IoOperation &operation_s);
+ void reportZramMmStat();
+ void reportZramBdStat();
+
+ unsigned int getValueFromStatus(std::string &f2fsStatus, const char * key);
const char *const kSlowioReadCntPath;
const char *const kSlowioWriteCntPath;
@@ -102,16 +92,11 @@
const char *const kUFSLifetimeA;
const char *const kUFSLifetimeB;
const char *const kUFSLifetimeC;
- const char *const kUFSHostResetPath;
const char *const kF2fsStatsPath;
+ const char *const kUserdataBlockProp;
const char *const kZramMmStatPath;
const char *const kZramBdStatPath;
- const char *const kEEPROMPath;
- const char *const kPowerMitigationStatsPath;
-
- BatteryEEPROMReporter battery_EEPROM_reporter_;
- MmMetricsReporter mm_metrics_reporter_;
- MitigationStatsReporter mitigation_stats_reporter_;
+ sp<IStats> stats_;
// Proto messages are 1-indexed and VendorAtom field numbers start at 2, so
// store everything in the values array at the index of the field number
@@ -119,7 +104,6 @@
const int kVendorAtomOffset = 2;
bool log_once_reported = false;
- int64_t prev_huge_pages_since_boot_ = -1;
};
} // namespace pixel
diff --git a/pixelstats/include/pixelstats/UeventListener.h b/pixelstats/include/pixelstats/UeventListener.h
index cd701e0..6ffcfb2 100644
--- a/pixelstats/include/pixelstats/UeventListener.h
+++ b/pixelstats/include/pixelstats/UeventListener.h
@@ -17,20 +17,18 @@
#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_UEVENTLISTENER_H
#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_UEVENTLISTENER_H
-#include <aidl/android/frameworks/stats/IStats.h>
#include <android-base/chrono_utils.h>
+#include <android/frameworks/stats/1.0/IStats.h>
#include <pixelstats/BatteryCapacityReporter.h>
-#include <pixelstats/PcaChargeStats.h>
-#include <pixelstats/WirelessChargeStats.h>
-#include <pixelstats/WlcReporter.h>
+
+using android::frameworks::stats::V1_0::IStats;
+using android::frameworks::stats::V1_0::UsbPortOverheatEvent;
namespace android {
namespace hardware {
namespace google {
namespace pixel {
-using aidl::android::frameworks::stats::IStats;
-
/**
* A class to listen for uevents and report reliability events to
* the PixelStats HAL.
@@ -39,37 +37,11 @@
*/
class UeventListener {
public:
- /* Both WirelessChargerPtmcUevent and WirelessChargerPtmcPath is use to get
- * wireless charger ptmx id, for most case we don't need asisign both of
- * them.
- **/
- struct UeventPaths {
- const char *const AudioUevent;
- const char *const SsocDetailsPath;
- const char *const OverheatPath;
- const char *const ChargeMetricsPath;
- const char *const TypeCPartnerVidPath;
- const char *const TypeCPartnerPidPath;
- const char *const WirelessChargerPtmcUevent;
- const char *const WirelessChargerPtmcPath;
- };
- constexpr static const char *const ssoc_details_path =
- "/sys/class/power_supply/battery/ssoc_details";
- constexpr static const char *const overheat_path_default =
- "/sys/devices/platform/soc/soc:google,overheat_mitigation";
- constexpr static const char *const charge_metrics_path_default =
- "/sys/class/power_supply/battery/charge_stats";
- constexpr static const char *const typec_partner_vid_path_default =
- "/sys/class/typec/port0-partner/identity/id_header";
- constexpr static const char *const typec_partner_pid_path_default =
- "/sys/class/typec/port0-partner/identity/product";
-
- UeventListener(const std::string audio_uevent, const std::string ssoc_details_path = "",
- const std::string overheat_path = overheat_path_default,
- const std::string charge_metrics_path = charge_metrics_path_default,
- const std::string typec_partner_vid_path = typec_partner_vid_path_default,
- const std::string typec_partner_pid_path = typec_partner_pid_path_default);
- UeventListener(const struct UeventPaths &paths);
+ UeventListener(
+ const std::string audio_uevent, const std::string ssoc_details_path = "",
+ const std::string overheat_path =
+ "/sys/devices/platform/soc/soc:google,overheat_mitigation",
+ const std::string charge_metrics_path = "/sys/class/power_supply/battery/charge_stats");
bool ProcessUevent(); // Process a single Uevent.
void ListenForever(); // Process Uevents forever
@@ -77,32 +49,19 @@
private:
bool ReadFileToInt(const std::string &path, int *val);
bool ReadFileToInt(const char *path, int *val);
- void ReportMicStatusUevents(const std::shared_ptr<IStats> &stats_client, const char *devpath,
- const char *mic_status);
- void ReportMicBrokenOrDegraded(const std::shared_ptr<IStats> &stats_client, const int mic,
- const bool isBroken);
- void ReportUsbPortOverheatEvent(const std::shared_ptr<IStats> &stats_client,
- const char *driver);
- void ReportChargeStats(const std::shared_ptr<IStats> &stats_client, const std::string line,
- const std::string wline_at, const std::string wline_ac,
- const std::string pca_line);
- void ReportVoltageTierStats(const std::shared_ptr<IStats> &stats_client, const char *line,
- const bool has_wireless, const std::string wfile_contents);
- void ReportChargeMetricsEvent(const std::shared_ptr<IStats> &stats_client, const char *driver);
- void ReportWlc(const std::shared_ptr<IStats> &stats_client, const bool pow_wireless,
- const bool online, const char *ptmc);
- void ReportBatteryCapacityFGEvent(const std::shared_ptr<IStats> &stats_client,
- const char *subsystem);
- void ReportTypeCPartnerId(const std::shared_ptr<IStats> &stats_client);
+ void ReportMicStatusUevents(const char *devpath, const char *mic_status);
+ void ReportMicBrokenOrDegraded(const int mic, const bool isBroken);
+ void ReportUsbPortOverheatEvent(const char *driver);
+ void ReportChargeStats(const sp<IStats> &stats_client, const char *line);
+ void ReportVoltageTierStats(const sp<IStats> &stats_client, const char *line);
+ void ReportChargeMetricsEvent(const char *driver);
+ void ReportWlc(const char *driver);
+ void ReportBatteryCapacityFGEvent(const char *subsystem);
const std::string kAudioUevent;
const std::string kBatterySSOCPath;
const std::string kUsbPortOverheatPath;
const std::string kChargeMetricsPath;
- const std::string kTypeCPartnerVidPath;
- const std::string kTypeCPartnerPidPath;
- const std::string kWirelessChargerPtmcUevent;
- const std::string kWirelessChargerPtmcPath;
BatteryCapacityReporter battery_capacity_reporter_;
@@ -112,12 +71,9 @@
const int kVendorAtomOffset = 2;
int uevent_fd_;
- int log_fd_;
- PcaChargeStats pca_charge_stats_;
- WirelessChargeStats wireless_charge_stats_;
-
- WlcReporter wlc_reporter_ = WlcReporter(kWirelessChargerPtmcPath.c_str());
+ bool wireless_charging_state_;
+ bool wireless_charging_supported_;
};
} // namespace pixel
diff --git a/pixelstats/include/pixelstats/WirelessChargeStats.h b/pixelstats/include/pixelstats/WirelessChargeStats.h
deleted file mode 100644
index 8a2e65c..0000000
--- a/pixelstats/include/pixelstats/WirelessChargeStats.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_WIRELESSCHARGESTATS_H
-#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_WIRELESSCHARGESTATS_H
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-
-class WirelessChargeStats {
- public:
- WirelessChargeStats(const std::string wireless_charge_metrics_path =
- "/sys/class/power_supply/wireless/device/charge_stats");
-
- int TranslateSysModeToAtomValue(const int sys_mode);
- bool CheckWirelessContentsAndAck(std::string *file_contents);
- void CalculateWirelessChargeStats(const int soc_tmp, const std::string file_contents);
-
- int pout_min_;
- int pout_avg_;
- int pout_max_;
- int of_freq_;
- int tier_soc_;
-
- private:
- void ResetChargeMetrics();
- void CalculateWirelessChargeMetrics(const int pout_min, const int pout_avg, const int pout_max,
- const int of_freq, const int alignment);
-
- const std::string kWirelessChargeMetricsPath;
-
- int alignment_;
- int count_;
-};
-
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_PIXELSTATS_WIRELESSCHARGESTATS_H
diff --git a/pixelstats/include/pixelstats/WlcReporter.h b/pixelstats/include/pixelstats/WlcReporter.h
index e979369..d29b7b4 100644
--- a/pixelstats/include/pixelstats/WlcReporter.h
+++ b/pixelstats/include/pixelstats/WlcReporter.h
@@ -17,77 +17,42 @@
#ifndef HARDWARE_GOOGLE_PIXEL_PIXELSTATS_WLCREPORTER_H
#define HARDWARE_GOOGLE_PIXEL_PIXELSTATS_WLCREPORTER_H
-#include <aidl/android/frameworks/stats/IStats.h>
-#include <utils/RefBase.h>
+#include <android/frameworks/stats/1.0/IStats.h>
+#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
-#include <cstdint>
+using android::frameworks::stats::V1_0::IStats;
namespace android {
namespace hardware {
namespace google {
namespace pixel {
-using aidl::android::frameworks::stats::IStats;
-
/**
* A class to upload wireless metrics
*/
class WlcReporter : public RefBase {
public:
- void checkAndReport(const std::shared_ptr<IStats> &stats_client, const bool online,
- const char *ptmc_uevent);
-
- WlcReporter(const char *ptmc_path);
+ /* checkAndReport
+ * isWirelessChargingLast: last wireless charge state
+ * true, for wireless charging
+ * Return: current wireless charge state
+ */
+ bool checkAndReport(bool isWirelessChargingLast);
+ bool isWlcSupported();
private:
- struct WlcStatus {
- bool is_charging;
- bool check_charger_vendor_id;
- bool check_charger_vendor_id_scheduled;
- int check_vendor_id_attempts;
- WlcStatus();
- };
- WlcStatus wlc_status_;
- struct ReportRecord {
- char const *name;
- int64_t last_reported_time_in_sec_today;
- int64_t last_reported_time_in_sec;
- int count_today;
- ReportRecord(char const *name_);
- };
- ReportRecord rec_wlc_vendor_{"wlc_vendor"};
- ReportRecord rec_orientation_{"orientation"};
+ bool isWlcOnline();
+ bool readFileToInt(const char *path, int *val);
- void checkVendorId(const std::shared_ptr<IStats> &stats_client, const char *ptmc_uevent);
- void scheduleReportVendorId(const std::shared_ptr<IStats> &stats_client);
- void reportOrientation(const std::shared_ptr<IStats> &stats_client);
- void reportVendor(const std::shared_ptr<IStats> &stats_client, const int ptmcId);
- bool reportVendorMayRetry(const std::shared_ptr<IStats> &stats_client, const char *ptmc_uevent);
+ void doLog();
// Translate device orientation value from sensor Hal to atom enum value
int translateDeviceOrientationToAtomValue(int orientation);
- void reportInBackground(const std::shared_ptr<IStats> &stats_client, const char *ptmc_path);
- /*
- * Wait timer for make delay before read ptmc path, return false on error
- * timerfd: fd create by timerfd_create, need create/close by caller
- **/
- bool ptmcWaitTimer(int timerfd);
- /* For some case (ex if wireless charger was connect to a low power PTMC AC
- * adapter), the wireless charger keep restaring (it might casuse will
- * check and update data in a not reasonable rare).
- * return: true, it has not hit upload rare limit
- * false, it has hit rate litmit, we should drop current
- * upload atom
- **/
- bool checkRateLimit(int64_t minSecond, int maxCount, ReportRecord *rec);
// Proto messages are 1-indexed and VendorAtom field numbers start at 2, so
// store everything in the values array at the index of the field number
// -2.
const int kVendorAtomOffset = 2;
- const int kMaxVendorIdAttempts = 5;
- const char *kWirelessChargerPtmcPath;
-
- int readPtmcId(const char *ptmc_str);
+ int readPtmcId();
};
} // namespace pixel
diff --git a/pixelstats/pixelatoms.proto b/pixelstats/pixelatoms.proto
index 1e6b0eb..dc2c32a 100644
--- a/pixelstats/pixelatoms.proto
+++ b/pixelstats/pixelatoms.proto
@@ -31,48 +31,24 @@
* - field # 1 - this will be occupied by the vendor namespace
*/
-/* Allocated atom IDs. */
-message Atom {
- oneof pushed {
- // AOSP atom ID range starts at 105000
- ChargeStats charge_stats = 105000;
- VoltageTierStats voltage_tier_stats = 105001;
- BatteryCapacity battery_capacity = 105002;
- StorageUfsHealth storage_ufs_health = 105003;
- F2fsStatsInfo f2fs_stats = 105004;
- ZramMmStat zram_mm_stat = 105005;
- ZramBdStat zram_bd_stat = 105006;
- BootStatsInfo boot_stats = 105007;
- WirelessChargingStats wireless_charging_stats = 105008;
- DeviceOrientation device_orientation = 105009;
- BatteryCapacityFG fg_capacity = 105010;
- PdVidPid pd_vid_pid = 105011;
- BatteryEEPROM battery_eeprom = 105012;
- VendorSpeakerImpedance vendor_speaker_impedance = 105013; // moved from atoms.proto
- StorageUfsResetCount ufs_reset_count = 105014;
- PixelMmMetricsPerHour pixel_mm_metrics_per_hour = 105015;
- PixelMmMetricsPerDay pixel_mm_metrics_per_day = 105016;
- F2fsCompressionInfo f2fs_compression_info = 105017;
- VendorChargeCycles vendor_charge_cycles = 105018; // moved from atoms.proto
- VendorHardwareFailed vendor_hardware_failed = 105019; // moved from atoms.proto
- VendorSlowIo vendor_slow_io = 105020; // moved from atoms.proto
- VendorSpeechDspStat vendor_speech_dsp_stat = 105021; // moved from atoms.proto
- VendorPhysicalDropDetected vendor_physical_drop_detected = 105022; // moved from atoms.proto
- VendorUsbPortOverheat vendor_usb_port_overheat = 105023; // moved from atoms.proto
- CmaStatus cma_status = 105024;
- CmaStatusExt cma_status_ext = 105025;
- VendorBatteryHealthSnapshot vendor_battery_health_snapshot = 105026; // moved from atoms.proto
- VendorBatteryCausedShutdown vendor_battery_caused_shutdown = 105027; // moved from atoms.proto
- F2fsGcSegmentInfo f2fs_gc_segment_info = 105028;
- PowerMitigationStats mitigation_stats = 105029; // moved from atoms.proto
-
- CitadelVersion citadel_version = 100018; // moved from vendor proprietary
- CitadelEvent citadel_event = 100019; // moved from vendor proprietary
- }
+/* Allocated Westworld atom IDs. */
+enum Ids {
+ // AOSP atom ID range starts at 105000
+ CHARGE_STATS = 105000;
+ VOLTAGE_TIER_STATS = 105001;
+ BATTERY_CAPACITY = 105002;
+ STORAGE_UFS_HEALTH = 105003;
+ F2FS_STATS = 105004;
+ ZRAM_MM_STAT = 105005;
+ ZRAM_BD_STAT = 105006;
+ BOOT_STATS = 105007;
+ WIRELESS_CHARGING_STATS = 105008;
+ DEVICE_ORIENTATION = 105009;
+ FG_CAPACITY = 105010;
// AOSP atom ID range ends at 109999
}
-/* Supported reverse domain names. */
+/* Westworld-supported reverse domain names. */
message ReverseDomainNames {
optional string pixel = 1 [default = "com.google.pixel"];
}
@@ -98,17 +74,7 @@
ADAPTER_TYPE_WLC = 14;
ADAPTER_TYPE_WLC_EPP = 15;
ADAPTER_TYPE_WLC_SPP = 16;
- ADAPTER_TYPE_GPP = 17;
- ADAPTER_TYPE_10W = 18;
- ADAPTER_TYPE_L7 = 19;
- ADAPTER_TYPE_DL = 20;
- ADAPTER_TYPE_WPC_EPP = 21;
- ADAPTER_TYPE_WPC_GPP = 22;
- ADAPTER_TYPE_WPC_10W = 23;
- ADAPTER_TYPE_WPC_BPP = 24;
- ADAPTER_TYPE_WPC_L7 = 25;
}
- optional string reverse_domain_name = 1;
/* Type of charge adapter, enumerated above. */
optional AdapterType adapter_type = 2;
/* Max negotiated voltage by charge adapter, in mV. */
@@ -127,34 +93,10 @@
optional int32 ssoc_out = 7;
/* Voltage in mV. */
optional int32 voltage_out = 8;
-
- /**
- * These values are meant to represent status of the charging device, used
- * to validate the charging algorithm and explain charging performances.
- * Examples of the content of the register:
- * - APDO, PDO (power capabilities of the device, eg. 5V3A, 9V2A, 20V2A) for wired charging
- * - Wireless charging MFG code. This is the value of a register of the WLC integrated
- * circuit to identify the vendor and type of WLC pad
- * - Receiver operating frequency
- * - Register status
- */
- optional int32 adapter_capabilities0 = 9;
- optional int32 adapter_capabilities1 = 10;
- optional int32 adapter_capabilities2 = 11;
- optional int32 adapter_capabilities3 = 12;
- optional int32 adapter_capabilities4 = 13;
-
- /**
- * These are values which reports the state of the wireless receiver, which will help in
- * debugging charging issues and alternate configurations.
- */
- optional int32 receiver_state0 = 14;
- optional int32 receiver_state1 = 15;
}
/* A message containing stats from each charge voltage tier. */
message VoltageTierStats {
- optional string reverse_domain_name = 1;
/* Voltage tier number, custom to implementation, should be <= 3. */
optional int32 voltage_tier = 2;
@@ -185,23 +127,10 @@
optional int32 icl_min = 15;
optional int32 icl_avg = 16;
optional int32 icl_max = 17;
-
- /**
- * Efficiency number, receiver operating frequency in kHz for wireless charging
- * (alignment)
- */
- optional int32 charging_operating_point = 18;
- /* The minimum power out of the adapter at the given charging tier */
- optional int32 min_adapter_power_out = 19;
- /* The time-averaged power out of the adapter at the given charging tier */
- optional int32 time_avg_adapter_power_out = 20;
- /* The maximum power out of the adapter at the given charging tier */
- optional int32 max_adapter_power_out = 21;
}
/* A message containing an alternate proprietary full battery capacity estimate. */
message BatteryCapacity {
- optional string reverse_domain_name = 1;
/* Sum of the change in coulomb count. */
optional int32 delta_cc_sum = 2;
/* Sum of the change in state of charge (battery level). */
@@ -210,7 +139,6 @@
/* A message containing health values of UFS */
message StorageUfsHealth {
- optional string reverse_domain_name = 1;
/* The value of lifetimeA for UFS health */
optional int32 lifetime_a = 2;
/* The value of lifetimeB for UFS health */
@@ -221,7 +149,6 @@
/* A message containing filesystem stats of F2FS */
message F2fsStatsInfo {
- optional string reverse_domain_name = 1;
/* The value of dirty segments of f2fs */
optional int32 dirty_segments = 2;
/* The value of free segments of f2fs */
@@ -243,7 +170,6 @@
}
message ZramMmStat {
- optional string reverse_domain_name = 1;
/* The value of original memory size */
optional int64 orig_data_size = 2;
/* The value of compressed memory size */
@@ -254,12 +180,9 @@
optional int64 same_pages = 5;
/* The value of number of incompressible page */
optional int64 huge_pages = 6;
- /* The value of number of incompressible pages since boot */
- optional int64 huge_pages_since_boot = 7;
}
message ZramBdStat {
- optional string reverse_domain_name = 1;
/* the number of pages in backing device */
optional int64 bd_count = 2;
/* The number of pages readed from backing device */
@@ -270,7 +193,6 @@
/* A message containing boot times */
message BootStatsInfo {
- optional string reverse_domain_name = 1;
/* The F2FS fsck time in secs */
optional int32 fsck_time_sec = 2;
/* The F2FS mounted time in secs */
@@ -287,7 +209,6 @@
VENDOR_GOOGLE = 1;
}
- optional string reverse_domain_name = 1;
optional ChargerVendor charger_vendor = 2;
}
@@ -301,7 +222,6 @@
ORIENTATION_270 = 4;
}
- optional string reverse_domain_name = 1;
/* Device orientation. */
optional Orientation orientation = 2;
}
@@ -317,7 +237,6 @@
LOG_REASON_DIVERGING_FG = 5;
}
- optional string reverse_domain_name = 1;
/* Uevent logging reason, enumerated above. */
optional LogReason capacity_log_reason = 2;
@@ -331,441 +250,3 @@
optional float capacity_ssoc_curve = 6;
}
-message PdVidPid {
- optional string reverse_domain_name = 1;
- /* Vendor ID of wired charger */
- optional int32 vid = 2;
- /* Product ID of wired charger */
- optional int32 pid = 3;
-}
-
-message BatteryEEPROM {
- optional string reverse_domain_name = 1;
- /* The cycle count number; record of charge/discharge times */
- optional int32 cycle_cnt = 2;
- /* The current full capacity of the battery under nominal conditions */
- optional int32 full_cap = 3;
- /* The battery equivalent series resistance */
- optional int32 esr = 4;
- /* Battery resistance related to temperature change */
- optional int32 rslow = 5;
- /* Battery health indicator reflecting the battery age state */
- optional int32 soh = 6;
- /* The battery temperature */
- optional int32 batt_temp = 7;
-
- /* Battery state of charge (SOC) shutdown point */
- optional int32 cutoff_soc = 8;
- /* Raw battery state of charge (SOC), based on battery current (CC = Coulomb Counter) */
- optional int32 cc_soc = 9;
- /* Estimated battery state of charge (SOC) from batt_soc with endpoint limiting (0% and 100%) */
- optional int32 sys_soc = 10;
- /* Filtered monotonic SOC, handles situations where the cutoff_soc is increased and
- * then decreased from the battery physical properties
- */
- optional int32 msoc = 11;
- /* Estimated SOC derived from cc_soc that provides voltage loop feedback correction using
- * battery voltage, current, and status values
- */
- optional int32 batt_soc = 12;
-
- /* Field used for data padding in the EEPROM data */
- optional int32 reserve = 13;
-
- /* The maximum battery temperature ever seen */
- optional int32 max_temp = 14;
- /* The minimum battery temperature ever seen */
- optional int32 min_temp = 15;
- /* The maximum battery voltage ever seen */
- optional int32 max_vbatt = 16;
- /* The minimum battery voltage ever seen */
- optional int32 min_vbatt = 17;
- /* The maximum battery current ever seen */
- optional int32 max_ibatt = 18;
- /* The minimum battery current ever seen */
- optional int32 min_ibatt = 19;
- /* Field used to verify the integrity of the EEPROM data */
- optional int32 checksum = 20;
-}
-
-/* A message containing an exceptional event from citadel. */
-message CitadelEvent {
- enum Event {
- ALERT = 1;
- REBOOTED = 2;
- UPGRADED = 3;
- ALERT_V2 = 4;
- };
- optional string reverse_domain_name = 1;
- optional Event event = 2;
- optional int32 reset_count = 3;
- optional int64 uptime_micros = 4;
- enum Priority {
- LOW = 0;
- MEDIUM = 1;
- HIGH = 2;
- };
- optional Priority priority = 5;
-
- // ALERT-specific fields. These fields correspond to the interrupt status
- // bits for alerts within citadel. When alerts fire one or more of these
- // bits are set to indicate the alert source.
- optional int32 intr_sts_0 = 6;
- optional int32 intr_sts_1 = 7;
- optional int32 intr_sts_2 = 8;
-
- // REBOOTED-specific fields. These fields correspond to the details of how
- // the hardware reboot occurred. A reboot is a noteworthy event for citadel,
- // as it can be triggered by events like stack overflow or other software
- // bugs.
- optional int32 rstsrc = 9;
- optional int32 exitpd = 10;
- optional int32 which0 = 11;
- optional int32 which1 = 12;
-
- // UPGRADED-specific field. This field corresponds to the result of FW
- // upgrade for citadel.
- optional int32 upgrade_state = 13;
-
- // ALERT_V2-specific field. This field corresponds to the GLOBALSEC Log
- // which contains normal globalsec, camo, temp and buserr.
- optional int32 alert_grp_0 = 14;
- optional int32 alert_grp_1 = 15;
- optional int32 alert_grp_2 = 16;
- optional int32 alert_grp_3 = 17;
- optional int32 camo_breaches_0 = 18;
- optional int32 camo_breaches_1 = 19;
- optional int32 temp_min = 20;
- optional int32 temp_max = 21;
- optional int32 bus_err = 22;
-}
-
-/* A message containing the citadel firmware version. */
-message CitadelVersion {
- optional string reverse_domain_name = 1;
- optional string version = 2;
-}
-
-/* A message containing the speaker impedance. */
- message VendorSpeakerImpedance {
- optional string reverse_domain_name = 1;
- optional int32 speaker_location = 2;
- optional int32 impedance = 3;
-}
-
-/* A message containing how many times of ufs host reset */
-message StorageUfsResetCount {
- optional string reverse_domain_name = 1;
- /* How many UFS error reset are triggered */
- optional int32 host_reset_count = 2;
-}
-
-/* A message containing Pixel memory metrics collected hourly. */
-message PixelMmMetricsPerHour {
- optional string reverse_domain_name = 1;
- optional int64 free_pages = 2;
- optional int64 anon_pages = 3;
- optional int64 file_pages = 4;
- optional int64 slab_reclaimable = 5;
- optional int64 zspages = 6;
- optional int64 unevictable = 7;
- optional int64 ion_total_pools = 8;
- optional int64 gpu_memory = 9;
-}
-
-/* A message containing Pixel memory metrics collected daily. */
-message PixelMmMetricsPerDay {
- optional string reverse_domain_name = 1;
- optional int64 workingset_refault = 2;
- optional int64 pswpin = 3;
- optional int64 pswpout = 4;
- optional int64 allocstall_dma = 5;
- optional int64 allocstall_dma32 = 6;
- optional int64 allocstall_normal = 7;
- optional int64 allocstall_movable = 8;
- optional int64 pgalloc_dma = 9;
- optional int64 pgalloc_dma32 = 10;
- optional int64 pgalloc_normal = 11;
- optional int64 pgalloc_movable = 12;
- optional int64 pgsteal_kswapd = 13;
- optional int64 pgsteal_direct = 14;
- optional int64 pgscan_kswapd = 15;
- optional int64 pgscan_direct = 16;
- optional int64 oom_kill = 17;
- optional int64 pgalloc_high = 18;
- optional int64 pgcache_hit = 19;
- optional int64 pgcache_miss = 20;
- optional int64 kswapd_stime_clks = 21;
- optional int64 kcompactd_stime_clks = 22;
-}
-
-/* A message containing CMA metrics collected from dogfooding only. */
-message CmaStatus {
- optional string reverse_domain_name = 1;
- optional int32 type = 2;
- optional int64 cma_alloc_pages_attempts = 3;
- optional int64 cma_alloc_pages_soft_attempts = 4;
- optional int64 cma_fail_pages = 5;
- optional int64 cma_fail_soft_pages = 6;
- optional int64 migrated_pages = 7;
-}
-
-/* A message containing CMA metrics (External). */
-message CmaStatusExt {
- optional string reverse_domain_name = 1;
- optional int32 type = 2;
- optional int64 cma_alloc_latency_low = 3;
- optional int64 cma_alloc_latency_mid = 4;
- optional int64 cma_alloc_latency_high = 5;
-}
-
-message F2fsCompressionInfo {
- optional string reverse_domain_name = 1;
- /* Show the block count written after compression since mount */
- optional int32 compr_written_blocks = 2;
- /* Show the saved block count with compression since mount */
- optional int32 compr_saved_blocks = 3;
- /* Show the count of inode newly enabled for compression since mount */
- optional int32 compr_new_inodes = 4;
-}
-
-/**
- * Log bucketed battery charge cycles.
- *
- * Each bucket represents cycles of the battery past
- * a given charge point. For example, bucket 1 is the
- * lowest 1/8th of the battery, and bucket 8 is 100%.
- *
- * Logged from:
- * /sys/class/power_supply/bms/cycle_count, via Vendor.
- */
-message VendorChargeCycles {
- optional string reverse_domain_name = 1;
- optional int32 cycle_bucket_1 = 2;
- optional int32 cycle_bucket_2 = 3;
- optional int32 cycle_bucket_3 = 4;
- optional int32 cycle_bucket_4 = 5;
- optional int32 cycle_bucket_5 = 6;
- optional int32 cycle_bucket_6 = 7;
- optional int32 cycle_bucket_7 = 8;
- optional int32 cycle_bucket_8 = 9;
- optional int32 cycle_bucket_9 = 10;
- optional int32 cycle_bucket_10 = 11;
-}
-
-/**
- * Logs the report of a failed hardware.
- *
- * Logged from:
- * Vendor HALs.
- *
- */
-message VendorHardwareFailed {
- enum HardwareType {
- HARDWARE_FAILED_UNKNOWN = 0;
- HARDWARE_FAILED_MICROPHONE = 1;
- HARDWARE_FAILED_CODEC = 2;
- HARDWARE_FAILED_SPEAKER = 3;
- HARDWARE_FAILED_FINGERPRINT = 4;
- }
- optional string reverse_domain_name = 1;
- optional HardwareType hardware_type = 2;
-
- /**
- * hardware_location allows vendors to differentiate between multiple
- * instances of the same hardware_type. The specific locations are vendor
- * defined integers, referring to board-specific numbering schemes.
- */
- optional int32 hardware_location = 3;
- /**
- * failure_code is specific to the HardwareType of the failed hardware.
- * It should use one of the enum values defined below.
- */
- enum HardwareErrorCode {
- UNKNOWN = 0;
- COMPLETE = 1;
- SPEAKER_HIGH_Z = 2;
- SPEAKER_SHORT = 3;
- FINGERPRINT_SENSOR_BROKEN = 4;
- FINGERPRINT_TOO_MANY_DEAD_PIXELS = 5;
- DEGRADE = 6;
- }
- optional int32 failure_code = 4;
-}
-
-/**
- * Log slow I/O operations on the primary storage.
- */
-message VendorSlowIo {
- // Classifications of IO Operations.
- enum IoOperation {
- UNKNOWN = 0;
- READ = 1;
- WRITE = 2;
- UNMAP = 3;
- SYNC = 4;
- }
- optional string reverse_domain_name = 1;
- optional IoOperation operation = 2;
-
- // The number of slow IO operations of this type over 24 hours.
- optional int32 count = 3;
-}
-
-/*
- * Logs the reported speech DSP status.
- * Logged from: Vendor audio implementation.
- */
-message VendorSpeechDspStat {
- optional string reverse_domain_name = 1;
- // The total Speech DSP uptime in milliseconds.
- optional int32 total_uptime_millis = 2;
- // The total Speech DSP downtime in milliseconds.
- optional int32 total_downtime_millis = 3;
- optional int32 total_crash_count = 4;
- optional int32 total_recover_count = 5;
-}
-
-/**
- * Log an event when the device has been physically dropped.
- * Reported from the /vendor partition.
- */
-message VendorPhysicalDropDetected {
- optional string reverse_domain_name = 1;
- // Confidence that the event was actually a drop, 0 -> 100
- optional int32 confidence_pctg = 2;
- // Peak acceleration of the drop, in 1/1000s of a g.
- optional int32 accel_peak_thousandths_g = 3;
- // Duration of freefall in ms
- optional int32 freefall_time_millis = 4;
-}
-
-/** Represents USB port overheat event. */
-message VendorUsbPortOverheat {
- optional string reverse_domain_name = 1;
- /* Temperature of USB port at USB plug event, in 1/10ths of degree C. */
- optional int32 plug_temperature_deci_c = 2;
- /* Maximum temperature of USB port during overheat event, in 1/10ths of degree
- * C. */
- optional int32 max_temperature_deci_c = 3;
- /* Time between USB plug event and overheat threshold trip, in seconds. */
- optional int32 time_to_overheat_secs = 4;
- /* Time between overheat threshold trip and hysteresis, in seconds. */
- optional int32 time_to_hysteresis_secs = 5;
- /* Time between hysteresis and active mitigation ending, in seconds. */
- optional int32 time_to_inactive_secs = 6;
-}
-
-/**
- * Log battery health snapshot.
- *
- * Resistance, Voltage, Open Circuit Voltage, Temperature, and Charge Level
- * are snapshotted periodically over 24hrs.
- */
-message VendorBatteryHealthSnapshot {
- enum BatterySnapshotType {
- BATTERY_SNAPSHOT_TYPE_UNKNOWN = 0;
- BATTERY_SNAPSHOT_TYPE_MIN_TEMP = 1; // Snapshot at min batt temp over 24hrs.
- BATTERY_SNAPSHOT_TYPE_MAX_TEMP = 2; // Snapshot at max batt temp over 24hrs.
- BATTERY_SNAPSHOT_TYPE_MIN_RESISTANCE = 3; // Snapshot at min batt resistance over 24hrs.
- BATTERY_SNAPSHOT_TYPE_MAX_RESISTANCE = 4; // Snapshot at max batt resistance over 24hrs.
- BATTERY_SNAPSHOT_TYPE_MIN_VOLTAGE = 5; // Snapshot at min batt voltage over 24hrs.
- BATTERY_SNAPSHOT_TYPE_MAX_VOLTAGE = 6; // Snapshot at max batt voltage over 24hrs.
- BATTERY_SNAPSHOT_TYPE_MIN_CURRENT = 7; // Snapshot at min batt current over 24hrs.
- BATTERY_SNAPSHOT_TYPE_MAX_CURRENT = 8; // Snapshot at max batt current over 24hrs.
- BATTERY_SNAPSHOT_TYPE_MIN_BATT_LEVEL = 9; // Snapshot at min battery level (SoC) over 24hrs.
- BATTERY_SNAPSHOT_TYPE_MAX_BATT_LEVEL = 10; // Snapshot at max battery level (SoC) over 24hrs.
- BATTERY_SNAPSHOT_TYPE_AVG_RESISTANCE = 11; // Snapshot at average battery resistance over 24hrs.
- }
- optional string reverse_domain_name = 1;
- optional BatterySnapshotType type = 2;
- // Temperature, in 1/10ths of degree C.
- optional int32 temperature_deci_celsius = 3;
- // Voltage Battery Voltage, in microVolts.
- optional int32 voltage_micro_volt = 4;
- // Current Battery current, in microAmps.
- optional int32 current_micro_amps = 5;
- // OpenCircuitVoltage Battery Open Circuit Voltage, in microVolts.
- optional int32 open_circuit_micro_volt = 6;
- // Resistance Battery Resistance, in microOhms.
- optional int32 resistance_micro_ohm = 7;
- // Level Battery Level, as % of full.
- optional int32 level_percent = 8;
-}
-
-/**
- * Log battery caused shutdown with the last recorded voltage.
- */
-message VendorBatteryCausedShutdown {
- optional string reverse_domain_name = 1;
- // The last recorded battery voltage prior to shutdown.
- optional int32 last_recorded_micro_volt = 2;
-}
-
-/**
- * Log mitigation statistics.
- */
-message PowerMitigationStats {
- optional string reverse_domain_name = 1;
- // The last triggered count: batoilo.
- optional int32 batoilo_count = 2;
- // The last triggered count: vdroop1.
- optional int32 vdroop1_count = 3;
- // The last triggered count: vdroop2.
- optional int32 vdroop2_count = 4;
- // The last triggered count: smpl_warn.
- optional int32 smpl_warn_count = 5;
- // The last triggered count: ocp_cpu1.
- optional int32 ocp_cpu1_count = 6;
- // The last triggered count: ocp_cpu2.
- optional int32 ocp_cpu2_count = 7;
- // The last triggered count: ocp_gpu.
- optional int32 ocp_gpu_count = 8;
- // The last triggered count: ocp_tpu.
- optional int32 ocp_tpu_count = 9;
- // The last triggered count: soft_ocp_cpu1.
- optional int32 soft_ocp_cpu1_count = 10;
- // The last triggered count: soft_ocp_cpu2.
- optional int32 soft_ocp_cpu2_count = 11;
- // The last triggered count: soft_ocp_gpu.
- optional int32 soft_ocp_gpu_count = 12;
- // The last triggered count: soft_ocp_tpu.
- optional int32 soft_ocp_tpu_count = 13;
- // The last triggered capacity: batoilo.
- optional int32 batoilo_cap = 14;
- // The last triggered capacity: vdroop1.
- optional int32 vdroop1_cap = 15;
- // The last triggered capacity: vdroop2.
- optional int32 vdroop2_cap = 16;
- // The last triggered capacity: smpl_warn.
- optional int32 smpl_warn_cap = 17;
- // The last triggered capacity: ocp_cpu1.
- optional int32 ocp_cpu1_cap = 18;
- // The last triggered capacity: ocp_cpu2.
- optional int32 ocp_cpu2_cap = 19;
- // The last triggered capacity: ocp_gpu.
- optional int32 ocp_gpu_cap = 20;
- // The last triggered capacity: ocp_tpu.
- optional int32 ocp_tpu_cap = 21;
- // The last triggered capacity: soft_ocp_cpu1.
- optional int32 soft_ocp_cpu1_cap = 22;
- // The last triggered capacity: soft_ocp_cpu2.
- optional int32 soft_ocp_cpu2_cap = 23;
- // The last triggered capacity: soft_ocp_gpu.
- optional int32 soft_ocp_gpu_cap = 24;
- // The last triggered capacity: soft_ocp_tpu.
- optional int32 soft_ocp_tpu_cap = 25;
-}
-
-/**
- * Log how many segments have been reclaimed in a specific GC mode.
- */
-message F2fsGcSegmentInfo {
- optional string reverse_domain_name = 1;
- /* Reclaimed segments in GC normal mode */
- optional int32 reclaimed_segments_normal = 2;
- /* Reclaimed segments in GC urgent high mode */
- optional int32 reclaimed_segments_urgent_high = 3;
- /* Reclaimed segments in GC urgent low mode */
- optional int32 reclaimed_segments_urgent_low = 4;
-}
diff --git a/power-libperfmgr/Android.bp b/power-libperfmgr/Android.bp
index 9049295..c4d0f87 100644
--- a/power-libperfmgr/Android.bp
+++ b/power-libperfmgr/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library {
name: "libdisppower-pixel",
proprietary: true,
@@ -33,8 +29,6 @@
],
}
-// Deprecated, do not use
-// Use pixel-power-ext for vendor extension
cc_library_headers {
name: "pixel_power_headers",
vendor: true,
@@ -42,13 +36,39 @@
}
cc_binary {
+ name: "android.hardware.power@1.3-service.pixel-libperfmgr",
+ relative_install_path: "hw",
+ vintf_fragments: ["hidl/android.hardware.power@1.3-service.pixel.xml"],
+ init_rc: ["hidl/android.hardware.power@1.3-service.pixel-libperfmgr.rc"],
+ srcs: ["hidl/service.cpp", "hidl/Power.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "libcutils",
+ "android.hardware.power@1.0",
+ "android.hardware.power@1.1",
+ "android.hardware.power@1.2",
+ "android.hardware.power@1.3",
+ "libdisppower-pixel",
+ "libperfmgr",
+ ],
+ proprietary: true,
+}
+
+cc_binary {
name: "android.hardware.power-service.pixel-libperfmgr",
relative_install_path: "hw",
init_rc: ["aidl/android.hardware.power-service.pixel-libperfmgr.rc"],
vintf_fragments: ["aidl/android.hardware.power-service.pixel.xml"],
vendor: true,
shared_libs: [
- "android.hardware.power-V2-ndk_platform",
+ "android.hardware.power-ndk_platform",
"libbase",
"libcutils",
"liblog",
@@ -56,14 +76,11 @@
"libbinder_ndk",
"libdisppower-pixel",
"libperfmgr",
- "libprocessgroup",
- "pixel-power-ext-V1-ndk_platform",
+ "pixel-power-ext-ndk_platform",
],
srcs: [
"aidl/service.cpp",
"aidl/Power.cpp",
"aidl/PowerExt.cpp",
- "aidl/PowerHintSession.cpp",
- "aidl/PowerSessionManager.cpp",
],
}
diff --git a/power-libperfmgr/aidl/Power.cpp b/power-libperfmgr/aidl/Power.cpp
index f232ff4..d944cf4 100644
--- a/power-libperfmgr/aidl/Power.cpp
+++ b/power-libperfmgr/aidl/Power.cpp
@@ -15,7 +15,7 @@
*/
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
-#define LOG_TAG "powerhal-libperfmgr"
+#define LOG_TAG "android.hardware.power-service.pixel-libperfmgr"
#include "Power.h"
@@ -26,13 +26,10 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
-#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/Trace.h>
-#include "PowerHintSession.h"
-#include "PowerSessionManager.h"
#include "disp-power/DisplayLowPower.h"
namespace aidl {
@@ -42,63 +39,56 @@
namespace impl {
namespace pixel {
-using ::aidl::google::hardware::power::impl::pixel::PowerHintSession;
-
constexpr char kPowerHalStateProp[] = "vendor.powerhal.state";
constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio";
constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering";
-constexpr char kPowerHalAdpfRateProp[] = "vendor.powerhal.adpf.rate";
-constexpr int64_t kPowerHalAdpfRateDefault = -1;
Power::Power(std::shared_ptr<HintManager> hm, std::shared_ptr<DisplayLowPower> dlpw)
: mHintManager(hm),
mDisplayLowPower(dlpw),
mInteractionHandler(nullptr),
mVRModeOn(false),
- mSustainedPerfModeOn(false),
- mAdpfRateNs(
- ::android::base::GetIntProperty(kPowerHalAdpfRateProp, kPowerHalAdpfRateDefault)) {
+ mSustainedPerfModeOn(false) {
mInteractionHandler = std::make_unique<InteractionHandler>(mHintManager);
mInteractionHandler->Init();
std::string state = ::android::base::GetProperty(kPowerHalStateProp, "");
if (state == "SUSTAINED_PERFORMANCE") {
- LOG(INFO) << "Initialize with SUSTAINED_PERFORMANCE on";
+ ALOGI("Initialize with SUSTAINED_PERFORMANCE on");
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
mSustainedPerfModeOn = true;
} else if (state == "VR") {
- LOG(INFO) << "Initialize with VR on";
+ ALOGI("Initialize with VR on");
mHintManager->DoHint(state);
mVRModeOn = true;
} else if (state == "VR_SUSTAINED_PERFORMANCE") {
- LOG(INFO) << "Initialize with SUSTAINED_PERFORMANCE and VR on";
+ ALOGI("Initialize with SUSTAINED_PERFORMANCE and VR on");
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
mSustainedPerfModeOn = true;
mVRModeOn = true;
} else {
- LOG(INFO) << "Initialize PowerHAL";
+ ALOGI("Initialize PowerHAL");
}
state = ::android::base::GetProperty(kPowerHalAudioProp, "");
if (state == "AUDIO_STREAMING_LOW_LATENCY") {
- LOG(INFO) << "Initialize with AUDIO_LOW_LATENCY on";
+ ALOGI("Initialize with AUDIO_LOW_LATENCY on");
mHintManager->DoHint(state);
}
state = ::android::base::GetProperty(kPowerHalRenderingProp, "");
if (state == "EXPENSIVE_RENDERING") {
- LOG(INFO) << "Initialize with EXPENSIVE_RENDERING on";
+ ALOGI("Initialize with EXPENSIVE_RENDERING on");
mHintManager->DoHint("EXPENSIVE_RENDERING");
}
// Now start to take powerhint
- LOG(INFO) << "PowerHAL ready to take hints, Adpf update rate: " << mAdpfRateNs;
+ ALOGI("PowerHAL ready to process hints");
}
ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled;
ATRACE_INT(toString(type).c_str(), enabled);
- PowerSessionManager::getInstance()->updateHintMode(toString(type), enabled);
switch (type) {
case Mode::LOW_POWER:
mDisplayLowPower->SetDisplayLowPower(enabled);
@@ -258,34 +248,6 @@
return STATUS_OK;
}
-ndk::ScopedAStatus Power::createHintSession(int32_t tgid, int32_t uid,
- const std::vector<int32_t> &threadIds,
- int64_t durationNanos,
- std::shared_ptr<IPowerHintSession> *_aidl_return) {
- if (mAdpfRateNs <= 0) {
- *_aidl_return = nullptr;
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
- if (threadIds.size() == 0) {
- LOG(ERROR) << "Error: threadIds.size() shouldn't be " << threadIds.size();
- *_aidl_return = nullptr;
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
- std::shared_ptr<IPowerHintSession> session = ndk::SharedRefBase::make<PowerHintSession>(
- tgid, uid, threadIds, durationNanos, nanoseconds(mAdpfRateNs));
- *_aidl_return = session;
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t *outNanoseconds) {
- *outNanoseconds = mAdpfRateNs;
- if (mAdpfRateNs <= 0) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-
- return ndk::ScopedAStatus::ok();
-}
-
} // namespace pixel
} // namespace impl
} // namespace power
diff --git a/power-libperfmgr/aidl/Power.h b/power-libperfmgr/aidl/Power.h
index 0739106..8b90cb4 100644
--- a/power-libperfmgr/aidl/Power.h
+++ b/power-libperfmgr/aidl/Power.h
@@ -33,8 +33,8 @@
namespace impl {
namespace pixel {
+using ::InteractionHandler;
using ::aidl::android::hardware::power::Boost;
-using ::aidl::android::hardware::power::IPowerHintSession;
using ::aidl::android::hardware::power::Mode;
using ::android::perfmgr::HintManager;
@@ -45,11 +45,6 @@
ndk::ScopedAStatus isModeSupported(Mode type, bool *_aidl_return) override;
ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override;
ndk::ScopedAStatus isBoostSupported(Boost type, bool *_aidl_return) override;
- ndk::ScopedAStatus createHintSession(int32_t tgid, int32_t uid,
- const std::vector<int32_t> &threadIds,
- int64_t durationNanos,
- std::shared_ptr<IPowerHintSession> *_aidl_return) override;
- ndk::ScopedAStatus getHintSessionPreferredRate(int64_t *outNanoseconds) override;
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
private:
@@ -58,7 +53,6 @@
std::unique_ptr<InteractionHandler> mInteractionHandler;
std::atomic<bool> mVRModeOn;
std::atomic<bool> mSustainedPerfModeOn;
- const int64_t mAdpfRateNs;
};
} // namespace pixel
diff --git a/power-libperfmgr/aidl/PowerExt.cpp b/power-libperfmgr/aidl/PowerExt.cpp
index 7fded31..24e855d 100644
--- a/power-libperfmgr/aidl/PowerExt.cpp
+++ b/power-libperfmgr/aidl/PowerExt.cpp
@@ -18,7 +18,6 @@
#define LOG_TAG "android.hardware.power-service.pixel.ext-libperfmgr"
#include "PowerExt.h"
-#include "PowerSessionManager.h"
#include <mutex>
@@ -47,7 +46,6 @@
} else {
mHintManager->EndHint(mode);
}
- PowerSessionManager::getInstance()->updateHintMode(mode, enabled);
return ndk::ScopedAStatus::ok();
}
diff --git a/power-libperfmgr/aidl/PowerHintSession.cpp b/power-libperfmgr/aidl/PowerHintSession.cpp
deleted file mode 100644
index 7a39dab..0000000
--- a/power-libperfmgr/aidl/PowerHintSession.cpp
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright 2021 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 LOG_TAG "powerhal-libperfmgr"
-#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
-
-#include <android-base/logging.h>
-#include <android-base/parsedouble.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <sys/syscall.h>
-#include <time.h>
-#include <utils/Trace.h>
-#include <atomic>
-
-#include "PowerHintSession.h"
-#include "PowerSessionManager.h"
-
-namespace aidl {
-namespace google {
-namespace hardware {
-namespace power {
-namespace impl {
-namespace pixel {
-
-using ::android::base::StringPrintf;
-using std::chrono::duration_cast;
-using std::chrono::nanoseconds;
-using std::literals::chrono_literals::operator""s;
-
-constexpr char kPowerHalAdpfPidPOver[] = "vendor.powerhal.adpf.pid_p.over";
-constexpr char kPowerHalAdpfPidPUnder[] = "vendor.powerhal.adpf.pid_p.under";
-constexpr char kPowerHalAdpfPidI[] = "vendor.powerhal.adpf.pid_i";
-constexpr char kPowerHalAdpfPidDOver[] = "vendor.powerhal.adpf.pid_d.over";
-constexpr char kPowerHalAdpfPidDUnder[] = "vendor.powerhal.adpf.pid_d.under";
-constexpr char kPowerHalAdpfPidIInit[] = "vendor.powerhal.adpf.pid_i.init";
-constexpr char kPowerHalAdpfPidIHighLimit[] = "vendor.powerhal.adpf.pid_i.high_limit";
-constexpr char kPowerHalAdpfPidILowLimit[] = "vendor.powerhal.adpf.pid_i.low_limit";
-constexpr char kPowerHalAdpfUclampEnable[] = "vendor.powerhal.adpf.uclamp";
-constexpr char kPowerHalAdpfUclampMinGranularity[] = "vendor.powerhal.adpf.uclamp_min.granularity";
-constexpr char kPowerHalAdpfUclampMinHighLimit[] = "vendor.powerhal.adpf.uclamp_min.high_limit";
-constexpr char kPowerHalAdpfUclampMinLowLimit[] = "vendor.powerhal.adpf.uclamp_min.low_limit";
-constexpr char kPowerHalAdpfStaleTimeFactor[] = "vendor.powerhal.adpf.stale_timeout_factor";
-constexpr char kPowerHalAdpfPSamplingWindow[] = "vendor.powerhal.adpf.p.window";
-constexpr char kPowerHalAdpfISamplingWindow[] = "vendor.powerhal.adpf.i.window";
-constexpr char kPowerHalAdpfDSamplingWindow[] = "vendor.powerhal.adpf.d.window";
-
-namespace {
-/* there is no glibc or bionic wrapper */
-struct sched_attr {
- __u32 size;
- __u32 sched_policy;
- __u64 sched_flags;
- __s32 sched_nice;
- __u32 sched_priority;
- __u64 sched_runtime;
- __u64 sched_deadline;
- __u64 sched_period;
- __u32 sched_util_min;
- __u32 sched_util_max;
-};
-
-static int sched_setattr(int pid, struct sched_attr *attr, unsigned int flags) {
- static const bool kPowerHalAdpfUclamp =
- ::android::base::GetBoolProperty(kPowerHalAdpfUclampEnable, true);
- if (!kPowerHalAdpfUclamp) {
- ALOGV("PowerHintSession:%s: skip", __func__);
- return 0;
- }
- return syscall(__NR_sched_setattr, pid, attr, flags);
-}
-
-static inline int64_t ns_to_100us(int64_t ns) {
- return ns / 100000;
-}
-
-static double getDoubleProperty(const char *prop, double value) {
- std::string result = ::android::base::GetProperty(prop, std::to_string(value).c_str());
- if (!::android::base::ParseDouble(result.c_str(), &value)) {
- ALOGE("PowerHintSession : failed to parse double in %s", prop);
- }
- return value;
-}
-
-static double sPidPOver = getDoubleProperty(kPowerHalAdpfPidPOver, 5.0);
-static double sPidPUnder = getDoubleProperty(kPowerHalAdpfPidPUnder, 3.0);
-static double sPidI = getDoubleProperty(kPowerHalAdpfPidI, 0.001);
-static double sPidDOver = getDoubleProperty(kPowerHalAdpfPidDOver, 500.0);
-static double sPidDUnder = getDoubleProperty(kPowerHalAdpfPidDUnder, 0.0);
-static const int64_t sPidIInit =
- (sPidI == 0) ? 0
- : static_cast<int64_t>(::android::base::GetIntProperty<int64_t>(
- kPowerHalAdpfPidIInit, 200) /
- sPidI);
-static const int64_t sPidIHighLimit =
- (sPidI == 0) ? 0
- : static_cast<int64_t>(::android::base::GetIntProperty<int64_t>(
- kPowerHalAdpfPidIHighLimit, 512) /
- sPidI);
-static const int64_t sPidILowLimit =
- (sPidI == 0) ? 0
- : static_cast<int64_t>(::android::base::GetIntProperty<int64_t>(
- kPowerHalAdpfPidILowLimit, -120) /
- sPidI);
-static const int32_t sUclampMinHighLimit =
- ::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfUclampMinHighLimit, 512);
-static const int32_t sUclampMinLowLimit =
- ::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfUclampMinLowLimit, 0);
-static const uint32_t sUclampMinGranularity =
- ::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfUclampMinGranularity, 5);
-static const int64_t sStaleTimeFactor =
- ::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfStaleTimeFactor, 20);
-static const int64_t sPSamplingWindow =
- ::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfPSamplingWindow, 1);
-static const int64_t sISamplingWindow =
- ::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfISamplingWindow, 0);
-static const int64_t sDSamplingWindow =
- ::android::base::GetUintProperty<uint32_t>(kPowerHalAdpfDSamplingWindow, 1);
-
-} // namespace
-
-PowerHintSession::PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds,
- int64_t durationNanos, const nanoseconds adpfRate)
- : kAdpfRate(adpfRate) {
- mDescriptor = new AppHintDesc(tgid, uid, threadIds);
- mDescriptor->duration = std::chrono::nanoseconds(durationNanos);
- mStaleHandler = sp<StaleHandler>(new StaleHandler(this));
- mPowerManagerHandler = PowerSessionManager::getInstance();
-
- if (ATRACE_ENABLED()) {
- const std::string idstr = getIdString();
- std::string sz = StringPrintf("adpf.%s-target", idstr.c_str());
- ATRACE_INT(sz.c_str(), (int64_t)mDescriptor->duration.count());
- sz = StringPrintf("adpf.%s-active", idstr.c_str());
- ATRACE_INT(sz.c_str(), mDescriptor->is_active.load());
- }
- PowerSessionManager::getInstance()->addPowerSession(this);
- // init boost
- setUclamp(sUclampMinHighLimit);
- ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str());
-}
-
-PowerHintSession::~PowerHintSession() {
- close();
- ALOGV("PowerHintSession deleted: %s", mDescriptor->toString().c_str());
- if (ATRACE_ENABLED()) {
- const std::string idstr = getIdString();
- std::string sz = StringPrintf("adpf.%s-target", idstr.c_str());
- ATRACE_INT(sz.c_str(), 0);
- sz = StringPrintf("adpf.%s-actl_last", idstr.c_str());
- ATRACE_INT(sz.c_str(), 0);
- sz = sz = StringPrintf("adpf.%s-active", idstr.c_str());
- ATRACE_INT(sz.c_str(), 0);
- }
- delete mDescriptor;
-}
-
-std::string PowerHintSession::getIdString() const {
- std::string idstr = StringPrintf("%" PRId32 "-%" PRId32 "-%" PRIxPTR, mDescriptor->tgid,
- mDescriptor->uid, reinterpret_cast<uintptr_t>(this) & 0xffff);
- return idstr;
-}
-
-void PowerHintSession::updateUniveralBoostMode() {
- PowerHintMonitor::getInstance()->getLooper()->sendMessage(mPowerManagerHandler, NULL);
-}
-
-int PowerHintSession::setUclamp(int32_t min, int32_t max) {
- std::lock_guard<std::mutex> guard(mLock);
- min = std::max(0, min);
- min = std::min(min, max);
- max = std::max(0, max);
- max = std::max(min, max);
- if (ATRACE_ENABLED()) {
- const std::string idstr = getIdString();
- std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
- ATRACE_INT(sz.c_str(), min);
- }
- for (const auto tid : mDescriptor->threadIds) {
- sched_attr attr = {};
- attr.size = sizeof(attr);
-
- attr.sched_flags = (SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP);
- attr.sched_util_min = min;
- attr.sched_util_max = max;
-
- int ret = sched_setattr(tid, &attr, 0);
- if (ret) {
- ALOGW("sched_setattr failed for thread %d, err=%d", tid, errno);
- }
- ALOGV("PowerHintSession tid: %d, uclamp(%d, %d)", tid, min, max);
- }
- mDescriptor->current_min = min;
- return 0;
-}
-
-ndk::ScopedAStatus PowerHintSession::pause() {
- if (!mDescriptor->is_active.load())
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- // Reset to default uclamp value.
- setUclamp(0);
- mDescriptor->is_active.store(false);
- if (ATRACE_ENABLED()) {
- const std::string idstr = getIdString();
- std::string sz = StringPrintf("adpf.%s-active", idstr.c_str());
- ATRACE_INT(sz.c_str(), mDescriptor->is_active.load());
- }
- updateUniveralBoostMode();
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus PowerHintSession::resume() {
- if (mDescriptor->is_active.load())
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- mDescriptor->is_active.store(true);
- mDescriptor->integral_error = std::max(sPidIInit, mDescriptor->integral_error);
- // resume boost
- setUclamp(sUclampMinHighLimit);
- if (ATRACE_ENABLED()) {
- const std::string idstr = getIdString();
- std::string sz = StringPrintf("adpf.%s-active", idstr.c_str());
- ATRACE_INT(sz.c_str(), mDescriptor->is_active.load());
- }
- updateUniveralBoostMode();
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus PowerHintSession::close() {
- bool sessionClosedExpectedToBe = false;
- if (!mSessionClosed.compare_exchange_strong(sessionClosedExpectedToBe, true)) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- PowerHintMonitor::getInstance()->getLooper()->removeMessages(mStaleHandler);
- setUclamp(0);
- PowerSessionManager::getInstance()->removePowerSession(this);
- updateUniveralBoostMode();
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus PowerHintSession::updateTargetWorkDuration(int64_t targetDurationNanos) {
- if (targetDurationNanos <= 0) {
- ALOGE("Error: targetDurationNanos(%" PRId64 ") should bigger than 0", targetDurationNanos);
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
- ALOGV("update target duration: %" PRId64 " ns", targetDurationNanos);
- double ratio =
- targetDurationNanos == 0 ? 1.0 : mDescriptor->duration.count() / targetDurationNanos;
- mDescriptor->integral_error =
- std::max(sPidIInit, static_cast<int64_t>(mDescriptor->integral_error * ratio));
-
- mDescriptor->duration = std::chrono::nanoseconds(targetDurationNanos);
- if (ATRACE_ENABLED()) {
- const std::string idstr = getIdString();
- std::string sz = StringPrintf("adpf.%s-target", idstr.c_str());
- ATRACE_INT(sz.c_str(), (int64_t)mDescriptor->duration.count());
- }
-
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus PowerHintSession::reportActualWorkDuration(
- const std::vector<WorkDuration> &actualDurations) {
- if (mDescriptor->duration.count() == 0LL) {
- ALOGE("Expect to call updateTargetWorkDuration() first.");
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- if (actualDurations.size() == 0) {
- ALOGE("Error: duration.size() shouldn't be %zu.", actualDurations.size());
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
- if (!mDescriptor->is_active.load()) {
- ALOGE("Error: shouldn't report duration during pause state.");
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- if (PowerHintMonitor::getInstance()->isRunning() && isStale()) {
- if (ATRACE_ENABLED()) {
- const std::string idstr = getIdString();
- std::string sz = StringPrintf("adpf.%s-stale", idstr.c_str());
- ATRACE_INT(sz.c_str(), 0);
- }
- mDescriptor->integral_error = std::max(sPidIInit, mDescriptor->integral_error);
- }
- int64_t targetDurationNanos = (int64_t)mDescriptor->duration.count();
- int64_t length = actualDurations.size();
- int64_t p_start =
- sPSamplingWindow == 0 || sPSamplingWindow > length ? 0 : length - sPSamplingWindow;
- int64_t i_start =
- sISamplingWindow == 0 || sISamplingWindow > length ? 0 : length - sISamplingWindow;
- int64_t d_start =
- sDSamplingWindow == 0 || sDSamplingWindow > length ? 0 : length - sDSamplingWindow;
- int64_t dt = ns_to_100us(targetDurationNanos);
- int64_t err_sum = 0;
- int64_t derivative_sum = 0;
- for (int64_t i = std::min({p_start, i_start, d_start}); i < length; i++) {
- int64_t actualDurationNanos = actualDurations[i].durationNanos;
- if (std::abs(actualDurationNanos) > targetDurationNanos * 20) {
- ALOGW("The actual duration is way far from the target (%" PRId64 " >> %" PRId64 ")",
- actualDurationNanos, targetDurationNanos);
- }
- // PID control algorithm
- int64_t error = ns_to_100us(actualDurationNanos - targetDurationNanos);
- if (i >= d_start) {
- derivative_sum += error - mDescriptor->previous_error;
- }
- if (i >= p_start) {
- err_sum += error;
- }
- if (i >= i_start) {
- mDescriptor->integral_error = mDescriptor->integral_error + error * dt;
- mDescriptor->integral_error = std::min(sPidIHighLimit, mDescriptor->integral_error);
- mDescriptor->integral_error = std::max(sPidILowLimit, mDescriptor->integral_error);
- }
- mDescriptor->previous_error = error;
- }
- int64_t pOut = static_cast<int64_t>((err_sum > 0 ? sPidPOver : sPidPUnder) * err_sum /
- (length - p_start));
- int64_t iOut = static_cast<int64_t>(sPidI * mDescriptor->integral_error);
- int64_t dOut = static_cast<int64_t>((derivative_sum > 0 ? sPidDOver : sPidDUnder) *
- derivative_sum / dt / (length - d_start));
-
- int64_t output = pOut + iOut + dOut;
- if (ATRACE_ENABLED()) {
- const std::string idstr = getIdString();
- std::string sz = StringPrintf("adpf.%s-actl_last", idstr.c_str());
- ATRACE_INT(sz.c_str(), actualDurations[length - 1].durationNanos);
- sz = StringPrintf("adpf.%s-target", idstr.c_str());
- ATRACE_INT(sz.c_str(), (int64_t)mDescriptor->duration.count());
- sz = StringPrintf("adpf.%s-sample_size", idstr.c_str());
- ATRACE_INT(sz.c_str(), length);
- sz = StringPrintf("adpf.%s-pid.count", idstr.c_str());
- ATRACE_INT(sz.c_str(), mDescriptor->update_count);
- sz = StringPrintf("adpf.%s-pid.pOut", idstr.c_str());
- ATRACE_INT(sz.c_str(), pOut);
- sz = StringPrintf("adpf.%s-pid.iOut", idstr.c_str());
- ATRACE_INT(sz.c_str(), iOut);
- sz = StringPrintf("adpf.%s-pid.dOut", idstr.c_str());
- ATRACE_INT(sz.c_str(), dOut);
- sz = StringPrintf("adpf.%s-pid.output", idstr.c_str());
- ATRACE_INT(sz.c_str(), output);
- }
- mDescriptor->update_count++;
-
- mStaleHandler->updateStaleTimer();
-
- /* apply to all the threads in the group */
- if (output != 0) {
- int next_min =
- std::min(sUclampMinHighLimit, mDescriptor->current_min + static_cast<int>(output));
- next_min = std::max(sUclampMinLowLimit, next_min);
- if (std::abs(mDescriptor->current_min - next_min) > sUclampMinGranularity) {
- setUclamp(next_min);
- }
- }
-
- return ndk::ScopedAStatus::ok();
-}
-
-std::string AppHintDesc::toString() const {
- std::string out =
- StringPrintf("session %" PRIxPTR "\n", reinterpret_cast<uintptr_t>(this) & 0xffff);
- const int64_t durationNanos = duration.count();
- out.append(StringPrintf(" duration: %" PRId64 " ns\n", durationNanos));
- out.append(StringPrintf(" uclamp.min: %d \n", current_min));
- out.append(StringPrintf(" uid: %d, tgid: %d\n", uid, tgid));
-
- out.append(" threadIds: [");
- bool first = true;
- for (int tid : threadIds) {
- if (!first) {
- out.append(", ");
- }
- out.append(std::to_string(tid));
- first = false;
- }
- out.append("]\n");
- return out;
-}
-
-bool PowerHintSession::isActive() {
- return mDescriptor->is_active.load();
-}
-
-bool PowerHintSession::isStale() {
- auto now = std::chrono::steady_clock::now();
- return now >= mStaleHandler->getStaleTime();
-}
-
-const std::vector<int> &PowerHintSession::getTidList() const {
- return mDescriptor->threadIds;
-}
-
-void PowerHintSession::setStale() {
- if (ATRACE_ENABLED()) {
- const std::string idstr = getIdString();
- std::string sz = StringPrintf("adpf.%s-stale", idstr.c_str());
- ATRACE_INT(sz.c_str(), 1);
- }
- // Reset to default uclamp value.
- setUclamp(0);
- // Deliver a task to check if all sessions are inactive.
- updateUniveralBoostMode();
-}
-
-void PowerHintSession::StaleHandler::updateStaleTimer() {
- std::lock_guard<std::mutex> guard(mStaleLock);
- if (PowerHintMonitor::getInstance()->isRunning()) {
- auto when = getStaleTime();
- auto now = std::chrono::steady_clock::now();
- mLastUpdatedTime.store(now);
- if (now > when) {
- mSession->updateUniveralBoostMode();
- }
- if (!mIsMonitoringStale.load()) {
- auto next = getStaleTime();
- PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
- duration_cast<nanoseconds>(next - now).count(), this, NULL);
- mIsMonitoringStale.store(true);
- }
- }
-}
-
-time_point<steady_clock> PowerHintSession::StaleHandler::getStaleTime() {
- return mLastUpdatedTime.load() +
- std::chrono::duration_cast<milliseconds>(mSession->kAdpfRate) * sStaleTimeFactor;
-}
-
-void PowerHintSession::StaleHandler::handleMessage(const Message &) {
- std::lock_guard<std::mutex> guard(mStaleLock);
- auto now = std::chrono::steady_clock::now();
- auto when = getStaleTime();
- // Check if the session is stale based on the last_updated_time.
- if (now > when) {
- mSession->setStale();
- mIsMonitoringStale.store(false);
- return;
- }
- // Schedule for the next checking time.
- PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
- duration_cast<nanoseconds>(when - now).count(), this, NULL);
-}
-
-} // namespace pixel
-} // namespace impl
-} // namespace power
-} // namespace hardware
-} // namespace google
-} // namespace aidl
diff --git a/power-libperfmgr/aidl/PowerHintSession.h b/power-libperfmgr/aidl/PowerHintSession.h
deleted file mode 100644
index e3c0f84..0000000
--- a/power-libperfmgr/aidl/PowerHintSession.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 2021 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 <aidl/android/hardware/power/BnPowerHintSession.h>
-#include <aidl/android/hardware/power/WorkDuration.h>
-#include <utils/Looper.h>
-#include <utils/Thread.h>
-
-#include <mutex>
-#include <unordered_map>
-
-namespace aidl {
-namespace google {
-namespace hardware {
-namespace power {
-namespace impl {
-namespace pixel {
-
-using aidl::android::hardware::power::BnPowerHintSession;
-using aidl::android::hardware::power::WorkDuration;
-using ::android::Message;
-using ::android::MessageHandler;
-using ::android::sp;
-using std::chrono::milliseconds;
-using std::chrono::nanoseconds;
-using std::chrono::steady_clock;
-using std::chrono::time_point;
-
-static const int32_t kMaxUclampValue = 1024;
-struct AppHintDesc {
- AppHintDesc(int32_t tgid, int32_t uid, std::vector<int> threadIds)
- : tgid(tgid),
- uid(uid),
- threadIds(std::move(threadIds)),
- duration(0LL),
- current_min(0),
- is_active(true),
- update_count(0),
- integral_error(0),
- previous_error(0) {}
- std::string toString() const;
- const int32_t tgid;
- const int32_t uid;
- const std::vector<int> threadIds;
- nanoseconds duration;
- int current_min;
- // status
- std::atomic<bool> is_active;
- // pid
- uint64_t update_count;
- int64_t integral_error;
- int64_t previous_error;
-};
-
-class PowerHintSession : public BnPowerHintSession {
- public:
- explicit PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds,
- int64_t durationNanos, nanoseconds adpfRate);
- ~PowerHintSession();
- ndk::ScopedAStatus close() override;
- ndk::ScopedAStatus pause() override;
- ndk::ScopedAStatus resume() override;
- ndk::ScopedAStatus updateTargetWorkDuration(int64_t targetDurationNanos) override;
- ndk::ScopedAStatus reportActualWorkDuration(
- const std::vector<WorkDuration> &actualDurations) override;
- bool isActive();
- bool isStale();
- const std::vector<int> &getTidList() const;
-
- private:
- class StaleHandler : public MessageHandler {
- public:
- StaleHandler(PowerHintSession *session)
- : mSession(session), mIsMonitoringStale(false), mLastUpdatedTime(steady_clock::now()) {}
- void handleMessage(const Message &message) override;
- void updateStaleTimer();
- time_point<steady_clock> getStaleTime();
-
- private:
- PowerHintSession *mSession;
- std::atomic<bool> mIsMonitoringStale;
- std::atomic<time_point<steady_clock>> mLastUpdatedTime;
- std::mutex mStaleLock;
- };
-
- private:
- void setStale();
- void updateUniveralBoostMode();
- int setUclamp(int32_t min, int32_t max = kMaxUclampValue);
- std::string getIdString() const;
- AppHintDesc *mDescriptor = nullptr;
- sp<StaleHandler> mStaleHandler;
- sp<MessageHandler> mPowerManagerHandler;
- std::mutex mLock;
- const nanoseconds kAdpfRate;
- std::atomic<bool> mSessionClosed = false;
-};
-
-} // namespace pixel
-} // namespace impl
-} // namespace power
-} // namespace hardware
-} // namespace google
-} // namespace aidl
diff --git a/power-libperfmgr/aidl/PowerSessionManager.cpp b/power-libperfmgr/aidl/PowerSessionManager.cpp
deleted file mode 100644
index fc73c01..0000000
--- a/power-libperfmgr/aidl/PowerSessionManager.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2021 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 LOG_TAG "powerhal-libperfmgr"
-#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
-
-#include <log/log.h>
-#include <processgroup/processgroup.h>
-#include <utils/Trace.h>
-
-#include "PowerSessionManager.h"
-
-namespace aidl {
-namespace google {
-namespace hardware {
-namespace power {
-namespace impl {
-namespace pixel {
-
-void PowerSessionManager::setHintManager(std::shared_ptr<HintManager> const &hint_manager) {
- // Only initialize hintmanager instance if hint is supported.
- if (hint_manager->IsHintSupported(kDisableBoostHintName)) {
- mHintManager = hint_manager;
- }
-}
-
-void PowerSessionManager::updateHintMode(const std::string &mode, bool enabled) {
- ALOGV("PowerSessionManager::updateHintMode: mode: %s, enabled: %d", mode.c_str(), enabled);
- if (enabled && mode.compare(0, 8, "REFRESH_") == 0) {
- if (mode.compare("REFRESH_120FPS") == 0) {
- mDisplayRefreshRate = 120;
- } else if (mode.compare("REFRESH_90FPS") == 0) {
- mDisplayRefreshRate = 90;
- } else if (mode.compare("REFRESH_60FPS") == 0) {
- mDisplayRefreshRate = 60;
- }
- }
-}
-
-int PowerSessionManager::getDisplayRefreshRate() {
- return mDisplayRefreshRate;
-}
-
-void PowerSessionManager::addPowerSession(PowerHintSession *session) {
- std::lock_guard<std::mutex> guard(mLock);
- for (auto t : session->getTidList()) {
- if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) {
- if (!SetTaskProfiles(t, {"ResetUclampGrp"})) {
- ALOGW("Failed to set ResetUclampGrp task profile for tid:%d", t);
- } else {
- mTidRefCountMap[t] = 1;
- }
- continue;
- }
- if (mTidRefCountMap[t] <= 0) {
- ALOGE("Error! Unexpected zero/negative RefCount:%d for tid:%d", mTidRefCountMap[t], t);
- continue;
- }
- mTidRefCountMap[t]++;
- }
- mSessions.insert(session);
-}
-
-void PowerSessionManager::removePowerSession(PowerHintSession *session) {
- std::lock_guard<std::mutex> guard(mLock);
- for (auto t : session->getTidList()) {
- if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) {
- ALOGE("Unexpected Error! Failed to look up tid:%d in TidRefCountMap", t);
- continue;
- }
- mTidRefCountMap[t]--;
- if (mTidRefCountMap[t] <= 0) {
- if (!SetTaskProfiles(t, {"NoResetUclampGrp"})) {
- ALOGW("Failed to set NoResetUclampGrp task profile for tid:%d", t);
- }
- mTidRefCountMap.erase(t);
- }
- }
- mSessions.erase(session);
-}
-
-std::optional<bool> PowerSessionManager::isAnySessionActive() {
- std::lock_guard<std::mutex> guard(mLock);
- bool active = false;
- for (PowerHintSession *s : mSessions) {
- // session active and not stale is actually active.
- if (s->isActive() && !s->isStale()) {
- active = true;
- break;
- }
- }
- if (active == mActive) {
- return std::nullopt;
- } else {
- mActive = active;
- }
-
- return active;
-}
-
-void PowerSessionManager::handleMessage(const Message &) {
- auto active = isAnySessionActive();
- if (!active.has_value()) {
- return;
- }
- if (active.value()) {
- disableSystemTopAppBoost();
- } else {
- enableSystemTopAppBoost();
- }
-}
-
-void PowerSessionManager::enableSystemTopAppBoost() {
- if (mHintManager) {
- ALOGV("PowerSessionManager::enableSystemTopAppBoost!!");
- mHintManager->EndHint(kDisableBoostHintName);
- }
-}
-
-void PowerSessionManager::disableSystemTopAppBoost() {
- if (mHintManager) {
- ALOGV("PowerSessionManager::disableSystemTopAppBoost!!");
- mHintManager->DoHint(kDisableBoostHintName);
- }
-}
-
-// =========== PowerHintMonitor implementation start from here ===========
-void PowerHintMonitor::start() {
- if (!isRunning()) {
- run("PowerHintMonitor", ::android::PRIORITY_HIGHEST);
- }
-}
-
-bool PowerHintMonitor::threadLoop() {
- while (true) {
- mLooper->pollOnce(-1);
- }
- return true;
-}
-
-sp<Looper> PowerHintMonitor::getLooper() {
- return mLooper;
-}
-
-} // namespace pixel
-} // namespace impl
-} // namespace power
-} // namespace hardware
-} // namespace google
-} // namespace aidl
diff --git a/power-libperfmgr/aidl/PowerSessionManager.h b/power-libperfmgr/aidl/PowerSessionManager.h
deleted file mode 100644
index 4b7c36d..0000000
--- a/power-libperfmgr/aidl/PowerSessionManager.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2021 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 "PowerHintSession.h"
-
-#include <android-base/properties.h>
-#include <perfmgr/HintManager.h>
-#include <utils/Looper.h>
-
-#include <mutex>
-#include <optional>
-#include <unordered_set>
-
-namespace aidl {
-namespace google {
-namespace hardware {
-namespace power {
-namespace impl {
-namespace pixel {
-
-using ::android::Looper;
-using ::android::Message;
-using ::android::MessageHandler;
-using ::android::Thread;
-using ::android::perfmgr::HintManager;
-
-constexpr char kPowerHalAdpfDisableTopAppBoost[] = "vendor.powerhal.adpf.disable.hint";
-
-class PowerSessionManager : public MessageHandler {
- public:
- // current hint info
- void updateHintMode(const std::string &mode, bool enabled);
- int getDisplayRefreshRate();
- // monitoring session status
- void addPowerSession(PowerHintSession *session);
- void removePowerSession(PowerHintSession *session);
-
- void handleMessage(const Message &message) override;
- void setHintManager(std::shared_ptr<HintManager> const &hint_manager);
-
- // Singleton
- static sp<PowerSessionManager> getInstance() {
- static sp<PowerSessionManager> instance = new PowerSessionManager();
- return instance;
- }
-
- private:
- std::optional<bool> isAnySessionActive();
- void disableSystemTopAppBoost();
- void enableSystemTopAppBoost();
- const std::string kDisableBoostHintName;
- std::shared_ptr<HintManager> mHintManager;
- std::unordered_set<PowerHintSession *> mSessions; // protected by mLock
- std::unordered_map<int, int> mTidRefCountMap; // protected by mLock
- std::mutex mLock;
- int mDisplayRefreshRate;
- bool mActive; // protected by mLock
- // Singleton
- PowerSessionManager()
- : kDisableBoostHintName(::android::base::GetProperty(kPowerHalAdpfDisableTopAppBoost,
- "ADPF_DISABLE_TA_BOOST")),
- mHintManager(nullptr),
- mDisplayRefreshRate(60),
- mActive(false) {}
- PowerSessionManager(PowerSessionManager const &) = delete;
- void operator=(PowerSessionManager const &) = delete;
-};
-
-class PowerHintMonitor : public Thread {
- public:
- void start();
- bool threadLoop() override;
- sp<Looper> getLooper();
- // Singleton
- static sp<PowerHintMonitor> getInstance() {
- static sp<PowerHintMonitor> instance = new PowerHintMonitor();
- return instance;
- }
- PowerHintMonitor(PowerHintMonitor const &) = delete;
- void operator=(PowerHintMonitor const &) = delete;
-
- private:
- sp<Looper> mLooper;
- // Singleton
- PowerHintMonitor() : Thread(false), mLooper(new Looper(true)) {}
-};
-
-} // namespace pixel
-} // namespace impl
-} // namespace power
-} // namespace hardware
-} // namespace google
-} // namespace aidl
diff --git a/power-libperfmgr/aidl/android.hardware.power-service.pixel-libperfmgr.rc b/power-libperfmgr/aidl/android.hardware.power-service.pixel-libperfmgr.rc
index ef15b12..8367da9 100644
--- a/power-libperfmgr/aidl/android.hardware.power-service.pixel-libperfmgr.rc
+++ b/power-libperfmgr/aidl/android.hardware.power-service.pixel-libperfmgr.rc
@@ -4,9 +4,6 @@
group system
priority -20
-on late-fs
- start vendor.power-hal-aidl
-
# restart powerHAL when framework died
on property:init.svc.zygote=restarting && property:vendor.powerhal.state=*
setprop vendor.powerhal.state ""
@@ -18,12 +15,3 @@
on property:init.svc.vendor.audio-hal-2-0=restarting && property:vendor.powerhal.audio=AUDIO_STREAMING_LOW_LATENCY
setprop vendor.powerhal.audio ""
restart vendor.power-hal-aidl
-
-# Clean up after b/163539793 resolved
-on property:vendor.powerhal.dalvik.vm.dex2oat-threads=*
- setprop dalvik.vm.dex2oat-threads ${vendor.powerhal.dalvik.vm.dex2oat-threads}
- setprop dalvik.vm.restore-dex2oat-threads ${vendor.powerhal.dalvik.vm.dex2oat-threads}
-
-on property:vendor.powerhal.dalvik.vm.dex2oat-cpu-set=*
- setprop dalvik.vm.dex2oat-cpu-set ${vendor.powerhal.dalvik.vm.dex2oat-cpu-set}
- setprop dalvik.vm.restore-dex2oat-cpu-set ${vendor.powerhal.dalvik.vm.dex2oat-cpu-set}
diff --git a/power-libperfmgr/aidl/android.hardware.power-service.pixel.xml b/power-libperfmgr/aidl/android.hardware.power-service.pixel.xml
index 9f56deb..caf6ea2 100644
--- a/power-libperfmgr/aidl/android.hardware.power-service.pixel.xml
+++ b/power-libperfmgr/aidl/android.hardware.power-service.pixel.xml
@@ -1,7 +1,6 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.power</name>
- <version>2</version>
<fqname>IPower/default</fqname>
</hal>
</manifest>
diff --git a/power-libperfmgr/aidl/service.cpp b/power-libperfmgr/aidl/service.cpp
index 3c1cf98..aeb6356 100644
--- a/power-libperfmgr/aidl/service.cpp
+++ b/power-libperfmgr/aidl/service.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "powerhal-libperfmgr"
+#define LOG_TAG "android.hardware.power-service.pixel-libperfmgr"
#include <thread>
@@ -25,31 +25,22 @@
#include "Power.h"
#include "PowerExt.h"
-#include "PowerSessionManager.h"
#include "disp-power/DisplayLowPower.h"
-using aidl::google::hardware::power::impl::pixel::DisplayLowPower;
using aidl::google::hardware::power::impl::pixel::Power;
using aidl::google::hardware::power::impl::pixel::PowerExt;
-using aidl::google::hardware::power::impl::pixel::PowerHintMonitor;
-using aidl::google::hardware::power::impl::pixel::PowerSessionManager;
using ::android::perfmgr::HintManager;
-constexpr std::string_view kPowerHalInitProp("vendor.powerhal.init");
-constexpr std::string_view kConfigProperty("vendor.powerhal.config");
-constexpr std::string_view kConfigDefaultFileName("powerhint.json");
+constexpr char kPowerHalConfigPath[] = "/vendor/etc/powerhint.json";
+constexpr char kPowerHalInitProp[] = "vendor.powerhal.init";
int main() {
- const std::string config_path =
- "/vendor/etc/" +
- android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data());
- LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is starting with config: "
- << config_path;
+ LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is starting.";
// Parse config but do not start the looper
- std::shared_ptr<HintManager> hm = HintManager::GetFromJSON(config_path, false);
+ std::shared_ptr<HintManager> hm = HintManager::GetFromJSON(kPowerHalConfigPath, false);
if (!hm) {
- LOG(FATAL) << "Invalid config: " << config_path;
+ LOG(FATAL) << "Invalid config: " << kPowerHalConfigPath;
}
std::shared_ptr<DisplayLowPower> dlpw = std::make_shared<DisplayLowPower>();
@@ -72,13 +63,8 @@
CHECK(status == STATUS_OK);
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is started.";
- if (::android::base::GetIntProperty("vendor.powerhal.adpf.rate", -1) != -1) {
- PowerHintMonitor::getInstance()->start();
- PowerSessionManager::getInstance()->setHintManager(hm);
- }
-
std::thread initThread([&]() {
- ::android::base::WaitForProperty(kPowerHalInitProp.data(), "1");
+ ::android::base::WaitForProperty(kPowerHalInitProp, "1");
hm->Start();
dlpw->Init();
});
diff --git a/power-libperfmgr/disp-power/DisplayLowPower.cpp b/power-libperfmgr/disp-power/DisplayLowPower.cpp
index f2da574..d38972a 100644
--- a/power-libperfmgr/disp-power/DisplayLowPower.cpp
+++ b/power-libperfmgr/disp-power/DisplayLowPower.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "powerhal-libperfmgr"
+#define LOG_TAG "android.hardware.power@-service.pixel-libperfmgr"
#include <errno.h>
#include <unistd.h>
@@ -24,13 +24,6 @@
#include "DisplayLowPower.h"
-namespace aidl {
-namespace google {
-namespace hardware {
-namespace power {
-namespace impl {
-namespace pixel {
-
DisplayLowPower::DisplayLowPower() : mFossStatus(false) {}
void DisplayLowPower::Init() {
@@ -78,10 +71,3 @@
mFossStatus = enable;
}
}
-
-} // namespace pixel
-} // namespace impl
-} // namespace power
-} // namespace hardware
-} // namespace google
-} // namespace aidl
diff --git a/power-libperfmgr/disp-power/DisplayLowPower.h b/power-libperfmgr/disp-power/DisplayLowPower.h
index 53eb6c9..c0d6c33 100644
--- a/power-libperfmgr/disp-power/DisplayLowPower.h
+++ b/power-libperfmgr/disp-power/DisplayLowPower.h
@@ -16,16 +16,9 @@
#pragma once
-#include <string_view>
-
#include <android-base/unique_fd.h>
-namespace aidl {
-namespace google {
-namespace hardware {
-namespace power {
-namespace impl {
-namespace pixel {
+#include <string_view>
class DisplayLowPower {
public:
@@ -39,13 +32,6 @@
int SendPpsCommand(const std::string_view cmd);
void SetFoss(bool enable);
- ::android::base::unique_fd mPpsSocket;
+ android::base::unique_fd mPpsSocket;
bool mFossStatus;
};
-
-} // namespace pixel
-} // namespace impl
-} // namespace power
-} // namespace hardware
-} // namespace google
-} // namespace aidl
diff --git a/power-libperfmgr/disp-power/InteractionHandler.cpp b/power-libperfmgr/disp-power/InteractionHandler.cpp
index f6cd0e9..1826958 100644
--- a/power-libperfmgr/disp-power/InteractionHandler.cpp
+++ b/power-libperfmgr/disp-power/InteractionHandler.cpp
@@ -14,73 +14,33 @@
* limitations under the License.
*/
-#define LOG_TAG "powerhal-libperfmgr"
+#define LOG_TAG "android.hardware.power@-service.pixel-libperfmgr"
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
-#include <array>
-#include <memory>
-
#include <fcntl.h>
#include <poll.h>
#include <sys/eventfd.h>
#include <time.h>
#include <unistd.h>
-
-#include <android-base/properties.h>
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <memory>
#include "InteractionHandler.h"
#define MAX_LENGTH 64
#define MSINSEC 1000L
-#define NSINMS 1000000L
+#define USINMS 1000000L
-namespace aidl {
-namespace google {
-namespace hardware {
-namespace power {
-namespace impl {
-namespace pixel {
-
-namespace {
-
-static const bool kDisplayIdleSupport =
- ::android::base::GetBoolProperty("vendor.powerhal.disp.idle_support", true);
-static const std::array<const char *, 2> kDispIdlePath = {"/sys/class/drm/card0/device/idle_state",
- "/sys/class/graphics/fb0/idle_state"};
-static const uint32_t kWaitMs =
- ::android::base::GetUintProperty("vendor.powerhal.disp.idle_wait", /*default*/ 100U);
-static const uint32_t kMinDurationMs =
- ::android::base::GetUintProperty("vendor.powerhal.interaction.min", /*default*/ 1400U);
-static const uint32_t kMaxDurationMs =
- ::android::base::GetUintProperty("vendor.powerhal.interaction.max", /*default*/ 5650U);
-static const uint32_t kDurationOffsetMs =
- ::android::base::GetUintProperty("vendor.powerhal.interaction.offset", /*default*/ 650U);
-
-static size_t CalcTimespecDiffMs(struct timespec start, struct timespec end) {
- size_t diff_in_ms = 0;
- diff_in_ms += (end.tv_sec - start.tv_sec) * MSINSEC;
- diff_in_ms += (end.tv_nsec - start.tv_nsec) / NSINMS;
- return diff_in_ms;
-}
-
-static int FbIdleOpen(void) {
- int fd;
- for (const auto &path : kDispIdlePath) {
- fd = open(path, O_RDONLY);
- if (fd >= 0)
- return fd;
- }
- ALOGE("Unable to open fb idle state path (%d)", errno);
- return -1;
-}
-
-} // namespace
+static const std::vector<std::string> fb_idle_patch = {"/sys/class/drm/card0/device/idle_state",
+ "/sys/class/graphics/fb0/idle_state"};
InteractionHandler::InteractionHandler(std::shared_ptr<HintManager> const &hint_manager)
: mState(INTERACTION_STATE_UNINITIALIZED),
+ mWaitMs(100),
+ mMinDurationMs(1400),
+ mMaxDurationMs(5650),
mDurationMs(0),
mHintManager(hint_manager) {}
@@ -88,13 +48,24 @@
Exit();
}
+static int fb_idle_open(void) {
+ int fd;
+ for (auto &path : fb_idle_patch) {
+ fd = open(path.c_str(), O_RDONLY);
+ if (fd >= 0)
+ return fd;
+ }
+ ALOGE("Unable to open fb idle state path (%d)", errno);
+ return -1;
+}
+
bool InteractionHandler::Init() {
std::lock_guard<std::mutex> lk(mLock);
if (mState != INTERACTION_STATE_UNINITIALIZED)
return true;
- int fd = FbIdleOpen();
+ int fd = fb_idle_open();
if (fd < 0)
return false;
mIdleFd = fd;
@@ -144,28 +115,31 @@
ATRACE_INT("interaction_lock", 0);
}
+size_t InteractionHandler::CalcTimespecDiffMs(struct timespec start, struct timespec end) {
+ size_t diff_in_us = 0;
+ diff_in_us += (end.tv_sec - start.tv_sec) * MSINSEC;
+ diff_in_us += (end.tv_nsec - start.tv_nsec) / USINMS;
+ return diff_in_us;
+}
+
void InteractionHandler::Acquire(int32_t duration) {
ATRACE_CALL();
std::lock_guard<std::mutex> lk(mLock);
-
- int inputDuration = duration + kDurationOffsetMs;
- int finalDuration;
- if (inputDuration > kMaxDurationMs)
- finalDuration = kMaxDurationMs;
- else if (inputDuration > kMinDurationMs)
- finalDuration = inputDuration;
- else
- finalDuration = kMinDurationMs;
-
- // Fallback to do boost directly
- // 1) override property is set OR
- // 2) InteractionHandler not initialized
- if (!kDisplayIdleSupport || mState == INTERACTION_STATE_UNINITIALIZED) {
- mHintManager->DoHint("INTERACTION", std::chrono::milliseconds(finalDuration));
+ if (mState == INTERACTION_STATE_UNINITIALIZED) {
+ ALOGW("%s: called while uninitialized", __func__);
return;
}
+ int inputDuration = duration + 650;
+ int finalDuration;
+ if (inputDuration > mMaxDurationMs)
+ finalDuration = mMaxDurationMs;
+ else if (inputDuration > mMinDurationMs)
+ finalDuration = inputDuration;
+ else
+ finalDuration = mMinDurationMs;
+
struct timespec cur_timespec;
clock_gettime(CLOCK_MONOTONIC, &cur_timespec);
if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) {
@@ -261,7 +235,6 @@
}
void InteractionHandler::Routine() {
- pthread_setname_np(pthread_self(), "DispIdle");
std::unique_lock<std::mutex> lk(mLock, std::defer_lock);
while (true) {
@@ -272,14 +245,7 @@
mState = INTERACTION_STATE_WAITING;
lk.unlock();
- WaitForIdle(kWaitMs, mDurationMs);
+ WaitForIdle(mWaitMs, mDurationMs);
Release();
}
}
-
-} // namespace pixel
-} // namespace impl
-} // namespace power
-} // namespace hardware
-} // namespace google
-} // namespace aidl
diff --git a/power-libperfmgr/disp-power/InteractionHandler.h b/power-libperfmgr/disp-power/InteractionHandler.h
index 77ade88..ba767f1 100644
--- a/power-libperfmgr/disp-power/InteractionHandler.h
+++ b/power-libperfmgr/disp-power/InteractionHandler.h
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#pragma once
+#ifndef POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
+#define POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
#include <condition_variable>
#include <memory>
@@ -24,16 +25,9 @@
#include <perfmgr/HintManager.h>
-namespace aidl {
-namespace google {
-namespace hardware {
-namespace power {
-namespace impl {
-namespace pixel {
-
using ::android::perfmgr::HintManager;
-enum InteractionState {
+enum interaction_state {
INTERACTION_STATE_UNINITIALIZED,
INTERACTION_STATE_IDLE,
INTERACTION_STATE_INTERACTION,
@@ -57,20 +51,24 @@
void PerfLock();
void PerfRel();
- enum InteractionState mState;
+ size_t CalcTimespecDiffMs(struct timespec start, struct timespec end);
+
+ enum interaction_state mState;
+
int mIdleFd;
int mEventFd;
+
+ int32_t mWaitMs;
+ int32_t mMinDurationMs;
+ int32_t mMaxDurationMs;
int32_t mDurationMs;
+
struct timespec mLastTimespec;
+
std::unique_ptr<std::thread> mThread;
std::mutex mLock;
std::condition_variable mCond;
std::shared_ptr<HintManager> mHintManager;
};
-} // namespace pixel
-} // namespace impl
-} // namespace power
-} // namespace hardware
-} // namespace google
-} // namespace aidl
+#endif // POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
diff --git a/power-libperfmgr/hidl/DEPRECATED b/power-libperfmgr/hidl/DEPRECATED
deleted file mode 100644
index e69de29..0000000
--- a/power-libperfmgr/hidl/DEPRECATED
+++ /dev/null
diff --git a/power-libperfmgr/hidl/Power.cpp b/power-libperfmgr/hidl/Power.cpp
new file mode 100644
index 0000000..2b43b0f
--- /dev/null
+++ b/power-libperfmgr/hidl/Power.cpp
@@ -0,0 +1,388 @@
+/*
+ * 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 ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
+#define LOG_TAG "android.hardware.power@1.3-service.pixel-libperfmgr"
+
+#include "Power.h"
+
+#include <mutex>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include "AudioStreaming.h"
+#include "disp-power/DisplayLowPower.h"
+
+namespace android {
+namespace hardware {
+namespace power {
+namespace V1_3 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::power::V1_0::Feature;
+using ::android::hardware::power::V1_0::Status;
+
+constexpr char kPowerHalStateProp[] = "vendor.powerhal.state";
+constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio";
+constexpr char kPowerHalInitProp[] = "vendor.powerhal.init";
+constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering";
+constexpr char kPowerHalConfigPath[] = "/vendor/etc/powerhint.json";
+
+static const std::map<enum CameraStreamingMode, std::string> kCamStreamingHint = {
+ {CAMERA_STREAMING_OFF, "CAMERA_STREAMING_OFF"},
+ {CAMERA_STREAMING, "CAMERA_STREAMING"},
+ {CAMERA_STREAMING_1080P, "CAMERA_STREAMING_1080P"},
+ {CAMERA_STREAMING_60FPS, "CAMERA_STREAMING_60FPS"},
+ {CAMERA_STREAMING_4K, "CAMERA_STREAMING_4K"},
+ {CAMERA_STREAMING_SECURE, "CAMERA_STREAMING_SECURE"}};
+
+Power::Power()
+ : mHintManager(nullptr),
+ mInteractionHandler(nullptr),
+ mDisplayLowPower(nullptr),
+ mVRModeOn(false),
+ mSustainedPerfModeOn(false),
+ mCameraStreamingMode(CAMERA_STREAMING_OFF),
+ mReady(false) {
+ mInitThread = std::thread([this]() {
+ android::base::WaitForProperty(kPowerHalInitProp, "1");
+ mHintManager = HintManager::GetFromJSON(kPowerHalConfigPath);
+ if (!mHintManager) {
+ LOG(FATAL) << "Invalid config: " << kPowerHalConfigPath;
+ }
+ mInteractionHandler = std::make_unique<InteractionHandler>(mHintManager);
+ mInteractionHandler->Init();
+ mDisplayLowPower = std::make_unique<DisplayLowPower>();
+ mDisplayLowPower->Init();
+ std::string state = android::base::GetProperty(kPowerHalStateProp, "");
+ if (state == "CAMERA_STREAMING") {
+ ALOGI("Initialize with CAMERA_STREAMING on");
+ mHintManager->DoHint("CAMERA_STREAMING");
+ mCameraStreamingMode = CAMERA_STREAMING;
+ } else if (state == "CAMERA_STREAMING_1080P") {
+ ALOGI("Initialize CAMERA_STREAMING_1080P on");
+ mHintManager->DoHint("CAMERA_STREAMING_1080P");
+ mCameraStreamingMode = CAMERA_STREAMING_1080P;
+ } else if (state == "CAMERA_STREAMING_60FPS") {
+ ALOGI("Initialize CAMERA_STREAMING_60FPS on");
+ mHintManager->DoHint("CAMERA_STREAMING_60FPS");
+ mCameraStreamingMode = CAMERA_STREAMING_60FPS;
+ } else if (state == "CAMERA_STREAMING_4K") {
+ ALOGI("Initialize with CAMERA_STREAMING_4K on");
+ mHintManager->DoHint("CAMERA_STREAMING_4K");
+ mCameraStreamingMode = CAMERA_STREAMING_4K;
+ } else if (state == "CAMERA_STREAMING_SECURE") {
+ ALOGI("Initialize with CAMERA_STREAMING_SECURE on");
+ mHintManager->DoHint("CAMERA_STREAMING_SECURE");
+ mCameraStreamingMode = CAMERA_STREAMING_SECURE;
+ } else if (state == "SUSTAINED_PERFORMANCE") {
+ ALOGI("Initialize with SUSTAINED_PERFORMANCE on");
+ mHintManager->DoHint("SUSTAINED_PERFORMANCE");
+ mSustainedPerfModeOn = true;
+ } else if (state == "VR_MODE") {
+ ALOGI("Initialize with VR_MODE on");
+ mHintManager->DoHint("VR_MODE");
+ mVRModeOn = true;
+ } else if (state == "VR_SUSTAINED_PERFORMANCE") {
+ ALOGI("Initialize with SUSTAINED_PERFORMANCE and VR_MODE on");
+ mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
+ mSustainedPerfModeOn = true;
+ mVRModeOn = true;
+ } else {
+ ALOGI("Initialize PowerHAL");
+ }
+
+ state = android::base::GetProperty(kPowerHalAudioProp, "");
+ if (state == "AUDIO_LOW_LATENCY") {
+ ALOGI("Initialize with AUDIO_LOW_LATENCY on");
+ mHintManager->DoHint("AUDIO_LOW_LATENCY");
+ }
+
+ state = android::base::GetProperty(kPowerHalRenderingProp, "");
+ if (state == "EXPENSIVE_RENDERING") {
+ ALOGI("Initialize with EXPENSIVE_RENDERING on");
+ mHintManager->DoHint("EXPENSIVE_RENDERING");
+ }
+ // Now start to take powerhint
+ mReady.store(true);
+ ALOGI("PowerHAL ready to process hints");
+ });
+ mInitThread.detach();
+}
+
+// Methods from ::android::hardware::power::V1_0::IPower follow.
+Return<void> Power::setInteractive(bool /* interactive */) {
+ return Void();
+}
+
+Return<void> Power::powerHint(PowerHint_1_0 hint, int32_t data) {
+ if (!mReady) {
+ return Void();
+ }
+ ATRACE_INT(android::hardware::power::V1_0::toString(hint).c_str(), data);
+ ALOGD_IF(hint != PowerHint_1_0::INTERACTION, "%s: %d",
+ android::hardware::power::V1_0::toString(hint).c_str(), static_cast<int>(data));
+ switch (hint) {
+ case PowerHint_1_0::INTERACTION:
+ if (mVRModeOn || mSustainedPerfModeOn) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ } else {
+ mInteractionHandler->Acquire(data);
+ }
+ break;
+ case PowerHint_1_0::SUSTAINED_PERFORMANCE:
+ if (data && !mSustainedPerfModeOn) {
+ if (!mVRModeOn) { // Sustained mode only.
+ mHintManager->DoHint("SUSTAINED_PERFORMANCE");
+ } else { // Sustained + VR mode.
+ mHintManager->EndHint("VR_MODE");
+ mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
+ }
+ mSustainedPerfModeOn = true;
+ } else if (!data && mSustainedPerfModeOn) {
+ mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
+ mHintManager->EndHint("SUSTAINED_PERFORMANCE");
+ if (mVRModeOn) { // Switch back to VR Mode.
+ mHintManager->DoHint("VR_MODE");
+ }
+ mSustainedPerfModeOn = false;
+ }
+ break;
+ case PowerHint_1_0::VR_MODE:
+ if (data && !mVRModeOn) {
+ if (!mSustainedPerfModeOn) { // VR mode only.
+ mHintManager->DoHint("VR_MODE");
+ } else { // Sustained + VR mode.
+ mHintManager->EndHint("SUSTAINED_PERFORMANCE");
+ mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
+ }
+ mVRModeOn = true;
+ } else if (!data && mVRModeOn) {
+ mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
+ mHintManager->EndHint("VR_MODE");
+ if (mSustainedPerfModeOn) { // Switch back to sustained Mode.
+ mHintManager->DoHint("SUSTAINED_PERFORMANCE");
+ }
+ mVRModeOn = false;
+ }
+ break;
+ case PowerHint_1_0::LAUNCH:
+ if (mVRModeOn || mSustainedPerfModeOn) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ } else {
+ if (data) {
+ // Hint until canceled
+ mHintManager->DoHint("LAUNCH");
+ } else {
+ mHintManager->EndHint("LAUNCH");
+ }
+ }
+ break;
+ case PowerHint_1_0::LOW_POWER:
+ mDisplayLowPower->SetDisplayLowPower(static_cast<bool>(data));
+ break;
+ default:
+ break;
+ }
+ return Void();
+}
+
+Return<void> Power::setFeature(Feature /*feature*/, bool /*activate*/) {
+ // Nothing to do
+ return Void();
+}
+
+Return<void> Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) {
+ LOG(ERROR) << "getPlatformLowPowerStats not supported. Use IPowerStats HAL.";
+ _hidl_cb({}, Status::SUCCESS);
+ return Void();
+}
+
+// Methods from ::android::hardware::power::V1_1::IPower follow.
+Return<void> Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) {
+ LOG(ERROR) << "getSubsystemLowPowerStats not supported. Use IPowerStats HAL.";
+ _hidl_cb({}, Status::SUCCESS);
+ return Void();
+}
+
+Return<void> Power::powerHintAsync(PowerHint_1_0 hint, int32_t data) {
+ // just call the normal power hint in this oneway function
+ return powerHint(hint, data);
+}
+
+// Methods from ::android::hardware::power::V1_2::IPower follow.
+Return<void> Power::powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) {
+ if (!mReady) {
+ return Void();
+ }
+
+ ATRACE_INT(android::hardware::power::V1_2::toString(hint).c_str(), data);
+ ALOGD_IF(hint >= PowerHint_1_2::AUDIO_STREAMING, "%s: %d",
+ android::hardware::power::V1_2::toString(hint).c_str(), static_cast<int>(data));
+
+ switch (hint) {
+ case PowerHint_1_2::AUDIO_LOW_LATENCY:
+ if (data) {
+ // Hint until canceled
+ mHintManager->DoHint("AUDIO_LOW_LATENCY");
+ } else {
+ mHintManager->EndHint("AUDIO_LOW_LATENCY");
+ }
+ break;
+ case PowerHint_1_2::AUDIO_STREAMING:
+ if (mVRModeOn || mSustainedPerfModeOn) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ } else {
+ if (data == static_cast<int32_t>(AUDIO_STREAMING_HINT::AUDIO_STREAMING_ON)) {
+ mHintManager->DoHint("AUDIO_STREAMING");
+ } else if (data ==
+ static_cast<int32_t>(AUDIO_STREAMING_HINT::AUDIO_STREAMING_OFF)) {
+ mHintManager->EndHint("AUDIO_STREAMING");
+ } else if (data == static_cast<int32_t>(AUDIO_STREAMING_HINT::TPU_BOOST_SHORT)) {
+ mHintManager->DoHint("TPU_BOOST",
+ std::chrono::milliseconds(TPU_HINT_DURATION_MS::SHORT));
+ } else if (data == static_cast<int32_t>(AUDIO_STREAMING_HINT::TPU_BOOST_LONG)) {
+ mHintManager->DoHint("TPU_BOOST",
+ std::chrono::milliseconds(TPU_HINT_DURATION_MS::LONG));
+ } else if (data == static_cast<int32_t>(AUDIO_STREAMING_HINT::TPU_BOOST_OFF)) {
+ mHintManager->EndHint("TPU_BOOST");
+ } else {
+ ALOGE("AUDIO STREAMING INVALID DATA: %d", data);
+ }
+ }
+ break;
+ case PowerHint_1_2::CAMERA_LAUNCH:
+ if (data > 0) {
+ mHintManager->DoHint("CAMERA_LAUNCH");
+ } else if (data == 0) {
+ mHintManager->EndHint("CAMERA_LAUNCH");
+ } else {
+ ALOGE("CAMERA LAUNCH INVALID DATA: %d", data);
+ }
+ break;
+ case PowerHint_1_2::CAMERA_STREAMING: {
+ const enum CameraStreamingMode mode = static_cast<enum CameraStreamingMode>(data);
+ if (mode < CAMERA_STREAMING_OFF || mode >= CAMERA_STREAMING_MAX) {
+ ALOGE("CAMERA STREAMING INVALID Mode: %d", mode);
+ break;
+ }
+
+ if (mCameraStreamingMode == mode)
+ break;
+
+ // turn it off first if any previous hint.
+ if ((mCameraStreamingMode != CAMERA_STREAMING_OFF)) {
+ const auto modeValue = kCamStreamingHint.at(mCameraStreamingMode);
+ mHintManager->EndHint(modeValue);
+ if ((mCameraStreamingMode != CAMERA_STREAMING_SECURE)) {
+ // Boost 1s for tear down if not secure streaming use case
+ mHintManager->DoHint("CAMERA_LAUNCH", std::chrono::seconds(1));
+ }
+ }
+
+ if (mode != CAMERA_STREAMING_OFF) {
+ const auto hintValue = kCamStreamingHint.at(mode);
+ mHintManager->DoHint(hintValue);
+ }
+
+ mCameraStreamingMode = mode;
+ const auto prop = (mCameraStreamingMode == CAMERA_STREAMING_OFF)
+ ? ""
+ : kCamStreamingHint.at(mode).c_str();
+ if (!android::base::SetProperty(kPowerHalStateProp, prop)) {
+ ALOGE("%s: could set powerHAL state %s property", __func__, prop);
+ }
+ break;
+ }
+ case PowerHint_1_2::CAMERA_SHOT:
+ if (data > 0) {
+ mHintManager->DoHint("CAMERA_SHOT", std::chrono::milliseconds(data));
+ } else if (data == 0) {
+ mHintManager->EndHint("CAMERA_SHOT");
+ } else {
+ ALOGE("CAMERA SHOT INVALID DATA: %d", data);
+ }
+ break;
+ default:
+ return powerHint(static_cast<PowerHint_1_0>(hint), data);
+ }
+ return Void();
+}
+
+// Methods from ::android::hardware::power::V1_3::IPower follow.
+Return<void> Power::powerHintAsync_1_3(PowerHint_1_3 hint, int32_t data) {
+ if (!mReady) {
+ return Void();
+ }
+
+ if (hint == PowerHint_1_3::EXPENSIVE_RENDERING) {
+ ATRACE_INT(android::hardware::power::V1_3::toString(hint).c_str(), data);
+ if (mVRModeOn || mSustainedPerfModeOn) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ } else {
+ if (data > 0) {
+ mHintManager->DoHint("EXPENSIVE_RENDERING");
+ } else {
+ mHintManager->EndHint("EXPENSIVE_RENDERING");
+ }
+ }
+ } else {
+ return powerHintAsync_1_2(static_cast<PowerHint_1_2>(hint), data);
+ }
+ return Void();
+}
+
+constexpr const char *boolToString(bool b) {
+ return b ? "true" : "false";
+}
+
+Return<void> Power::debug(const hidl_handle &handle, const hidl_vec<hidl_string> &) {
+ if (handle != nullptr && handle->numFds >= 1 && mReady) {
+ int fd = handle->data[0];
+
+ std::string buf(android::base::StringPrintf(
+ "HintManager Running: %s\n"
+ "VRMode: %s\n"
+ "CameraStreamingMode: %s\n"
+ "SustainedPerformanceMode: %s\n",
+ boolToString(mHintManager->IsRunning()), boolToString(mVRModeOn),
+ kCamStreamingHint.at(mCameraStreamingMode).c_str(),
+ boolToString(mSustainedPerfModeOn)));
+ // Dump nodes through libperfmgr
+ mHintManager->DumpToFd(fd);
+ if (!android::base::WriteStringToFd(buf, fd)) {
+ PLOG(ERROR) << "Failed to dump state to fd";
+ }
+ fsync(fd);
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace power
+} // namespace hardware
+} // namespace android
diff --git a/power-libperfmgr/hidl/Power.h b/power-libperfmgr/hidl/Power.h
new file mode 100644
index 0000000..9bac407
--- /dev/null
+++ b/power-libperfmgr/hidl/Power.h
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+#ifndef POWER_LIBPERFMGR_POWER_H_
+#define POWER_LIBPERFMGR_POWER_H_
+
+#include <atomic>
+#include <memory>
+#include <thread>
+
+#include <android/hardware/power/1.3/IPower.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <perfmgr/HintManager.h>
+
+#include "CameraMode.h"
+#include "disp-power/DisplayLowPower.h"
+#include "disp-power/InteractionHandler.h"
+
+namespace android {
+namespace hardware {
+namespace power {
+namespace V1_3 {
+namespace implementation {
+
+using ::InteractionHandler;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::power::V1_0::Feature;
+using ::android::hardware::power::V1_3::IPower;
+using PowerHint_1_0 = ::android::hardware::power::V1_0::PowerHint;
+using PowerHint_1_2 = ::android::hardware::power::V1_2::PowerHint;
+using PowerHint_1_3 = ::android::hardware::power::V1_3::PowerHint;
+using ::android::perfmgr::HintManager;
+
+class Power : public IPower {
+ public:
+ // Methods from ::android::hardware::power::V1_0::IPower follow.
+
+ Power();
+
+ Return<void> setInteractive(bool /* interactive */) override;
+ Return<void> powerHint(PowerHint_1_0 hint, int32_t data) override;
+ Return<void> setFeature(Feature feature, bool activate) override;
+ Return<void> getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::power::V1_1::IPower follow.
+ Return<void> getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) override;
+ Return<void> powerHintAsync(PowerHint_1_0 hint, int32_t data) override;
+
+ // Methods from ::android::hardware::power::V1_2::IPower follow.
+ Return<void> powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) override;
+
+ // Methods from ::android::hardware::power::V1_3::IPower follow.
+ Return<void> powerHintAsync_1_3(PowerHint_1_3 hint, int32_t data) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+ Return<void> debug(const hidl_handle &fd, const hidl_vec<hidl_string> &args) override;
+
+ private:
+ std::shared_ptr<HintManager> mHintManager;
+ std::unique_ptr<InteractionHandler> mInteractionHandler;
+ std::unique_ptr<DisplayLowPower> mDisplayLowPower;
+ std::atomic<bool> mVRModeOn;
+ std::atomic<bool> mSustainedPerfModeOn;
+ std::atomic<enum CameraStreamingMode> mCameraStreamingMode;
+ std::atomic<bool> mReady;
+ std::thread mInitThread;
+};
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace power
+} // namespace hardware
+} // namespace android
+
+#endif // POWER_LIBPERFMGR_POWER_H_
diff --git a/power-libperfmgr/hidl/android.hardware.power@1.3-service.pixel-libperfmgr.rc b/power-libperfmgr/hidl/android.hardware.power@1.3-service.pixel-libperfmgr.rc
new file mode 100644
index 0000000..a59c5b6
--- /dev/null
+++ b/power-libperfmgr/hidl/android.hardware.power@1.3-service.pixel-libperfmgr.rc
@@ -0,0 +1,26 @@
+service vendor.power-hal-1-3 /vendor/bin/hw/android.hardware.power@1.3-service.pixel-libperfmgr
+ class hal
+ user root
+ group system
+ priority -20
+ interface android.hardware.power@1.0::IPower default
+ interface android.hardware.power@1.1::IPower default
+ interface android.hardware.power@1.2::IPower default
+ interface android.hardware.power@1.3::IPower default
+
+# restart powerHAL when framework died
+on property:init.svc.zygote=restarting && property:vendor.powerhal.state=*
+ setprop vendor.powerhal.state ""
+ setprop vendor.powerhal.audio ""
+ setprop vendor.powerhal.rendering ""
+ restart vendor.power-hal-1-3
+
+# restart powerHAL when cameraHAL died
+on property:init.svc.vendor.camera-provider-2-4=restarting && property:vendor.powerhal.state=CAMERA_STREAMING
+ setprop vendor.powerhal.state ""
+ restart vendor.power-hal-1-3
+
+# restart powerHAL when audioHAL died
+on property:init.svc.vendor.audio-hal-2-0=restarting && property:vendor.powerhal.audio=AUDIO_LOW_LATENCY
+ setprop vendor.powerhal.audio ""
+ restart vendor.power-hal-1-3
diff --git a/power-libperfmgr/hidl/android.hardware.power@1.3-service.pixel.xml b/power-libperfmgr/hidl/android.hardware.power@1.3-service.pixel.xml
new file mode 100644
index 0000000..e52398c
--- /dev/null
+++ b/power-libperfmgr/hidl/android.hardware.power@1.3-service.pixel.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.power</name>
+ <transport>hwbinder</transport>
+ <version>1.3</version>
+ <interface>
+ <name>IPower</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/power-libperfmgr/hidl/device.mk b/power-libperfmgr/hidl/device.mk
new file mode 100644
index 0000000..5de6a2c
--- /dev/null
+++ b/power-libperfmgr/hidl/device.mk
@@ -0,0 +1,5 @@
+BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/power-libperfmgr
+
+# power HAL
+PRODUCT_PACKAGES += \
+ android.hardware.power@1.3-service.pixel-libperfmgr
diff --git a/power-libperfmgr/hidl/service.cpp b/power-libperfmgr/hidl/service.cpp
new file mode 100644
index 0000000..7bcc907
--- /dev/null
+++ b/power-libperfmgr/hidl/service.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 LOG_TAG "android.hardware.power@1.3-service.pixel-libperfmgr"
+
+#include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "Power.h"
+
+using android::OK;
+using android::sp;
+using android::status_t;
+
+// libhwbinder:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::hardware::power::V1_3::IPower;
+using android::hardware::power::V1_3::implementation::Power;
+
+int main(int /* argc */, char ** /* argv */) {
+ ALOGI("Power HAL Service 1.3 for Pixel is starting.");
+
+ android::sp<IPower> service = new Power();
+ if (service == nullptr) {
+ ALOGE("Can not create an instance of Power HAL Iface, exiting.");
+ return 1;
+ }
+ android::hardware::setMinSchedulerPolicy(service, SCHED_NORMAL, -20);
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+ status_t status = service->registerAsService();
+ if (status != OK) {
+ ALOGE("Could not register service for Power HAL Iface (%d), exiting.", status);
+ return 1;
+ }
+
+ ALOGI("Power Service is ready");
+ joinRpcThreadpool();
+
+ // In normal operation, we don't expect the thread pool to exit
+ ALOGE("Power Service is shutting down");
+ return 1;
+}
diff --git a/power-libperfmgr/libperfmgr/Android.bp b/power-libperfmgr/libperfmgr/Android.bp
index 2de7e75..c84e731 100644
--- a/power-libperfmgr/libperfmgr/Android.bp
+++ b/power-libperfmgr/libperfmgr/Android.bp
@@ -14,10 +14,6 @@
// limitations under the License.
//
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_defaults {
name: "libperfmgr_defaults",
local_include_dirs: ["include"],
diff --git a/power-libperfmgr/libperfmgr/FileNode.cc b/power-libperfmgr/libperfmgr/FileNode.cc
index e095aa8..070df54 100644
--- a/power-libperfmgr/libperfmgr/FileNode.cc
+++ b/power-libperfmgr/libperfmgr/FileNode.cc
@@ -55,12 +55,10 @@
// Update node only if request index changes
if (value_index != current_val_index_ || reset_on_init_) {
+ ATRACE_BEGIN(GetName().c_str());
const std::string& req_value =
req_sorted_[value_index].GetRequestValue();
- if (ATRACE_ENABLED()) {
- const std::string tag = GetName() + ":" + req_value;
- ATRACE_BEGIN(tag.c_str());
- }
+
android::base::Timer t;
fd_.reset(TEMP_FAILURE_RETRY(
open(node_path_.c_str(), O_WRONLY | O_CLOEXEC | O_TRUNC)));
@@ -93,9 +91,7 @@
current_val_index_ = value_index;
reset_on_init_ = false;
}
- if (ATRACE_ENABLED()) {
- ATRACE_END();
- }
+ ATRACE_END();
}
return expire_time;
}
diff --git a/power-libperfmgr/libperfmgr/HintManager.cc b/power-libperfmgr/libperfmgr/HintManager.cc
index b25ce45..1b546ae 100644
--- a/power-libperfmgr/libperfmgr/HintManager.cc
+++ b/power-libperfmgr/libperfmgr/HintManager.cc
@@ -20,11 +20,9 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
#include <json/reader.h>
#include <json/value.h>
-#include <inttypes.h>
#include <algorithm>
#include <set>
@@ -34,12 +32,6 @@
namespace android {
namespace perfmgr {
-namespace {
-constexpr std::chrono::milliseconds kMilliSecondZero = std::chrono::milliseconds(0);
-constexpr std::chrono::steady_clock::time_point kTimePointMax =
- std::chrono::steady_clock::time_point::max();
-} // namespace
-
bool HintManager::ValidateHint(const std::string& hint_type) const {
if (nm_.get() == nullptr) {
LOG(ERROR) << "NodeLooperThread not present";
@@ -56,134 +48,32 @@
return true;
}
-bool HintManager::IsHintEnabled(const std::string &hint_type) const {
- return actions_.at(hint_type).enabled;
-}
-
-bool HintManager::InitHintStatus(const std::unique_ptr<HintManager> &hm) {
- if (hm.get() == nullptr) {
- return false;
- }
- for (auto &a : hm->actions_) {
- // timeout_ms equaling kMilliSecondZero means forever until cancelling.
- // As a result, if there's one NodeAction has timeout_ms of 0, we will store
- // 0 instead of max. Also node actions could be empty, set to 0 in that case.
- std::chrono::milliseconds timeout = kMilliSecondZero;
- if (a.second.node_actions.size()) {
- auto [min, max] =
- std::minmax_element(a.second.node_actions.begin(), a.second.node_actions.end(),
- [](const auto act1, const auto act2) {
- return act1.timeout_ms < act2.timeout_ms;
- });
- timeout = min->timeout_ms == kMilliSecondZero ? kMilliSecondZero : max->timeout_ms;
- }
- a.second.status.reset(new HintStatus(timeout));
- }
- return true;
-}
-
-void HintManager::DoHintStatus(const std::string &hint_type, std::chrono::milliseconds timeout_ms) {
- std::lock_guard<std::mutex> lock(actions_.at(hint_type).status->mutex);
- actions_.at(hint_type).status->stats.count.fetch_add(1);
- auto now = std::chrono::steady_clock::now();
- if (now > actions_.at(hint_type).status->end_time) {
- actions_.at(hint_type).status->stats.duration_ms.fetch_add(
- std::chrono::duration_cast<std::chrono::milliseconds>(
- actions_.at(hint_type).status->end_time -
- actions_.at(hint_type).status->start_time)
- .count());
- actions_.at(hint_type).status->start_time = now;
- }
- actions_.at(hint_type).status->end_time =
- (timeout_ms == kMilliSecondZero) ? kTimePointMax : now + timeout_ms;
-}
-
-void HintManager::EndHintStatus(const std::string &hint_type) {
- std::lock_guard<std::mutex> lock(actions_.at(hint_type).status->mutex);
- // Update HintStats if the hint ends earlier than expected end_time
- auto now = std::chrono::steady_clock::now();
- if (now < actions_.at(hint_type).status->end_time) {
- actions_.at(hint_type).status->stats.duration_ms.fetch_add(
- std::chrono::duration_cast<std::chrono::milliseconds>(
- now - actions_.at(hint_type).status->start_time)
- .count());
- actions_.at(hint_type).status->end_time = now;
- }
-}
-
-void HintManager::DoHintAction(const std::string &hint_type) {
- for (auto &action : actions_.at(hint_type).hint_actions) {
- switch (action.type) {
- case HintActionType::DoHint:
- // TODO: add parse logic to prevent circular hints.
- DoHint(action.value);
- break;
- case HintActionType::EndHint:
- EndHint(action.value);
- break;
- case HintActionType::MaskHint:
- if (actions_.find(action.value) == actions_.end()) {
- LOG(ERROR) << "Failed to find " << action.value << " action";
- } else {
- actions_.at(action.value).enabled = false;
- }
- break;
- default:
- // should not reach here
- LOG(ERROR) << "Invalid "
- << static_cast<std::underlying_type<HintActionType>::type>(action.type)
- << " type";
- }
- }
-}
-
-void HintManager::EndHintAction(const std::string &hint_type) {
- for (auto &action : actions_.at(hint_type).hint_actions) {
- if (action.type == HintActionType::MaskHint &&
- actions_.find(action.value) != actions_.end()) {
- actions_.at(action.value).enabled = true;
- }
- }
-}
-
bool HintManager::DoHint(const std::string& hint_type) {
LOG(VERBOSE) << "Do Powerhint: " << hint_type;
- if (!ValidateHint(hint_type) || !IsHintEnabled(hint_type) ||
- !nm_->Request(actions_.at(hint_type).node_actions, hint_type)) {
- return false;
- }
- DoHintStatus(hint_type, actions_.at(hint_type).status->max_timeout);
- DoHintAction(hint_type);
- return true;
+ return ValidateHint(hint_type)
+ ? nm_->Request(actions_.at(hint_type), hint_type)
+ : false;
}
bool HintManager::DoHint(const std::string& hint_type,
std::chrono::milliseconds timeout_ms_override) {
LOG(VERBOSE) << "Do Powerhint: " << hint_type << " for "
<< timeout_ms_override.count() << "ms";
- if (!ValidateHint(hint_type) || !IsHintEnabled(hint_type)) {
+ if (!ValidateHint(hint_type)) {
return false;
}
- std::vector<NodeAction> actions_override = actions_.at(hint_type).node_actions;
+ std::vector<NodeAction> actions_override = actions_.at(hint_type);
for (auto& action : actions_override) {
action.timeout_ms = timeout_ms_override;
}
- if (!nm_->Request(actions_override, hint_type)) {
- return false;
- }
- DoHintStatus(hint_type, timeout_ms_override);
- DoHintAction(hint_type);
- return true;
+ return nm_->Request(actions_override, hint_type);
}
bool HintManager::EndHint(const std::string& hint_type) {
LOG(VERBOSE) << "End Powerhint: " << hint_type;
- if (!ValidateHint(hint_type) || !nm_->Cancel(actions_.at(hint_type).node_actions, hint_type)) {
- return false;
- }
- EndHintStatus(hint_type);
- EndHintAction(hint_type);
- return true;
+ return ValidateHint(hint_type)
+ ? nm_->Cancel(actions_.at(hint_type), hint_type)
+ : false;
}
bool HintManager::IsRunning() const {
@@ -198,17 +88,6 @@
return hints;
}
-HintStats HintManager::GetHintStats(const std::string &hint_type) const {
- HintStats hint_stats;
- if (ValidateHint(hint_type)) {
- hint_stats.count =
- actions_.at(hint_type).status->stats.count.load(std::memory_order_relaxed);
- hint_stats.duration_ms =
- actions_.at(hint_type).status->stats.duration_ms.load(std::memory_order_relaxed);
- }
- return hint_stats;
-}
-
void HintManager::DumpToFd(int fd) {
std::string header(
"========== Begin perfmgr nodes ==========\n"
@@ -224,29 +103,6 @@
if (!android::base::WriteStringToFd(footer, fd)) {
LOG(ERROR) << "Failed to dump fd: " << fd;
}
- header = "========== Begin perfmgr stats ==========\n"
- "Hint Name\t"
- "Counts\t"
- "Duration\n";
- if (!android::base::WriteStringToFd(header, fd)) {
- LOG(ERROR) << "Failed to dump fd: " << fd;
- }
- std::string hint_stats_string;
- std::vector<std::string> keys(GetHints());
- std::sort(keys.begin(), keys.end());
- for (const auto &ordered_key : keys) {
- HintStats hint_stats(GetHintStats(ordered_key));
- hint_stats_string +=
- android::base::StringPrintf("%s\t%" PRIu32 "\t%" PRIu64 "\n", ordered_key.c_str(),
- hint_stats.count, hint_stats.duration_ms);
- }
- if (!android::base::WriteStringToFd(hint_stats_string, fd)) {
- LOG(ERROR) << "Failed to dump fd: " << fd;
- }
- footer = "========== End perfmgr stats ==========\n";
- if (!android::base::WriteStringToFd(footer, fd)) {
- LOG(ERROR) << "Failed to dump fd: " << fd;
- }
fsync(fd);
}
@@ -268,7 +124,8 @@
LOG(ERROR) << "Failed to parse Nodes section from " << config_path;
return nullptr;
}
- std::unordered_map<std::string, Hint> actions = HintManager::ParseActions(json_doc, nodes);
+ std::map<std::string, std::vector<NodeAction>> actions =
+ HintManager::ParseActions(json_doc, nodes);
if (actions.empty()) {
LOG(ERROR) << "Failed to parse Actions section from " << config_path;
@@ -279,11 +136,6 @@
std::unique_ptr<HintManager> hm =
std::make_unique<HintManager>(std::move(nm), actions);
- if (!HintManager::InitHintStatus(hm)) {
- LOG(ERROR) << "Failed to initialize hint status";
- return nullptr;
- }
-
LOG(INFO) << "Initialized HintManager from JSON config: " << config_path;
if (start) {
@@ -299,12 +151,10 @@
std::set<std::string> nodes_name_parsed;
std::set<std::string> nodes_path_parsed;
Json::Value root;
- Json::CharReaderBuilder builder;
- std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
- std::string errorMessage;
+ Json::Reader reader;
- if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) {
- LOG(ERROR) << "Failed to parse JSON config: " << errorMessage;
+ if (!reader.parse(json_doc, root)) {
+ LOG(ERROR) << "Failed to parse JSON config";
return nodes_parsed;
}
@@ -346,8 +196,8 @@
std::string node_type = nodes[i]["Type"].asString();
LOG(VERBOSE) << "Node[" << i << "]'s Type: " << node_type;
if (node_type.empty()) {
- LOG(VERBOSE) << "Failed to read "
- << "Node[" << i << "]'s Type, set to 'File' as default";
+ LOG(ERROR) << "Failed to read "
+ << "Node[" << i << "]'s Type, set to 'File' as default";
} else if (node_type == "File") {
is_file = true;
} else if (node_type == "Property") {
@@ -440,16 +290,15 @@
return nodes_parsed;
}
-std::unordered_map<std::string, Hint> HintManager::ParseActions(
- const std::string &json_doc, const std::vector<std::unique_ptr<Node>> &nodes) {
+std::map<std::string, std::vector<NodeAction>> HintManager::ParseActions(
+ const std::string& json_doc,
+ const std::vector<std::unique_ptr<Node>>& nodes) {
// function starts
- std::unordered_map<std::string, Hint> actions_parsed;
+ std::map<std::string, std::vector<NodeAction>> actions_parsed;
Json::Value root;
- Json::CharReaderBuilder builder;
- std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
- std::string errorMessage;
+ Json::Reader reader;
- if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) {
+ if (!reader.parse(json_doc, root)) {
LOG(ERROR) << "Failed to parse JSON config";
return actions_parsed;
}
@@ -472,61 +321,48 @@
return actions_parsed;
}
- HintActionType action_type = HintActionType::Node;
- std::string type_string = actions[i]["Type"].asString();
- LOG(VERBOSE) << "Action[" << i << "]'s Type: " << type_string;
- if (type_string.empty()) {
- LOG(VERBOSE) << "Failed to read "
- << "Action[" << i << "]'s Type, set to 'Node' as default";
- } else if (type_string == "DoHint") {
- action_type = HintActionType::DoHint;
- } else if (type_string == "EndHint") {
- action_type = HintActionType::EndHint;
- } else if (type_string == "MaskHint") {
- action_type = HintActionType::MaskHint;
- } else {
- LOG(ERROR) << "Invalid Action[" << i << "]'s Type: " << type_string;
+ std::string node_name = actions[i]["Node"].asString();
+ LOG(VERBOSE) << "Action[" << i << "]'s Node: " << node_name;
+ std::size_t node_index;
+
+ if (nodes_index.find(node_name) == nodes_index.end()) {
+ LOG(ERROR) << "Failed to find "
+ << "Action[" << i << "]'s Node from Nodes section: ["
+ << node_name << "]";
actions_parsed.clear();
return actions_parsed;
}
- if (action_type == HintActionType::Node) {
- std::string node_name = actions[i]["Node"].asString();
- LOG(VERBOSE) << "Action[" << i << "]'s Node: " << node_name;
- std::size_t node_index;
+ node_index = nodes_index[node_name];
- if (nodes_index.find(node_name) == nodes_index.end()) {
- LOG(ERROR) << "Failed to find "
- << "Action[" << i << "]'s Node from Nodes section: [" << node_name
- << "]";
- actions_parsed.clear();
- return actions_parsed;
- }
- node_index = nodes_index[node_name];
+ std::string value_name = actions[i]["Value"].asString();
+ LOG(VERBOSE) << "Action[" << i << "]'s Value: " << value_name;
+ std::size_t value_index = 0;
- std::string value_name = actions[i]["Value"].asString();
- LOG(VERBOSE) << "Action[" << i << "]'s Value: " << value_name;
- std::size_t value_index = 0;
+ if (!nodes[node_index]->GetValueIndex(value_name, &value_index)) {
+ LOG(ERROR) << "Failed to read Action[" << i << "]'s Value";
+ LOG(ERROR) << "Action[" << i << "]'s Value " << value_name
+ << " is not defined in Node[" << node_name << "]";
+ actions_parsed.clear();
+ return actions_parsed;
+ }
+ LOG(VERBOSE) << "Action[" << i << "]'s ValueIndex: " << value_index;
- if (!nodes[node_index]->GetValueIndex(value_name, &value_index)) {
- LOG(ERROR) << "Failed to read Action[" << i << "]'s Value";
- LOG(ERROR) << "Action[" << i << "]'s Value " << value_name
- << " is not defined in Node[" << node_name << "]";
- actions_parsed.clear();
- return actions_parsed;
- }
- LOG(VERBOSE) << "Action[" << i << "]'s ValueIndex: " << value_index;
+ Json::UInt64 duration = 0;
+ if (actions[i]["Duration"].empty() ||
+ !actions[i]["Duration"].isUInt64()) {
+ LOG(ERROR) << "Failed to read Action[" << i << "]'s Duration";
+ actions_parsed.clear();
+ return actions_parsed;
+ } else {
+ duration = actions[i]["Duration"].asUInt64();
+ }
+ LOG(VERBOSE) << "Action[" << i << "]'s Duration: " << duration;
- Json::UInt64 duration = 0;
- if (actions[i]["Duration"].empty() || !actions[i]["Duration"].isUInt64()) {
- LOG(ERROR) << "Failed to read Action[" << i << "]'s Duration";
- actions_parsed.clear();
- return actions_parsed;
- } else {
- duration = actions[i]["Duration"].asUInt64();
- }
- LOG(VERBOSE) << "Action[" << i << "]'s Duration: " << duration;
-
- for (const auto &action : actions_parsed[hint_type].node_actions) {
+ if (actions_parsed.find(hint_type) == actions_parsed.end()) {
+ actions_parsed[hint_type] = std::vector<NodeAction>{
+ {node_index, value_index, std::chrono::milliseconds(duration)}};
+ } else {
+ for (const auto& action : actions_parsed[hint_type]) {
if (action.node_index == node_index) {
LOG(ERROR)
<< "Action[" << i
@@ -535,30 +371,18 @@
return actions_parsed;
}
}
- actions_parsed[hint_type].node_actions.emplace_back(
- node_index, value_index, std::chrono::milliseconds(duration));
-
- } else {
- const std::string &hint_value = actions[i]["Value"].asString();
- LOG(VERBOSE) << "Action[" << i << "]'s Value: " << hint_value;
- if (hint_value.empty()) {
- LOG(ERROR) << "Failed to read "
- << "Action[" << i << "]'s Value";
- actions_parsed.clear();
- return actions_parsed;
- }
- actions_parsed[hint_type].hint_actions.emplace_back(action_type, hint_value);
+ actions_parsed[hint_type].emplace_back(
+ node_index, value_index, std::chrono::milliseconds(duration));
}
++total_parsed;
}
- LOG(INFO) << total_parsed << " actions parsed successfully";
+ LOG(INFO) << total_parsed << " Actions parsed successfully";
for (const auto& action : actions_parsed) {
- LOG(INFO) << "PowerHint " << action.first << " has " << action.second.node_actions.size()
- << " node actions"
- << ", and " << action.second.hint_actions.size() << " hint actions parsed";
+ LOG(INFO) << "PowerHint " << action.first << " has "
+ << action.second.size() << " actions parsed";
}
return actions_parsed;
diff --git a/power-libperfmgr/libperfmgr/PropertyNode.cc b/power-libperfmgr/libperfmgr/PropertyNode.cc
index 486d670..a06b304 100644
--- a/power-libperfmgr/libperfmgr/PropertyNode.cc
+++ b/power-libperfmgr/libperfmgr/PropertyNode.cc
@@ -49,12 +49,10 @@
// Update node only if request index changes
if (value_index != current_val_index_ || reset_on_init_) {
+ ATRACE_BEGIN(GetName().c_str());
const std::string& req_value =
req_sorted_[value_index].GetRequestValue();
- if (ATRACE_ENABLED()) {
- const std::string tag = GetName() + ":" + req_value;
- ATRACE_BEGIN(tag.c_str());
- }
+
if (!android::base::SetProperty(node_path_, req_value)) {
LOG(WARNING) << "Failed to set property to : " << node_path_
<< " with value: " << req_value;
@@ -63,9 +61,7 @@
current_val_index_ = value_index;
reset_on_init_ = false;
}
- if (ATRACE_ENABLED()) {
- ATRACE_END();
- }
+ ATRACE_END();
}
return expire_time;
}
diff --git a/power-libperfmgr/libperfmgr/include/perfmgr/HintManager.h b/power-libperfmgr/libperfmgr/include/perfmgr/HintManager.h
index 747e5c4..bfb96fd 100644
--- a/power-libperfmgr/libperfmgr/include/perfmgr/HintManager.h
+++ b/power-libperfmgr/libperfmgr/include/perfmgr/HintManager.h
@@ -17,13 +17,10 @@
#ifndef ANDROID_LIBPERFMGR_HINTMANAGER_H_
#define ANDROID_LIBPERFMGR_HINTMANAGER_H_
-#include <atomic>
#include <cstddef>
-#include <cstdint>
+#include <map>
#include <memory>
-#include <mutex>
#include <string>
-#include <unordered_map>
#include <utility>
#include <vector>
@@ -32,55 +29,15 @@
namespace android {
namespace perfmgr {
-struct HintStats {
- HintStats() : count(0), duration_ms(0) {}
- uint32_t count;
- uint64_t duration_ms;
-};
-
-struct HintStatus {
- const std::chrono::milliseconds max_timeout;
- HintStatus() : max_timeout(std::chrono::milliseconds(0)) {}
- HintStatus(std::chrono::milliseconds max_timeout)
- : max_timeout(max_timeout),
- start_time(std::chrono::steady_clock::time_point::min()),
- end_time(std::chrono::steady_clock::time_point::min()) {}
- std::chrono::steady_clock::time_point start_time;
- std::chrono::steady_clock::time_point end_time;
- std::mutex mutex;
- struct HintStatsInternal {
- HintStatsInternal() : count(0), duration_ms(0) {}
- std::atomic<uint32_t> count;
- std::atomic<uint64_t> duration_ms;
- } stats;
-};
-
-enum class HintActionType { Node, DoHint, EndHint, MaskHint };
-
-struct HintAction {
- HintAction(HintActionType t, std::string v) : type(t), value(v) {}
- HintActionType type;
- std::string value;
-};
-
-struct Hint {
- Hint() : enabled(true) {}
- std::vector<NodeAction> node_actions;
- std::vector<HintAction> hint_actions;
- // No locking for `enabled' flag
- // There should not be multiple writers
- bool enabled;
- std::shared_ptr<HintStatus> status;
-};
-
// HintManager is the external interface of the library to be used by PowerHAL
// to do power hints with sysfs nodes. HintManager maintains a representation of
// the actions that are parsed from the configuration file as a mapping from a
// PowerHint to the set of actions that are performed for that PowerHint.
class HintManager {
public:
- HintManager(sp<NodeLooperThread> nm, const std::unordered_map<std::string, Hint> &actions)
- : nm_(std::move(nm)), actions_(std::move(actions)) {}
+ HintManager(sp<NodeLooperThread> nm,
+ const std::map<std::string, std::vector<NodeAction>>& actions)
+ : nm_(std::move(nm)), actions_(actions) {}
~HintManager() {
if (nm_.get() != nullptr) nm_->Stop();
}
@@ -106,9 +63,6 @@
// Query if given hint supported.
bool IsHintSupported(const std::string& hint_type) const;
- // Query if given hint enabled.
- bool IsHintEnabled(const std::string &hint_type) const;
-
// Static method to construct HintManager from the JSON config file.
static std::unique_ptr<HintManager> GetFromJSON(
const std::string& config_path, bool start = true);
@@ -116,9 +70,6 @@
// Return available hints managed by HintManager
std::vector<std::string> GetHints() const;
- // Return stats of hints managed by HintManager
- HintStats GetHintStats(const std::string &hint_type) const;
-
// Dump internal status to fd
void DumpToFd(int fd);
@@ -128,24 +79,17 @@
protected:
static std::vector<std::unique_ptr<Node>> ParseNodes(
const std::string& json_doc);
- static std::unordered_map<std::string, Hint> ParseActions(
- const std::string &json_doc, const std::vector<std::unique_ptr<Node>> &nodes);
- static bool InitHintStatus(const std::unique_ptr<HintManager> &hm);
+ static std::map<std::string, std::vector<NodeAction>> ParseActions(
+ const std::string& json_doc,
+ const std::vector<std::unique_ptr<Node>>& nodes);
private:
HintManager(HintManager const&) = delete;
void operator=(HintManager const&) = delete;
bool ValidateHint(const std::string& hint_type) const;
- // Helper function to update the HintStatus when DoHint
- void DoHintStatus(const std::string &hint_type, std::chrono::milliseconds timeout_ms);
- // Helper function to update the HintStatus when EndHint
- void EndHintStatus(const std::string &hint_type);
- // Helper function to take hint actions when DoHint
- void DoHintAction(const std::string &hint_type);
- // Helper function to take hint actions when EndHint
- void EndHintAction(const std::string &hint_type);
+
sp<NodeLooperThread> nm_;
- std::unordered_map<std::string, Hint> actions_;
+ const std::map<std::string, std::vector<NodeAction>> actions_;
};
} // namespace perfmgr
diff --git a/power-libperfmgr/libperfmgr/tests/FileNodeTest.cc b/power-libperfmgr/libperfmgr/tests/FileNodeTest.cc
index 60cb36c..d163be8 100644
--- a/power-libperfmgr/libperfmgr/tests/FileNodeTest.cc
+++ b/power-libperfmgr/libperfmgr/tests/FileNodeTest.cc
@@ -26,7 +26,7 @@
namespace android {
namespace perfmgr {
-using std::literals::chrono_literals::operator""ms;
+using namespace std::chrono_literals;
constexpr double kTIMING_TOLERANCE_MS = std::chrono::milliseconds(25).count();
constexpr auto kSLEEP_TOLERANCE_MS = 2ms;
diff --git a/power-libperfmgr/libperfmgr/tests/HintManagerTest.cc b/power-libperfmgr/libperfmgr/tests/HintManagerTest.cc
index 3dc9ab3..a4d3188 100644
--- a/power-libperfmgr/libperfmgr/tests/HintManagerTest.cc
+++ b/power-libperfmgr/libperfmgr/tests/HintManagerTest.cc
@@ -30,98 +30,101 @@
namespace android {
namespace perfmgr {
-using std::literals::chrono_literals::operator""ms;
+using namespace std::chrono_literals;
constexpr auto kSLEEP_TOLERANCE_MS = 50ms;
-constexpr char kJSON_RAW[] = R"(
-{
- "Nodes": [
- {
- "Name": "CPUCluster0MinFreq",
- "Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq",
- "Values": [
- "1512000",
- "1134000",
- "384000"
- ],
- "DefaultIndex": 2,
- "ResetOnInit": true
- },
- {
- "Name": "CPUCluster1MinFreq",
- "Path": "/sys/devices/system/cpu/cpu4/cpufreq/scaling_min_freq",
- "Values": [
- "1512000",
- "1134000",
- "384000"
- ],
- "HoldFd": true
- },
- {
- "Name": "ModeProperty",
- "Path": "vendor.pwhal.mode",
- "Values": [
- "HIGH",
- "LOW",
- "NONE"
- ],
- "Type": "Property"
- }
- ],
- "Actions": [
- {
- "PowerHint": "INTERACTION",
- "Node": "CPUCluster1MinFreq",
- "Value": "1134000",
- "Duration": 800
- },
- {
- "PowerHint": "INTERACTION",
- "Node": "ModeProperty",
- "Value": "LOW",
- "Duration": 800
- },
- {
- "PowerHint": "LAUNCH",
- "Node": "CPUCluster0MinFreq",
- "Value": "1134000",
- "Duration": 500
- },
- {
- "PowerHint": "LAUNCH",
- "Node": "ModeProperty",
- "Value": "HIGH",
- "Duration": 500
- },
- {
- "PowerHint": "LAUNCH",
- "Node": "CPUCluster1MinFreq",
- "Value": "1512000",
- "Duration": 2000
- },
- {
- "PowerHint": "MASK_LAUNCH_MODE",
- "Type": "MaskHint",
- "Value": "LAUNCH"
- },
- {
- "PowerHint": "END_LAUNCH_MODE",
- "Type": "EndHint",
- "Value": "LAUNCH"
- },
- {
- "PowerHint": "DO_LAUNCH_MODE",
- "Type": "DoHint",
- "Value": "LAUNCH"
- }
- ]
-}
-)";
+// JSON_CONFIG
+// {
+// "Nodes": [
+// {
+// "Name": "CPUCluster0MinFreq",
+// "Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq",
+// "Values": [
+// "1512000",
+// "1134000",
+// "384000"
+// ],
+// "DefaultIndex": 2,
+// "ResetOnInit": true
+// },
+// {
+// "Name": "CPUCluster1MinFreq",
+// "Path": "/sys/devices/system/cpu/cpu4/cpufreq/scaling_min_freq",
+// "Values": [
+// "1512000",
+// "1134000",
+// "384000"
+// ],
+// "HoldFd": true
+// },
+// {
+// "Name": "ModeProperty",
+// "Path": "vendor.pwhal.mode",
+// "Values": [
+// "HIGH",
+// "LOW",
+// "NONE"
+// ],
+// "Type": "Property"
+// }
+// ],
+// "Actions": [
+// {
+// "PowerHint": "INTERACTION",
+// "Node": "CPUCluster1MinFreq",
+// "Value": "1134000",
+// "Duration": 800
+// },
+// {
+// "PowerHint": "INTERACTION",
+// "Node": "ModeProperty",
+// "Value": "LOW",
+// "Duration": 800
+// },
+// {
+// "PowerHint": "LAUNCH",
+// "Node": "CPUCluster0MinFreq",
+// "Value": "1134000",
+// "Duration": 500
+// },
+// {
+// "PowerHint": "LAUNCH",
+// "Node": "ModeProperty",
+// "Value": "HIGH",
+// "Duration": 500
+// },
+// {
+// "PowerHint": "LAUNCH",
+// "Node": "CPUCluster1MinFreq",
+// "Value": "1512000",
+// "Duration": 2000
+// }
+// ]
+// }
+constexpr char kJSON_RAW[] =
+ "{\"Nodes\":[{\"Name\":\"CPUCluster0MinFreq\",\"Path\":\"/sys/devices/"
+ "system/cpu/cpu0/cpufreq/"
+ "scaling_min_freq\",\"Values\":[\"1512000\",\"1134000\",\"384000\"],"
+ "\"DefaultIndex\":2,\"ResetOnInit\":true},{\"Name\":\"CPUCluster1MinFreq\","
+ "\"Path\":\"/sys/devices/system/cpu/cpu4/cpufreq/"
+ "scaling_min_freq\",\"Values\":[\"1512000\",\"1134000\",\"384000\"],"
+ "\"HoldFd\":true},{\"Name\":\"ModeProperty\",\"Path\":\"vendor.pwhal."
+ "mode\",\"Values\":[\"HIGH\",\"LOW\",\"NONE\"],\"Type\":\"Property\"}],"
+ "\"Actions\":[{\"PowerHint\":\"INTERACTION\",\"Node\":"
+ "\"CPUCluster1MinFreq\",\"Value\":\"1134000\",\"Duration\":800},{"
+ "\"PowerHint\":\"INTERACTION\",\"Node\":\"ModeProperty\",\"Value\":\"LOW\","
+ "\"Duration\":800},{\"PowerHint\":\"LAUNCH\",\"Node\":"
+ "\"CPUCluster0MinFreq\",\"Value\":\"1134000\",\"Duration\":500},{"
+ "\"PowerHint\":\"LAUNCH\",\"Node\":\"ModeProperty\",\"Value\":\"HIGH\","
+ "\"Duration\":500},{\"PowerHint\":\"LAUNCH\",\"Node\":"
+ "\"CPUCluster1MinFreq\",\"Value\":\"1512000\",\"Duration\":2000}]}";
class HintManagerTest : public ::testing::Test, public HintManager {
protected:
- HintManagerTest() : HintManager(nullptr, std::unordered_map<std::string, Hint>{}) {
+ HintManagerTest()
+ : HintManager(nullptr,
+ std::map<std::string, std::vector<NodeAction>>{}) {
android::base::SetMinimumLogSeverity(android::base::VERBOSE);
prop_ = "vendor.pwhal.mode";
}
@@ -151,10 +154,9 @@
// Node0, value0, forever
// Node1, value0, 400ms
// Node2, value0, 400ms
- actions_["INTERACTION"].node_actions =
- std::vector<NodeAction>{{0, 1, 800ms}, {1, 1, 0ms}, {2, 1, 800ms}};
- actions_["LAUNCH"].node_actions =
- std::vector<NodeAction>{{0, 0, 0ms}, {1, 0, 400ms}, {2, 0, 400ms}};
+ actions_ = std::map<std::string, std::vector<NodeAction>>{
+ {"INTERACTION", {{0, 1, 800ms}, {1, 1, 0ms}, {2, 1, 800ms}}},
+ {"LAUNCH", {{0, 0, 0ms}, {1, 0, 400ms}, {2, 0, 400ms}}}};
// Prepare dummy files to replace the nodes' path in example json_doc
files_.emplace_back(std::make_unique<TemporaryFile>());
@@ -179,7 +181,7 @@
nm_ = nullptr;
}
sp<NodeLooperThread> nm_;
- std::unordered_map<std::string, Hint> actions_;
+ std::map<std::string, std::vector<NodeAction>> actions_;
std::vector<std::unique_ptr<Node>> nodes_;
std::vector<std::unique_ptr<TemporaryFile>> files_;
std::string json_doc_;
@@ -199,13 +201,6 @@
EXPECT_EQ(value, s);
}
-static inline void _VerifyStats(const HintStats &stats, uint32_t count, uint64_t duration_min,
- uint64_t duration_max) {
- EXPECT_EQ(stats.count, count);
- EXPECT_GE(stats.duration_ms, duration_min);
- EXPECT_LT(stats.duration_ms, duration_max);
-}
-
// Test GetHints
TEST_F(HintManagerTest, GetHintsTest) {
HintManager hm(nm_, actions_);
@@ -217,19 +212,6 @@
EXPECT_NE(std::find(hints.begin(), hints.end(), "LAUNCH"), hints.end());
}
-// Test GetHintStats
-TEST_F(HintManagerTest, GetHintStatsTest) {
- auto hm = std::make_unique<HintManager>(nm_, actions_);
- EXPECT_TRUE(InitHintStatus(hm));
- EXPECT_TRUE(hm->Start());
- HintStats launch_stats(hm->GetHintStats("LAUNCH"));
- EXPECT_EQ(0, launch_stats.count);
- EXPECT_EQ(0, launch_stats.duration_ms);
- HintStats interaction_stats(hm->GetHintStats("INTERACTION"));
- EXPECT_EQ(0, interaction_stats.count);
- EXPECT_EQ(0, interaction_stats.duration_ms);
-}
-
// Test initialization of default values
TEST_F(HintManagerTest, HintInitDefaultTest) {
HintManager hm(nm_, actions_);
@@ -251,25 +233,22 @@
// Test DumpToFd
TEST_F(HintManagerTest, DumpToFdTest) {
- auto hm = std::make_unique<HintManager>(nm_, actions_);
- EXPECT_TRUE(InitHintStatus(hm));
+ HintManager hm(nm_, actions_);
TemporaryFile dumptf;
- hm->DumpToFd(dumptf.fd);
+ hm.DumpToFd(dumptf.fd);
fsync(dumptf.fd);
std::ostringstream dump_buf;
dump_buf << "========== Begin perfmgr nodes ==========\nNode Name\tNode "
"Path\tCurrent Index\tCurrent Value\nn0\t"
<< files_[0]->path << "\t2\t\nn1\t" << files_[1]->path
<< "\t2\t\nn2\tvendor.pwhal.mode\t2\t\n========== End perfmgr "
- "nodes ==========\n========== Begin perfmgr stats ==========\n"
- "Hint Name\tCounts\tDuration\nINTERACTION\t0\t0\nLAUNCH\t0\t0\n"
- "========== End perfmgr stats ==========\n";
+ "nodes ==========\n";
_VerifyPathValue(dumptf.path, dump_buf.str());
TemporaryFile dumptf_started;
- EXPECT_TRUE(hm->Start());
+ EXPECT_TRUE(hm.Start());
std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
- EXPECT_TRUE(hm->IsRunning());
- hm->DumpToFd(dumptf_started.fd);
+ EXPECT_TRUE(hm.IsRunning());
+ hm.DumpToFd(dumptf_started.fd);
fsync(dumptf_started.fd);
dump_buf.str("");
dump_buf.clear();
@@ -277,32 +256,29 @@
"Path\tCurrent Index\tCurrent Value\nn0\t"
<< files_[0]->path << "\t2\t\nn1\t" << files_[1]->path
<< "\t2\tn1_value2\nn2\tvendor.pwhal.mode\t2\tn2_value2\n========="
- "= End perfmgr nodes ==========\n========== Begin perfmgr "
- "stats ==========\nHint Name\tCounts\tDuration\nINTERACTION\t0\t"
- "0\nLAUNCH\t0\t0\n========== End perfmgr stats ==========\n";
+ "= End perfmgr nodes ==========\n";
_VerifyPathValue(dumptf_started.path, dump_buf.str());
}
// Test hint/cancel/expire with dummy actions
TEST_F(HintManagerTest, HintTest) {
- auto hm = std::make_unique<HintManager>(nm_, actions_);
- EXPECT_TRUE(InitHintStatus(hm));
- EXPECT_TRUE(hm->Start());
- EXPECT_TRUE(hm->IsRunning());
- EXPECT_TRUE(hm->DoHint("INTERACTION"));
+ HintManager hm(nm_, actions_);
+ EXPECT_TRUE(hm.Start());
+ EXPECT_TRUE(hm.IsRunning());
+ EXPECT_TRUE(hm.DoHint("INTERACTION"));
std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
_VerifyPathValue(files_[0]->path, "n0_value1");
_VerifyPathValue(files_[1]->path, "n1_value1");
_VerifyPropertyValue(prop_, "n2_value1");
// this won't change the expire time of INTERACTION hint
- EXPECT_TRUE(hm->DoHint("INTERACTION", 200ms));
+ EXPECT_TRUE(hm.DoHint("INTERACTION", 200ms));
// now place new hint
- EXPECT_TRUE(hm->DoHint("LAUNCH"));
+ EXPECT_TRUE(hm.DoHint("LAUNCH"));
std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
_VerifyPathValue(files_[0]->path, "n0_value0");
_VerifyPathValue(files_[1]->path, "n1_value0");
_VerifyPropertyValue(prop_, "n2_value0");
- EXPECT_TRUE(hm->DoHint("LAUNCH", 500ms));
+ EXPECT_TRUE(hm.DoHint("LAUNCH", 500ms));
// "LAUNCH" node1 not expired
std::this_thread::sleep_for(400ms);
_VerifyPathValue(files_[0]->path, "n0_value0");
@@ -313,7 +289,7 @@
_VerifyPathValue(files_[0]->path, "n0_value0");
_VerifyPathValue(files_[1]->path, "n1_value1");
_VerifyPropertyValue(prop_, "n2_value1");
- EXPECT_TRUE(hm->EndHint("LAUNCH"));
+ EXPECT_TRUE(hm.EndHint("LAUNCH"));
std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
// "LAUNCH" canceled
_VerifyPathValue(files_[0]->path, "n0_value1");
@@ -324,7 +300,7 @@
_VerifyPathValue(files_[0]->path, "n0_value2");
_VerifyPathValue(files_[1]->path, "n1_value1");
_VerifyPropertyValue(prop_, "n2_value2");
- EXPECT_TRUE(hm->EndHint("INTERACTION"));
+ EXPECT_TRUE(hm.EndHint("INTERACTION"));
std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
// "INTERACTION" canceled
_VerifyPathValue(files_[0]->path, "n0_value2");
@@ -332,48 +308,6 @@
_VerifyPropertyValue(prop_, "n2_value2");
}
-// Test collecting stats with simple actions
-TEST_F(HintManagerTest, HintStatsTest) {
- auto hm = std::make_unique<HintManager>(nm_, actions_);
- EXPECT_TRUE(InitHintStatus(hm));
- EXPECT_TRUE(hm->Start());
- EXPECT_TRUE(hm->IsRunning());
- EXPECT_TRUE(hm->DoHint("INTERACTION"));
- std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
- _VerifyPathValue(files_[0]->path, "n0_value1");
- _VerifyPathValue(files_[1]->path, "n1_value1");
- _VerifyPropertyValue(prop_, "n2_value1");
- // now place "LAUNCH" hint with timeout of 500ms
- EXPECT_TRUE(hm->DoHint("LAUNCH", 500ms));
- std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
- _VerifyPathValue(files_[0]->path, "n0_value0");
- _VerifyPathValue(files_[1]->path, "n1_value0");
- _VerifyPropertyValue(prop_, "n2_value0");
- // "LAUNCH" expired
- std::this_thread::sleep_for(500ms + kSLEEP_TOLERANCE_MS);
- _VerifyPathValue(files_[0]->path, "n0_value1");
- _VerifyPathValue(files_[1]->path, "n1_value1");
- _VerifyPropertyValue(prop_, "n2_value1");
- HintStats launch_stats(hm->GetHintStats("LAUNCH"));
- // Since duration is recorded at the next DoHint,
- // duration should be 0.
- _VerifyStats(launch_stats, 1, 0, 100);
- std::this_thread::sleep_for(100ms + kSLEEP_TOLERANCE_MS);
- EXPECT_TRUE(hm->EndHint("INTERACTION"));
- std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
- // "INTERACTION" canceled
- _VerifyPathValue(files_[0]->path, "n0_value2");
- _VerifyPathValue(files_[1]->path, "n1_value2");
- _VerifyPropertyValue(prop_, "n2_value2");
- HintStats interaction_stats(hm->GetHintStats("INTERACTION"));
- _VerifyStats(interaction_stats, 1, 800, 900);
- std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
- // Second LAUNCH hint sent to get the first duration recorded.
- EXPECT_TRUE(hm->DoHint("LAUNCH"));
- launch_stats = hm->GetHintStats("LAUNCH");
- _VerifyStats(launch_stats, 2, 500, 600);
-}
-
// Test parsing nodes
TEST_F(HintManagerTest, ParseNodesTest) {
std::vector<std::unique_ptr<Node>> nodes =
@@ -513,70 +447,63 @@
TEST_F(HintManagerTest, ParseActionsTest) {
std::vector<std::unique_ptr<Node>> nodes =
HintManager::ParseNodes(json_doc_);
- std::unordered_map<std::string, Hint> actions = HintManager::ParseActions(json_doc_, nodes);
- EXPECT_EQ(5u, actions.size());
+ std::map<std::string, std::vector<NodeAction>> actions =
+ HintManager::ParseActions(json_doc_, nodes);
+ EXPECT_EQ(2u, actions.size());
- EXPECT_EQ(2u, actions["INTERACTION"].node_actions.size());
- EXPECT_EQ(1u, actions["INTERACTION"].node_actions[0].node_index);
- EXPECT_EQ(1u, actions["INTERACTION"].node_actions[0].value_index);
+ EXPECT_EQ(2u, actions["INTERACTION"].size());
+ EXPECT_EQ(1u, actions["INTERACTION"][0].node_index);
+ EXPECT_EQ(1u, actions["INTERACTION"][0].value_index);
EXPECT_EQ(std::chrono::milliseconds(800).count(),
- actions["INTERACTION"].node_actions[0].timeout_ms.count());
+ actions["INTERACTION"][0].timeout_ms.count());
- EXPECT_EQ(2u, actions["INTERACTION"].node_actions[1].node_index);
- EXPECT_EQ(1u, actions["INTERACTION"].node_actions[1].value_index);
+ EXPECT_EQ(2u, actions["INTERACTION"][1].node_index);
+ EXPECT_EQ(1u, actions["INTERACTION"][1].value_index);
EXPECT_EQ(std::chrono::milliseconds(800).count(),
- actions["INTERACTION"].node_actions[1].timeout_ms.count());
+ actions["INTERACTION"][1].timeout_ms.count());
- EXPECT_EQ(3u, actions["LAUNCH"].node_actions.size());
+ EXPECT_EQ(3u, actions["LAUNCH"].size());
- EXPECT_EQ(0u, actions["LAUNCH"].node_actions[0].node_index);
- EXPECT_EQ(1u, actions["LAUNCH"].node_actions[0].value_index);
+ EXPECT_EQ(0u, actions["LAUNCH"][0].node_index);
+ EXPECT_EQ(1u, actions["LAUNCH"][0].value_index);
EXPECT_EQ(std::chrono::milliseconds(500).count(),
- actions["LAUNCH"].node_actions[0].timeout_ms.count());
+ actions["LAUNCH"][0].timeout_ms.count());
- EXPECT_EQ(2u, actions["LAUNCH"].node_actions[1].node_index);
- EXPECT_EQ(0u, actions["LAUNCH"].node_actions[1].value_index);
+ EXPECT_EQ(2u, actions["LAUNCH"][1].node_index);
+ EXPECT_EQ(0u, actions["LAUNCH"][1].value_index);
EXPECT_EQ(std::chrono::milliseconds(500).count(),
- actions["LAUNCH"].node_actions[1].timeout_ms.count());
+ actions["LAUNCH"][1].timeout_ms.count());
- EXPECT_EQ(1u, actions["LAUNCH"].node_actions[2].node_index);
- EXPECT_EQ(0u, actions["LAUNCH"].node_actions[2].value_index);
+ EXPECT_EQ(1u, actions["LAUNCH"][2].node_index);
+ EXPECT_EQ(0u, actions["LAUNCH"][2].value_index);
EXPECT_EQ(std::chrono::milliseconds(2000).count(),
- actions["LAUNCH"].node_actions[2].timeout_ms.count());
-
- EXPECT_EQ(1u, actions["MASK_LAUNCH_MODE"].hint_actions.size());
- EXPECT_EQ(HintActionType::MaskHint, actions["MASK_LAUNCH_MODE"].hint_actions[0].type);
- EXPECT_TRUE("LAUNCH" == actions["MASK_LAUNCH_MODE"].hint_actions[0].value);
-
- EXPECT_EQ(1u, actions["DO_LAUNCH_MODE"].hint_actions.size());
- EXPECT_EQ(HintActionType::DoHint, actions["DO_LAUNCH_MODE"].hint_actions[0].type);
- EXPECT_TRUE("LAUNCH" == actions["DO_LAUNCH_MODE"].hint_actions[0].value);
-
- EXPECT_EQ(1u, actions["END_LAUNCH_MODE"].hint_actions.size());
- EXPECT_EQ(HintActionType::EndHint, actions["END_LAUNCH_MODE"].hint_actions[0].type);
- EXPECT_TRUE("LAUNCH" == actions["END_LAUNCH_MODE"].hint_actions[0].value);
+ actions["LAUNCH"][2].timeout_ms.count());
}
// Test parsing actions with duplicate File node
TEST_F(HintManagerTest, ParseActionDuplicateFileNodeTest) {
- std::string from = R"("Node": "CPUCluster0MinFreq")";
+ std::string from = "\"Node\":\"CPUCluster0MinFreq\"";
size_t start_pos = json_doc_.find(from);
- json_doc_.replace(start_pos, from.length(), R"("Node": "CPUCluster1MinFreq")");
+ json_doc_.replace(start_pos, from.length(),
+ "\"Node\":\"CPUCluster1MinFreq\"");
std::vector<std::unique_ptr<Node>> nodes =
HintManager::ParseNodes(json_doc_);
EXPECT_EQ(3u, nodes.size());
- auto actions = HintManager::ParseActions(json_doc_, nodes);
+ std::map<std::string, std::vector<NodeAction>> actions =
+ HintManager::ParseActions(json_doc_, nodes);
EXPECT_EQ(0u, actions.size());
}
// Test parsing actions with duplicate Property node
TEST_F(HintManagerTest, ParseActionDuplicatePropertyNodeTest) {
- std::string from = R"("Node": "CPUCluster0MinFreq")";
+ std::string from = "\"Node\":\"CPUCluster0MinFreq\"";
size_t start_pos = json_doc_.find(from);
- json_doc_.replace(start_pos, from.length(), R"("Node": "ModeProperty")");
- auto nodes = HintManager::ParseNodes(json_doc_);
+ json_doc_.replace(start_pos, from.length(), "\"Node\":\"ModeProperty\"");
+ std::vector<std::unique_ptr<Node>> nodes =
+ HintManager::ParseNodes(json_doc_);
EXPECT_EQ(3u, nodes.size());
- auto actions = HintManager::ParseActions(json_doc_, nodes);
+ std::map<std::string, std::vector<NodeAction>> actions =
+ HintManager::ParseActions(json_doc_, nodes);
EXPECT_EQ(0u, actions.size());
}
@@ -584,7 +511,8 @@
TEST_F(HintManagerTest, ParseBadActionsTest) {
std::vector<std::unique_ptr<Node>> nodes =
HintManager::ParseNodes(json_doc_);
- auto actions = HintManager::ParseActions("invalid json", nodes);
+ std::map<std::string, std::vector<NodeAction>> actions =
+ HintManager::ParseActions("invalid json", nodes);
EXPECT_EQ(0u, actions.size());
actions = HintManager::ParseActions(
"{\"devices\":{\"15\":[\"armeabi-v7a\"],\"16\":[\"armeabi-v7a\"],"
@@ -641,36 +569,6 @@
_VerifyPathValue(files_[0 + 2]->path, "384000");
_VerifyPathValue(files_[1 + 2]->path, "384000");
_VerifyPropertyValue(prop_, "NONE");
-
- // Mask LAUNCH and do LAUNCH
- EXPECT_TRUE(hm->DoHint("MASK_LAUNCH_MODE"));
- EXPECT_FALSE(hm->DoHint("LAUNCH")); // should fail
- std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
- _VerifyPathValue(files_[0 + 2]->path, "384000");
- _VerifyPathValue(files_[1 + 2]->path, "384000");
- _VerifyPropertyValue(prop_, "NONE");
-
- // UnMask LAUNCH and do LAUNCH
- EXPECT_TRUE(hm->EndHint("MASK_LAUNCH_MODE"));
- EXPECT_TRUE(hm->DoHint("LAUNCH"));
- std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
- _VerifyPathValue(files_[0 + 2]->path, "1134000");
- _VerifyPathValue(files_[1 + 2]->path, "1512000");
- _VerifyPropertyValue(prop_, "HIGH");
- // END_LAUNCH_MODE should deactivate LAUNCH
- EXPECT_TRUE(hm->DoHint("END_LAUNCH_MODE"));
- std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
- _VerifyPathValue(files_[0 + 2]->path, "384000");
- _VerifyPathValue(files_[1 + 2]->path, "384000");
- _VerifyPropertyValue(prop_, "NONE");
- EXPECT_TRUE(hm->EndHint("END_LAUNCH_MODE"));
-
- // DO_LAUNCH_MODE should activate LAUNCH
- EXPECT_TRUE(hm->DoHint("DO_LAUNCH_MODE"));
- std::this_thread::sleep_for(kSLEEP_TOLERANCE_MS);
- _VerifyPathValue(files_[0 + 2]->path, "1134000");
- _VerifyPathValue(files_[1 + 2]->path, "1512000");
- _VerifyPropertyValue(prop_, "HIGH");
}
} // namespace perfmgr
diff --git a/power-libperfmgr/libperfmgr/tests/NodeLooperThreadTest.cc b/power-libperfmgr/libperfmgr/tests/NodeLooperThreadTest.cc
index 89533b4..9283d9f 100644
--- a/power-libperfmgr/libperfmgr/tests/NodeLooperThreadTest.cc
+++ b/power-libperfmgr/libperfmgr/tests/NodeLooperThreadTest.cc
@@ -26,7 +26,7 @@
namespace android {
namespace perfmgr {
-using std::literals::chrono_literals::operator""ms;
+using namespace std::chrono_literals;
constexpr auto kSLEEP_TOLERANCE_MS = 50ms;
diff --git a/power-libperfmgr/libperfmgr/tests/PropertyNodeTest.cc b/power-libperfmgr/libperfmgr/tests/PropertyNodeTest.cc
index 29951ab..73f41c5 100644
--- a/power-libperfmgr/libperfmgr/tests/PropertyNodeTest.cc
+++ b/power-libperfmgr/libperfmgr/tests/PropertyNodeTest.cc
@@ -27,7 +27,7 @@
namespace android {
namespace perfmgr {
-using std::literals::chrono_literals::operator""ms;
+using namespace std::chrono_literals;
constexpr double kTIMING_TOLERANCE_MS = std::chrono::milliseconds(25).count();
constexpr auto kSLEEP_TOLERANCE_MS = 2ms;
diff --git a/power-libperfmgr/libperfmgr/tests/RequestGroupTest.cc b/power-libperfmgr/libperfmgr/tests/RequestGroupTest.cc
index 8021a7e..f7a67a3 100644
--- a/power-libperfmgr/libperfmgr/tests/RequestGroupTest.cc
+++ b/power-libperfmgr/libperfmgr/tests/RequestGroupTest.cc
@@ -24,7 +24,7 @@
namespace android {
namespace perfmgr {
-using std::literals::chrono_literals::operator""ms;
+using namespace std::chrono_literals;
constexpr double kTIMING_TOLERANCE_MS = std::chrono::milliseconds(25).count();
diff --git a/power-libperfmgr/libperfmgr/tools/ConfigVerifier.cc b/power-libperfmgr/libperfmgr/tools/ConfigVerifier.cc
index 85c1473..ad95910 100644
--- a/power-libperfmgr/libperfmgr/tools/ConfigVerifier.cc
+++ b/power-libperfmgr/libperfmgr/tools/ConfigVerifier.cc
@@ -47,9 +47,9 @@
}
private:
- NodeVerifier() = delete;
- NodeVerifier(NodeVerifier const &) = delete;
- void operator=(NodeVerifier const &) = delete;
+ NodeVerifier(sp<NodeLooperThread> nm,
+ const std::map<std::string, std::vector<NodeAction>>& actions)
+ : HintManager(std::move(nm), actions) {}
};
} // namespace perfmgr
diff --git a/powerstats/Android.bp b/powerstats/Android.bp
index 707f73a..e5ce813 100644
--- a/powerstats/Android.bp
+++ b/powerstats/Android.bp
@@ -1,7 +1,3 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library_static {
name: "libpixelpowerstats",
vendor_available: true,
@@ -13,7 +9,6 @@
"GenericStateResidencyDataProvider.cpp",
"WlanStateResidencyDataProvider.cpp",
"AidlStateResidencyDataProvider.cpp",
- "DisplayStateResidencyDataProvider.cpp",
],
cflags: [
@@ -29,56 +24,3 @@
"libbinder",
],
}
-
-cc_library {
- name: "android.hardware.power.stats-impl.pixel",
- vendor_available: true,
- export_include_dirs: ["include"],
- defaults: ["powerstats_pixel_defaults"],
-
- srcs: [
- "dataproviders/*.cpp",
- "PowerStatsAidl.cpp",
- ],
-}
-
-cc_defaults {
- name: "powerstats_pixel_defaults",
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "libbase",
- "libbinder_ndk",
- "libcutils",
- "libhardware",
- "liblog",
- "libutils",
- "pixel_stateresidency_provider_aidl_interface-ndk_platform",
- "android.hardware.power.stats-V1-ndk_platform",
- ],
-}
-
-filegroup {
- name: "pixel_powerstats_rc",
- srcs: ["android.hardware.power.stats-service.pixel.rc"],
-}
-
-filegroup {
- name: "pixel_powerstats_xml",
- srcs: ["android.hardware.power.stats-service.pixel.xml"],
-}
-
-cc_defaults {
- name: "powerstats_pixel_binary_defaults",
- defaults: ["powerstats_pixel_defaults"],
- init_rc: [":pixel_powerstats_rc"],
- vintf_fragments: [":pixel_powerstats_xml"],
- relative_install_path: "hw",
- proprietary: true,
- shared_libs: [
- "android.hardware.power.stats-impl.pixel",
- ],
-}
diff --git a/powerstats/DisplayStateResidencyDataProvider.cpp b/powerstats/DisplayStateResidencyDataProvider.cpp
deleted file mode 100644
index 071e16d..0000000
--- a/powerstats/DisplayStateResidencyDataProvider.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-// TODO(b/167628903): Delete this file
-#define LOG_TAG "libpixelpowerstats"
-
-#include <android-base/chrono_utils.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-
-#include <pixelpowerstats/DisplayStateResidencyDataProvider.h>
-#include <pixelpowerstats/PowerStatsUtils.h>
-
-#include <chrono>
-#include <cstdio>
-#include <cstring>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-DisplayStateResidencyDataProvider::DisplayStateResidencyDataProvider(
- uint32_t id, std::string path, std::vector<std::string> states)
- : mPath(std::move(path)),
- mPowerEntityId(id),
- mStates(states),
- mCurState(-1),
- mLooper(new Looper(true)) {
- // Construct mResidencies
- mResidencies.reserve(mStates.size());
- for (uint32_t i = 0; i < mStates.size(); ++i) {
- PowerEntityStateResidencyData p = {.powerEntityStateId = i};
- mResidencies.emplace_back(p);
- }
-
- // Open display state file descriptor
- LOG(VERBOSE) << "Opening " << mPath;
- mFd = open(mPath.c_str(), O_RDONLY | O_NONBLOCK);
- if (mFd < 0) {
- PLOG(ERROR) << ":Failed to open file " << mPath;
- return;
- }
-
- // Add display state file descriptor to be polled by the looper
- mLooper->addFd(mFd, 0, Looper::EVENT_ERROR, nullptr, nullptr);
-
- // Run the thread that will poll for changes to display state
- LOG(VERBOSE) << "Starting DisplayStateWatcherThread";
- mThread = std::thread(&DisplayStateResidencyDataProvider::pollLoop, this);
-}
-
-DisplayStateResidencyDataProvider::~DisplayStateResidencyDataProvider() {
- if (mFd > 0) {
- close(mFd);
- }
-}
-
-bool DisplayStateResidencyDataProvider::getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
- std::scoped_lock lk(mLock);
-
- // Get current time since boot in milliseconds
- uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
- ::android::base::boot_clock::now().time_since_epoch())
- .count();
-
- // Construct residency result based on current residency data
- PowerEntityStateResidencyResult result = {.powerEntityId = mPowerEntityId,
- .stateResidencyData = mResidencies};
-
- if (mCurState > -1) {
- result.stateResidencyData[mCurState].totalTimeInStateMs +=
- now - result.stateResidencyData[mCurState].lastEntryTimestampMs;
- }
-
- results.emplace(mPowerEntityId, result);
- return true;
-}
-
-std::vector<PowerEntityStateSpace> DisplayStateResidencyDataProvider::getStateSpaces() {
- PowerEntityStateSpace s = {.powerEntityId = mPowerEntityId};
- s.states.resize(mStates.size());
- for (uint32_t i = 0; i < mStates.size(); ++i) {
- s.states[i] = {.powerEntityStateId = i, .powerEntityStateName = mStates[i]};
- }
-
- return {s};
-}
-
-// Called when there is new data to be read from
-// display state file descriptor indicating a state change
-void DisplayStateResidencyDataProvider::updateStats() {
- char data[32];
-
- // Get current time since boot in milliseconds
- uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
- ::android::base::boot_clock::now().time_since_epoch())
- .count();
- // Read display state
- ssize_t ret = pread(mFd, data, sizeof(data) - 1, 0);
- if (ret < 0) {
- PLOG(WARNING) << "Failed to read display state";
- return;
- }
- data[ret] = '\0';
-
- LOG(VERBOSE) << "display state: " << data;
-
- // Update residency stats based on state read
- { // acquire lock
- std::scoped_lock lk(mLock);
- for (uint32_t i = 0; i < mStates.size(); ++i) {
- if (strstr(data, mStates[i].c_str())) {
- // Update total time of the previous state
- if (mCurState > -1) {
- mResidencies[mCurState].totalTimeInStateMs +=
- now - mResidencies[mCurState].lastEntryTimestampMs;
- }
-
- // Set current state
- mCurState = i;
- mResidencies[i].totalStateEntryCount++;
- mResidencies[i].lastEntryTimestampMs = now;
- break;
- }
- }
- } // release lock
-}
-
-void DisplayStateResidencyDataProvider::pollLoop() {
- LOG(VERBOSE) << "DisplayStateResidencyDataProvider polling...";
- while (true) {
- // Poll for display state changes. Timeout set to poll indefinitely
- if (mLooper->pollOnce(-1) >= 0) {
- updateStats();
- }
- }
-}
-
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/powerstats/GenericStateResidencyDataProvider.cpp b/powerstats/GenericStateResidencyDataProvider.cpp
index 5723904..3c4bcca 100644
--- a/powerstats/GenericStateResidencyDataProvider.cpp
+++ b/powerstats/GenericStateResidencyDataProvider.cpp
@@ -13,14 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// TODO(b/167628903): Delete this file
+
#define LOG_TAG "libpixelpowerstats"
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <pixelpowerstats/GenericStateResidencyDataProvider.h>
#include <pixelpowerstats/PowerStatsUtils.h>
-
#include <cstdio>
#include <cstring>
#include <memory>
@@ -36,8 +35,8 @@
namespace powerstats {
std::vector<StateResidencyConfig> generateGenericStateResidencyConfigs(
- const StateResidencyConfig &stateConfig,
- const std::vector<std::pair<std::string, std::string>> &stateHeaders) {
+ const StateResidencyConfig &stateConfig,
+ const std::vector<std::pair<std::string, std::string>> &stateHeaders) {
std::vector<StateResidencyConfig> stateResidencyConfigs;
stateResidencyConfigs.reserve(stateHeaders.size());
for (auto h : stateHeaders) {
@@ -54,40 +53,35 @@
PowerEntityConfig::PowerEntityConfig(const std::string &header,
const std::vector<StateResidencyConfig> &stateResidencyConfigs)
- : PowerEntityConfig(0, header, stateResidencyConfigs) {}
-
-PowerEntityConfig::PowerEntityConfig(const uint32_t start_id, const std::string &header,
- const std::vector<StateResidencyConfig> &stateResidencyConfigs)
: mHeader(header) {
mStateResidencyConfigs.reserve(stateResidencyConfigs.size());
- for (uint32_t i = start_id; i < start_id + stateResidencyConfigs.size(); ++i) {
- mStateResidencyConfigs.emplace_back(i, stateResidencyConfigs[i - start_id]);
+ for (uint32_t i = 0; i < stateResidencyConfigs.size(); ++i) {
+ mStateResidencyConfigs.emplace_back(i, stateResidencyConfigs[i]);
}
}
-static bool parseState(PowerEntityStateResidencyData *data, const StateResidencyConfig &config,
- FILE *fp, char **line, size_t *len) {
+static bool parseState(PowerEntityStateResidencyData &data, const StateResidencyConfig &config,
+ FILE *fp, char *&line, size_t &len) {
size_t numFieldsRead = 0;
const size_t numFields =
- config.entryCountSupported + config.totalTimeSupported + config.lastEntrySupported;
+ config.entryCountSupported + config.totalTimeSupported + config.lastEntrySupported;
- while ((numFieldsRead < numFields) && (getline(line, len, fp) != -1)) {
+ while ((numFieldsRead < numFields) && (getline(&line, &len, fp) != -1)) {
uint64_t stat = 0;
// Attempt to extract data from the current line
- if (config.entryCountSupported &&
- utils::extractStat(*line, config.entryCountPrefix, stat)) {
- data->totalStateEntryCount =
- config.entryCountTransform ? config.entryCountTransform(stat) : stat;
+ if (config.entryCountSupported && utils::extractStat(line, config.entryCountPrefix, stat)) {
+ data.totalStateEntryCount =
+ config.entryCountTransform ? config.entryCountTransform(stat) : stat;
++numFieldsRead;
} else if (config.totalTimeSupported &&
- utils::extractStat(*line, config.totalTimePrefix, stat)) {
- data->totalTimeInStateMs =
- config.totalTimeTransform ? config.totalTimeTransform(stat) : stat;
+ utils::extractStat(line, config.totalTimePrefix, stat)) {
+ data.totalTimeInStateMs =
+ config.totalTimeTransform ? config.totalTimeTransform(stat) : stat;
++numFieldsRead;
} else if (config.lastEntrySupported &&
- utils::extractStat(*line, config.lastEntryPrefix, stat)) {
- data->lastEntryTimestampMs =
- config.lastEntryTransform ? config.lastEntryTransform(stat) : stat;
+ utils::extractStat(line, config.lastEntryPrefix, stat)) {
+ data.lastEntryTimestampMs =
+ config.lastEntryTransform ? config.lastEntryTransform(stat) : stat;
++numFieldsRead;
}
}
@@ -103,16 +97,16 @@
}
template <class T, class Func>
-static auto findNext(const std::vector<T> &collection, FILE *fp, char **line, size_t *len,
+static auto findNext(const std::vector<T> &collection, FILE *fp, char *&line, size_t &len,
Func pred) {
// handling the case when there is no header to look for
if (pred(collection.front(), "")) {
return collection.cbegin();
}
- while (getline(line, len, fp) != -1) {
+ while (getline(&line, &len, fp) != -1) {
for (auto it = collection.cbegin(); it != collection.cend(); ++it) {
- if (pred(*it, *line)) {
+ if (pred(*it, line)) {
return it;
}
}
@@ -122,9 +116,9 @@
}
static bool getStateData(
- PowerEntityStateResidencyResult *result,
- const std::vector<std::pair<uint32_t, StateResidencyConfig>> &stateResidencyConfigs,
- FILE *fp, char **line, size_t *len) {
+ PowerEntityStateResidencyResult &result,
+ const std::vector<std::pair<uint32_t, StateResidencyConfig>> &stateResidencyConfigs, FILE *fp,
+ char *&line, size_t &len) {
size_t numStatesRead = 0;
size_t numStates = stateResidencyConfigs.size();
auto nextState = stateResidencyConfigs.cbegin();
@@ -134,16 +128,16 @@
return (a.second.header == android::base::Trim(std::string(b)));
};
- result->stateResidencyData.resize(numStates);
+ result.stateResidencyData.resize(numStates);
// Search for state headers until we have found them all or can't find anymore
while ((numStatesRead < numStates) &&
(nextState = findNext<std::pair<uint32_t, StateResidencyConfig>>(
- stateResidencyConfigs, fp, line, len, pred)) != endState) {
+ stateResidencyConfigs, fp, line, len, pred)) != endState) {
// Found a matching state header. Parse the contents
PowerEntityStateResidencyData data = {.powerEntityStateId = nextState->first};
- if (parseState(&data, nextState->second, fp, line, len)) {
- result->stateResidencyData[numStatesRead] = data;
+ if (parseState(data, nextState->second, fp, line, len)) {
+ result.stateResidencyData[numStatesRead] = data;
++numStatesRead;
} else {
break;
@@ -159,7 +153,7 @@
}
bool GenericStateResidencyDataProvider::getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
+ std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
// Using FILE* instead of std::ifstream for performance reasons (b/122253123)
std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(mPath.c_str(), "r"), fclose);
if (!fp) {
@@ -178,44 +172,19 @@
// return true if b matches the header contained in a, ignoring whitespace
return (a.second.mHeader == android::base::Trim(std::string(b)));
};
- bool skipFindNext = false;
// Search for entity headers until we have found them all or can't find anymore
while ((numEntitiesRead < numEntities) &&
- (skipFindNext ||
- (nextConfig = findNext<decltype(mPowerEntityConfigs)::value_type>(
- mPowerEntityConfigs, fp.get(), &line, &len, pred)) != endConfig)) {
+ (nextConfig = findNext<decltype(mPowerEntityConfigs)::value_type>(
+ mPowerEntityConfigs, fp.get(), line, len, pred)) != endConfig) {
// Found a matching header. Retrieve its state data
PowerEntityStateResidencyResult result = {.powerEntityId = nextConfig->first};
- if (getStateData(&result, nextConfig->second.mStateResidencyConfigs, fp.get(), &line,
- &len)) {
- // If a power entity already exists, then merge in the
- // StateResidencyData.
- if (results.find(nextConfig->first) != results.end()) {
- uint32_t size = results[nextConfig->first].stateResidencyData.size();
- results[nextConfig->first].stateResidencyData.resize(
- size + result.stateResidencyData.size());
- for (uint32_t i = 0; i < result.stateResidencyData.size(); i++) {
- results[nextConfig->first].stateResidencyData[size + i] =
- result.stateResidencyData[i];
- }
- } else {
- results.emplace(nextConfig->first, result);
- }
+ if (getStateData(result, nextConfig->second.mStateResidencyConfigs, fp.get(), line, len)) {
+ results.emplace(nextConfig->first, result);
++numEntitiesRead;
} else {
break;
}
-
- // If the header of the next PowerEntityConfig is equal to the
- // current, don't search for it within the file since we'll be search
- // for more states.
- auto currConfig = nextConfig++;
- if (nextConfig != endConfig && nextConfig->second.mHeader == currConfig->second.mHeader) {
- skipFindNext = true;
- } else {
- skipFindNext = false;
- }
}
free(line);
@@ -242,8 +211,8 @@
for (uint32_t i = 0; i < config.second.mStateResidencyConfigs.size(); ++i) {
s.states[i] = {
- .powerEntityStateId = config.second.mStateResidencyConfigs[i].first,
- .powerEntityStateName = config.second.mStateResidencyConfigs[i].second.name};
+ .powerEntityStateId = config.second.mStateResidencyConfigs[i].first,
+ .powerEntityStateName = config.second.mStateResidencyConfigs[i].second.name};
}
stateSpaces.emplace_back(s);
}
diff --git a/powerstats/PowerStatsAidl.cpp b/powerstats/PowerStatsAidl.cpp
deleted file mode 100644
index 1e0d2b7..0000000
--- a/powerstats/PowerStatsAidl.cpp
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include "include/PowerStatsAidl.h"
-#include <aidl/android/hardware/power/stats/BnPowerStats.h>
-
-#include <android-base/chrono_utils.h>
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include <inttypes.h>
-#include <chrono>
-#include <numeric>
-#include <string>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-void PowerStats::addStateResidencyDataProvider(std::unique_ptr<IStateResidencyDataProvider> p) {
- if (!p) {
- return;
- }
-
- int32_t id = mPowerEntityInfos.size();
- auto info = p->getInfo();
-
- size_t index = mStateResidencyDataProviders.size();
- mStateResidencyDataProviders.emplace_back(std::move(p));
-
- for (const auto &[entityName, states] : info) {
- PowerEntity i = {
- .id = id++,
- .name = entityName,
- .states = states,
- };
- mPowerEntityInfos.emplace_back(i);
- mStateResidencyDataProviderIndex.emplace_back(index);
- }
-}
-
-ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector<PowerEntity> *_aidl_return) {
- *_aidl_return = mPowerEntityInfos;
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus PowerStats::getStateResidency(const std::vector<int32_t> &in_powerEntityIds,
- std::vector<StateResidencyResult> *_aidl_return) {
- if (mPowerEntityInfos.empty()) {
- return ndk::ScopedAStatus::ok();
- }
-
- // If in_powerEntityIds is empty then return data for all supported entities
- if (in_powerEntityIds.empty()) {
- std::vector<int32_t> v(mPowerEntityInfos.size());
- std::iota(std::begin(v), std::end(v), 0);
- return getStateResidency(v, _aidl_return);
- }
-
- std::unordered_map<std::string, std::vector<StateResidency>> stateResidencies;
-
- for (const int32_t id : in_powerEntityIds) {
- // check for invalid ids
- if (id < 0 || id >= mPowerEntityInfos.size()) {
- return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
- }
-
- // Check to see if we already have data for the given id
- std::string powerEntityName = mPowerEntityInfos[id].name;
- if (stateResidencies.find(powerEntityName) == stateResidencies.end()) {
- mStateResidencyDataProviders.at(mStateResidencyDataProviderIndex.at(id))
- ->getStateResidencies(&stateResidencies);
- }
-
- // Append results if we have them
- auto stateResidency = stateResidencies.find(powerEntityName);
- if (stateResidency != stateResidencies.end()) {
- StateResidencyResult res = {
- .id = id,
- .stateResidencyData = stateResidency->second,
- };
- _aidl_return->emplace_back(res);
- } else {
- // Failed to get results for the given id.
- LOG(ERROR) << "Failed to get results for " << powerEntityName;
- }
- }
-
- return ndk::ScopedAStatus::ok();
-}
-
-void PowerStats::addEnergyConsumer(std::unique_ptr<IEnergyConsumer> p) {
- if (!p) {
- return;
- }
-
- std::pair<EnergyConsumerType, std::string> info = p->getInfo();
-
- int32_t count = count_if(mEnergyConsumerInfos.begin(), mEnergyConsumerInfos.end(),
- [&info](const EnergyConsumer &c) { return info.first == c.type; });
- int32_t id = mEnergyConsumers.size();
- mEnergyConsumerInfos.emplace_back(
- EnergyConsumer{.id = id, .ordinal = count, .type = info.first, .name = info.second});
- mEnergyConsumers.emplace_back(std::move(p));
-}
-
-ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector<EnergyConsumer> *_aidl_return) {
- *_aidl_return = mEnergyConsumerInfos;
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus PowerStats::getEnergyConsumed(const std::vector<int32_t> &in_energyConsumerIds,
- std::vector<EnergyConsumerResult> *_aidl_return) {
- if (mEnergyConsumers.empty()) {
- return ndk::ScopedAStatus::ok();
- }
-
- // If in_powerEntityIds is empty then return data for all supported energy consumers
- if (in_energyConsumerIds.empty()) {
- std::vector<int32_t> v(mEnergyConsumerInfos.size());
- std::iota(std::begin(v), std::end(v), 0);
- return getEnergyConsumed(v, _aidl_return);
- }
-
- for (const auto id : in_energyConsumerIds) {
- // check for invalid ids
- if (id < 0 || id >= mEnergyConsumers.size()) {
- return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
- }
-
- auto resopt = mEnergyConsumers[id]->getEnergyConsumed();
- if (resopt) {
- EnergyConsumerResult res = resopt.value();
- res.id = id;
- _aidl_return->emplace_back(res);
- } else {
- // Failed to get results for the given id.
- LOG(ERROR) << "Failed to get results for " << mEnergyConsumerInfos[id].name;
- }
- }
-
- return ndk::ScopedAStatus::ok();
-}
-
-void PowerStats::setEnergyMeterDataProvider(std::unique_ptr<IEnergyMeterDataProvider> p) {
- mEnergyMeterDataProvider = std::move(p);
-}
-
-ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector<Channel> *_aidl_return) {
- if (!mEnergyMeterDataProvider) {
- return ndk::ScopedAStatus::ok();
- }
- return mEnergyMeterDataProvider->getEnergyMeterInfo(_aidl_return);
-}
-
-ndk::ScopedAStatus PowerStats::readEnergyMeter(const std::vector<int32_t> &in_channelIds,
- std::vector<EnergyMeasurement> *_aidl_return) {
- if (!mEnergyMeterDataProvider) {
- return ndk::ScopedAStatus::ok();
- }
- return mEnergyMeterDataProvider->readEnergyMeter(in_channelIds, _aidl_return);
-}
-
-void PowerStats::getEntityStateNames(
- std::unordered_map<int32_t, std::string> *entityNames,
- std::unordered_map<int32_t, std::unordered_map<int32_t, std::string>> *stateNames) {
- std::vector<PowerEntity> infos;
- getPowerEntityInfo(&infos);
-
- for (const auto &info : infos) {
- entityNames->emplace(info.id, info.name);
- stateNames->emplace(info.id, std::unordered_map<int32_t, std::string>());
- auto &entityStateNames = stateNames->at(info.id);
- for (const auto &state : info.states) {
- entityStateNames.emplace(state.id, state.name);
- }
- }
-}
-
-void PowerStats::getChannelNames(std::unordered_map<int32_t, std::string> *channelNames) {
- std::vector<Channel> infos;
- getEnergyMeterInfo(&infos);
-
- for (const auto &info : infos) {
- channelNames->emplace(info.id, "[" + info.name + "]:" + info.subsystem);
- }
-}
-
-void PowerStats::dumpEnergyMeter(std::ostringstream &oss, bool delta) {
- const char *headerFormat = " %32s %18s\n";
- const char *dataFormat = " %32s %14.2f mWs\n";
- const char *headerFormatDelta = " %32s %18s (%14s)\n";
- const char *dataFormatDelta = " %32s %14.2f mWs (%14.2f)\n";
-
- std::unordered_map<int32_t, std::string> channelNames;
- getChannelNames(&channelNames);
-
- oss << "\n============= PowerStats HAL 2.0 energy meter ==============\n";
-
- std::vector<EnergyMeasurement> energyData;
- readEnergyMeter({}, &energyData);
-
- if (delta) {
- static std::vector<EnergyMeasurement> prevEnergyData;
- ::android::base::boot_clock::time_point curTime = ::android::base::boot_clock::now();
- static ::android::base::boot_clock::time_point prevTime = curTime;
-
- oss << "Elapsed time: "
- << std::chrono::duration_cast<std::chrono::milliseconds>(curTime - prevTime).count()
- << " ms\n";
-
- oss << ::android::base::StringPrintf(headerFormatDelta, "Channel", "Cumulative Energy",
- "Delta ");
-
- std::unordered_map<int32_t, int64_t> prevEnergyDataMap;
- for (const auto &data : prevEnergyData) {
- prevEnergyDataMap.emplace(data.id, data.energyUWs);
- }
-
- for (const auto &data : energyData) {
- auto prevEnergyDataIt = prevEnergyDataMap.find(data.id);
- int64_t deltaEnergy = 0;
- if (prevEnergyDataIt != prevEnergyDataMap.end()) {
- deltaEnergy = data.energyUWs - prevEnergyDataIt->second;
- }
-
- oss << ::android::base::StringPrintf(dataFormatDelta, channelNames.at(data.id).c_str(),
- static_cast<float>(data.energyUWs) / 1000.0,
- static_cast<float>(deltaEnergy) / 1000.0);
- }
-
- prevEnergyData = energyData;
- prevTime = curTime;
- } else {
- oss << ::android::base::StringPrintf(headerFormat, "Channel", "Cumulative Energy");
-
- for (const auto &data : energyData) {
- oss << ::android::base::StringPrintf(dataFormat, channelNames.at(data.id).c_str(),
- static_cast<float>(data.energyUWs) / 1000.0);
- }
- }
-
- oss << "========== End of PowerStats HAL 2.0 energy meter ==========\n";
-}
-
-void PowerStats::dumpStateResidency(std::ostringstream &oss, bool delta) {
- const char *headerFormat = " %16s %18s %16s %15s %17s\n";
- const char *dataFormat =
- " %16s %18s %13" PRIu64 " ms %15" PRIu64 " %14" PRIu64 " ms\n";
- const char *headerFormatDelta = " %16s %18s %16s (%14s) %15s (%16s) %17s (%14s)\n";
- const char *dataFormatDelta = " %16s %18s %13" PRIu64 " ms (%14" PRId64 ") %15" PRIu64
- " (%16" PRId64 ") %14" PRIu64 " ms (%14" PRId64 ")\n";
-
- // Construct maps to entity and state names
- std::unordered_map<int32_t, std::string> entityNames;
- std::unordered_map<int32_t, std::unordered_map<int32_t, std::string>> stateNames;
- getEntityStateNames(&entityNames, &stateNames);
-
- oss << "\n============= PowerStats HAL 2.0 state residencies ==============\n";
-
- std::vector<StateResidencyResult> results;
- getStateResidency({}, &results);
-
- if (delta) {
- static std::vector<StateResidencyResult> prevResults;
- ::android::base::boot_clock::time_point curTime = ::android::base::boot_clock::now();
- static ::android::base::boot_clock::time_point prevTime = curTime;
-
- oss << "Elapsed time: "
- << std::chrono::duration_cast<std::chrono::milliseconds>(curTime - prevTime).count()
- << " ms\n";
-
- oss << ::android::base::StringPrintf(headerFormatDelta, "Entity", "State", "Total time",
- "Delta ", "Total entries", "Delta ",
- "Last entry tstamp", "Delta ");
-
- // Process prevResults into a 2-tier lookup table for easy reference
- std::unordered_map<int32_t, std::unordered_map<int32_t, StateResidency>> prevResultsMap;
- for (const auto &prevResult : prevResults) {
- prevResultsMap.emplace(prevResult.id, std::unordered_map<int32_t, StateResidency>());
- for (auto stateResidency : prevResult.stateResidencyData) {
- prevResultsMap.at(prevResult.id).emplace(stateResidency.id, stateResidency);
- }
- }
-
- // Iterate over the new result data (one "result" per entity)
- for (const auto &result : results) {
- const char *entityName = entityNames.at(result.id).c_str();
-
- // Look up previous result data for the same entity
- auto prevEntityResultIt = prevResultsMap.find(result.id);
-
- // Iterate over individual states within the current entity's new result
- for (const auto &stateResidency : result.stateResidencyData) {
- const char *stateName = stateNames.at(result.id).at(stateResidency.id).c_str();
-
- // If a previous result was found for the same entity, see if that
- // result also contains data for the current state
- int64_t deltaTotalTime = 0;
- int64_t deltaTotalCount = 0;
- int64_t deltaTimestamp = 0;
- if (prevEntityResultIt != prevResultsMap.end()) {
- auto prevStateResidencyIt = prevEntityResultIt->second.find(stateResidency.id);
- // If a previous result was found for the current entity and state, calculate
- // the deltas and display them along with new result
- if (prevStateResidencyIt != prevEntityResultIt->second.end()) {
- deltaTotalTime = stateResidency.totalTimeInStateMs -
- prevStateResidencyIt->second.totalTimeInStateMs;
- deltaTotalCount = stateResidency.totalStateEntryCount -
- prevStateResidencyIt->second.totalStateEntryCount;
- deltaTimestamp = stateResidency.lastEntryTimestampMs -
- prevStateResidencyIt->second.lastEntryTimestampMs;
- }
- }
-
- oss << ::android::base::StringPrintf(
- dataFormatDelta, entityName, stateName, stateResidency.totalTimeInStateMs,
- deltaTotalTime, stateResidency.totalStateEntryCount, deltaTotalCount,
- stateResidency.lastEntryTimestampMs, deltaTimestamp);
- }
- }
-
- prevResults = results;
- prevTime = curTime;
- } else {
- oss << ::android::base::StringPrintf(headerFormat, "Entity", "State", "Total time",
- "Total entries", "Last entry tstamp");
- for (const auto &result : results) {
- for (const auto &stateResidency : result.stateResidencyData) {
- oss << ::android::base::StringPrintf(
- dataFormat, entityNames.at(result.id).c_str(),
- stateNames.at(result.id).at(stateResidency.id).c_str(),
- stateResidency.totalTimeInStateMs, stateResidency.totalStateEntryCount,
- stateResidency.lastEntryTimestampMs);
- }
- }
- }
-
- oss << "========== End of PowerStats HAL 2.0 state residencies ==========\n";
-}
-
-void PowerStats::dumpEnergyConsumer(std::ostringstream &oss, bool delta) {
- (void)delta;
-
- std::vector<EnergyConsumerResult> results;
- getEnergyConsumed({}, &results);
-
- oss << "\n============= PowerStats HAL 2.0 energy consumers ==============\n";
-
- for (const auto &result : results) {
- oss << ::android::base::StringPrintf("%-12s : %14.2f mWs\n",
- mEnergyConsumers[result.id]->getConsumerName().c_str(),
- static_cast<float>(result.energyUWs) / 1000.0);
- for (auto &attr : result.attribution) {
- oss << ::android::base::StringPrintf(" %10d - %14.2f mWs\n", attr.uid,
- static_cast<float>(attr.energyUWs) / 1000.0);
- }
- }
-
- oss << "========== End of PowerStats HAL 2.0 energy consumers ==========\n";
-}
-
-binder_status_t PowerStats::dump(int fd, const char **args, uint32_t numArgs) {
- std::ostringstream oss;
- bool delta = (numArgs == 1) && (std::string(args[0]) == "delta");
-
- // Generate debug output for state residency
- dumpStateResidency(oss, delta);
-
- // Generate debug output for energy consumer
- dumpEnergyConsumer(oss, delta);
-
- // Generate debug output energy meter
- dumpEnergyMeter(oss, delta);
-
- ::android::base::WriteStringToFd(oss.str(), fd);
- fsync(fd);
- return STATUS_OK;
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/WlanStateResidencyDataProvider.cpp b/powerstats/WlanStateResidencyDataProvider.cpp
index d7a4e50..5d5f18e 100644
--- a/powerstats/WlanStateResidencyDataProvider.cpp
+++ b/powerstats/WlanStateResidencyDataProvider.cpp
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// TODO(b/167628903): Delete this file
+
#define LOG_TAG "libpixelpowerstats"
#include <android-base/logging.h>
@@ -45,7 +45,7 @@
std::string wlanDriverStatus = android::base::GetProperty("wlan.driver.status", "unloaded");
if (wlanDriverStatus != "ok") {
- LOG(DEBUG) << __func__ << ": wlan is " << wlanDriverStatus;
+ LOG(ERROR) << __func__ << ": wlan is " << wlanDriverStatus;
// Return 0s for Wlan stats, because the driver is unloaded
results.insert(std::make_pair(mPowerEntityId, result));
return true;
diff --git a/powerstats/aidl/Android.bp b/powerstats/aidl/Android.bp
index 8dc02aa..c499e41 100644
--- a/powerstats/aidl/Android.bp
+++ b/powerstats/aidl/Android.bp
@@ -14,10 +14,6 @@
* limitations under the License.
*/
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
aidl_interface {
name: "pixelpowerstats_provider_aidl_interface",
unstable: true,
@@ -27,26 +23,12 @@
"android/vendor/powerstats/StateResidencyData.aidl",
],
- vendor_available: true,
-}
-
-aidl_interface {
- name: "pixel_stateresidency_provider_aidl_interface",
- unstable: true,
- imports: ["android.hardware.power.stats-V1"],
- srcs: [
- "android/vendor/powerstats/IPixelStateResidencyProvider.aidl",
- "android/vendor/powerstats/IPixelStateResidencyCallback.aidl",
- ],
+// TODO(b/124131159): I get an error when I remove this
backend: {
- java: {
- platform_apis: true,
- },
- cpp: {
+ ndk: {
enabled: false,
},
},
-
vendor_available: true,
- host_supported: true,
}
+
diff --git a/powerstats/aidl/android/vendor/powerstats/IPixelStateResidencyCallback.aidl b/powerstats/aidl/android/vendor/powerstats/IPixelStateResidencyCallback.aidl
deleted file mode 100644
index f4ae9e8..0000000
--- a/powerstats/aidl/android/vendor/powerstats/IPixelStateResidencyCallback.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-package android.vendor.powerstats;
-
-import android.hardware.power.stats.StateResidency;
-
-interface IPixelStateResidencyCallback
-{
- StateResidency[] getStateResidency();
-}
diff --git a/powerstats/aidl/android/vendor/powerstats/IPixelStateResidencyProvider.aidl b/powerstats/aidl/android/vendor/powerstats/IPixelStateResidencyProvider.aidl
deleted file mode 100644
index f2c0faf..0000000
--- a/powerstats/aidl/android/vendor/powerstats/IPixelStateResidencyProvider.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-package android.vendor.powerstats;
-
-import android.vendor.powerstats.IPixelStateResidencyCallback;
-
-interface IPixelStateResidencyProvider
-{
- void registerCallback(in @utf8InCpp String entityName, in IPixelStateResidencyCallback cb);
- void unregisterCallback(in IPixelStateResidencyCallback cb);
-}
diff --git a/powerstats/android.hardware.power.stats-service.pixel.rc b/powerstats/android.hardware.power.stats-service.pixel.rc
deleted file mode 100644
index f5e49f2..0000000
--- a/powerstats/android.hardware.power.stats-service.pixel.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service vendor.power.stats /vendor/bin/hw/android.hardware.power.stats-service.pixel
- class hal
- user system
- group system
diff --git a/powerstats/android.hardware.power.stats-service.pixel.xml b/powerstats/android.hardware.power.stats-service.pixel.xml
deleted file mode 100644
index 3b1a216..0000000
--- a/powerstats/android.hardware.power.stats-service.pixel.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<manifest version="1.0" type="device">
- <hal format="aidl">
- <name>android.hardware.power.stats</name>
- <fqname>IPowerStats/default</fqname>
- </hal>
-</manifest>
diff --git a/powerstats/dataproviders/DisplayStateResidencyDataProvider.cpp b/powerstats/dataproviders/DisplayStateResidencyDataProvider.cpp
deleted file mode 100644
index c074bf6..0000000
--- a/powerstats/dataproviders/DisplayStateResidencyDataProvider.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include <dataproviders/DisplayStateResidencyDataProvider.h>
-
-#include <android-base/chrono_utils.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-
-#include <chrono>
-#include <cstdio>
-#include <cstring>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-DisplayStateResidencyDataProvider::DisplayStateResidencyDataProvider(
- std::string name, std::string path, std::vector<std::string> states)
- : mPath(std::move(path)),
- mName(std::move(name)),
- mStates(states),
- mCurState(-1),
- mLooper(new ::android::Looper(true)) {
- // Construct mResidencies
- mResidencies.reserve(mStates.size());
- for (int32_t i = 0; i < mStates.size(); ++i) {
- StateResidency p = {.id = i};
- mResidencies.emplace_back(p);
- }
-
- // Open display state file descriptor
- LOG(VERBOSE) << "Opening " << mPath;
- mFd = open(mPath.c_str(), O_RDONLY | O_NONBLOCK);
- if (mFd < 0) {
- PLOG(ERROR) << ":Failed to open file " << mPath;
- return;
- }
-
- // Add display state file descriptor to be polled by the looper
- mLooper->addFd(mFd, 0, ::android::Looper::EVENT_ERROR, nullptr, nullptr);
-
- // Run the thread that will poll for changes to display state
- LOG(VERBOSE) << "Starting DisplayStateWatcherThread";
- mThread = std::thread(&DisplayStateResidencyDataProvider::pollLoop, this);
-}
-
-DisplayStateResidencyDataProvider::~DisplayStateResidencyDataProvider() {
- if (mFd >= 0) {
- close(mFd);
- }
-}
-
-bool DisplayStateResidencyDataProvider::getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
- std::scoped_lock lk(mLock);
-
- // Get current time since boot in milliseconds
- uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
- ::android::base::boot_clock::now().time_since_epoch())
- .count();
-
- // Construct residency result based on current residency data
- auto result = mResidencies;
-
- if (mCurState > -1) {
- result[mCurState].totalTimeInStateMs += now - result[mCurState].lastEntryTimestampMs;
- }
-
- residencies->emplace(mName, result);
- return true;
-}
-
-std::unordered_map<std::string, std::vector<State>> DisplayStateResidencyDataProvider::getInfo() {
- std::vector<State> stateInfos;
- stateInfos.reserve(mStates.size());
- for (int32_t i = 0; i < mStates.size(); ++i) {
- stateInfos.push_back({.id = i, .name = mStates[i]});
- }
-
- return {{mName, stateInfos}};
-}
-
-// Called when there is new data to be read from
-// display state file descriptor indicating a state change
-void DisplayStateResidencyDataProvider::updateStats() {
- char data[32];
-
- // Get current time since boot in milliseconds
- uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
- ::android::base::boot_clock::now().time_since_epoch())
- .count();
- // Read display state
- ssize_t ret = pread(mFd, data, sizeof(data) - 1, 0);
- if (ret < 0) {
- PLOG(ERROR) << "Failed to read display state";
- return;
- }
- data[ret] = '\0';
-
- LOG(VERBOSE) << "display state: " << data;
-
- // Update residency stats based on state read
- { // acquire lock
- std::scoped_lock lk(mLock);
- for (uint32_t i = 0; i < mStates.size(); ++i) {
- if (strstr(data, mStates[i].c_str())) {
- // Update total time of the previous state
- if (mCurState > -1) {
- mResidencies[mCurState].totalTimeInStateMs +=
- now - mResidencies[mCurState].lastEntryTimestampMs;
- }
-
- // Set current state
- mCurState = i;
- mResidencies[i].totalStateEntryCount++;
- mResidencies[i].lastEntryTimestampMs = now;
- break;
- }
- }
- } // release lock
-}
-
-void DisplayStateResidencyDataProvider::pollLoop() {
- LOG(VERBOSE) << "DisplayStateResidencyDataProvider polling...";
- while (true) {
- // Poll for display state changes. Timeout set to poll indefinitely
- if (mLooper->pollOnce(-1) >= 0) {
- updateStats();
- }
- }
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/dataproviders/GenericStateResidencyDataProvider.cpp b/powerstats/dataproviders/GenericStateResidencyDataProvider.cpp
deleted file mode 100644
index dae52cc..0000000
--- a/powerstats/dataproviders/GenericStateResidencyDataProvider.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-
-#include <dataproviders/GenericStateResidencyDataProvider.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-std::vector<GenericStateResidencyDataProvider::StateResidencyConfig>
-generateGenericStateResidencyConfigs(
- const GenericStateResidencyDataProvider::StateResidencyConfig &stateConfig,
- const std::vector<std::pair<std::string, std::string>> &stateHeaders) {
- std::vector<GenericStateResidencyDataProvider::StateResidencyConfig> stateResidencyConfigs;
- stateResidencyConfigs.reserve(stateHeaders.size());
- for (auto h : stateHeaders) {
- GenericStateResidencyDataProvider::StateResidencyConfig cfg = {stateConfig};
- cfg.name = h.first;
- cfg.header = h.second;
- stateResidencyConfigs.emplace_back(cfg);
- }
- return stateResidencyConfigs;
-}
-
-static bool extractStat(const char *line, const std::string &prefix, uint64_t *stat) {
- char const *prefixStart = strstr(line, prefix.c_str());
- if (prefixStart == nullptr) {
- // Did not find the given prefix
- return false;
- }
-
- *stat = strtoull(prefixStart + prefix.length(), nullptr, 0);
- return true;
-}
-
-static bool parseState(StateResidency *data,
- const GenericStateResidencyDataProvider::StateResidencyConfig &config,
- FILE *fp, char **line, size_t *len) {
- size_t numFieldsRead = 0;
- const size_t numFields =
- config.entryCountSupported + config.totalTimeSupported + config.lastEntrySupported;
-
- while ((numFieldsRead < numFields) && (getline(line, len, fp) != -1)) {
- uint64_t stat = 0;
- // Attempt to extract data from the current line
- if (config.entryCountSupported && extractStat(*line, config.entryCountPrefix, &stat)) {
- data->totalStateEntryCount =
- config.entryCountTransform ? config.entryCountTransform(stat) : stat;
- ++numFieldsRead;
- } else if (config.totalTimeSupported && extractStat(*line, config.totalTimePrefix, &stat)) {
- data->totalTimeInStateMs =
- config.totalTimeTransform ? config.totalTimeTransform(stat) : stat;
- ++numFieldsRead;
- } else if (config.lastEntrySupported && extractStat(*line, config.lastEntryPrefix, &stat)) {
- data->lastEntryTimestampMs =
- config.lastEntryTransform ? config.lastEntryTransform(stat) : stat;
- ++numFieldsRead;
- }
- }
-
- // End of file was reached and not all state data was parsed. Something
- // went wrong
- if (numFieldsRead != numFields) {
- LOG(ERROR) << "Failed to parse stats for " << config.name;
- return false;
- }
-
- return true;
-}
-
-template <class T, class Func>
-static int32_t findNextIndex(const std::vector<T> &collection, FILE *fp, char **line, size_t *len,
- Func pred) {
- // handling the case when there is no header to look for
- if (pred(collection[0], "")) {
- return 0;
- }
-
- while (getline(line, len, fp) != -1) {
- for (int32_t i = 0; i < collection.size(); ++i) {
- if (pred(collection[i], *line)) {
- return i;
- }
- }
- }
-
- return -1;
-}
-
-static bool getStateData(std::vector<StateResidency> *result,
- const std::vector<GenericStateResidencyDataProvider::StateResidencyConfig>
- &stateResidencyConfigs,
- FILE *fp, char **line, size_t *len) {
- size_t numStatesRead = 0;
- size_t numStates = stateResidencyConfigs.size();
- int32_t nextState = -1;
- auto pred = [](auto a, char const *b) {
- // return true if b matches the header contained in a, ignoring whitespace
- return (a.header == ::android::base::Trim(std::string(b)));
- };
-
- result->reserve(numStates);
-
- // Search for state headers until we have found them all or can't find anymore
- while ((numStatesRead < numStates) &&
- (nextState = findNextIndex<GenericStateResidencyDataProvider::StateResidencyConfig>(
- stateResidencyConfigs, fp, line, len, pred)) >= 0) {
- // Found a matching state header. Parse the contents
- StateResidency data = {.id = nextState};
- if (parseState(&data, stateResidencyConfigs[nextState], fp, line, len)) {
- result->emplace_back(data);
- ++numStatesRead;
- } else {
- break;
- }
- }
-
- // There was a problem parsing and we failed to get data for all of the states
- if (numStatesRead != numStates) {
- return false;
- }
-
- return true;
-}
-
-bool GenericStateResidencyDataProvider::getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
- // Using FILE* instead of std::ifstream for performance reasons
- std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(mPath.c_str(), "r"), fclose);
- if (!fp) {
- PLOG(ERROR) << "Failed to open file " << mPath;
- return false;
- }
-
- size_t len = 0;
- char *line = nullptr;
- size_t numEntitiesRead = 0;
- size_t numEntities = mPowerEntityConfigs.size();
- int32_t nextConfig = -1;
- auto pred = [](auto a, char const *b) {
- // return true if b matches the header contained in a, ignoring whitespace
- return (a.mHeader == ::android::base::Trim(std::string(b)));
- };
-
- // Search for entity headers until we have found them all or can't find anymore
- while ((numEntitiesRead < numEntities) &&
- (nextConfig = findNextIndex<decltype(mPowerEntityConfigs)::value_type>(
- mPowerEntityConfigs, fp.get(), &line, &len, pred)) >= 0) {
- // Found a matching header. Retrieve its state data
- std::vector<StateResidency> result;
- if (getStateData(&result, mPowerEntityConfigs[nextConfig].mStateResidencyConfigs, fp.get(),
- &line, &len)) {
- residencies->emplace(mPowerEntityConfigs[nextConfig].mName, result);
- ++numEntitiesRead;
- } else {
- break;
- }
- }
-
- free(line);
-
- // There was a problem gathering state residency data for one or more entities
- if (numEntitiesRead != numEntities) {
- LOG(ERROR) << "Failed to get results for " << mPath;
- return false;
- }
-
- return true;
-}
-
-std::unordered_map<std::string, std::vector<State>> GenericStateResidencyDataProvider::getInfo() {
- std::unordered_map<std::string, std::vector<State>> ret;
- for (const auto &entityConfig : mPowerEntityConfigs) {
- int32_t stateId = 0;
- std::vector<State> stateInfos;
- for (const auto &stateConfig : entityConfig.mStateResidencyConfigs) {
- State stateInfo = {.id = stateId++, .name = stateConfig.name};
- stateInfos.emplace_back(stateInfo);
- }
-
- ret.emplace(entityConfig.mName, stateInfos);
- }
- return ret;
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/dataproviders/IioEnergyMeterDataProvider.cpp b/powerstats/dataproviders/IioEnergyMeterDataProvider.cpp
deleted file mode 100644
index 9f4358d..0000000
--- a/powerstats/dataproviders/IioEnergyMeterDataProvider.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include <dataproviders/IioEnergyMeterDataProvider.h>
-#include <dataproviders/IioEnergyMeterDataSelector.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <inttypes.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-using aidl::android::hardware::power::stats::IioEnergyMeterDataSelector;
-
-#define MAX_RAIL_NAME_LEN 50
-#define STR(s) #s
-#define XSTR(s) STR(s)
-
-void IioEnergyMeterDataProvider::findIioEnergyMeterNodes() {
- struct dirent *ent;
-
- DIR *iioDir = opendir(kIioRootDir.c_str());
- if (!iioDir) {
- PLOG(ERROR) << "Error opening directory" << kIioRootDir;
- return;
- }
-
- // Find any iio:devices that match the given kDeviceNames
- while (ent = readdir(iioDir), ent) {
- std::string devTypeDir = ent->d_name;
- if (devTypeDir.find(kDeviceType) != std::string::npos) {
- std::string devicePath = kIioRootDir + devTypeDir;
- std::string deviceNameContents;
-
- if (!::android::base::ReadFileToString(devicePath + kNameNode, &deviceNameContents)) {
- LOG(WARNING) << "Failed to read device name from " << devicePath;
- } else {
- for (const auto &deviceName : kDeviceNames) {
- if (deviceNameContents.find(deviceName) != std::string::npos) {
- mDevicePaths.emplace(devicePath, deviceName);
- }
- }
- }
- }
- }
-
- closedir(iioDir);
- return;
-}
-
-void IioEnergyMeterDataProvider::parseEnabledRails() {
- std::string data;
- int32_t id = 0;
- for (const auto &path : mDevicePaths) {
- // Get list of enabled rails
- if (!::android::base::ReadFileToString(path.first + kEnabledRailsNode, &data)) {
- LOG(ERROR) << "Error reading enabled rails from " << path.first;
- continue;
- }
-
- // Build RailInfos from list of enabled rails
- std::istringstream railNames(data);
- std::string line;
- while (std::getline(railNames, line)) {
- /* Format example: CH2[VSYS_PWR_RFFE]:Cellular */
- std::vector<std::string> words = ::android::base::Split(line, ":][");
- if (words.size() == 4) {
- const std::string channelName = words[1];
- const std::string subsystemName = words[3];
- if (mChannelIds.count(channelName) == 0) {
- mChannelInfos.push_back(
- {.id = id, .name = channelName, .subsystem = subsystemName});
- mChannelIds.emplace(channelName, id);
- id++;
- } else {
- LOG(WARNING) << "There exists rails with the same name (not supported): "
- << channelName << ". Only the last occurrence of rail energy will "
- << "be provided.";
- }
- } else {
- LOG(WARNING) << "Unexpected enabled rail format in " << path.first;
- }
- }
- }
-}
-
-IioEnergyMeterDataProvider::IioEnergyMeterDataProvider(
- const std::vector<const std::string> &deviceNames, const bool useSelector)
- : kDeviceNames(std::move(deviceNames)) {
- findIioEnergyMeterNodes();
- if (useSelector) {
- /* Run meter selection in constructor; object can be discarded afterwards */
- IioEnergyMeterDataSelector selector(mDevicePaths);
- }
- parseEnabledRails();
- mReading.resize(mChannelInfos.size());
-}
-
-int IioEnergyMeterDataProvider::parseEnergyContents(const std::string &contents) {
- std::istringstream energyData(contents);
- std::string line;
-
- int ret = 0;
- uint64_t timestamp = 0;
- bool timestampRead = false;
-
- while (std::getline(energyData, line)) {
- bool parseLineSuccess = false;
-
- if (timestampRead == false) {
- /* Read timestamp from boot (ms) */
- if (sscanf(line.c_str(), "t=%" PRIu64, ×tamp) == 1) {
- if (timestamp == 0 || timestamp == ULLONG_MAX) {
- LOG(ERROR) << "Potentially wrong timestamp: " << timestamp;
- }
- timestampRead = true;
- parseLineSuccess = true;
- }
-
- } else {
- /* Read rail energy */
- uint64_t energy = 0;
- uint64_t duration = 0;
- char railNameRaw[MAX_RAIL_NAME_LEN + 1];
-
- /* Format example: CH3(T=358356)[S2M_VDD_CPUCL2], 761330 */
- if (sscanf(line.c_str(),
- "CH%*d(T=%" PRIu64 ")[%" XSTR(MAX_RAIL_NAME_LEN) "[^]]], %" PRIu64,
- &duration, railNameRaw, &energy) == 3) {
- std::string railName(railNameRaw);
-
- /* If the count == 0, the rail may not be enabled */
- /* The count cannot be > 1; mChannelIds is a map */
- if (mChannelIds.count(railName) == 1) {
- size_t index = mChannelIds[railName];
- mReading[index].id = index;
- mReading[index].timestampMs = timestamp;
- mReading[index].durationMs = duration;
- mReading[index].energyUWs = energy;
- if (mReading[index].energyUWs == ULLONG_MAX) {
- LOG(ERROR) << "Potentially wrong energy value on rail: " << railName;
- }
- }
- parseLineSuccess = true;
- }
- }
-
- if (parseLineSuccess == false) {
- ret = -1;
- break;
- }
- }
-
- return ret;
-}
-
-int IioEnergyMeterDataProvider::parseEnergyValue(std::string path) {
- int ret = 0;
- std::string data;
- if (!::android::base::ReadFileToString(path + kEnergyValueNode, &data)) {
- LOG(ERROR) << "Error reading energy value in " << path;
- return -1;
- }
-
- ret = parseEnergyContents(data);
- if (ret != 0) {
- LOG(ERROR) << "Unexpected format in " << path;
- }
- return ret;
-}
-
-ndk::ScopedAStatus IioEnergyMeterDataProvider::readEnergyMeter(
- const std::vector<int32_t> &in_channelIds, std::vector<EnergyMeasurement> *_aidl_return) {
- std::scoped_lock lock(mLock);
-
- for (const auto &devicePath : mDevicePaths) {
- if (parseEnergyValue(devicePath.first) < 0) {
- LOG(ERROR) << "Error in parsing " << devicePath.first;
- return ndk::ScopedAStatus::ok();
- }
- }
-
- if (in_channelIds.empty()) {
- *_aidl_return = mReading;
- } else {
- _aidl_return->reserve(in_channelIds.size());
- for (const auto &id : in_channelIds) {
- // check for invalid ids
- if (id < 0 || id >= mChannelInfos.size()) {
- return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
- }
-
- _aidl_return->emplace_back(mReading[id]);
- }
- }
-
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus IioEnergyMeterDataProvider::getEnergyMeterInfo(
- std::vector<Channel> *_aidl_return) {
- std::scoped_lock lk(mLock);
- *_aidl_return = mChannelInfos;
-
- return ndk::ScopedAStatus::ok();
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/dataproviders/IioEnergyMeterDataSelector.cpp b/powerstats/dataproviders/IioEnergyMeterDataSelector.cpp
deleted file mode 100644
index b09081b..0000000
--- a/powerstats/dataproviders/IioEnergyMeterDataSelector.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include <dataproviders/IioEnergyMeterDataSelector.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <inttypes.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-void IioEnergyMeterDataSelector::parseConfigData(
- const std::string data,
- std::unordered_map<std::string, std::list<std::string>> *deviceConfigs) {
- std::string deviceName; /* Initialized empty */
- std::list<std::string> deviceConfig;
-
- /* Parse the configuration from the config file */
- std::istringstream input(data);
- std::string line;
- while (std::getline(input, line)) {
- /* Skip whitespace/tab lines */
- if (line.find_first_not_of("\t ") == std::string::npos) {
- continue;
- }
-
- /* Look for "[Device Name]" in the line */
- std::vector<std::string> words = ::android::base::Split(line, "][");
- if (words.size() == 3) {
- if (deviceName.empty() == false) {
- /* End of device config - store config in map */
- deviceConfigs->emplace(deviceName, deviceConfig);
- deviceConfig.clear();
- }
-
- deviceName = words[1];
- } else {
- if (deviceName.empty() == false) {
- /* We current have a device name set, store the line */
- deviceConfig.emplace_back(line);
- } /* Else skip line - no device name is yet associated with config line */
- }
- }
-
- /* End of file - store config in map */
- if (deviceName.empty() == false) {
- deviceConfigs->emplace(deviceName, deviceConfig);
- }
-}
-
-void IioEnergyMeterDataSelector::applyConfigToDevices(
- const std::unordered_map<std::string, std::list<std::string>> &deviceConfigs) {
- for (const auto &devicePathPair : kDevicePaths) {
- std::string devicePath = devicePathPair.first;
- std::string deviceName = devicePathPair.second;
-
- /* Check if a config exists for this device */
- if (deviceConfigs.count(deviceName) == 1) {
- LOG(INFO) << "Attempting to configure: " << deviceName;
- std::string nodePath = devicePath + kSelectionNode;
- std::list<std::string> config = deviceConfigs.at(deviceName);
- for (const auto &railConfig : config) {
- bool success = ::android::base::WriteStringToFile(railConfig, nodePath);
- if (!success) {
- LOG(ERROR) << "Failed to write: " << railConfig << " to: " << nodePath;
- } else {
- LOG(INFO) << "Wrote rail config: " << railConfig;
- }
- }
- }
- }
-}
-
-void IioEnergyMeterDataSelector::applyConfigsByAscendingPriority() {
- std::string data;
-
- /* Parsed in order of initialization. Thus, the last item will have highest priority */
- for (const auto &configPath : kConfigPaths) {
- if (!::android::base::ReadFileToString(configPath, &data)) {
- LOG(DEBUG) << "Could not parse rail config from " << configPath;
- continue;
- }
-
- /* key: device name, value: list of config lines */
- std::unordered_map<std::string, std::list<std::string>> deviceConfigs;
- parseConfigData(data, &deviceConfigs);
- applyConfigToDevices(deviceConfigs);
- }
-}
-
-/**
- * Sends configuration complete to the driver
- */
-void IioEnergyMeterDataSelector::sendConfigurationComplete() {
- for (const auto &devicePathPair : kDevicePaths) {
- /* Sends configuration complete to the driver */
- std::string devicePath = devicePathPair.first;
- std::string nodePath = devicePath + kSelectionNode;
- bool success = ::android::base::WriteStringToFile(kSelectionComplete, nodePath);
- if (!success) {
- LOG(ERROR) << "Failed to write: " << kSelectionComplete << " to: " << nodePath;
- }
- }
-}
-
-IioEnergyMeterDataSelector::IioEnergyMeterDataSelector(
- const std::unordered_map<std::string, std::string> &devicePaths)
- : kDevicePaths(std::move(devicePaths)) {
- applyConfigsByAscendingPriority();
- sendConfigurationComplete();
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/dataproviders/PixelStateResidencyDataProvider.cpp b/powerstats/dataproviders/PixelStateResidencyDataProvider.cpp
deleted file mode 100644
index ce1951e..0000000
--- a/powerstats/dataproviders/PixelStateResidencyDataProvider.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include <dataproviders/PixelStateResidencyDataProvider.h>
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android/binder_status.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-PixelStateResidencyDataProvider::PixelStateResidencyDataProvider()
- : mProviderService(ndk::SharedRefBase::make<ProviderService>(this)) {}
-
-void PixelStateResidencyDataProvider::addEntity(std::string name, std::vector<State> states) {
- std::lock_guard<std::mutex> lock(mLock);
-
- mEntries.emplace_back(name, states);
-}
-
-void PixelStateResidencyDataProvider::start() {
- binder_status_t status =
- AServiceManager_addService(mProviderService->asBinder().get(), kInstance.c_str());
- if (status != STATUS_OK) {
- LOG(ERROR) << "Failed to start " << kInstance;
- }
-}
-
-::ndk::ScopedAStatus PixelStateResidencyDataProvider::getStateResidenciesTimed(
- const Entry &entry, std::vector<StateResidency> *residency) {
- const uint64_t MAX_LATENCY_US = 2000;
-
- if (!entry.mCallback) {
- LOG(ERROR) << "callback for " << entry.mName << " is not registered";
- return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
- }
-
- struct timespec then;
- struct timespec now;
-
- clock_gettime(CLOCK_BOOTTIME, &then);
- ::ndk::ScopedAStatus status = entry.mCallback->getStateResidency(residency);
- clock_gettime(CLOCK_BOOTTIME, &now);
-
- uint64_t timeElapsedUs =
- ((now.tv_sec - then.tv_sec) * 1000000) + ((now.tv_nsec - then.tv_nsec) / 1000);
- if (timeElapsedUs > MAX_LATENCY_US) {
- LOG(WARNING) << "getStateResidency latency for " << entry.mName
- << " exceeded time allowed: " << timeElapsedUs << "us";
- }
-
- return status;
-}
-
-bool PixelStateResidencyDataProvider::getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
- std::lock_guard<std::mutex> lock(mLock);
-
- size_t numResultsFound = 0;
- size_t numResults = mEntries.size();
- for (auto &entry : mEntries) {
- std::vector<StateResidency> residency;
- ::ndk::ScopedAStatus status = getStateResidenciesTimed(entry, &residency);
-
- if (!status.isOk()) {
- LOG(ERROR) << "getStateResidency for " << entry.mName << " failed";
-
- if (status.getStatus() == STATUS_DEAD_OBJECT) {
- LOG(ERROR) << "Unregistering dead callback for " << entry.mName;
- entry.mCallback = nullptr;
- }
- }
- if (!residency.empty()) {
- residencies->emplace(entry.mName, residency);
- numResultsFound++;
- }
- }
-
- return (numResultsFound == numResults);
-}
-
-std::unordered_map<std::string, std::vector<State>> PixelStateResidencyDataProvider::getInfo() {
- std::lock_guard<std::mutex> lock(mLock);
-
- std::unordered_map<std::string, std::vector<State>> ret;
- for (const auto &entry : mEntries) {
- ret.emplace(entry.mName, entry.mStates);
- }
-
- return ret;
-}
-
-::ndk::ScopedAStatus PixelStateResidencyDataProvider::registerCallback(
- const std::string &in_entityName,
- const std::shared_ptr<IPixelStateResidencyCallback> &in_cb) {
- std::lock_guard<std::mutex> lock(mLock);
-
- if (!in_cb) {
- return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
- }
-
- auto toRegister =
- std::find_if(mEntries.begin(), mEntries.end(),
- [&in_entityName](const auto &it) { return it.mName == in_entityName; });
-
- if (toRegister == mEntries.end()) {
- LOG(ERROR) << __func__ << " Invalid entityName: " << in_entityName;
- return ::ndk::ScopedAStatus::fromStatus(STATUS_BAD_VALUE);
- }
-
- toRegister->mCallback = in_cb;
-
- LOG(INFO) << __func__ << ": Registered " << in_entityName;
- return ::ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus PixelStateResidencyDataProvider::unregisterCallback(
- const std::shared_ptr<IPixelStateResidencyCallback> &in_cb) {
- std::lock_guard<std::mutex> lock(mLock);
-
- if (!in_cb) {
- return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
- }
-
- auto toRemove = std::find_if(mEntries.begin(), mEntries.end(), [&in_cb](const auto &it) {
- return it.mCallback->asBinder().get() == in_cb->asBinder().get();
- });
-
- if (toRemove == mEntries.end()) {
- return ndk::ScopedAStatus::fromStatus(STATUS_BAD_VALUE);
- }
-
- toRemove->mCallback = nullptr;
-
- return ::ndk::ScopedAStatus::ok();
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/dataproviders/PowerStatsEnergyAttribution.cpp b/powerstats/dataproviders/PowerStatsEnergyAttribution.cpp
deleted file mode 100644
index ca72a93..0000000
--- a/powerstats/dataproviders/PowerStatsEnergyAttribution.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include <dataproviders/PowerStatsEnergyAttribution.h>
-
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-
-#include <utility>
-
-using android::base::Split;
-using android::base::Trim;
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-bool PowerStatsEnergyAttribution::readUidTimeInState(AttributionStats *attrStats,
- std::string path) {
- std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(path.c_str(), "r"), fclose);
- if (!fp) {
- PLOG(ERROR) << __func__ << ":Failed to open file " << path;
- return false;
- }
-
- char *buf = nullptr;
- size_t size = 0;
- getline(&buf, &size, fp.get());
- attrStats->uidTimeInStateNames = Split(Trim(buf), " ");
- // first element will be "uid:" and it's useless
- attrStats->uidTimeInStateNames.erase(attrStats->uidTimeInStateNames.begin());
-
- while (getline(&buf, &size, fp.get()) != -1) {
- std::vector<std::string> uidInfos = Split(Trim(buf), " ");
- uidInfos[0].pop_back();
- int32_t uid;
- if (!::android::base::ParseInt(uidInfos[0], &uid)) {
- PLOG(ERROR) << __func__ << "Failed to parse uid from " << path;
- free(buf);
- return false;
- }
-
- std::vector<long> uidStats;
- // first element will be uid number so skipping it
- for (auto it = ++uidInfos.begin(); it != uidInfos.end(); ++it) {
- long uidStat;
- if (!::android::base::ParseInt(*it, &uidStat)) {
- PLOG(ERROR) << __func__ << "Failed to parse uidStat from " << path;
- free(buf);
- return false;
- }
- uidStats.push_back(uidStat);
- }
- attrStats->uidTimeInStats.emplace(uid, uidStats);
- }
-
- free(buf);
- return true;
-}
-
-AttributionStats PowerStatsEnergyAttribution::getAttributionStats(
- std::unordered_map<int32_t,
- std::string> paths) {
- AttributionStats attrStats;
-
- if (paths.count(UID_TIME_IN_STATE) &&
- !readUidTimeInState(&attrStats, paths.at(UID_TIME_IN_STATE))) {
- PLOG(ERROR) << ":Failed to read uid_time_in_state";
- return {};
- }
-
- return attrStats;
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/dataproviders/PowerStatsEnergyConsumer.cpp b/powerstats/dataproviders/PowerStatsEnergyConsumer.cpp
deleted file mode 100644
index c242596..0000000
--- a/powerstats/dataproviders/PowerStatsEnergyConsumer.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include <dataproviders/PowerStatsEnergyConsumer.h>
-
-#include <android-base/logging.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-PowerStatsEnergyConsumer::PowerStatsEnergyConsumer(std::shared_ptr<PowerStats> p,
- EnergyConsumerType type, std::string name,
- bool attr)
- : kType(type), kName(name), mPowerStats(p), mWithAttribution(attr) {}
-
-std::unique_ptr<PowerStatsEnergyConsumer> PowerStatsEnergyConsumer::createMeterConsumer(
- std::shared_ptr<PowerStats> p, EnergyConsumerType type, std::string name,
- std::set<std::string> channelNames) {
- return createMeterAndEntityConsumer(p, type, name, channelNames, "", {});
-}
-
-std::unique_ptr<PowerStatsEnergyConsumer> PowerStatsEnergyConsumer::createEntityConsumer(
- std::shared_ptr<PowerStats> p, EnergyConsumerType type, std::string name,
- std::string powerEntityName, std::map<std::string, int32_t> stateCoeffs) {
- return createMeterAndEntityConsumer(p, type, name, {}, powerEntityName, stateCoeffs);
-}
-
-std::unique_ptr<PowerStatsEnergyConsumer> PowerStatsEnergyConsumer::createMeterAndEntityConsumer(
- std::shared_ptr<PowerStats> p, EnergyConsumerType type, std::string name,
- std::set<std::string> channelNames, std::string powerEntityName,
- std::map<std::string, int32_t> stateCoeffs) {
- auto ret =
- std::unique_ptr<PowerStatsEnergyConsumer>(new PowerStatsEnergyConsumer(p, type, name));
-
- if (ret->addEnergyMeter(channelNames) && ret->addPowerEntity(powerEntityName, stateCoeffs)) {
- return ret;
- }
-
- LOG(ERROR) << "Failed to create PowerStatsEnergyConsumer for " << name;
- return nullptr;
-}
-
-std::unique_ptr<PowerStatsEnergyConsumer> PowerStatsEnergyConsumer::createMeterAndAttrConsumer(
- std::shared_ptr<PowerStats> p, EnergyConsumerType type, std::string name,
- std::set<std::string> channelNames, std::unordered_map<int32_t, std::string> paths,
- std::map<std::string, int32_t> stateCoeffs) {
- auto ret = std::unique_ptr<PowerStatsEnergyConsumer>(
- new PowerStatsEnergyConsumer(p, type, name, true));
-
- if (ret->addEnergyMeter(channelNames) && ret->addAttribution(paths, stateCoeffs)) {
- return ret;
- }
-
- LOG(ERROR) << "Failed to create PowerStatsEnergyConsumer for " << name;
- return nullptr;
-}
-
-bool PowerStatsEnergyConsumer::addEnergyMeter(std::set<std::string> channelNames) {
- if (channelNames.empty()) {
- return true;
- }
-
- std::vector<Channel> channels;
- mPowerStats->getEnergyMeterInfo(&channels);
-
- for (const auto &c : channels) {
- if (channelNames.count(c.name)) {
- mChannelIds.push_back(c.id);
- }
- }
-
- return (mChannelIds.size() == channelNames.size());
-}
-
-bool PowerStatsEnergyConsumer::addPowerEntity(std::string powerEntityName,
- std::map<std::string, int32_t> stateCoeffs) {
- if (powerEntityName.empty() || stateCoeffs.empty()) {
- return true;
- }
-
- std::vector<PowerEntity> powerEntities;
- mPowerStats->getPowerEntityInfo(&powerEntities);
-
- for (const auto &p : powerEntities) {
- if (powerEntityName == p.name) {
- mPowerEntityId = p.id;
- for (const auto &s : p.states) {
- if (stateCoeffs.count(s.name)) {
- mCoefficients.emplace(s.id, stateCoeffs.at(s.name));
- }
- }
- break;
- }
- }
-
- return (mCoefficients.size() == stateCoeffs.size());
-}
-
-bool PowerStatsEnergyConsumer::addAttribution(std::unordered_map<int32_t, std::string> paths,
- std::map<std::string, int32_t> stateCoeffs) {
- mAttrInfoPath = paths;
-
- if (paths.count(UID_TIME_IN_STATE)) {
- mEnergyAttribution = PowerStatsEnergyAttribution();
- AttributionStats attrStats = mEnergyAttribution.getAttributionStats(paths);
- if (attrStats.uidTimeInStats.empty() || attrStats.uidTimeInStateNames.empty()) {
- LOG(ERROR) << "Missing uid_time_in_state";
- return false;
- }
-
- // stateCoeffs should not blocking energy consumer to return power meter
- // so just handle this in getEnergyConsumed()
- if (stateCoeffs.empty()) {
- return true;
- }
-
- int32_t stateId = 0;
- for (const auto &stateName : attrStats.uidTimeInStateNames) {
- if (stateCoeffs.count(stateName)) {
- // When uid_time_in_state is not the only type of attribution,
- // should condider to separate the coefficients just for attribution.
- mCoefficients.emplace(stateId, stateCoeffs.at(stateName));
- }
- stateId++;
- }
- }
-
- return (mCoefficients.size() == stateCoeffs.size());
-}
-
-std::optional<EnergyConsumerResult> PowerStatsEnergyConsumer::getEnergyConsumed() {
- int64_t totalEnergyUWs = 0;
- int64_t timestampMs = 0;
-
- if (!mChannelIds.empty()) {
- std::vector<EnergyMeasurement> measurements;
- if (mPowerStats->readEnergyMeter(mChannelIds, &measurements).isOk()) {
- for (const auto &m : measurements) {
- totalEnergyUWs += m.energyUWs;
- timestampMs = m.timestampMs;
- }
- } else {
- LOG(ERROR) << "Failed to read energy meter";
- return {};
- }
- }
-
- std::vector<EnergyConsumerAttribution> attribution;
- if (!mCoefficients.empty()) {
- if (mWithAttribution) {
- AttributionStats attrStats = mEnergyAttribution.getAttributionStats(mAttrInfoPath);
- if (attrStats.uidTimeInStats.empty() || attrStats.uidTimeInStateNames.empty()) {
- LOG(ERROR) << "Missing uid_time_in_state";
- return {};
- }
-
- int64_t totalRelativeEnergyUWs = 0;
- for (const auto &uidTimeInStat : attrStats.uidTimeInStats) {
- int64_t uidEnergyUWs = 0;
- for (int id = 0; id < uidTimeInStat.second.size(); id++) {
- if (mCoefficients.count(id)) {
- int64_t d_time_in_state = uidTimeInStat.second.at(id);
- if (mUidTimeInStateSS.count(uidTimeInStat.first)) {
- d_time_in_state -= mUidTimeInStateSS.at(uidTimeInStat.first).at(id);
- }
- uidEnergyUWs += mCoefficients.at(id) * d_time_in_state;
- }
- }
- totalRelativeEnergyUWs += uidEnergyUWs;
-
- EnergyConsumerAttribution attr = {
- .uid = uidTimeInStat.first,
- .energyUWs = uidEnergyUWs,
- };
- attribution.emplace_back(attr);
- }
-
- int64_t d_totalEnergyUWs = totalEnergyUWs - mTotalEnergySS;
- float powerScale = 0;
- if (totalRelativeEnergyUWs != 0) {
- powerScale = static_cast<float>(d_totalEnergyUWs) / totalRelativeEnergyUWs;
- }
- for (auto &attr : attribution) {
- attr.energyUWs = (int64_t)(attr.energyUWs * powerScale) +
- (mUidEnergySS.count(attr.uid) ? mUidEnergySS.at(attr.uid) : 0);
- mUidEnergySS[attr.uid] = attr.energyUWs;
- }
-
- mUidTimeInStateSS = attrStats.uidTimeInStats;
- mTotalEnergySS = totalEnergyUWs;
- } else {
- std::vector<StateResidencyResult> results;
- if (mPowerStats->getStateResidency({mPowerEntityId}, &results).isOk()) {
- for (const auto &s : results[0].stateResidencyData) {
- if (mCoefficients.count(s.id)) {
- totalEnergyUWs += mCoefficients.at(s.id) * s.totalTimeInStateMs;
- }
- }
- } else {
- LOG(ERROR) << "Failed to get state residency";
- return {};
- }
- }
- }
-
- return EnergyConsumerResult{.timestampMs = timestampMs,
- .energyUWs = totalEnergyUWs,
- .attribution = attribution};
-}
-
-std::string PowerStatsEnergyConsumer::getConsumerName() {
- return kName;
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/dataproviders/WlanStateResidencyDataProvider.cpp b/powerstats/dataproviders/WlanStateResidencyDataProvider.cpp
deleted file mode 100644
index 59a57fe..0000000
--- a/powerstats/dataproviders/WlanStateResidencyDataProvider.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/strings.h>
-
-#include <dataproviders/WlanStateResidencyDataProvider.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-enum {
- ACTIVE_ID = 0,
- DEEPSLEEP_ID = 1,
-};
-
-static bool extractStat(const char *line, const std::string &prefix, uint64_t *stat) {
- char const *prefixStart = strstr(line, prefix.c_str());
- if (prefixStart == nullptr) {
- // Did not find the given prefix
- return false;
- }
-
- *stat = strtoull(prefixStart + prefix.length(), nullptr, 0);
- return true;
-}
-
-bool WlanStateResidencyDataProvider::getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
- std::vector<StateResidency> result = {{.id = ACTIVE_ID}, {.id = DEEPSLEEP_ID}};
-
- std::string wlanDriverStatus = ::android::base::GetProperty("wlan.driver.status", "unloaded");
- if (wlanDriverStatus != "ok") {
- LOG(ERROR) << ": wlan is " << wlanDriverStatus;
- // Return 0s for Wlan stats, because the driver is unloaded
- residencies->emplace(mName, result);
- return true;
- }
-
- // Using FILE* instead of std::ifstream for performance reasons (b/122253123)
- std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(mPath.c_str(), "r"), fclose);
- if (!fp) {
- PLOG(ERROR) << ":Failed to open file " << mPath;
- return false;
- }
- size_t numFieldsRead = 0;
- const size_t numFields = 4;
- size_t len = 0;
- char *line = nullptr;
-
- while ((numFieldsRead < numFields) && (getline(&line, &len, fp.get()) != -1)) {
- uint64_t stat = 0;
- if (extractStat(line, "cumulative_sleep_time_ms:", &stat)) {
- result[1].totalTimeInStateMs = stat;
- ++numFieldsRead;
- } else if (extractStat(line, "cumulative_total_on_time_ms:", &stat)) {
- result[0].totalTimeInStateMs = stat;
- ++numFieldsRead;
- } else if (extractStat(line, "deep_sleep_enter_counter:", &stat)) {
- result[0].totalStateEntryCount = stat;
- result[1].totalStateEntryCount = stat;
- ++numFieldsRead;
- } else if (extractStat(line, "last_deep_sleep_enter_tstamp_ms:", &stat)) {
- result[1].lastEntryTimestampMs = stat;
- ++numFieldsRead;
- }
- }
-
- free(line);
-
- // End of file was reached and not all state data was parsed. Something
- // went wrong
- if (numFieldsRead != numFields) {
- LOG(ERROR) << __func__ << ": failed to parse stats for wlan";
- return false;
- }
-
- residencies->emplace(mName, result);
-
- return true;
-}
-
-std::unordered_map<std::string, std::vector<State>> WlanStateResidencyDataProvider::getInfo() {
- std::unordered_map<std::string, std::vector<State>> ret = {
- {mName,
- {{.id = ACTIVE_ID, .name = "Active"}, {.id = DEEPSLEEP_ID, .name = "Deep-Sleep"}}},
- };
- return ret;
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/PowerStatsAidl.h b/powerstats/include/PowerStatsAidl.h
deleted file mode 100644
index cc03898..0000000
--- a/powerstats/include/PowerStatsAidl.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2020 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 <aidl/android/hardware/power/stats/BnPowerStats.h>
-
-#include <optional>
-#include <unordered_map>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class PowerStats : public BnPowerStats {
- public:
- class IStateResidencyDataProvider {
- public:
- virtual ~IStateResidencyDataProvider() = default;
- virtual bool getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) = 0;
- virtual std::unordered_map<std::string, std::vector<State>> getInfo() = 0;
- };
-
- class IEnergyConsumer {
- public:
- virtual ~IEnergyConsumer() = default;
- virtual std::pair<EnergyConsumerType, std::string> getInfo() = 0;
- virtual std::optional<EnergyConsumerResult> getEnergyConsumed() = 0;
- virtual std::string getConsumerName() = 0;
- };
-
- class IEnergyMeterDataProvider {
- public:
- virtual ~IEnergyMeterDataProvider() = default;
- virtual ndk::ScopedAStatus readEnergyMeter(
- const std::vector<int32_t> &in_channelIds,
- std::vector<EnergyMeasurement> *_aidl_return) = 0;
- virtual ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel> *_aidl_return) = 0;
- };
-
- PowerStats() = default;
- void addStateResidencyDataProvider(std::unique_ptr<IStateResidencyDataProvider> p);
- void addEnergyConsumer(std::unique_ptr<IEnergyConsumer> p);
- void setEnergyMeterDataProvider(std::unique_ptr<IEnergyMeterDataProvider> p);
-
- // Methods from aidl::android::hardware::power::stats::IPowerStats
- ndk::ScopedAStatus getPowerEntityInfo(std::vector<PowerEntity> *_aidl_return) override;
- ndk::ScopedAStatus getStateResidency(const std::vector<int32_t> &in_powerEntityIds,
- std::vector<StateResidencyResult> *_aidl_return) override;
- ndk::ScopedAStatus getEnergyConsumerInfo(std::vector<EnergyConsumer> *_aidl_return) override;
- ndk::ScopedAStatus getEnergyConsumed(const std::vector<int32_t> &in_energyConsumerIds,
- std::vector<EnergyConsumerResult> *_aidl_return) override;
- ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel> *_aidl_return) override;
- ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t> &in_channelIds,
- std::vector<EnergyMeasurement> *_aidl_return) override;
- binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
-
- private:
- void getEntityStateNames(
- std::unordered_map<int32_t, std::string> *entityNames,
- std::unordered_map<int32_t, std::unordered_map<int32_t, std::string>> *stateNames);
- void getChannelNames(std::unordered_map<int32_t, std::string> *channelNames);
- void dumpStateResidency(std::ostringstream &oss, bool delta);
- void dumpStateResidencyDelta(std::ostringstream &oss,
- const std::vector<StateResidencyResult> &results);
- void dumpStateResidencyOneShot(std::ostringstream &oss,
- const std::vector<StateResidencyResult> &results);
- void dumpEnergyConsumer(std::ostringstream &oss, bool delta);
- void dumpEnergyMeter(std::ostringstream &oss, bool delta);
-
- std::vector<std::unique_ptr<IStateResidencyDataProvider>> mStateResidencyDataProviders;
- std::vector<PowerEntity> mPowerEntityInfos;
- /* Index that maps each power entity id to an entry in mStateResidencyDataProviders */
- std::vector<size_t> mStateResidencyDataProviderIndex;
-
- std::vector<std::unique_ptr<IEnergyConsumer>> mEnergyConsumers;
- std::vector<EnergyConsumer> mEnergyConsumerInfos;
-
- std::unique_ptr<IEnergyMeterDataProvider> mEnergyMeterDataProvider;
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/dataproviders/DisplayStateResidencyDataProvider.h b/powerstats/include/dataproviders/DisplayStateResidencyDataProvider.h
deleted file mode 100644
index 70c814b..0000000
--- a/powerstats/include/dataproviders/DisplayStateResidencyDataProvider.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2020 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 <PowerStatsAidl.h>
-
-#include <utils/Looper.h>
-#include <utils/Thread.h>
-
-#include <cstdio>
-#include <cstring>
-#include <mutex>
-#include <thread>
-#include <unordered_map>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class DisplayStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
- public:
- // name = powerEntityName to be associated with this data provider
- // path = path to the display state file descriptor
- // state = list of states to be tracked
- DisplayStateResidencyDataProvider(std::string name, std::string path,
- std::vector<std::string> states);
- ~DisplayStateResidencyDataProvider();
-
- // Methods from PowerStats::IStateResidencyDataProvider
- bool getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
- std::unordered_map<std::string, std::vector<State>> getInfo() override;
-
- private:
- // Poll for display state changes
- void pollLoop();
- // Main function to update the stats when display state change is detected
- void updateStats();
-
- // File descriptor of display state
- int mFd;
- // Path to display state file descriptor
- const std::string mPath;
- // Power Entity name associated with this data provider
- const std::string mName;
- // List of states to track indexed by mCurState
- std::vector<std::string> mStates;
- // Lock to protect concurrent read/write to mResidencies and mCurState
- std::mutex mLock;
- // Accumulated display state stats indexed by mCurState
- std::vector<StateResidency> mResidencies;
- // Index of current state
- int mCurState;
- // Looper to facilitate polling of display state file desciptor
- ::android::sp<::android::Looper> mLooper;
-
- std::thread mThread;
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/dataproviders/GenericStateResidencyDataProvider.h b/powerstats/include/dataproviders/GenericStateResidencyDataProvider.h
deleted file mode 100644
index 75b8618..0000000
--- a/powerstats/include/dataproviders/GenericStateResidencyDataProvider.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2020 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 <PowerStatsAidl.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class GenericStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
- public:
- class StateResidencyConfig {
- public:
- std::string name;
- std::string header;
-
- bool entryCountSupported;
- std::string entryCountPrefix;
- std::function<uint64_t(uint64_t)> entryCountTransform;
-
- bool totalTimeSupported;
- std::string totalTimePrefix;
- std::function<uint64_t(uint64_t)> totalTimeTransform;
-
- bool lastEntrySupported;
- std::string lastEntryPrefix;
- std::function<uint64_t(uint64_t)> lastEntryTransform;
- };
-
- class PowerEntityConfig {
- public:
- PowerEntityConfig(const std::vector<StateResidencyConfig> &stateResidencyConfigs,
- const std::string &name, const std::string &header = "")
- : mStateResidencyConfigs(std::move(stateResidencyConfigs)),
- mName(std::move(name)),
- mHeader(std::move(header)) {}
- const std::vector<StateResidencyConfig> mStateResidencyConfigs;
- const std::string mName;
- const std::string mHeader;
- };
-
- GenericStateResidencyDataProvider(const std::string &path,
- const std::vector<PowerEntityConfig> &configs)
- : mPath(std::move(path)), mPowerEntityConfigs(std::move(configs)) {}
- ~GenericStateResidencyDataProvider() = default;
-
- // Methods from PowerStats::IStateResidencyDataProvider
- bool getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
- std::unordered_map<std::string, std::vector<State>> getInfo() override;
-
- private:
- const std::string mPath;
- const std::vector<PowerEntityConfig> mPowerEntityConfigs;
-};
-
-std::vector<GenericStateResidencyDataProvider::StateResidencyConfig>
-generateGenericStateResidencyConfigs(
- const GenericStateResidencyDataProvider::StateResidencyConfig &stateConfig,
- const std::vector<std::pair<std::string, std::string>> &stateHeaders);
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/dataproviders/IioEnergyMeterDataProvider.h b/powerstats/include/dataproviders/IioEnergyMeterDataProvider.h
deleted file mode 100644
index 2f202c5..0000000
--- a/powerstats/include/dataproviders/IioEnergyMeterDataProvider.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2020 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 <PowerStatsAidl.h>
-
-#include <unordered_map>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class IioEnergyMeterDataProvider : public PowerStats::IEnergyMeterDataProvider {
- public:
- IioEnergyMeterDataProvider(const std::vector<const std::string> &deviceNames,
- const bool useSelector = false);
-
- // Methods from PowerStats::IRailEnergyDataProvider
- ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t> &in_channelIds,
- std::vector<EnergyMeasurement> *_aidl_return) override;
- ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel> *_aidl_return) override;
-
- private:
- void findIioEnergyMeterNodes();
- void parseEnabledRails();
- int parseEnergyValue(std::string path);
- int parseEnergyContents(const std::string &contents);
-
- std::mutex mLock;
- std::unordered_map<std::string, std::string> mDevicePaths; // key: path, value: device name
- std::unordered_map<std::string, int32_t> mChannelIds; // key: name, value: id
- std::vector<Channel> mChannelInfos;
- std::vector<EnergyMeasurement> mReading;
-
- const std::vector<const std::string> kDeviceNames;
- const std::string kDeviceType = "iio:device";
- const std::string kIioRootDir = "/sys/bus/iio/devices/";
- const std::string kNameNode = "/name";
- const std::string kEnabledRailsNode = "/enabled_rails";
- const std::string kEnergyValueNode = "/energy_value";
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/dataproviders/IioEnergyMeterDataSelector.h b/powerstats/include/dataproviders/IioEnergyMeterDataSelector.h
deleted file mode 100644
index 37d8340..0000000
--- a/powerstats/include/dataproviders/IioEnergyMeterDataSelector.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2020 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 <list>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-/**
- * This class provides the necessary functionality for selection of energy meter
- * based on file configurations.
- */
-class IioEnergyMeterDataSelector {
- public:
- IioEnergyMeterDataSelector(const std::unordered_map<std::string, std::string> &devicePaths);
-
- private:
- void parseConfigData(const std::string data,
- std::unordered_map<std::string, std::list<std::string>> *deviceConfigs);
- void applyConfigToDevices(
- const std::unordered_map<std::string, std::list<std::string>> &deviceConfigs);
- void applyConfigsByAscendingPriority();
- void sendConfigurationComplete();
-
- const std::unordered_map<std::string, std::string> kDevicePaths;
- const std::string kSelectionNode = "/enabled_rails";
- const std::string kSelectionComplete = "CONFIG_COMPLETE";
-
- /* Order matters (ascending priority), see applyConfigsByAscendingPriority() */
- const std::vector<const std::string> kConfigPaths = {
- "/data/vendor/powerstats/odpm_config",
- };
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/dataproviders/PixelStateResidencyDataProvider.h b/powerstats/include/dataproviders/PixelStateResidencyDataProvider.h
deleted file mode 100644
index 6352c1f..0000000
--- a/powerstats/include/dataproviders/PixelStateResidencyDataProvider.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2021 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 <PowerStatsAidl.h>
-#include <aidl/android/vendor/powerstats/BnPixelStateResidencyCallback.h>
-#include <aidl/android/vendor/powerstats/BnPixelStateResidencyProvider.h>
-
-#include <android/binder_manager.h>
-
-using ::aidl::android::vendor::powerstats::BnPixelStateResidencyProvider;
-using ::aidl::android::vendor::powerstats::IPixelStateResidencyCallback;
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class PixelStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
- public:
- PixelStateResidencyDataProvider();
- ~PixelStateResidencyDataProvider() = default;
- void addEntity(std::string name, std::vector<State> states);
- void start();
-
- // Methods from PowerStats::IStateResidencyDataProvider
- bool getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
- std::unordered_map<std::string, std::vector<State>> getInfo() override;
-
- private:
- class ProviderService : public BnPixelStateResidencyProvider {
- public:
- ProviderService(PixelStateResidencyDataProvider *enclosed) : mEnclosed(enclosed) {}
- // Methods from BnPixelStateResidencyProvider
- ::ndk::ScopedAStatus registerCallback(
- const std::string &in_entityName,
- const std::shared_ptr<IPixelStateResidencyCallback> &in_cb) override {
- return mEnclosed->registerCallback(in_entityName, in_cb);
- }
-
- ::ndk::ScopedAStatus unregisterCallback(
- const std::shared_ptr<IPixelStateResidencyCallback> &in_cb) override {
- return mEnclosed->unregisterCallback(in_cb);
- }
-
- private:
- PixelStateResidencyDataProvider *mEnclosed;
- };
-
- struct Entry {
- Entry(std::string name, std::vector<State> states)
- : mName(name), mStates(states), mCallback(nullptr) {}
- std::string mName;
- std::vector<State> mStates;
- std::shared_ptr<IPixelStateResidencyCallback> mCallback;
- };
-
- ::ndk::ScopedAStatus registerCallback(
- const std::string &in_entityName,
- const std::shared_ptr<IPixelStateResidencyCallback> &in_cb);
-
- ::ndk::ScopedAStatus unregisterCallback(
- const std::shared_ptr<IPixelStateResidencyCallback> &in_cb);
-
- ::ndk::ScopedAStatus getStateResidenciesTimed(const Entry &entry,
- std::vector<StateResidency> *residency);
-
- const std::string kInstance = "power.stats-vendor";
- std::mutex mLock;
- std::shared_ptr<ProviderService> mProviderService;
- std::vector<Entry> mEntries;
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/dataproviders/PowerStatsEnergyAttribution.h b/powerstats/include/dataproviders/PowerStatsEnergyAttribution.h
deleted file mode 100644
index dacc54a..0000000
--- a/powerstats/include/dataproviders/PowerStatsEnergyAttribution.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2020 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 <map>
-#include <unordered_map>
-#include <vector>
-#include <string>
-
-enum AttributionType {
- /* Parsing uid_time_in_state like following format.
- * (see /proc/uid_time_in_state)
- * uid: state_name_0, state_name_1, ..
- * uid_0: time_in_state_0, time_in_state_1, ..
- * uid_1: time_in_state_0, time_in_state_1, ..
- */
- UID_TIME_IN_STATE,
-};
-
-// Declaring different return values for each type of attributions
-struct AttributionStats {
- /* Members for UID_TIME_IN_STATE
- * uidTimeInStats: key = uid, val = {uid_time_in_state}
- * uidTimeInStateNames: state_name_0, state_name_1, ..
- */
- std::unordered_map<int32_t, std::vector<long>> uidTimeInStats;
- std::vector<std::string> uidTimeInStateNames;
-};
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class PowerStatsEnergyAttribution {
- public:
- PowerStatsEnergyAttribution() = default;
- ~PowerStatsEnergyAttribution() = default;
- AttributionStats getAttributionStats(std::unordered_map<int32_t, std::string> paths);
-private:
- bool readUidTimeInState(AttributionStats *attrStats, std::string path);
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/dataproviders/PowerStatsEnergyConsumer.h b/powerstats/include/dataproviders/PowerStatsEnergyConsumer.h
deleted file mode 100644
index a37520b..0000000
--- a/powerstats/include/dataproviders/PowerStatsEnergyConsumer.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2020 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 <PowerStatsAidl.h>
-#include "PowerStatsEnergyAttribution.h"
-
-#include <utils/RefBase.h>
-
-#include <map>
-#include <set>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-using ::android::sp;
-
-/**
- * PowerStatsEnergyConsumer is an energy consumer that can be represented as
- * EnergyConsumed = SUM_i(E_i) + SUM_j(C_j * T_j)
- * where E_i is the energy of channel i of the EnergyMeter and
- * where C_j is the coefficient (in mW) of state j and T_j is the total time (in ms) in state j
- *
- * Factory functions are provided to create PowerStatsEnergyConsumer of three varieties
- * 1. MeterAndEntityConsumer - number of channels is > 0, and there is at least one C_j != 0
- * 2. MeterConsumer - number of channels is > 0, and all C_j = 0
- * 3. EntityConsumer - number of channels is 0, and there is at least one C_j != 0
- */
-class PowerStatsEnergyConsumer : public PowerStats::IEnergyConsumer {
- public:
- static std::unique_ptr<PowerStatsEnergyConsumer> createMeterConsumer(
- std::shared_ptr<PowerStats> p, EnergyConsumerType type, std::string name,
- std::set<std::string> channelNames);
- static std::unique_ptr<PowerStatsEnergyConsumer> createEntityConsumer(
- std::shared_ptr<PowerStats> p, EnergyConsumerType type, std::string name,
- std::string powerEntityName, std::map<std::string, int32_t> stateCoeffs);
-
- static std::unique_ptr<PowerStatsEnergyConsumer> createMeterAndEntityConsumer(
- std::shared_ptr<PowerStats> p, EnergyConsumerType type, std::string name,
- std::set<std::string> channelNames, std::string powerEntityName,
- std::map<std::string, int32_t> stateCoeffs);
-
- static std::unique_ptr<PowerStatsEnergyConsumer> createMeterAndAttrConsumer(
- std::shared_ptr<PowerStats> p, EnergyConsumerType type, std::string name,
- std::set<std::string> channelNames, std::unordered_map<int32_t, std::string> paths,
- std::map<std::string, int32_t> stateCoeffs);
-
- std::pair<EnergyConsumerType, std::string> getInfo() override { return {kType, kName}; }
-
- std::optional<EnergyConsumerResult> getEnergyConsumed() override;
-
- std::string getConsumerName() override;
-
- private:
- PowerStatsEnergyConsumer(std::shared_ptr<PowerStats> p, EnergyConsumerType type,
- std::string name, bool attr = false);
- bool addEnergyMeter(std::set<std::string> channelNames);
- bool addPowerEntity(std::string powerEntityName, std::map<std::string, int32_t> stateCoeffs);
- bool addAttribution(std::unordered_map<int32_t, std::string> paths,
- std::map<std::string, int32_t> stateCoeffs);
-
- const EnergyConsumerType kType;
- const std::string kName;
- std::shared_ptr<PowerStats> mPowerStats;
- std::vector<int32_t> mChannelIds;
- int32_t mPowerEntityId;
- bool mWithAttribution;
- std::unordered_map<int32_t, std::string> mAttrInfoPath;
- PowerStatsEnergyAttribution mEnergyAttribution;
- // Snapshot of each uid's energy, uid_time_in_state and total energy from power meter
- // mUidTimeInStateSS: key = uid, val = {uid_time_in_state}
- // mUidEnergySS: key = uid, val = {uid's energy(UWs)}
- // mTotalEnergySS: total energy from power meter
- std::unordered_map<int32_t, std::vector<long>> mUidTimeInStateSS;
- std::unordered_map<int32_t, int64_t> mUidEnergySS;
- int64_t mTotalEnergySS = 0;
- std::map<int32_t, int32_t> mCoefficients; // key = stateId, val = coefficients (mW)
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/dataproviders/WlanStateResidencyDataProvider.h b/powerstats/include/dataproviders/WlanStateResidencyDataProvider.h
deleted file mode 100644
index fe23963..0000000
--- a/powerstats/include/dataproviders/WlanStateResidencyDataProvider.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2020 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 <PowerStatsAidl.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class WlanStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
- public:
- WlanStateResidencyDataProvider(std::string name, std::string path)
- : mName(std::move(name)), mPath(std::move(path)) {}
- ~WlanStateResidencyDataProvider() = default;
-
- // Methods from PowerStats::IStateResidencyDataProvider
- bool getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
- std::unordered_map<std::string, std::vector<State>> getInfo() override;
-
- private:
- const std::string mName;
- const std::string mPath;
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/include/pixelpowerstats/DisplayStateResidencyDataProvider.h b/powerstats/include/pixelpowerstats/DisplayStateResidencyDataProvider.h
deleted file mode 100644
index 4a88dc3..0000000
--- a/powerstats/include/pixelpowerstats/DisplayStateResidencyDataProvider.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_POWERSTATS_DISPLAYSTATERESIDENCYDATAPROVIDER_H
-#define HARDWARE_GOOGLE_PIXEL_POWERSTATS_DISPLAYSTATERESIDENCYDATAPROVIDER_H
-// TODO(b/167628903): Delete this file
-#include <pixelpowerstats/PowerStats.h>
-#include <utils/Looper.h>
-#include <utils/Thread.h>
-#include <cstdio>
-#include <cstring>
-#include <mutex>
-#include <thread>
-#include <unordered_map>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-class DisplayStateResidencyDataProvider : public IStateResidencyDataProvider {
- public:
- // id = powerEntityId to be associated with this data provider
- // path = path to the display state file descriptor
- // state = list of states to be tracked
- DisplayStateResidencyDataProvider(uint32_t id, std::string path,
- std::vector<std::string> states);
- ~DisplayStateResidencyDataProvider();
- bool getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) override;
- std::vector<PowerEntityStateSpace> getStateSpaces() override;
-
- private:
- // Poll for display state changes
- void pollLoop();
- // Main function to update the stats when display state change is detected
- void updateStats();
-
- // File descriptor of display state
- int mFd;
- // Path to display state file descriptor
- const std::string mPath;
- // powerEntityId associated with this data provider
- const uint32_t mPowerEntityId;
- // List of states to track indexed by mCurState
- std::vector<std::string> mStates;
- // Lock to protect concurrent read/write to mResidencies and mCurState
- std::mutex mLock;
- // Accumulated display state stats indexed by mCurState
- std::vector<PowerEntityStateResidencyData> mResidencies;
- // Index of current state
- int mCurState;
- // Looper to facilitate polling of display state file desciptor
- sp<Looper> mLooper;
-
- std::thread mThread;
-};
-
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_POWERSTATS_DISPLAYSTATERESIDENCYDATAPROVIDER_H
diff --git a/powerstats/include/pixelpowerstats/GenericStateResidencyDataProvider.h b/powerstats/include/pixelpowerstats/GenericStateResidencyDataProvider.h
index 0b8fe32..2e11ea5 100644
--- a/powerstats/include/pixelpowerstats/GenericStateResidencyDataProvider.h
+++ b/powerstats/include/pixelpowerstats/GenericStateResidencyDataProvider.h
@@ -1,22 +1,6 @@
-/*
- * Copyright (C) 2020 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.
- */
-
#ifndef HARDWARE_GOOGLE_PIXEL_POWERSTATS_GENERICSTATERESIDENCYDATAPROVIDER_H
#define HARDWARE_GOOGLE_PIXEL_POWERSTATS_GENERICSTATERESIDENCYDATAPROVIDER_H
-// TODO(b/167628903): Delete this file
+
#include <pixelpowerstats/PowerStats.h>
namespace android {
@@ -48,19 +32,17 @@
PowerEntityConfig(const std::vector<StateResidencyConfig> &stateResidencyConfigs);
PowerEntityConfig(const std::string &header,
const std::vector<StateResidencyConfig> &stateResidencyConfigs);
- PowerEntityConfig(const uint32_t start_id, const std::string &header,
- const std::vector<StateResidencyConfig> &stateResidencyConfigs);
std::string mHeader;
std::vector<std::pair<uint32_t, StateResidencyConfig>> mStateResidencyConfigs;
};
class GenericStateResidencyDataProvider : public IStateResidencyDataProvider {
public:
- GenericStateResidencyDataProvider(std::string path) : mPath(std::move(path)) {}
+ GenericStateResidencyDataProvider(std::string path) : mPath(std::move(path)){};
~GenericStateResidencyDataProvider() = default;
void addEntity(uint32_t id, const PowerEntityConfig &config);
- bool getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) override;
+ bool getResults(std::unordered_map<uint32_t, PowerEntityStateResidencyResult>
+ &results) override;
std::vector<PowerEntityStateSpace> getStateSpaces() override;
private:
@@ -69,8 +51,8 @@
};
std::vector<StateResidencyConfig> generateGenericStateResidencyConfigs(
- const StateResidencyConfig &stateConfig,
- const std::vector<std::pair<std::string, std::string>> &stateHeaders);
+ const StateResidencyConfig &stateConfig,
+ const std::vector<std::pair<std::string, std::string>> &stateHeaders);
} // namespace powerstats
} // namespace pixel
@@ -78,4 +60,4 @@
} // namespace hardware
} // namespace android
-#endif // HARDWARE_GOOGLE_PIXEL_POWERSTATS_GENERICSTATERESIDENCYDATAPROVIDER_H
+#endif // HARDWARE_GOOGLE_PIXEL_POWERSTATS_GENERICSTATERESIDENCYDATAPROVIDER_H
\ No newline at end of file
diff --git a/powerstats/include/pixelpowerstats/WlanStateResidencyDataProvider.h b/powerstats/include/pixelpowerstats/WlanStateResidencyDataProvider.h
index 296ff73..988e0d0 100644
--- a/powerstats/include/pixelpowerstats/WlanStateResidencyDataProvider.h
+++ b/powerstats/include/pixelpowerstats/WlanStateResidencyDataProvider.h
@@ -1,6 +1,6 @@
#ifndef HARDWARE_GOOGLE_PIXEL_POWERSTATS_WLANSTATERESIDENCYDATAPROVIDER_H
#define HARDWARE_GOOGLE_PIXEL_POWERSTATS_WLANSTATERESIDENCYDATAPROVIDER_H
-// TODO(b/167628903): Delete this file
+
#include <pixelpowerstats/PowerStats.h>
#include <unordered_map>
diff --git a/pwrstats_util/Android.bp b/pwrstats_util/Android.bp
index 6703efe..ee9f824 100644
--- a/pwrstats_util/Android.bp
+++ b/pwrstats_util/Android.bp
@@ -12,12 +12,8 @@
// 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.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library_static {
- name: "libpwrstatsutil",
+ name: "libpowerstatsutil",
defaults: ["pwrstatsutil_defaults"],
export_include_dirs: ["."],
srcs: [
@@ -63,15 +59,12 @@
],
tidy_flags: [
"-warnings-as-errors="
- + "android-*"
- + ",clang-analyzer-security*"
- + ",cert-*"
- + ",google-*"
- + ",performance-*"
- + ",misc-*"
- + ",-cert-oop54-cpp" // in powerstats_util.pb.h
- + ",-bugprone-unhandled-self-assignment" // in powerstats_util.pb.h
- + ",-google-global-names-in-headers" // in PowerStatsCollector.h
+ + "'android-*'"
+ + ",'clang-analyzer-security*'"
+ + ",'cert-*'"
+ + ",'google-*'"
+ + ",'performance-*'"
+ + ",'misc-*'"
],
shared_libs: [
"libbase",
diff --git a/radio/Android.bp b/radio/Android.bp
deleted file mode 100644
index c0ac5e6..0000000
--- a/radio/Android.bp
+++ /dev/null
@@ -1,13 +0,0 @@
-// Define the soong config module for Pixel in this Android.bp
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-
-soong_config_module_type {
- name: "pixel_glog_cc_defaults",
- module_type: "cc_defaults",
- config_namespace: "glog",
- bool_variables: ["enable_glog"],
- properties: ["cflags", "shared_libs", "header_libs"],
-}
diff --git a/radio/gril_carrier_nv_headers/Android.bp b/radio/gril_carrier_nv_headers/Android.bp
deleted file mode 100644
index 845945a..0000000
--- a/radio/gril_carrier_nv_headers/Android.bp
+++ /dev/null
@@ -1,14 +0,0 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-cc_library_headers {
- name: "gril_carrier_nv_headers",
- sanitize:{
- integer_overflow: true,
- },
- vendor: true,
- export_include_dirs: [
- "inc/",
- ],
-}
diff --git a/radio/gril_carrier_nv_headers/inc/gril_carrier_nv.h b/radio/gril_carrier_nv_headers/inc/gril_carrier_nv.h
deleted file mode 100644
index 698d430..0000000
--- a/radio/gril_carrier_nv_headers/inc/gril_carrier_nv.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2020 Google Inc.
- *
- * 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.
- */
-
-#ifndef GRIL_CARRIER_NV_H
-#define GRIL_CARRIER_NV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- GRIL_CARRIER_OPEN_MARKET = 0x00,
- GRIL_CARRIER_VZW = 0x01,
- GRIL_CARRIER_SPRINT = 0x02,
- GRIL_CARRIER_ATT = 0x03,
- GRIL_CARRIER_VODAFONE = 0x04,
- GRIL_CARRIER_TMOBILE = 0x05,
- GRIL_CARRIER_TELUS_V01 = 0x06,
- GRIL_CARRIER_KDDI = 0x07,
- GRIL_CARRIER_GEN_UMTS_EU = 0x08,
- GRIL_CARRIER_GEN_UMTS_NA = 0x09,
- GRIL_CARRIER_GEN_C2K = 0x0A,
- GRIL_CARRIER_ORANGE = 0x0B,
- GRIL_CARRIER_TELEFONICA = 0x0C,
- GRIL_CARRIER_DOCOMO = 0x0D,
- GRIL_CARRIER_TEL_ITALIA = 0x0E,
- GRIL_CARRIER_TELSTRA = 0x0F,
- GRIL_CARRIER_LUCACELL = 0x10,
- GRIL_CARRIER_BELL_MOB = 0x11,
- GRIL_CARRIER_TELCOM_NZ = 0x12,
- GRIL_CARRIER_CHINA_TEL = 0x13,
- GRIL_CARRIER_C2K_OMH = 0x14,
- GRIL_CARRIER_CHINA_UNI = 0x15,
- GRIL_CARRIER_AMX = 0x16,
- GRIL_CARRIER_NORX = 0x17,
- GRIL_CARRIER_US_CELLULAR = 0x18,
- GRIL_CARRIER_WONE = 0x19,
- GRIL_CARRIER_AIRTEL = 0x1A,
- GRIL_CARRIER_RELIANCE = 0x1B,
- GRIL_CARRIER_SOFTBANK = 0x1C,
- GRIL_CARRIER_DT = 0x1F,
- GRIL_CARRIER_CMCC = 0x20,
- GRIL_CARRIER_VIVO = 0x21,
- GRIL_CARRIER_EE = 0x22,
- GRIL_CARRIER_CHERRY = 0x23,
- GRIL_CARRIER_IMOBILE = 0x24,
- GRIL_CARRIER_SMARTFREN = 0x25,
- GRIL_CARRIER_LGU = 0x26,
- GRIL_CARRIER_SKT = 0x27,
- GRIL_CARRIER_TTA = 0x28,
- GRIL_CARRIER_BEELINE = 0x29,
- GRIL_CARRIER_H3G = 0x2A,
- GRIL_CARRIER_TIM = 0x2B,
- GRIL_CARRIER_MOV = 0x2C,
- GRIL_CARRIER_YTL = 0x2D,
- GRIL_CARRIER_AIS = 0x2E,
- GRIL_CARRIER_TRUEMOVE = 0x2F,
- GRIL_CARRIER_DTAC = 0x30,
- GRIL_CARRIER_HKT = 0x31,
- GRIL_CARRIER_M1 = 0x32,
- GRIL_CARRIER_STARHUB = 0x33,
- GRIL_CARRIER_SINGTEL = 0x34,
- GRIL_CARRIER_CSL = 0x35,
- GRIL_CARRIER_3HK = 0x36,
- GRIL_CARRIER_SMARTONE = 0x37,
- GRIL_CARRIER_SFR = 0x38,
- GRIL_CARRIER_PI = 0x39,
- GRIL_CARRIER_RUSSIA = 0x3A,
- GRIL_CARRIER_BOUYGUES = 0x3B,
- GRIL_CARRIER_MEGAFON = 0x3C,
- GRIL_CARRIER_UMOBILE = 0x3D,
- GRIL_CARRIER_SUNRISE = 0x3E,
- GRIL_CARRIER_OPTUS_ELISA = 0x44,
- GRIL_CARRIER_BELL = 0x47,
- GRIL_CARRIER_TELUS = 0x49,
- GRIL_CARRIER_FREEDOM = 0x51,
- GRIL_CARRIER_KOODO = 0x52,
- GRIL_CARRIER_FIRSTNET = 0x53,
- GRIL_CARRIER_ATT_5G = 0x57,
- GRIL_CARRIER_CSPIRE = 0x59,
- GRIL_CARRIER_CBRS = 0x64,
- GRIL_CARRIER_PLUS_PL = 0xB0,
- GRIL_CARRIER_CRICKET_5G = 0xE2,
- GRIL_CARRIER_USCC_FI = 0xFB,
- GRIL_CARRIER_SPRINT_FI = 0xFC,
- GRIL_CARRIER_TMO_FI = 0xFD,
- GRIL_CARRIER_INVALID = 0xFFFFFFFF
-} gril_carrier_nv_enum;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/rebalance_interrupts/Android.bp b/rebalance_interrupts/Android.bp
deleted file mode 100644
index cb617d7..0000000
--- a/rebalance_interrupts/Android.bp
+++ /dev/null
@@ -1,12 +0,0 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-cc_binary {
- name: "rebalance_interrupts-vendor",
- init_rc: ["rebalance_interrupts-vendor.gs101.rc"],
- srcs: ["rebalance_interrupts.cpp"],
- shared_libs: ["libbase",
- "liblog",],
- proprietary: true,
-}
diff --git a/rebalance_interrupts/rebalance_interrupts-vendor.gs101.rc b/rebalance_interrupts/rebalance_interrupts-vendor.gs101.rc
deleted file mode 100644
index 31a9c04..0000000
--- a/rebalance_interrupts/rebalance_interrupts-vendor.gs101.rc
+++ /dev/null
@@ -1,12 +0,0 @@
-service vendor.rebalance_interrupts-vendor /vendor/bin/rebalance_interrupts-vendor
- disabled
- oneshot
- user root
- group system
-
-on early-boot
- start vendor.rebalance_interrupts-vendor
-
-on property:sys.boot_completed=1
- start vendor.rebalance_interrupts-vendor
-
diff --git a/rebalance_interrupts/rebalance_interrupts.cpp b/rebalance_interrupts/rebalance_interrupts.cpp
deleted file mode 100644
index 77a0bfb..0000000
--- a/rebalance_interrupts/rebalance_interrupts.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- *
- * rebalance-interrupts:
- *
- * One-shot distribution of unassigned* IRQs to CPU cores.
- * Useful for devices with the ARM-GIC-v3, as the Linux driver will take any
- * interrupt assigned with an all-cores mask and always have it run on core 0.
- *
- * This should be run once, long enough after boot that all drivers have
- * registered their interrupts.
- *
- * This program is configured to spread the load across all the cores in
- * CPUFREQ policy 0. This is because other cores may be hotplugged in
- * or out, and if hotplugged out the interrupts would be sent to core0 always.
- *
- * It might be wise to avoid core0 so that any later-added IRQs don't overcrowd
- * core 0.
- *
- * Any program that has an actual IRQ related performance constraint should
- * override any settings assigned by this and assign the IRQ to the same
- * core as the code whose performance is impacted by the IRQ.
- *
- */
-
-#include <sys/types.h>
-#include <dirent.h>
-
-#include <iostream>
-#include <list>
-#include <map>
-#include <vector>
-
-#define LOG_TAG "rebalance_interrupts"
-
-#include <android-base/file.h>
-#include <android-base/format.h>
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-
-
-#define POLICY0_CORES_PATH "/sys/devices/system/cpu/cpufreq/policy0/affected_cpus"
-#define SYSFS_IRQDIR "/sys/kernel/irq"
-#define PROC_IRQDIR "/proc/irq"
-
-using android::base::ParseInt;
-using android::base::ParseUint;
-using android::base::ReadFileToString;
-using android::base::Trim;
-using android::base::WriteStringToFile;
-using std::list;
-using std::map;
-using std::pair;
-using std::string;
-using std::vector;
-
-// Return a vector of strings describing the affected CPUs for cpufreq
-// Policy 0.
-vector<int> Policy0AffectedCpus() {
- string policy0_cores_unparsed;
- if (!ReadFileToString(POLICY0_CORES_PATH, &policy0_cores_unparsed))
- return vector<int>();
- string policy0_trimmed = android::base::Trim(policy0_cores_unparsed);
- vector<string> cpus_as_string = android::base::Split(policy0_trimmed, " ");
-
- vector<int> cpus_as_int;
- for (int i = 0; i < cpus_as_string.size(); ++i) {
- int cpu;
- if (!ParseInt(cpus_as_string[i].c_str(), &cpu))
- return vector<int>();
- cpus_as_int.push_back(cpu);
- }
- return cpus_as_int;
-}
-
-// Return a vector of strings describing the CPU masks for cpufreq Policy 0.
-vector<string> Policy0CpuMasks() {
- vector<int> cpus = Policy0AffectedCpus();
- vector<string> cpu_masks;
- for (int i = 0; i < cpus.size(); ++i)
- cpu_masks.push_back(fmt::format("{0:02x}", 1 << cpus[i]));
- return cpu_masks;
-}
-
-// Read the actions for the given irq# from sysfs, and add it to action_to_irq
-bool AddEntryToIrqmap(const char* irq,
- map<string, list<string>>& action_to_irqs) {
- const string irq_base(SYSFS_IRQDIR "/");
- string irq_actions_path = irq_base + irq + "/actions";
-
- string irq_actions;
- if (!ReadFileToString(irq_actions_path, &irq_actions))
- return false;
-
- irq_actions = Trim(irq_actions);
-
- if (irq_actions == "(null)")
- irq_actions = "";
-
- action_to_irqs[irq_actions].push_back(irq);
-
- return true;
-}
-
-// Get a mapping of driver "action" to IRQ#s for each IRQ# in
-// SYSFS_IRQDIR.
-bool GetIrqmap(map<string, list<string>>& action_to_irqs) {
- bool some_success = false;
- std::unique_ptr<DIR, decltype(&closedir)> irq_dir(opendir(SYSFS_IRQDIR), closedir);
- if (!irq_dir) {
- PLOG(ERROR) << "opening dir " SYSFS_IRQDIR;
- return false;
- }
-
- struct dirent* entry;
- while ((entry = readdir(irq_dir.get()))) {
-
- // If the directory entry isn't a parsable number, skip it.
- // . and .. get skipped here.
- unsigned throwaway;
- if (!ParseUint(entry->d_name, &throwaway))
- continue;
-
- some_success |= AddEntryToIrqmap(entry->d_name, action_to_irqs);
- }
- return some_success;
-}
-
-// Given a map of irq actions -> IRQs,
-// find out which ones haven't been assigned and add those to
-// rebalance_actions.
-void FindUnassignedIrqs(const map<string, list<string>>& action_to_irqs,
- list<pair<string, list<string>>>& rebalance_actions) {
- for (const auto &action_to_irqs_entry: action_to_irqs) {
- bool rebalance = true;
- for (const auto& irq: action_to_irqs_entry.second) {
- string smp_affinity;
- string proc_path(PROC_IRQDIR "/");
- proc_path += irq + "/smp_affinity";
- ReadFileToString(proc_path, &smp_affinity);
- smp_affinity = Trim(smp_affinity);
-
- // Try to respect previoulsy set IRQ affinities.
- // On ARM interrupt controllers under Linux, if an IRQ is assigned
- // to more than one core it will only be assigned to the lowest core.
- // Assume any IRQ which is set to more than one core in the lowest four
- // CPUs hasn't been assigned and needs to be rebalanced.
- if (smp_affinity.back() == '0' ||
- smp_affinity.back() == '1' ||
- smp_affinity.back() == '2' ||
- smp_affinity.back() == '4' ||
- smp_affinity.back() == '8') {
- rebalance = false;
- }
-
- // Treat each unnamed action IRQ as independent.
- if (action_to_irqs_entry.first.empty()) {
- if (rebalance) {
- pair<string, list<string>> empty_action_irq;
- empty_action_irq.first = "";
- empty_action_irq.second.push_back(irq);
- rebalance_actions.push_back(empty_action_irq);
- }
- rebalance = true;
- }
- }
- if (rebalance && !action_to_irqs_entry.first.empty()) {
- rebalance_actions.push_back(std::make_pair(action_to_irqs_entry.first,
- action_to_irqs_entry.second));
- }
- }
-}
-
-// Read the file at `path`, Trim whitespace, see if it matches `expected_value`.
-// Print the results to stdout.
-void ReportIfAffinityUpdated(const std::string expected_value,
- const std::string path) {
- std::string readback, report;
- ReadFileToString(path, &readback);
- readback = Trim(readback);
- if (readback != expected_value) {
- report += "Unable to set ";
- } else {
- report += "Success setting ";
- }
- report += path;
- report += ": found " + readback + " vs " + expected_value + "\n";
- LOG(DEBUG) << report;
-}
-
-// Evenly distribute the IRQ actions across all the Policy0 CPUs.
-// Assign all the IRQs of an action to a single CPU core.
-bool RebalanceIrqs(const list<pair<string, list<string>>>& action_to_irqs) {
- int mask_index = 0;
- std::vector<std::string> affinity_masks = Policy0CpuMasks();
-
- if (affinity_masks.empty()) {
- LOG(ERROR) << "Unable to find Policy0 CPUs for IRQ assignment.";
- return false;
- }
-
- for (const auto &action_to_irq: action_to_irqs) {
- for (const auto& irq: action_to_irq.second) {
- std::string affinity_path(PROC_IRQDIR "/");
- affinity_path += irq + "/smp_affinity";
- WriteStringToFile(affinity_masks[mask_index], affinity_path);
- ReportIfAffinityUpdated(affinity_masks[mask_index], affinity_path);
- }
- mask_index = (mask_index + 1) % affinity_masks.size();
- }
- return true;
-}
-
-void ChownIrqAffinity() {
- std::unique_ptr<DIR, decltype(&closedir)> irq_dir(opendir(PROC_IRQDIR), closedir);
- if (!irq_dir) {
- PLOG(ERROR) << "opening dir " PROC_IRQDIR;
- return;
- }
-
- struct dirent *entry;
- while ((entry = readdir(irq_dir.get()))) {
- // If the directory entry isn't a parsable number, skip it.
- // . and .. get skipped here.
- unsigned throwaway;
- if (!ParseUint(entry->d_name, &throwaway))
- continue;
-
- string affinity_path(PROC_IRQDIR "/");
- affinity_path += entry->d_name;
- affinity_path += "/smp_affinity";
- chown(affinity_path.c_str(), 1000, 1000);
-
- string affinity_list_path(PROC_IRQDIR "/");
- affinity_list_path += entry->d_name;
- affinity_list_path += "/smp_affinity_list";
- chown(affinity_list_path.c_str(), 1000, 1000);
- }
-}
-
-int main(int /* argc */, char* /* argv */[]) {
- map<string, list<string>> irq_mapping;
- list<pair<string, list<string>>> action_to_irqs;
-
- // Find the mapping of "irq actions" to IRQs.
- // Each IRQ has an assocatied irq_actions field, showing the actions
- // associated with it. Multiple IRQs have the same actions.
- // Generate the mapping of actions to IRQs with that action,
- // as these IRQs should all be mapped to the same cores.
- if (!GetIrqmap(irq_mapping)) {
- LOG(ERROR) << "Unable to read IRQ mappings. Are you root?";
- return 1;
- }
-
- // Change ownership of smp_affinity and smp_affinity_list handles
- // from root to system.
- ChownIrqAffinity();
-
- // Some IRQs are already assigned to a subset of cores, usually for
- // good reason (like some drivers have an IRQ per core, for per-core
- // queues.) Find the set of IRQs that haven't been mapped to specific
- // cores.
- FindUnassignedIrqs(irq_mapping, action_to_irqs);
-
- // Distribute the rebalancable IRQs across all cores.
- return RebalanceIrqs(action_to_irqs) ? 0 : 1;
-}
-
diff --git a/rebalance_interrupts/rebalance_interrupts.mk b/rebalance_interrupts/rebalance_interrupts.mk
deleted file mode 100644
index 541bd3b..0000000
--- a/rebalance_interrupts/rebalance_interrupts.mk
+++ /dev/null
@@ -1,2 +0,0 @@
-PRODUCT_PACKAGES += rebalance_interrupts-vendor
-BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/rebalance_interrupts
diff --git a/recovery/Android.bp b/recovery/Android.bp
index 4c7e0c7..d904e8e 100644
--- a/recovery/Android.bp
+++ b/recovery/Android.bp
@@ -1,7 +1,3 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library_static {
name: "librecovery_ui_pixel",
owner: "google",
diff --git a/recovery/recovery_ui.cpp b/recovery/recovery_ui.cpp
index 838d683..f404f93 100644
--- a/recovery/recovery_ui.cpp
+++ b/recovery/recovery_ui.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <dlfcn.h>
#include <stdint.h>
#include <string.h>
@@ -65,18 +64,6 @@
return true;
}
-/** Call device-specifc WipeKeys function, if any. */
-bool WipeKeysHook(::RecoveryUI *const ui) {
- bool *(*WipeKeysFunc)(::RecoveryUI *const);
- reinterpret_cast<void *&>(WipeKeysFunc) = dlsym(RTLD_DEFAULT, "WipeKeys");
- if (WipeKeysFunc == nullptr) {
- LOG(INFO) << "No WipeKeys implementation";
- return true;
- }
-
- return (*WipeKeysFunc)(ui);
-}
-
// Wipes the provisioned flag as part of data wipe.
bool WipeProvisionedFlag() {
// Must be consistent with the one in init.hardware.rc (10-byte `theme-dark`).
@@ -111,20 +98,11 @@
/** Hook to wipe user data not stored in /data */
bool PostWipeData() override {
// Try to do everything but report a failure if anything wasn't successful
- bool totalSuccess = false;
+ bool totalSuccess = true;
::RecoveryUI* const ui = GetUI();
ui->Print("Wiping Titan M...\n");
-
- uint32_t retries = 5;
- while (retries--) {
- if (WipeTitanM()) {
- totalSuccess = true;
- break;
- }
- }
-
- if (!WipeKeysHook(ui)) {
+ if (!WipeTitanM()) {
totalSuccess = false;
}
diff --git a/thermal/Android.bp b/thermal/Android.bp
index 76f4248..7875ea4 100644
--- a/thermal/Android.bp
+++ b/thermal/Android.bp
@@ -1,13 +1,3 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "hardware_google_pixel_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- // SPDX-license-identifier-BSD
- default_applicable_licenses: ["hardware_google_pixel_license"],
-}
-
cc_binary {
name: "android.hardware.thermal@2.0-service.pixel",
defaults: [
@@ -26,7 +16,6 @@
"utils/config_parser.cpp",
"utils/thermal_files.cpp",
"utils/thermal_watcher.cpp",
- "utils/power_files.cpp",
],
shared_libs: [
"libbase",
@@ -34,12 +23,8 @@
"libhidlbase",
"libjsoncpp",
"libutils",
- "libnl",
- "libbinder_ndk",
"android.hardware.thermal@1.0",
"android.hardware.thermal@2.0",
- "android.hardware.power-V1-ndk_platform",
- "pixel-power-ext-V1-ndk_platform"
],
cflags: [
"-Wall",
@@ -66,12 +51,3 @@
"pixel-thermal-logd.rc",
],
}
-
-sh_binary {
- name: "thermal_symlinks",
- src: "init.thermal.symlinks.sh",
- vendor: true,
- init_rc: [
- "pixel-thermal-symlinks.rc",
- ],
-}
diff --git a/thermal/Thermal.cpp b/thermal/Thermal.cpp
index c448b70..bd47f6e 100644
--- a/thermal/Thermal.cpp
+++ b/thermal/Thermal.cpp
@@ -36,6 +36,7 @@
using ::android::hardware::interfacesEqual;
using ::android::hardware::thermal::V1_0::ThermalStatus;
using ::android::hardware::thermal::V1_0::ThermalStatusCode;
+using ::android::hidl::base::V1_0::IBase;
template <typename T, typename U>
Return<void> setFailureAndCallback(T _hidl_cb, hidl_vec<U> data, std::string_view debug_msg) {
@@ -121,7 +122,7 @@
return setInitFailureAndCallback(_hidl_cb, temperatures);
}
- if (!thermal_helper_.fillCurrentTemperatures(filterType, false, type, &temperatures)) {
+ if (!thermal_helper_.fillCurrentTemperatures(filterType, type, &temperatures)) {
return setFailureAndCallback(_hidl_cb, temperatures, "Failed to read thermal sensors.");
}
@@ -171,8 +172,6 @@
bool filterType, TemperatureType_2_0 type,
registerThermalChangedCallback_cb _hidl_cb) {
ThermalStatus status;
- hidl_vec<Temperature_2_0> temperatures;
-
if (callback == nullptr) {
status.code = ThermalStatusCode::FAILURE;
status.debugMessage = "Invalid nullptr callback";
@@ -195,21 +194,6 @@
<< " Type: " << android::hardware::thermal::V2_0::toString(type);
}
_hidl_cb(status);
-
- // Send notification right away after thermal callback registration
- if (thermal_helper_.fillCurrentTemperatures(filterType, true, type, &temperatures)) {
- for (const auto &t : temperatures) {
- if (!filterType || t.type == type) {
- LOG(INFO) << "Sending notification: "
- << " Type: " << android::hardware::thermal::V2_0::toString(t.type)
- << " Name: " << t.name << " CurrentValue: " << t.value
- << " ThrottlingStatus: "
- << android::hardware::thermal::V2_0::toString(t.throttlingStatus);
- callback->notifyThrottling(t);
- }
- }
- }
-
return Void();
}
@@ -250,15 +234,14 @@
return Void();
}
-void Thermal::sendThermalChangedCallback(const Temperature_2_0 &t) {
+void Thermal::sendThermalChangedCallback(const std::vector<Temperature_2_0> &temps) {
std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
-
- LOG(VERBOSE) << "Sending notification: "
- << " Type: " << android::hardware::thermal::V2_0::toString(t.type)
- << " Name: " << t.name << " CurrentValue: " << t.value << " ThrottlingStatus: "
- << android::hardware::thermal::V2_0::toString(t.throttlingStatus);
-
- callbacks_.erase(
+ for (auto &t : temps) {
+ LOG(INFO) << "Sending notification: "
+ << " Type: " << android::hardware::thermal::V2_0::toString(t.type)
+ << " Name: " << t.name << " CurrentValue: " << t.value << " ThrottlingStatus: "
+ << android::hardware::thermal::V2_0::toString(t.throttlingStatus);
+ callbacks_.erase(
std::remove_if(callbacks_.begin(), callbacks_.end(),
[&](const CallbackSetting &c) {
if (!c.is_filter_type || t.type == c.type) {
@@ -270,276 +253,6 @@
return false;
}),
callbacks_.end());
-}
-
-void Thermal::dumpVirtualSensorInfo(std::ostringstream *dump_buf) {
- *dump_buf << "VirtualSensorInfo:" << std::endl;
- const auto &map = thermal_helper_.GetSensorInfoMap();
- for (const auto &sensor_info_pair : map) {
- if (sensor_info_pair.second.virtual_sensor_info != nullptr) {
- *dump_buf << " Name: " << sensor_info_pair.first << std::endl;
- *dump_buf << " LinkedSensorName: [";
- for (size_t i = 0;
- i < sensor_info_pair.second.virtual_sensor_info->linked_sensors.size(); i++) {
- *dump_buf << sensor_info_pair.second.virtual_sensor_info->linked_sensors[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " LinkedSensorCoefficient: [";
- for (size_t i = 0; i < sensor_info_pair.second.virtual_sensor_info->coefficients.size();
- i++) {
- *dump_buf << sensor_info_pair.second.virtual_sensor_info->coefficients[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " Offset: " << sensor_info_pair.second.virtual_sensor_info->offset
- << std::endl;
- *dump_buf << " Trigger Sensor: "
- << (sensor_info_pair.second.virtual_sensor_info->trigger_sensor.empty()
- ? "N/A"
- : sensor_info_pair.second.virtual_sensor_info->trigger_sensor)
- << std::endl;
- *dump_buf << " Formula: ";
- switch (sensor_info_pair.second.virtual_sensor_info->formula) {
- case FormulaOption::COUNT_THRESHOLD:
- *dump_buf << "COUNT_THRESHOLD";
- break;
- case FormulaOption::WEIGHTED_AVG:
- *dump_buf << "WEIGHTED_AVG";
- break;
- case FormulaOption::MAXIMUM:
- *dump_buf << "MAXIMUM";
- break;
- case FormulaOption::MINIMUM:
- *dump_buf << "MINIMUM";
- break;
- default:
- *dump_buf << "NONE";
- break;
- }
-
- *dump_buf << std::endl;
- }
- }
-}
-
-void Thermal::dumpThrottlingInfo(std::ostringstream *dump_buf) {
- *dump_buf << "Throttling Info:" << std::endl;
- const auto &map = thermal_helper_.GetSensorInfoMap();
- for (const auto &name_info_pair : map) {
- if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) {
- *dump_buf << " Name: " << name_info_pair.first << std::endl;
- *dump_buf << " PID Info:" << std::endl;
- *dump_buf << " K_po: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << name_info_pair.second.throttling_info->k_po[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " K_pu: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << name_info_pair.second.throttling_info->k_pu[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " K_i: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << name_info_pair.second.throttling_info->k_i[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " K_d: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << name_info_pair.second.throttling_info->k_d[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " i_max: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << name_info_pair.second.throttling_info->i_max[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " max_alloc_power: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << name_info_pair.second.throttling_info->max_alloc_power[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " min_alloc_power: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << name_info_pair.second.throttling_info->min_alloc_power[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " s_power: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << name_info_pair.second.throttling_info->s_power[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " i_cutoff: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << name_info_pair.second.throttling_info->i_cutoff[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " Binded CDEV Info:" << std::endl;
- if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) {
- for (const auto &binded_cdev_info_pair :
- name_info_pair.second.throttling_info->binded_cdev_info_map) {
- *dump_buf << " Cooling device name: " << binded_cdev_info_pair.first
- << std::endl;
- *dump_buf << " WeightForPID: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << binded_cdev_info_pair.second.cdev_weight_for_pid[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " Ceiling: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << binded_cdev_info_pair.second.cdev_ceiling[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " Floor with PowerLink: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << binded_cdev_info_pair.second.cdev_floor_with_power_link[i]
- << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " Hard limit: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << binded_cdev_info_pair.second.limit_info[i] << " ";
- }
- *dump_buf << "]" << std::endl;
-
- if (!binded_cdev_info_pair.second.power_rail.empty()) {
- *dump_buf << " Binded power rail: "
- << binded_cdev_info_pair.second.power_rail << std::endl;
- *dump_buf << " Power threshold: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- *dump_buf << binded_cdev_info_pair.second.power_thresholds[i] << " ";
- }
- *dump_buf << "]" << std::endl;
- *dump_buf << " Release logic: ";
- switch (binded_cdev_info_pair.second.release_logic) {
- case ReleaseLogic::INCREASE:
- *dump_buf << "INCREASE";
- break;
- case ReleaseLogic::DECREASE:
- *dump_buf << "DECREASE";
- break;
- case ReleaseLogic::STEPWISE:
- *dump_buf << "STEPWISE";
- break;
- case ReleaseLogic::RELEASE_TO_FLOOR:
- *dump_buf << "RELEASE_TO_FLOOR";
- break;
- default:
- *dump_buf << "NONE";
- break;
- }
- *dump_buf << std::endl;
- *dump_buf << " high_power_check: " << std::boolalpha
- << binded_cdev_info_pair.second.high_power_check << std::endl;
- *dump_buf << " throttling_with_power_link: " << std::boolalpha
- << binded_cdev_info_pair.second.throttling_with_power_link
- << std::endl;
- }
- }
- }
- }
- }
-}
-
-void Thermal::dumpThrottlingRequestStatus(std::ostringstream *dump_buf) {
- const auto &sensor_status_map = thermal_helper_.GetSensorStatusMap();
- const auto &cdev_status_map = thermal_helper_.GetCdevStatusMap();
- const auto &release_map = thermal_helper_.GetThrottlingReleaseMap();
- *dump_buf << "Throttling Request Status " << std::endl;
- for (const auto &cdev_status_pair : cdev_status_map) {
- *dump_buf << " Name: " << cdev_status_pair.first << std::endl;
- for (const auto &request_pair : cdev_status_pair.second) {
- *dump_buf << " Request Sensor: " << request_pair.first << std::endl;
- *dump_buf << " Request Throttling State: " << request_pair.second << std::endl;
- if (sensor_status_map.at(request_pair.first).pid_request_map.size() &&
- sensor_status_map.at(request_pair.first)
- .pid_request_map.count(cdev_status_pair.first)) {
- *dump_buf << " PID Request State: "
- << sensor_status_map.at(request_pair.first)
- .pid_request_map.at(cdev_status_pair.first)
- << std::endl;
- }
- if (sensor_status_map.at(request_pair.first).hard_limit_request_map.size() &&
- sensor_status_map.at(request_pair.first)
- .hard_limit_request_map.count(cdev_status_pair.first)) {
- *dump_buf << " Hard Limit Request State: "
- << sensor_status_map.at(request_pair.first)
- .hard_limit_request_map.at(cdev_status_pair.first)
- << std::endl;
- }
- if (release_map.count(request_pair.first) &&
- release_map.at(request_pair.first).count(cdev_status_pair.first)) {
- const auto &cdev_release_info =
- release_map.at(request_pair.first).at(cdev_status_pair.first);
- *dump_buf << " Release Step: " << cdev_release_info.release_step << std::endl;
- }
- }
- }
-}
-
-void Thermal::dumpPowerRailInfo(std::ostringstream *dump_buf) {
- const auto &power_rail_info_map = thermal_helper_.GetPowerRailInfoMap();
- const auto &power_status_map = thermal_helper_.GetPowerStatusMap();
-
- *dump_buf << "Power Rail Info " << std::endl;
- for (const auto &power_rail_pair : power_rail_info_map) {
- *dump_buf << " Power Rail: " << power_rail_pair.first << std::endl;
- *dump_buf << " Power Sample Count: " << power_rail_pair.second.power_sample_count
- << std::endl;
- *dump_buf << " Power Sample Delay: " << power_rail_pair.second.power_sample_delay.count()
- << std::endl;
- for (const auto &power_status_pair : power_status_map) {
- if (power_status_pair.second.count(power_rail_pair.first)) {
- auto power_history =
- power_status_pair.second.at(power_rail_pair.first).power_history;
- *dump_buf << " Request Sensor: " << power_status_pair.first << std::endl;
- *dump_buf
- << " Last Updated AVG Power: "
- << power_status_pair.second.at(power_rail_pair.first).last_updated_avg_power
- << " mW" << std::endl;
- if (power_rail_pair.second.virtual_power_rail_info != nullptr) {
- *dump_buf << " Formula=";
- switch (power_rail_pair.second.virtual_power_rail_info->formula) {
- case FormulaOption::COUNT_THRESHOLD:
- *dump_buf << "COUNT_THRESHOLD";
- break;
- case FormulaOption::WEIGHTED_AVG:
- *dump_buf << "WEIGHTED_AVG";
- break;
- case FormulaOption::MAXIMUM:
- *dump_buf << "MAXIMUM";
- break;
- case FormulaOption::MINIMUM:
- *dump_buf << "MINIMUM";
- break;
- default:
- *dump_buf << "NONE";
- break;
- }
- *dump_buf << std::endl;
- }
- for (size_t i = 0; i < power_history.size(); ++i) {
- if (power_rail_pair.second.virtual_power_rail_info != nullptr) {
- *dump_buf << " Linked power rail "
- << power_rail_pair.second.virtual_power_rail_info
- ->linked_power_rails[i]
- << std::endl;
- *dump_buf << " Coefficient="
- << power_rail_pair.second.virtual_power_rail_info->coefficients[i]
- << std::endl;
- *dump_buf << " Power Samples: ";
- } else {
- *dump_buf << " Power Samples: ";
- }
- while (power_history[i].size() > 0) {
- const auto power_sample = power_history[i].front();
- power_history[i].pop();
- *dump_buf << "(T=" << power_sample.duration
- << ", uWs=" << power_sample.energy_counter << ") ";
- }
- *dump_buf << std::endl;
- }
- }
- }
}
}
@@ -582,8 +295,8 @@
{
dump_buf << "getCurrentTemperatures:" << std::endl;
hidl_vec<Temperature_2_0> temperatures;
- if (!thermal_helper_.fillCurrentTemperatures(
- false, false, TemperatureType_2_0::SKIN, &temperatures)) {
+ if (!thermal_helper_.fillCurrentTemperatures(false, TemperatureType_2_0::SKIN,
+ &temperatures)) {
dump_buf << "Failed to getCurrentTemperatures." << std::endl;
}
@@ -656,38 +369,13 @@
}
}
{
- dump_buf << "SendCallback" << std::endl;
- dump_buf << " Enabled List: ";
+ dump_buf << "Monitor:" << std::endl;
const auto &map = thermal_helper_.GetSensorInfoMap();
for (const auto &name_info_pair : map) {
- if (name_info_pair.second.send_cb) {
- dump_buf << name_info_pair.first << " ";
- }
+ dump_buf << " Name: " << name_info_pair.first;
+ dump_buf << " Monitor: " << std::boolalpha << name_info_pair.second.is_monitor
+ << std::noboolalpha << std::endl;
}
- dump_buf << std::endl;
- }
- {
- dump_buf << "SendPowerHint" << std::endl;
- dump_buf << " Enabled List: ";
- const auto &map = thermal_helper_.GetSensorInfoMap();
- for (const auto &name_info_pair : map) {
- if (name_info_pair.second.send_powerhint) {
- dump_buf << name_info_pair.first << " ";
- }
- }
- dump_buf << std::endl;
- }
- dumpVirtualSensorInfo(&dump_buf);
- dumpThrottlingInfo(&dump_buf);
- dumpThrottlingRequestStatus(&dump_buf);
- dumpPowerRailInfo(&dump_buf);
- {
- dump_buf << "AIDL Power Hal exist: " << std::boolalpha
- << thermal_helper_.isAidlPowerHalExist() << std::endl;
- dump_buf << "AIDL Power Hal connected: " << std::boolalpha
- << thermal_helper_.isPowerHalConnected() << std::endl;
- dump_buf << "AIDL Power Hal Ext connected: " << std::boolalpha
- << thermal_helper_.isPowerHalExtConnected() << std::endl;
}
}
std::string buf = dump_buf.str();
diff --git a/thermal/Thermal.h b/thermal/Thermal.h
index d33e77d..317936f 100644
--- a/thermal/Thermal.h
+++ b/thermal/Thermal.h
@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#pragma once
+#ifndef ANDROID_HARDWARE_THERMAL_V2_0_CROSSHATCH_THERMAL_H
+#define ANDROID_HARDWARE_THERMAL_V2_0_CROSSHATCH_THERMAL_H
#include <mutex>
#include <thread>
@@ -40,7 +40,7 @@
struct CallbackSetting {
CallbackSetting(sp<IThermalChangedCallback> callback, bool is_filter_type,
TemperatureType_2_0 type)
- : callback(std::move(callback)), is_filter_type(is_filter_type), type(type) {}
+ : callback(callback), is_filter_type(is_filter_type), type(type) {}
sp<IThermalChangedCallback> callback;
bool is_filter_type;
TemperatureType_2_0 type;
@@ -65,9 +65,9 @@
getCurrentTemperatures_cb _hidl_cb) override;
Return<void> getTemperatureThresholds(bool filterType, TemperatureType_2_0 type,
getTemperatureThresholds_cb _hidl_cb) override;
- Return<void> registerThermalChangedCallback(
- const sp<IThermalChangedCallback> &callback, bool filterType, TemperatureType_2_0 type,
- registerThermalChangedCallback_cb _hidl_cb) override;
+ Return<void> registerThermalChangedCallback(const sp<IThermalChangedCallback> &callback,
+ bool filterType, TemperatureType_2_0 type,
+ registerThermalChangedCallback_cb _hidl_cb) override;
Return<void> unregisterThermalChangedCallback(
const sp<IThermalChangedCallback> &callback,
unregisterThermalChangedCallback_cb _hidl_cb) override;
@@ -78,14 +78,10 @@
Return<void> debug(const hidl_handle &fd, const hidl_vec<hidl_string> &args) override;
// Helper function for calling callbacks
- void sendThermalChangedCallback(const Temperature_2_0 &t);
+ void sendThermalChangedCallback(const std::vector<Temperature_2_0> &temps);
private:
ThermalHelper thermal_helper_;
- void dumpVirtualSensorInfo(std::ostringstream *dump_buf);
- void dumpThrottlingInfo(std::ostringstream *dump_buf);
- void dumpThrottlingRequestStatus(std::ostringstream *dump_buf);
- void dumpPowerRailInfo(std::ostringstream *dump_buf);
std::mutex thermal_callback_mutex_;
std::vector<CallbackSetting> callbacks_;
};
@@ -95,3 +91,5 @@
} // namespace thermal
} // namespace hardware
} // namespace android
+
+#endif // ANDROID_HARDWARE_THERMAL_V2_0_CROSSHATCH_THERMAL_H
diff --git a/thermal/android.hardware.thermal@2.0-service.pixel.rc b/thermal/android.hardware.thermal@2.0-service.pixel.rc
index 0e23bef..fd2735b 100644
--- a/thermal/android.hardware.thermal@2.0-service.pixel.rc
+++ b/thermal/android.hardware.thermal@2.0-service.pixel.rc
@@ -1,16 +1,6 @@
-on property:vendor.thermal.link_ready=1
- # queue the trigger to start thermal-hal and continue execute
- # per-device thermal setup "on property:vendor.thermal.link_ready=1"
- trigger enable-thermal-hal
-
-on enable-thermal-hal
- start vendor.thermal-hal-2-0
-
service vendor.thermal-hal-2-0 /vendor/bin/hw/android.hardware.thermal@2.0-service.pixel
interface android.hardware.thermal@1.0::IThermal default
interface android.hardware.thermal@2.0::IThermal default
class hal
user system
group system
- priority -20
- disabled
diff --git a/thermal/device.mk b/thermal/device.mk
index d316633..a2d68a3 100644
--- a/thermal/device.mk
+++ b/thermal/device.mk
@@ -1,7 +1,6 @@
# Thermal HAL
PRODUCT_PACKAGES += \
android.hardware.thermal@2.0-service.pixel \
- thermal_symlinks
ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
PRODUCT_PACKAGES += \
diff --git a/thermal/init.thermal.symlinks.sh b/thermal/init.thermal.symlinks.sh
deleted file mode 100755
index d990897..0000000
--- a/thermal/init.thermal.symlinks.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/vendor/bin/sh
-
-for f in /sys/class/thermal/thermal_zone*
-do
- tz_name=`cat $f/type`
- ln -s $f /dev/thermal/tz-by-name/$tz_name
-done
-for f in /sys/class/thermal/cooling_device*
-do
- cdev_name=`cat $f/type`
- ln -s $f /dev/thermal/cdev-by-name/$cdev_name
-done
-setprop vendor.thermal.link_ready 1
diff --git a/thermal/pixel-thermal-logd.rc b/thermal/pixel-thermal-logd.rc
index 1362c73..c69282d 100644
--- a/thermal/pixel-thermal-logd.rc
+++ b/thermal/pixel-thermal-logd.rc
@@ -12,125 +12,3 @@
user root
group root system
disabled
-
-# Switch thermal protection for Pixels
-on property:persist.vendor.disable.thermal.control=*
- setprop vendor.disable.thermal.control ${persist.vendor.disable.thermal.control}
-
-on property:persist.vendor.disable.usb.overheat.mitigation=*
- setprop vendor.disable.usb.overheat.mitigation.control ${persist.vendor.disable.usb.overheat.mitigation}
-
-on property:persist.vendor.disable.thermal.tj.control=*
- setprop vendor.disable.thermal.tj.control ${persist.vendor.disable.thermal.tj.control}
-
-on property:persist.vendor.disable.bcl.control=*
- setprop vendor.disable.bcl.control ${persist.vendor.disable.bcl.control}
-
-on property:vendor.disable.thermal.control=1 && property:vendor.thermal.link_ready=1
- # common
- stop vendor.thermal-engine
- restart vendor.thermal-hal-2-0
- # sdm845
- write /dev/thermal/tz-by-name/quiet-therm-adc/mode disabled
- write /dev/thermal/tz-by-name/quiet-therm-monitor/mode disabled
- write /dev/thermal/tz-by-name/fps-therm-adc/mode disabled
- write /dev/thermal/tz-by-name/fps-therm-monitor/mode disabled
- # sdm670
- write /dev/thermal/tz-by-name/mb-therm-adc/mode disabled
- write /dev/thermal/tz-by-name/mb-therm-monitor/mode disabled
- # sm8150
- write /dev/thermal/tz-by-name/sdm-therm/mode disabled
- write /dev/thermal/tz-by-name/sdm-therm-monitor/mode disabled
- # sm7150
- write /dev/thermal/tz-by-name/skin-therm-adc/mode disabled
- write /dev/thermal/tz-by-name/skin-therm-monitor/mode disabled
- # sm7250
- write /dev/thermal/tz-by-name/skin-therm/emul_temp 25000
- write /dev/thermal/tz-by-name/skin-therm/mode disabled
- write /dev/thermal/tz-by-name/skin-therm-cpu/emul_temp 25000
- write /dev/thermal/tz-by-name/skin-therm-cpu/mode disabled
- write /dev/thermal/tz-by-name/skin-therm-monitor/emul_temp 25000
- write /dev/thermal/tz-by-name/skin-therm-monitor/mode disabled
- write /dev/thermal/tz-by-name/panel-audio-therm/emul_temp 25000
- write /dev/thermal/tz-by-name/panel-audio-therm/mode disabled
- write /dev/thermal/tz-by-name/cellular-emergency/emul_temp 25000
- write /dev/thermal/tz-by-name/cellular-emergency/mode disabled
- write /dev/thermal/tz-by-name/sdm-therm/emul_temp 25000
- write /dev/thermal/tz-by-name/sdm-therm/mode disabled
- write /dev/thermal/tz-by-name/charger-therm/emul_temp 25000
- write /dev/thermal/tz-by-name/charger-therm/mode disabled
- # P21
- write /dev/thermal/tz-by-name/disp_therm/mode disabled
-
-on property:vendor.disable.thermal.control=0 && property:vendor.thermal.link_ready=1
- # common
- start vendor.thermal-engine
- restart vendor.thermal-hal-2-0
- # sdm845
- write /dev/thermal/tz-by-name/quiet-therm-adc/mode enabled
- write /dev/thermal/tz-by-name/quiet-therm-monitor/mode enabled
- write /dev/thermal/tz-by-name/fps-therm-adc/mode enabled
- write /dev/thermal/tz-by-name/fps-therm-monitor/mode enabled
- # sdm670
- write /dev/thermal/tz-by-name/mb-therm-adc/mode enabled
- write /dev/thermal/tz-by-name/mb-therm-monitor/mode enabled
- # sm8150
- write /dev/thermal/tz-by-name/sdm-therm/mode enabled
- write /dev/thermal/tz-by-name/sdm-therm-monitor/mode enabled
- # sm7150
- write /dev/thermal/tz-by-name/skin-therm-adc/mode enabled
- write /dev/thermal/tz-by-name/skin-therm-monitor/mode enabled
- # sm7250
- write /dev/thermal/tz-by-name/skin-therm/emul_temp 0
- write /dev/thermal/tz-by-name/skin-therm/mode enabled
- write /dev/thermal/tz-by-name/skin-therm-cpu/emul_temp 0
- write /dev/thermal/tz-by-name/skin-therm-cpu/mode enabled
- write /dev/thermal/tz-by-name/skin-therm-monitor/emul_temp 0
- write /dev/thermal/tz-by-name/skin-therm-monitor/mode enabled
- write /dev/thermal/tz-by-name/panel-audio-therm/emul_temp 0
- write /dev/thermal/tz-by-name/panel-audio-therm/mode enabled
- write /dev/thermal/tz-by-name/cellular-emergency/emul_temp 0
- write /dev/thermal/tz-by-name/cellular-emergency/mode enabled
- write /dev/thermal/tz-by-name/sdm-therm/emul_temp 0
- write /dev/thermal/tz-by-name/sdm-therm/mode enabled
- write /dev/thermal/tz-by-name/charger-therm/emul_temp 0
- write /dev/thermal/tz-by-name/charger-therm/mode enabled
- # P21
- write /dev/thermal/tz-by-name/disp_therm/mode enabled
-
-# Switch Tj thermal protection
-on property:vendor.disable.thermal.tj.control=1
- # P21
- write /dev/thermal/tz-by-name/BIG/mode disabled
- write /dev/thermal/tz-by-name/MID/mode disabled
- write /dev/thermal/tz-by-name/LITTLE/mode disabled
- write /dev/thermal/tz-by-name/G3D/mode disabled
- write /dev/thermal/tz-by-name/ISP/mode disabled
- write /dev/thermal/tz-by-name/TPU/mode disabled
- write /sys/kernel/debug/gs101-thermal/emul_call 1
-
-on property:vendor.disable.thermal.tj.control=0
- # P21
- write /dev/thermal/tz-by-name/BIG/mode enabled
- write /dev/thermal/tz-by-name/MID/mode enabled
- write /dev/thermal/tz-by-name/LITTLE/mode enabled
- write /dev/thermal/tz-by-name/G3D/mode enabled
- write /dev/thermal/tz-by-name/ISP/mode enabled
- write /dev/thermal/tz-by-name/TPU/mode enabled
- write /sys/kernel/debug/gs101-thermal/emul_call 0
-
-# Toggle BCL control
-on property:vendor.disable.bcl.control=1
- write /dev/thermal/tz-by-name/soc/mode disabled
-
-on property:vendor.disable.bcl.control=0
- write /dev/thermal/tz-by-name/soc/mode enabled
-
-# Switch USB port overheat protection
-on property:vendor.disable.usb.overheat.mitigation.control=1
- write /sys/module/overheat_mitigation/parameters/enable 0
- write /dev/thermal/tz-by-name/usb_pwr_therm2/emul_temp 25000
-
-on property:vendor.disable.usb.overheat.mitigation.control=0
- write /sys/module/overheat_mitigation/parameters/enable 1
- write /dev/thermal/tz-by-name/usb_pwr_therm2/emul_temp 0
diff --git a/thermal/pixel-thermal-symlinks.rc b/thermal/pixel-thermal-symlinks.rc
deleted file mode 100644
index a1f6509..0000000
--- a/thermal/pixel-thermal-symlinks.rc
+++ /dev/null
@@ -1,11 +0,0 @@
-on early-boot
- mkdir /dev/thermal 0750 system system
- mkdir /dev/thermal/tz-by-name 0750 system system
- mkdir /dev/thermal/cdev-by-name 0750 system system
- start vendor.thermal.symlinks
-
-service vendor.thermal.symlinks /vendor/bin/thermal_symlinks
- class hal
- user system
- group system
- oneshot
diff --git a/thermal/service.cpp b/thermal/service.cpp
index 895437e..190269b 100644
--- a/thermal/service.cpp
+++ b/thermal/service.cpp
@@ -17,8 +17,6 @@
#include <hidl/HidlTransportSupport.h>
#include "Thermal.h"
-constexpr std::string_view kThermalLogTag("pixel-thermal");
-
using ::android::OK;
using ::android::status_t;
@@ -36,7 +34,6 @@
}
int main(int /* argc */, char ** /* argv */) {
- android::base::SetDefaultTag(kThermalLogTag.data());
status_t status;
android::sp<IThermal> service = nullptr;
diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp
index 6eb0d50..725578d 100644
--- a/thermal/thermal-helper.cpp
+++ b/thermal/thermal-helper.cpp
@@ -25,7 +25,6 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
-#include <android/binder_manager.h>
#include <hidl/HidlTransportSupport.h>
#include "thermal-helper.h"
@@ -50,16 +49,11 @@
constexpr std::string_view kSensorTripPointHystZeroFile("trip_point_0_hyst");
constexpr std::string_view kUserSpaceSuffix("user_space");
constexpr std::string_view kCoolingDeviceCurStateSuffix("cur_state");
-constexpr std::string_view kCoolingDeviceMaxStateSuffix("max_state");
-constexpr std::string_view kCoolingDeviceState2powerSuffix("state2power_table");
constexpr std::string_view kConfigProperty("vendor.thermal.config");
constexpr std::string_view kConfigDefaultFileName("thermal_info_config.json");
-constexpr std::string_view kThermalGenlProperty("persist.vendor.enable.thermal.genl");
-constexpr std::string_view kThermalDisabledProperty("vendor.disable.thermal.control");
namespace {
using android::base::StringPrintf;
-using android::hardware::thermal::V2_0::toString;
/*
* Pixel don't offline CPU, so std::thread::hardware_concurrency(); should work.
@@ -70,7 +64,7 @@
* For Android systems this approach is safer than using cpufeatures, see bug
* b/36941727.
*/
-static int getNumberOfCores() {
+std::size_t getNumberOfCores() {
std::string file;
if (!android::base::ReadFileToString(kCpuPresentFile.data(), &file)) {
LOG(ERROR) << "Error reading Cpu present file: " << kCpuPresentFile;
@@ -89,29 +83,31 @@
}
return static_cast<std::size_t>(max_core - min_core + 1);
}
-const int kMaxCpus = getNumberOfCores();
+const std::size_t kMaxCpus = getNumberOfCores();
void parseCpuUsagesFileAndAssignUsages(hidl_vec<CpuUsage> *cpu_usages) {
+ uint64_t cpu_num, user, nice, system, idle;
+ std::string cpu_name;
std::string data;
if (!android::base::ReadFileToString(kCpuUsageFile.data(), &data)) {
- LOG(ERROR) << "Error reading cpu usage file: " << kCpuUsageFile;
+ LOG(ERROR) << "Error reading Cpu usage file: " << kCpuUsageFile;
return;
}
std::istringstream stat_data(data);
std::string line;
while (std::getline(stat_data, line)) {
- if (!line.find("cpu") && isdigit(line[3])) {
+ if (line.find("cpu") == 0 && isdigit(line[3])) {
// Split the string using spaces.
std::vector<std::string> words = android::base::Split(line, " ");
- std::string cpu_name = words[0];
- int cpu_num = std::stoi(cpu_name.substr(3));
+ cpu_name = words[0];
+ cpu_num = std::stoi(cpu_name.substr(3));
if (cpu_num < kMaxCpus) {
- uint64_t user = std::stoull(words[1]);
- uint64_t nice = std::stoull(words[2]);
- uint64_t system = std::stoull(words[3]);
- uint64_t idle = std::stoull(words[4]);
+ user = std::stoi(words[1]);
+ nice = std::stoi(words[2]);
+ system = std::stoi(words[3]);
+ idle = std::stoi(words[4]);
// Check if the CPU is online by reading the online file.
std::string cpu_online_path =
@@ -120,14 +116,11 @@
std::string is_online;
if (!android::base::ReadFileToString(cpu_online_path, &is_online)) {
LOG(ERROR) << "Could not open Cpu online file: " << cpu_online_path;
- if (cpu_num != 0) {
- return;
- }
- // Some architecture cannot offline cpu0, so assuming it is online
- is_online = "1";
+ return;
}
is_online = android::base::Trim(is_online);
+ (*cpu_usages)[cpu_num].name = cpu_name;
(*cpu_usages)[cpu_num].active = user + nice + system;
(*cpu_usages)[cpu_num].total = user + nice + system + idle;
(*cpu_usages)[cpu_num].isOnline = (is_online == "1") ? true : false;
@@ -139,8 +132,8 @@
}
}
-std::unordered_map<std::string, std::string> parseThermalPathMap(std::string_view prefix) {
- std::unordered_map<std::string, std::string> path_map;
+std::map<std::string, std::string> parseThermalPathMap(std::string_view prefix) {
+ std::map<std::string, std::string> path_map;
std::unique_ptr<DIR, int (*)(DIR *)> dir(opendir(kThermalSensorsRoot.data()), closedir);
if (!dir) {
return path_map;
@@ -174,91 +167,6 @@
}
} // namespace
-PowerHalService::PowerHalService()
- : power_hal_aidl_exist_(true), power_hal_aidl_(nullptr), power_hal_ext_aidl_(nullptr) {
- connect();
-}
-
-bool PowerHalService::connect() {
- std::lock_guard<std::mutex> lock(lock_);
- if (!power_hal_aidl_exist_)
- return false;
-
- if (power_hal_aidl_ != nullptr)
- return true;
-
- const std::string kInstance = std::string(IPower::descriptor) + "/default";
- ndk::SpAIBinder power_binder = ndk::SpAIBinder(AServiceManager_getService(kInstance.c_str()));
- ndk::SpAIBinder ext_power_binder;
-
- if (power_binder.get() == nullptr) {
- LOG(ERROR) << "Cannot get Power Hal Binder";
- power_hal_aidl_exist_ = false;
- return false;
- }
-
- power_hal_aidl_ = IPower::fromBinder(power_binder);
-
- if (power_hal_aidl_ == nullptr) {
- power_hal_aidl_exist_ = false;
- LOG(ERROR) << "Cannot get Power Hal AIDL" << kInstance.c_str();
- return false;
- }
-
- if (STATUS_OK != AIBinder_getExtension(power_binder.get(), ext_power_binder.getR()) ||
- ext_power_binder.get() == nullptr) {
- LOG(ERROR) << "Cannot get Power Hal Extension Binder";
- power_hal_aidl_exist_ = false;
- return false;
- }
-
- power_hal_ext_aidl_ = IPowerExt::fromBinder(ext_power_binder);
- if (power_hal_ext_aidl_ == nullptr) {
- LOG(ERROR) << "Cannot get Power Hal Extension AIDL";
- power_hal_aidl_exist_ = false;
- }
-
- return true;
-}
-
-bool PowerHalService::isModeSupported(const std::string &type, const ThrottlingSeverity &t) {
- bool isSupported = false;
- if (!isPowerHalConnected()) {
- return false;
- }
- std::string power_hint = StringPrintf("THERMAL_%s_%s", type.c_str(), toString(t).c_str());
- lock_.lock();
- if (!power_hal_ext_aidl_->isModeSupported(power_hint, &isSupported).isOk()) {
- LOG(ERROR) << "Fail to check supported mode, Hint: " << power_hint;
- power_hal_aidl_exist_ = false;
- power_hal_ext_aidl_ = nullptr;
- power_hal_aidl_ = nullptr;
- lock_.unlock();
- return false;
- }
- lock_.unlock();
- return isSupported;
-}
-
-void PowerHalService::setMode(const std::string &type, const ThrottlingSeverity &t,
- const bool &enable) {
- if (!isPowerHalConnected()) {
- return;
- }
-
- std::string power_hint = StringPrintf("THERMAL_%s_%s", type.c_str(), toString(t).c_str());
- LOG(INFO) << "Send Hint " << power_hint << " Enable: " << std::boolalpha << enable;
- lock_.lock();
- if (!power_hal_ext_aidl_->setMode(power_hint, enable).isOk()) {
- LOG(ERROR) << "Fail to set mode, Hint: " << power_hint;
- power_hal_aidl_exist_ = false;
- power_hal_ext_aidl_ = nullptr;
- power_hal_aidl_ = nullptr;
- lock_.unlock();
- return;
- }
- lock_.unlock();
-}
/*
* Populate the sensor_name_to_file_map_ map by walking through the file tree,
@@ -268,13 +176,21 @@
ThermalHelper::ThermalHelper(const NotificationCallback &cb)
: thermal_watcher_(new ThermalWatcher(
std::bind(&ThermalHelper::thermalWatcherCallbackFunc, this, std::placeholders::_1))),
- cb_(cb) {
- const std::string config_path =
- "/vendor/etc/" +
- android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data());
- cooling_device_info_map_ = ParseCoolingDevice(config_path);
- sensor_info_map_ = ParseSensorInfo(config_path);
- power_rail_info_map_ = ParsePowerRailInfo(config_path);
+ cb_(cb),
+ cooling_device_info_map_(ParseCoolingDevice(
+ "/vendor/etc/" +
+ android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data()))),
+ sensor_info_map_(ParseSensorInfo(
+ "/vendor/etc/" +
+ android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data()))) {
+ for (auto const &name_status_pair : sensor_info_map_) {
+ sensor_status_map_[name_status_pair.first] = {
+ .severity = ThrottlingSeverity::NONE,
+ .prev_hot_severity = ThrottlingSeverity::NONE,
+ .prev_cold_severity = ThrottlingSeverity::NONE,
+ };
+ }
+
auto tz_map = parseThermalPathMap(kSensorPrefix.data());
auto cdev_map = parseThermalPathMap(kCoolingDevicePrefix.data());
@@ -282,143 +198,23 @@
if (!is_initialized_) {
LOG(FATAL) << "ThermalHAL could not be initialized properly.";
}
-
- for (auto const &name_status_pair : sensor_info_map_) {
- sensor_status_map_[name_status_pair.first] = {
- .severity = ThrottlingSeverity::NONE,
- .prev_hot_severity = ThrottlingSeverity::NONE,
- .prev_cold_severity = ThrottlingSeverity::NONE,
- .prev_hint_severity = ThrottlingSeverity::NONE,
- .last_update_time = boot_clock::time_point::min(),
- .err_integral = 0.0,
- .prev_err = NAN,
- };
-
- bool invalid_binded_cdev = false;
- for (auto &binded_cdev_pair :
- name_status_pair.second.throttling_info->binded_cdev_info_map) {
- if (!cooling_device_info_map_.count(binded_cdev_pair.first)) {
- invalid_binded_cdev = true;
- LOG(ERROR) << "Could not find " << binded_cdev_pair.first
- << " in cooling device info map";
- }
-
- for (const auto &cdev_weight : binded_cdev_pair.second.cdev_weight_for_pid) {
- if (!std::isnan(cdev_weight)) {
- sensor_status_map_[name_status_pair.first]
- .pid_request_map[binded_cdev_pair.first] = 0;
- cdev_status_map_[binded_cdev_pair.first][name_status_pair.first] = 0;
- break;
- }
- }
-
- for (const auto &limit_info : binded_cdev_pair.second.limit_info) {
- if (limit_info > 0) {
- sensor_status_map_[name_status_pair.first]
- .hard_limit_request_map[binded_cdev_pair.first] = 0;
- cdev_status_map_[binded_cdev_pair.first][name_status_pair.first] = 0;
- }
- }
- const auto &cdev_info = cooling_device_info_map_.at(binded_cdev_pair.first);
-
- for (auto &cdev_ceiling : binded_cdev_pair.second.cdev_ceiling) {
- if (cdev_ceiling > cdev_info.max_state) {
- if (cdev_ceiling != std::numeric_limits<int>::max()) {
- LOG(ERROR) << "Sensor " << name_status_pair.first << "'s "
- << binded_cdev_pair.first << " cdev_ceiling:" << cdev_ceiling
- << " is higher than max state:" << cdev_info.max_state;
- }
- cdev_ceiling = cdev_info.max_state;
- }
- }
-
- if (power_rail_info_map_.count(binded_cdev_pair.second.power_rail) &&
- power_rail_info_map_.at(binded_cdev_pair.second.power_rail).power_sample_count &&
- power_files_.findEnergySourceToWatch()) {
- const auto &power_rail_info =
- power_rail_info_map_.at(binded_cdev_pair.second.power_rail);
- if (!power_files_.registerPowerRailsToWatch(
- name_status_pair.first, binded_cdev_pair.first, binded_cdev_pair.second,
- cdev_info, power_rail_info)) {
- invalid_binded_cdev = true;
- LOG(ERROR) << "Could not find " << binded_cdev_pair.first
- << "'s power energy source: " << binded_cdev_pair.second.power_rail;
- }
- }
- }
-
- if (invalid_binded_cdev) {
- name_status_pair.second.throttling_info->binded_cdev_info_map.clear();
- sensor_status_map_[name_status_pair.first].hard_limit_request_map.clear();
- sensor_status_map_[name_status_pair.first].pid_request_map.clear();
- }
-
- if (name_status_pair.second.virtual_sensor_info != nullptr &&
- name_status_pair.second.is_monitor) {
- if (sensor_info_map_.count(
- name_status_pair.second.virtual_sensor_info->trigger_sensor)) {
- sensor_info_map_[name_status_pair.second.virtual_sensor_info->trigger_sensor]
- .is_monitor = true;
- } else {
- LOG(FATAL) << name_status_pair.first << " does not have trigger sensor: "
- << name_status_pair.second.virtual_sensor_info->trigger_sensor;
- }
- }
- }
-
- const bool thermal_throttling_disabled =
- android::base::GetBoolProperty(kThermalDisabledProperty.data(), false);
-
- if (thermal_throttling_disabled) {
- LOG(INFO) << kThermalDisabledProperty.data() << " is true";
- for (const auto &cdev_pair : cooling_device_info_map_) {
- if (cooling_devices_.writeCdevFile(cdev_pair.first, std::to_string(0))) {
- LOG(INFO) << "Successfully clear cdev " << cdev_pair.first << " to 0";
- }
- }
- return;
- }
-
- const bool thermal_genl_enabled =
- android::base::GetBoolProperty(kThermalGenlProperty.data(), false);
-
std::set<std::string> monitored_sensors;
- initializeTrip(tz_map, &monitored_sensors, thermal_genl_enabled);
+ std::transform(sensor_info_map_.cbegin(), sensor_info_map_.cend(),
+ std::inserter(monitored_sensors, monitored_sensors.begin()),
+ [](std::pair<std::string, SensorInfo> const &sensor) {
+ if (sensor.second.is_monitor)
+ return sensor.first;
+ else
+ return std::string();
+ });
- if (thermal_genl_enabled) {
- thermal_watcher_->registerFilesToWatchNl(monitored_sensors);
- } else {
- thermal_watcher_->registerFilesToWatch(monitored_sensors);
- }
+ thermal_watcher_->registerFilesToWatch(monitored_sensors, initializeTrip(tz_map));
// Need start watching after status map initialized
is_initialized_ = thermal_watcher_->startWatchingDeviceFiles();
if (!is_initialized_) {
LOG(FATAL) << "ThermalHAL could not start watching thread properly.";
}
-
- if (!connectToPowerHal()) {
- LOG(ERROR) << "Fail to connect to Power Hal";
- } else {
- updateSupportedPowerHints();
- }
-}
-
-bool getThermalZoneTypeById(int tz_id, std::string *type) {
- std::string tz_type;
- std::string path =
- android::base::StringPrintf("%s/%s%d/%s", kThermalSensorsRoot.data(),
- kSensorPrefix.data(), tz_id, kThermalNameFile.data());
- LOG(INFO) << "TZ Path: " << path;
- if (!::android::base::ReadFileToString(path, &tz_type)) {
- LOG(ERROR) << "Failed to read sensor: " << tz_type;
- return false;
- }
-
- // Strip the newline.
- *type = ::android::base::Trim(tz_type);
- LOG(INFO) << "TZ type: " << *type;
- return true;
}
bool ThermalHelper::readCoolingDevice(std::string_view cooling_device,
@@ -431,8 +227,7 @@
return false;
}
- const CdevInfo &cdev_info = cooling_device_info_map_.at(cooling_device.data());
- const CoolingType &type = cdev_info.type;
+ const CoolingType &type = cooling_device_info_map_.at(cooling_device.data());
out->type = type;
out->name = cooling_device.data();
@@ -441,26 +236,18 @@
return true;
}
-bool ThermalHelper::readTemperature(std::string_view sensor_name, Temperature_1_0 *out,
- bool is_virtual_sensor) const {
+bool ThermalHelper::readTemperature(std::string_view sensor_name, Temperature_1_0 *out) const {
// Read the file. If the file can't be read temp will be empty string.
std::string temp;
- if (!is_virtual_sensor) {
- if (!thermal_sensors_.readThermalFile(sensor_name, &temp)) {
- LOG(ERROR) << "readTemperature: sensor not found: " << sensor_name;
- return false;
- }
+ if (!thermal_sensors_.readThermalFile(sensor_name, &temp)) {
+ LOG(ERROR) << "readTemperature: sensor not found: " << sensor_name;
+ return false;
+ }
- if (temp.empty()) {
- LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name;
- return false;
- }
- } else {
- if (!checkVirtualSensor(sensor_name.data(), &temp)) {
- LOG(ERROR) << "readTemperature: failed to read virtual sensor: " << sensor_name;
- return false;
- }
+ if (temp.empty()) {
+ LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name;
+ return false;
}
const SensorInfo &sensor_info = sensor_info_map_.at(sensor_name.data());
@@ -482,26 +269,18 @@
bool ThermalHelper::readTemperature(
std::string_view sensor_name, Temperature_2_0 *out,
- std::pair<ThrottlingSeverity, ThrottlingSeverity> *throtting_status,
- bool is_virtual_sensor) const {
+ std::pair<ThrottlingSeverity, ThrottlingSeverity> *throtting_status) const {
// Read the file. If the file can't be read temp will be empty string.
std::string temp;
- if (!is_virtual_sensor) {
- if (!thermal_sensors_.readThermalFile(sensor_name, &temp)) {
- LOG(ERROR) << "readTemperature: sensor not found: " << sensor_name;
- return false;
- }
+ if (!thermal_sensors_.readThermalFile(sensor_name, &temp)) {
+ LOG(ERROR) << "readTemperature: sensor not found: " << sensor_name;
+ return false;
+ }
- if (temp.empty()) {
- LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name;
- return false;
- }
- } else {
- if (!checkVirtualSensor(sensor_name.data(), &temp)) {
- LOG(ERROR) << "readTemperature: failed to read virtual sensor: " << sensor_name;
- return false;
- }
+ if (temp.empty()) {
+ LOG(ERROR) << "readTemperature: failed to read sensor: " << sensor_name;
+ return false;
}
const auto &sensor_info = sensor_info_map_.at(sensor_name.data());
@@ -556,207 +335,6 @@
return true;
}
-// To find the next PID target state according to the current thermal severity
-size_t ThermalHelper::getTargetStateOfPID(const SensorInfo &sensor_info,
- const SensorStatus &sensor_status) {
- size_t target_state = 0;
-
- for (const auto &severity : hidl_enum_range<ThrottlingSeverity>()) {
- size_t state = static_cast<size_t>(severity);
- if (std::isnan(sensor_info.throttling_info->s_power[state])) {
- continue;
- }
- target_state = state;
- if (severity > sensor_status.severity) {
- break;
- }
- }
- return target_state;
-}
-
-// Return the power budget which is computed by PID algorithm
-float ThermalHelper::pidPowerCalculator(const Temperature_2_0 &temp, const SensorInfo &sensor_info,
- SensorStatus *sensor_status,
- std::chrono::milliseconds time_elapsed_ms,
- size_t target_state) {
- float p = 0, i = 0, d = 0;
- float power_budget = std::numeric_limits<float>::max();
-
- LOG(VERBOSE) << "PID target state=" << target_state;
- if (!target_state || (sensor_status->severity == ThrottlingSeverity::NONE)) {
- sensor_status->err_integral = 0;
- sensor_status->prev_err = NAN;
- return power_budget;
- }
-
- // Compute PID
- float err = sensor_info.hot_thresholds[target_state] - temp.value;
- p = err * (err < 0 ? sensor_info.throttling_info->k_po[target_state]
- : sensor_info.throttling_info->k_pu[target_state]);
- i = sensor_status->err_integral * sensor_info.throttling_info->k_i[target_state];
- if (err < sensor_info.throttling_info->i_cutoff[target_state]) {
- float i_next = i + err * sensor_info.throttling_info->k_i[target_state];
- if (abs(i_next) < sensor_info.throttling_info->i_max[target_state]) {
- i = i_next;
- sensor_status->err_integral += err;
- }
- }
-
- if (!std::isnan(sensor_status->prev_err) &&
- time_elapsed_ms != std::chrono::milliseconds::zero()) {
- d = sensor_info.throttling_info->k_d[target_state] * (err - sensor_status->prev_err) /
- time_elapsed_ms.count();
- }
-
- sensor_status->prev_err = err;
- // Calculate power budget
- power_budget = sensor_info.throttling_info->s_power[target_state] + p + i + d;
- if (power_budget < sensor_info.throttling_info->min_alloc_power[target_state]) {
- power_budget = sensor_info.throttling_info->min_alloc_power[target_state];
- }
- if (power_budget > sensor_info.throttling_info->max_alloc_power[target_state]) {
- power_budget = sensor_info.throttling_info->max_alloc_power[target_state];
- }
-
- LOG(VERBOSE) << "power_budget=" << power_budget << " err=" << err
- << " err_integral=" << sensor_status->err_integral
- << " s_power=" << sensor_info.throttling_info->s_power[target_state]
- << " time_elpased_ms=" << time_elapsed_ms.count() << " p=" << p << " i=" << i
- << " d=" << d;
-
- return power_budget;
-}
-
-bool ThermalHelper::requestCdevByPower(std::string_view sensor_name, SensorStatus *sensor_status,
- const SensorInfo &sensor_info, float total_power_budget,
- size_t target_state) {
- float total_weight = 0, cdev_power_budget;
- size_t j;
-
- for (const auto &binded_cdev_info_pair : sensor_info.throttling_info->binded_cdev_info_map) {
- if (!std::isnan(binded_cdev_info_pair.second.cdev_weight_for_pid[target_state])) {
- total_weight += binded_cdev_info_pair.second.cdev_weight_for_pid[target_state];
- }
- }
-
- if (!total_weight) {
- LOG(ERROR) << "Sensor: " << sensor_name.data() << " total weight value is zero";
- return false;
- }
-
- // Map cdev state by power
- for (const auto &binded_cdev_info_pair : sensor_info.throttling_info->binded_cdev_info_map) {
- const auto cdev_weight = binded_cdev_info_pair.second.cdev_weight_for_pid[target_state];
- if (!std::isnan(cdev_weight)) {
- cdev_power_budget = total_power_budget * (cdev_weight / total_weight);
-
- const CdevInfo &cdev_info_pair =
- cooling_device_info_map_.at(binded_cdev_info_pair.first);
- for (j = 0; j < cdev_info_pair.state2power.size() - 1; ++j) {
- if (cdev_power_budget > cdev_info_pair.state2power[j]) {
- break;
- }
- }
- sensor_status->pid_request_map.at(binded_cdev_info_pair.first) = static_cast<int>(j);
- LOG(VERBOSE) << "Power allocator: Sensor " << sensor_name.data() << " allocate "
- << cdev_power_budget << "mW to " << binded_cdev_info_pair.first
- << "(cdev_weight=" << cdev_weight << ") update state to " << j;
- }
- }
- return true;
-}
-
-void ThermalHelper::requestCdevBySeverity(std::string_view sensor_name, SensorStatus *sensor_status,
- const SensorInfo &sensor_info) {
- for (auto const &binded_cdev_info_pair : sensor_info.throttling_info->binded_cdev_info_map) {
- sensor_status->hard_limit_request_map.at(binded_cdev_info_pair.first) =
- binded_cdev_info_pair.second
- .limit_info[static_cast<size_t>(sensor_status->severity)];
- LOG(VERBOSE) << "Hard Limit: Sensor " << sensor_name.data() << " update cdev "
- << binded_cdev_info_pair.first << " to "
- << sensor_status->hard_limit_request_map.at(binded_cdev_info_pair.first);
- }
-}
-
-void ThermalHelper::computeCoolingDevicesRequest(
- std::string_view sensor_name, const SensorInfo &sensor_info,
- const SensorStatus &sensor_status, std::vector<std::string> *cooling_devices_to_update) {
- int release_step = 0;
-
- std::unique_lock<std::shared_mutex> _lock(cdev_status_map_mutex_);
- for (auto &cdev_request_pair : cdev_status_map_) {
- if (!cdev_request_pair.second.count(sensor_name.data())) {
- continue;
- }
- int pid_request = 0;
- int hard_limit_request = 0;
- const auto &binded_cdev_info =
- sensor_info.throttling_info->binded_cdev_info_map.at(cdev_request_pair.first);
- const auto cdev_ceiling =
- binded_cdev_info.cdev_ceiling[static_cast<size_t>(sensor_status.severity)];
- const auto cdev_floor =
- binded_cdev_info
- .cdev_floor_with_power_link[static_cast<size_t>(sensor_status.severity)];
- release_step = 0;
-
- if (sensor_status.pid_request_map.count(cdev_request_pair.first)) {
- pid_request = sensor_status.pid_request_map.at(cdev_request_pair.first);
- }
-
- if (sensor_status.hard_limit_request_map.count(cdev_request_pair.first)) {
- hard_limit_request = sensor_status.hard_limit_request_map.at(cdev_request_pair.first);
- }
-
- release_step = power_files_.getReleaseStep(sensor_name, cdev_request_pair.first);
- LOG(VERBOSE) << "Sensor: " << sensor_name.data() << " binded cooling device "
- << cdev_request_pair.first << "'s pid_request=" << pid_request
- << " hard_limit_request=" << hard_limit_request
- << " release_step=" << release_step
- << " cdev_floor_with_power_link=" << cdev_floor
- << " cdev_ceiling=" << cdev_ceiling;
-
- auto request_state = std::max(pid_request, hard_limit_request);
- if (release_step) {
- if (release_step >= request_state) {
- request_state = 0;
- } else {
- request_state = request_state - release_step;
- }
- // Only check the cdev_floor when release step is non zero
- if (request_state < cdev_floor) {
- request_state = cdev_floor;
- }
- }
-
- if (request_state > cdev_ceiling) {
- request_state = cdev_ceiling;
- }
- if (cdev_request_pair.second.at(sensor_name.data()) != request_state) {
- cdev_request_pair.second.at(sensor_name.data()) = request_state;
- cooling_devices_to_update->emplace_back(cdev_request_pair.first);
- LOG(INFO) << "Sensor: " << sensor_name.data() << " request " << cdev_request_pair.first
- << " to " << request_state;
- }
- }
-}
-
-void ThermalHelper::updateCoolingDevices(const std::vector<std::string> &updated_cdev) {
- int max_state;
-
- for (const auto &target_cdev : updated_cdev) {
- max_state = 0;
- const CdevRequestStatus &cdev_status = cdev_status_map_.at(target_cdev);
- for (auto &sensor_request_pair : cdev_status) {
- if (sensor_request_pair.second > max_state) {
- max_state = sensor_request_pair.second;
- }
- }
- if (cooling_devices_.writeCdevFile(target_cdev, std::to_string(max_state))) {
- LOG(VERBOSE) << "Successfully update cdev " << target_cdev << " sysfs to " << max_state;
- }
- }
-}
-
std::pair<ThrottlingSeverity, ThrottlingSeverity> ThermalHelper::getSeverityFromThresholds(
const ThrottlingArray &hot_thresholds, const ThrottlingArray &cold_thresholds,
const ThrottlingArray &hot_hysteresis, const ThrottlingArray &cold_hysteresis,
@@ -798,161 +376,66 @@
return std::make_pair(ret_hot, ret_cold);
}
-bool ThermalHelper::initializeSensorMap(
- const std::unordered_map<std::string, std::string> &path_map) {
+bool ThermalHelper::initializeSensorMap(const std::map<std::string, std::string> &path_map) {
for (const auto &sensor_info_pair : sensor_info_map_) {
std::string_view sensor_name = sensor_info_pair.first;
- if (sensor_info_pair.second.virtual_sensor_info != nullptr) {
- continue;
- }
if (!path_map.count(sensor_name.data())) {
LOG(ERROR) << "Could not find " << sensor_name << " in sysfs";
- return false;
+ continue;
}
-
- std::string path;
- if (sensor_info_pair.second.temp_path.empty()) {
- path = android::base::StringPrintf("%s/%s", path_map.at(sensor_name.data()).c_str(),
- kSensorTempSuffix.data());
- } else {
- path = sensor_info_pair.second.temp_path;
- }
-
+ std::string path = android::base::StringPrintf(
+ "%s/%s", path_map.at(sensor_name.data()).c_str(), kSensorTempSuffix.data());
if (!thermal_sensors_.addThermalFile(sensor_name, path)) {
LOG(ERROR) << "Could not add " << sensor_name << "to sensors map";
- return false;
}
}
- return true;
+ if (sensor_info_map_.size() == thermal_sensors_.getNumThermalFiles()) {
+ return true;
+ }
+ return false;
}
-bool ThermalHelper::initializeCoolingDevices(
- const std::unordered_map<std::string, std::string> &path_map) {
- for (auto &cooling_device_info_pair : cooling_device_info_map_) {
- std::string cooling_device_name = cooling_device_info_pair.first;
- if (!path_map.count(cooling_device_name)) {
+bool ThermalHelper::initializeCoolingDevices(const std::map<std::string, std::string> &path_map) {
+ for (const auto &cooling_device_info_pair : cooling_device_info_map_) {
+ std::string_view cooling_device_name = cooling_device_info_pair.first;
+ if (!path_map.count(cooling_device_name.data())) {
LOG(ERROR) << "Could not find " << cooling_device_name << " in sysfs";
continue;
}
- // Add cooling device path for thermalHAL to get current state
- std::string_view path = path_map.at(cooling_device_name);
- std::string read_path;
- if (!cooling_device_info_pair.second.read_path.empty()) {
- read_path = cooling_device_info_pair.second.read_path.data();
- } else {
- read_path = android::base::StringPrintf("%s/%s", path.data(),
- kCoolingDeviceCurStateSuffix.data());
- }
- if (!cooling_devices_.addThermalFile(cooling_device_name, read_path)) {
- LOG(ERROR) << "Could not add " << cooling_device_name
- << " read path to cooling device map";
- continue;
- }
-
- std::string state2power_path = android::base::StringPrintf(
- "%s/%s", path.data(), kCoolingDeviceState2powerSuffix.data());
- std::string state2power_str;
- if (android::base::ReadFileToString(state2power_path, &state2power_str)) {
- LOG(INFO) << "Cooling device " << cooling_device_info_pair.first
- << " use state2power read from sysfs";
- cooling_device_info_pair.second.state2power.clear();
-
- std::stringstream power(state2power_str);
- unsigned int power_number;
- int i = 0;
- while (power >> power_number) {
- cooling_device_info_pair.second.state2power.push_back(
- static_cast<float>(power_number));
- LOG(INFO) << "Cooling device " << cooling_device_info_pair.first << " state:" << i
- << " power: " << power_number;
- i++;
- }
- }
-
- // Get max cooling device request state
- std::string max_state;
- std::string max_state_path = android::base::StringPrintf(
- "%s/%s", path.data(), kCoolingDeviceMaxStateSuffix.data());
- if (!android::base::ReadFileToString(max_state_path, &max_state)) {
- LOG(ERROR) << cooling_device_info_pair.first
- << " could not open max state file:" << max_state_path;
- cooling_device_info_pair.second.max_state = std::numeric_limits<int>::max();
- } else {
- cooling_device_info_pair.second.max_state = std::stoi(android::base::Trim(max_state));
- LOG(INFO) << "Cooling device " << cooling_device_info_pair.first
- << " max state: " << cooling_device_info_pair.second.max_state
- << " state2power number: "
- << cooling_device_info_pair.second.state2power.size();
- if (cooling_device_info_pair.second.state2power.size() > 0 &&
- cooling_device_info_pair.second.state2power.size() !=
- (size_t)cooling_device_info_pair.second.max_state + 1) {
- LOG(ERROR) << "Invalid state2power number: "
- << cooling_device_info_pair.second.state2power.size()
- << ", number should be " << cooling_device_info_pair.second.max_state + 1
- << " (max_state + 1)";
- }
- }
-
- // Add cooling device path for thermalHAL to request state
- cooling_device_name =
- android::base::StringPrintf("%s_%s", cooling_device_name.c_str(), "w");
- std::string write_path;
- if (!cooling_device_info_pair.second.write_path.empty()) {
- write_path = cooling_device_info_pair.second.write_path.data();
- } else {
- write_path = android::base::StringPrintf("%s/%s", path.data(),
- kCoolingDeviceCurStateSuffix.data());
- }
-
- if (!cooling_devices_.addThermalFile(cooling_device_name, write_path)) {
- LOG(ERROR) << "Could not add " << cooling_device_name
- << " write path to cooling device map";
+ std::string path = android::base::StringPrintf(
+ "%s/%s", path_map.at(cooling_device_name.data()).c_str(),
+ kCoolingDeviceCurStateSuffix.data());
+ if (!cooling_devices_.addThermalFile(cooling_device_name, path)) {
+ LOG(ERROR) << "Could not add " << cooling_device_name << "to cooling device map";
continue;
}
}
- if (cooling_device_info_map_.size() * 2 != cooling_devices_.getNumThermalFiles()) {
- LOG(ERROR) << "Some cooling device can not be initialized";
+ if (cooling_device_info_map_.size() == cooling_devices_.getNumThermalFiles()) {
+ return true;
}
- return true;
+ return false;
}
-void ThermalHelper::setMinTimeout(SensorInfo *sensor_info) {
- sensor_info->polling_delay = kMinPollIntervalMs;
- sensor_info->passive_delay = kMinPollIntervalMs;
-}
-
-void ThermalHelper::initializeTrip(const std::unordered_map<std::string, std::string> &path_map,
- std::set<std::string> *monitored_sensors,
- bool thermal_genl_enabled) {
- for (auto &sensor_info : sensor_info_map_) {
- if (!sensor_info.second.is_monitor || (sensor_info.second.virtual_sensor_info != nullptr)) {
- continue;
- }
-
- bool trip_update = false;
- std::string_view sensor_name = sensor_info.first;
- std::string_view tz_path = path_map.at(sensor_name.data());
- std::string tz_policy;
- std::string path =
- android::base::StringPrintf("%s/%s", (tz_path.data()), kSensorPolicyFile.data());
-
- if (thermal_genl_enabled) {
- trip_update = true;
- } else {
- // Check if thermal zone support uevent notify
+bool ThermalHelper::initializeTrip(const std::map<std::string, std::string> &path_map) {
+ for (const auto &sensor_info : sensor_info_map_) {
+ if (sensor_info.second.is_monitor) {
+ std::string_view sensor_name = sensor_info.first;
+ std::string_view tz_path = path_map.at(sensor_name.data());
+ std::string tz_policy;
+ std::string path = android::base::StringPrintf("%s/%s", (tz_path.data()),
+ kSensorPolicyFile.data());
if (!android::base::ReadFileToString(path, &tz_policy)) {
LOG(ERROR) << sensor_name << " could not open tz policy file:" << path;
- } else {
- tz_policy = android::base::Trim(tz_policy);
- if (tz_policy != kUserSpaceSuffix) {
- LOG(ERROR) << sensor_name << " does not support uevent notify";
- } else {
- trip_update = true;
- }
+ return false;
}
- }
- if (trip_update) {
+ // Check if thermal zone support uevent notify
+ tz_policy = android::base::Trim(tz_policy);
+ if (tz_policy != kUserSpaceSuffix) {
+ LOG(ERROR) << sensor_name << " does not support uevent notify";
+ return false;
+ }
+
// Update thermal zone trip point
for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
if (!std::isnan(sensor_info.second.hot_thresholds[i]) &&
@@ -963,10 +446,9 @@
path = android::base::StringPrintf("%s/%s", (tz_path.data()),
kSensorTripPointTempZeroFile.data());
if (!android::base::WriteStringToFile(threshold, path)) {
- LOG(ERROR) << "fail to update " << sensor_name << " trip point: " << path
- << " to " << threshold;
- trip_update = false;
- break;
+ LOG(ERROR) << "fail to update " << sensor_name
+ << " trip point: " << threshold << path;
+ return false;
}
// Update trip_point_0_hyst threshold
threshold = std::to_string(static_cast<int>(
@@ -976,35 +458,25 @@
if (!android::base::WriteStringToFile(threshold, path)) {
LOG(ERROR) << "fail to update " << sensor_name << "trip hyst" << threshold
<< path;
- trip_update = false;
- break;
+ return false;
}
break;
} else if (i == kThrottlingSeverityCount - 1) {
LOG(ERROR) << sensor_name << ":all thresholds are NAN";
- trip_update = false;
- break;
+ return false;
}
}
- monitored_sensors->insert(sensor_info.first);
- }
-
- if (!trip_update) {
- LOG(INFO) << "config Sensor: " << sensor_info.first
- << " to default polling interval: " << kMinPollIntervalMs.count();
- setMinTimeout(&sensor_info.second);
}
}
+ return true;
}
-
bool ThermalHelper::fillTemperatures(hidl_vec<Temperature_1_0> *temperatures) const {
temperatures->resize(sensor_info_map_.size());
int current_index = 0;
for (const auto &name_info_pair : sensor_info_map_) {
Temperature_1_0 temp;
- if (readTemperature(name_info_pair.first, &temp,
- name_info_pair.second.virtual_sensor_info != nullptr)) {
+ if (readTemperature(name_info_pair.first, &temp)) {
(*temperatures)[current_index] = temp;
} else {
LOG(ERROR) << __func__
@@ -1016,8 +488,7 @@
return current_index > 0;
}
-bool ThermalHelper::fillCurrentTemperatures(bool filterType, bool filterCallback,
- TemperatureType_2_0 type,
+bool ThermalHelper::fillCurrentTemperatures(bool filterType, TemperatureType_2_0 type,
hidl_vec<Temperature_2_0> *temperatures) const {
std::vector<Temperature_2_0> ret;
for (const auto &name_info_pair : sensor_info_map_) {
@@ -1025,15 +496,12 @@
if (filterType && name_info_pair.second.type != type) {
continue;
}
- if (filterCallback && !name_info_pair.second.send_cb) {
- continue;
- }
- if (readTemperature(name_info_pair.first, &temp, nullptr,
- name_info_pair.second.virtual_sensor_info != nullptr)) {
+ if (readTemperature(name_info_pair.first, &temp)) {
ret.emplace_back(std::move(temp));
} else {
LOG(ERROR) << __func__
<< ": error reading temperature for sensor: " << name_info_pair.first;
+ return false;
}
}
*temperatures = ret;
@@ -1065,7 +533,7 @@
std::vector<CoolingDevice_2_0> ret;
for (const auto &name_info_pair : cooling_device_info_map_) {
CoolingDevice_2_0 value;
- if (filterType && name_info_pair.second.type != type) {
+ if (filterType && name_info_pair.second != type) {
continue;
}
if (readCoolingDevice(name_info_pair.first, &value)) {
@@ -1081,144 +549,35 @@
bool ThermalHelper::fillCpuUsages(hidl_vec<CpuUsage> *cpu_usages) const {
cpu_usages->resize(kMaxCpus);
- for (int i = 0; i < kMaxCpus; i++) {
- (*cpu_usages)[i].name = StringPrintf("cpu%d", i);
- (*cpu_usages)[i].active = 0;
- (*cpu_usages)[i].total = 0;
- (*cpu_usages)[i].isOnline = false;
- }
parseCpuUsagesFileAndAssignUsages(cpu_usages);
return true;
}
-bool ThermalHelper::checkVirtualSensor(std::string_view sensor_name, std::string *temp) const {
- float temp_val = 0.0;
-
- const auto &sensor_info = sensor_info_map_.at(sensor_name.data());
- float offset = sensor_info.virtual_sensor_info->offset;
- for (size_t i = 0; i < sensor_info.virtual_sensor_info->linked_sensors.size(); i++) {
- std::string data;
- const auto &linked_sensor_info =
- sensor_info_map_.at(sensor_info.virtual_sensor_info->linked_sensors[i].data());
- if (linked_sensor_info.virtual_sensor_info == nullptr) {
- if (!thermal_sensors_.readThermalFile(
- sensor_info.virtual_sensor_info->linked_sensors[i], &data)) {
- continue;
- }
- } else if (!checkVirtualSensor(sensor_info.virtual_sensor_info->linked_sensors[i], &data)) {
- return false;
- }
-
- LOG(VERBOSE) << sensor_name.data() << "'s linked sensor "
- << sensor_info.virtual_sensor_info->linked_sensors[i] << ": temp = " << data;
- data = ::android::base::Trim(data);
- float sensor_reading = std::stof(data);
- if (std::isnan(sensor_info.virtual_sensor_info->coefficients[i])) {
- return false;
- }
- float coefficient = sensor_info.virtual_sensor_info->coefficients[i];
- switch (sensor_info.virtual_sensor_info->formula) {
- case FormulaOption::COUNT_THRESHOLD:
- if ((coefficient < 0 && sensor_reading < -coefficient) ||
- (coefficient >= 0 && sensor_reading >= coefficient))
- temp_val += 1;
- break;
- case FormulaOption::WEIGHTED_AVG:
- temp_val += sensor_reading * coefficient;
- break;
- case FormulaOption::MAXIMUM:
- if (i == 0)
- temp_val = std::numeric_limits<float>::lowest();
- if (sensor_reading * coefficient > temp_val)
- temp_val = sensor_reading * coefficient;
- break;
- case FormulaOption::MINIMUM:
- if (i == 0)
- temp_val = std::numeric_limits<float>::max();
- if (sensor_reading * coefficient < temp_val)
- temp_val = sensor_reading * coefficient;
- break;
- default:
- break;
- }
- }
- *temp = std::to_string(temp_val + offset);
- return true;
-}
-
// This is called in the different thread context and will update sensor_status
// uevent_sensors is the set of sensors which trigger uevent from thermal core driver.
-std::chrono::milliseconds ThermalHelper::thermalWatcherCallbackFunc(
- const std::set<std::string> &uevent_sensors) {
+bool ThermalHelper::thermalWatcherCallbackFunc(const std::set<std::string> &uevent_sensors) {
std::vector<Temperature_2_0> temps;
- std::vector<std::string> cooling_devices_to_update;
- std::set<std::string> updated_power_rails;
- boot_clock::time_point now = boot_clock::now();
- auto min_sleep_ms = std::chrono::milliseconds::max();
-
+ bool thermal_triggered = false;
for (auto &name_status_pair : sensor_status_map_) {
- bool force_update = false;
- bool severity_changed = false;
Temperature_2_0 temp;
TemperatureThreshold threshold;
SensorStatus &sensor_status = name_status_pair.second;
const SensorInfo &sensor_info = sensor_info_map_.at(name_status_pair.first);
-
- // Only handle the sensors in allow list
+ // Only send notification on whitelisted sensors
if (!sensor_info.is_monitor) {
continue;
}
-
- std::chrono::milliseconds time_elapsed_ms = std::chrono::milliseconds::zero();
- auto sleep_ms = (sensor_status.severity != ThrottlingSeverity::NONE)
- ? sensor_info.passive_delay
- : sensor_info.polling_delay;
- // Check if the sensor need to be updated
- if (sensor_status.last_update_time == boot_clock::time_point::min()) {
- force_update = true;
- LOG(VERBOSE) << "Force update " << name_status_pair.first
- << "'s temperature after booting";
- } else {
- time_elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
- now - sensor_status.last_update_time);
-
- if (time_elapsed_ms > sleep_ms) {
- // Update the sensor because sleep timeout
- force_update = true;
- } else if (uevent_sensors.size() &&
- uevent_sensors.find((sensor_info.virtual_sensor_info != nullptr)
- ? sensor_info.virtual_sensor_info->trigger_sensor
- : name_status_pair.first) !=
- uevent_sensors.end()) {
- // Update the sensor from uevent
- force_update = true;
- } else if (sensor_info.virtual_sensor_info != nullptr) {
- // Update the virtual sensor if it's trigger sensor over the threshold
- const auto trigger_sensor_status =
- sensor_status_map_.at(sensor_info.virtual_sensor_info->trigger_sensor);
- if (trigger_sensor_status.severity != ThrottlingSeverity::NONE) {
- force_update = true;
- }
+ // If callback is triggered by uevent, only check the sensors within uevent_sensors
+ if (uevent_sensors.size() != 0 &&
+ uevent_sensors.find(name_status_pair.first) == uevent_sensors.end()) {
+ if (sensor_status.severity != ThrottlingSeverity::NONE) {
+ thermal_triggered = true;
}
- }
-
- LOG(VERBOSE) << "sensor " << name_status_pair.first
- << ": time_elpased=" << time_elapsed_ms.count()
- << ", sleep_ms=" << sleep_ms.count() << ", force_update = " << force_update;
-
- if (!force_update) {
- auto timeout_remaining = sleep_ms - time_elapsed_ms;
- if (min_sleep_ms > timeout_remaining) {
- min_sleep_ms = timeout_remaining;
- }
- LOG(VERBOSE) << "sensor " << name_status_pair.first
- << ": timeout_remaining=" << timeout_remaining.count();
continue;
}
std::pair<ThrottlingSeverity, ThrottlingSeverity> throtting_status;
- if (!readTemperature(name_status_pair.first, &temp, &throtting_status,
- (sensor_info.virtual_sensor_info != nullptr))) {
+ if (!readTemperature(name_status_pair.first, &temp, &throtting_status)) {
LOG(ERROR) << __func__
<< ": error reading temperature for sensor: " << name_status_pair.first;
continue;
@@ -1240,141 +599,21 @@
}
if (temp.throttlingStatus != sensor_status.severity) {
temps.push_back(temp);
- severity_changed = true;
sensor_status.severity = temp.throttlingStatus;
- sleep_ms = (sensor_status.severity != ThrottlingSeverity::NONE)
- ? sensor_info.passive_delay
- : sensor_info.polling_delay;
}
}
-
if (sensor_status.severity != ThrottlingSeverity::NONE) {
- LOG(INFO) << temp.name << ": " << temp.value << " degC";
- } else {
- LOG(VERBOSE) << temp.name << ": " << temp.value << " degC";
- }
-
- // Start PID computation
- if (sensor_status.pid_request_map.size()) {
- size_t target_state = getTargetStateOfPID(sensor_info, sensor_status);
- float power_budget = pidPowerCalculator(temp, sensor_info, &sensor_status,
- time_elapsed_ms, target_state);
- if (!requestCdevByPower(name_status_pair.first, &sensor_status, sensor_info,
- power_budget, target_state)) {
- LOG(ERROR) << "Sensor " << temp.name << " PID request cdev failed";
- }
- }
-
- if (sensor_status.hard_limit_request_map.size()) {
- // Start hard limit computation
- requestCdevBySeverity(name_status_pair.first, &sensor_status, sensor_info);
- }
-
- // Aggregate cooling device request
- if (sensor_status.pid_request_map.size() || sensor_status.hard_limit_request_map.size()) {
- if (sensor_status.severity == ThrottlingSeverity::NONE) {
- power_files_.setPowerDataToDefault(name_status_pair.first);
- } else {
- for (const auto &binded_cdev_info_pair :
- sensor_info.throttling_info->binded_cdev_info_map) {
- if (binded_cdev_info_pair.second.power_rail != "") {
- const auto &power_rail_info =
- power_rail_info_map_.at(binded_cdev_info_pair.second.power_rail);
-
- if (power_files_.throttlingReleaseUpdate(
- name_status_pair.first, binded_cdev_info_pair.first,
- sensor_status.severity, time_elapsed_ms,
- binded_cdev_info_pair.second, power_rail_info,
- !updated_power_rails.count(
- binded_cdev_info_pair.second.power_rail),
- severity_changed)) {
- updated_power_rails.insert(binded_cdev_info_pair.second.power_rail);
- }
- }
- }
- }
- computeCoolingDevicesRequest(name_status_pair.first, sensor_info, sensor_status,
- &cooling_devices_to_update);
- }
-
- if (min_sleep_ms > sleep_ms) {
- min_sleep_ms = sleep_ms;
- }
- LOG(VERBOSE) << "Sensor " << name_status_pair.first << ": sleep_ms=" << sleep_ms.count()
- << ", min_sleep_ms voting result=" << min_sleep_ms.count();
- sensor_status.last_update_time = now;
- }
-
- if (!cooling_devices_to_update.empty()) {
- updateCoolingDevices(cooling_devices_to_update);
- }
-
- if (!temps.empty()) {
- for (const auto &t : temps) {
- if (sensor_info_map_.at(t.name).send_cb && cb_) {
- cb_(t);
- }
-
- if (sensor_info_map_.at(t.name).send_powerhint && isAidlPowerHalExist()) {
- sendPowerExtHint(t);
- }
+ thermal_triggered = true;
+ LOG(INFO) << temp.name << ": " << temp.value;
}
}
+ if (!temps.empty() && cb_) {
+ cb_(temps);
+ }
- power_files_.clearEnergyInfoMap();
- return min_sleep_ms < kMinPollIntervalMs ? kMinPollIntervalMs : min_sleep_ms;
+ return thermal_triggered;
}
-bool ThermalHelper::connectToPowerHal() {
- return power_hal_service_.connect();
-}
-
-void ThermalHelper::updateSupportedPowerHints() {
- for (auto const &name_status_pair : sensor_info_map_) {
- if (!(name_status_pair.second.send_powerhint)) {
- continue;
- }
- ThrottlingSeverity current_severity = ThrottlingSeverity::NONE;
- for (const auto &severity : hidl_enum_range<ThrottlingSeverity>()) {
- if (severity == ThrottlingSeverity::NONE) {
- supported_powerhint_map_[name_status_pair.first][ThrottlingSeverity::NONE] =
- ThrottlingSeverity::NONE;
- continue;
- }
-
- bool isSupported = false;
- ndk::ScopedAStatus isSupportedResult;
-
- if (power_hal_service_.isPowerHalExtConnected()) {
- isSupported = power_hal_service_.isModeSupported(name_status_pair.first, severity);
- }
- if (isSupported)
- current_severity = severity;
- supported_powerhint_map_[name_status_pair.first][severity] = current_severity;
- }
- }
-}
-
-void ThermalHelper::sendPowerExtHint(const Temperature_2_0 &t) {
- std::lock_guard<std::shared_mutex> lock(sensor_status_map_mutex_);
-
- ThrottlingSeverity prev_hint_severity;
- prev_hint_severity = sensor_status_map_.at(t.name).prev_hint_severity;
- ThrottlingSeverity current_hint_severity = supported_powerhint_map_[t.name][t.throttlingStatus];
-
- if (prev_hint_severity == current_hint_severity)
- return;
-
- if (prev_hint_severity != ThrottlingSeverity::NONE) {
- power_hal_service_.setMode(t.name, prev_hint_severity, false);
- }
-
- if (current_hint_severity != ThrottlingSeverity::NONE) {
- power_hal_service_.setMode(t.name, current_hint_severity, true);
- }
-
- sensor_status_map_[t.name].prev_hint_severity = current_hint_severity;
-}
} // namespace implementation
} // namespace V2_0
} // namespace thermal
diff --git a/thermal/thermal-helper.h b/thermal/thermal-helper.h
index 2020597..5eb389e 100644
--- a/thermal/thermal-helper.h
+++ b/thermal/thermal-helper.h
@@ -27,7 +27,8 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#pragma once
+#ifndef THERMAL_THERMAL_HELPER_H__
+#define THERMAL_THERMAL_HELPER_H__
#include <array>
#include <chrono>
@@ -39,12 +40,9 @@
#include <unordered_map>
#include <vector>
-#include <aidl/android/hardware/power/IPower.h>
-#include <aidl/google/hardware/power/extension/pixel/IPowerExt.h>
#include <android/hardware/thermal/2.0/IThermal.h>
#include "utils/config_parser.h"
-#include "utils/power_files.h"
#include "utils/thermal_files.h"
#include "utils/thermal_watcher.h"
@@ -54,8 +52,6 @@
namespace V2_0 {
namespace implementation {
-using ::aidl::android::hardware::power::IPower;
-using ::aidl::google::hardware::power::extension::pixel::IPowerExt;
using ::android::hardware::hidl_vec;
using ::android::hardware::thermal::V1_0::CpuUsage;
using ::android::hardware::thermal::V2_0::CoolingType;
@@ -69,50 +65,22 @@
using ::android::hardware::thermal::V2_0::TemperatureThreshold;
using ::android::hardware::thermal::V2_0::ThrottlingSeverity;
-using NotificationCallback = std::function<void(const Temperature_2_0 &t)>;
+using NotificationCallback = std::function<void(const std::vector<Temperature_2_0> &temps)>;
using NotificationTime = std::chrono::time_point<std::chrono::steady_clock>;
-using CdevRequestStatus = std::unordered_map<std::string, int>;
-
-// Get thermal_zone type
-bool getThermalZoneTypeById(int tz_id, std::string *);
struct SensorStatus {
ThrottlingSeverity severity;
ThrottlingSeverity prev_hot_severity;
ThrottlingSeverity prev_cold_severity;
- ThrottlingSeverity prev_hint_severity;
- boot_clock::time_point last_update_time;
- std::unordered_map<std::string, int> pid_request_map;
- std::unordered_map<std::string, int> hard_limit_request_map;
- float err_integral;
- float prev_err;
-};
-
-class PowerHalService {
- public:
- PowerHalService();
- ~PowerHalService() = default;
- bool connect();
- bool isAidlPowerHalExist() { return power_hal_aidl_exist_; }
- bool isModeSupported(const std::string &type, const ThrottlingSeverity &t);
- bool isPowerHalConnected() { return power_hal_aidl_ != nullptr; }
- bool isPowerHalExtConnected() { return power_hal_ext_aidl_ != nullptr; }
- void setMode(const std::string &type, const ThrottlingSeverity &t, const bool &enable);
-
- private:
- bool power_hal_aidl_exist_;
- std::shared_ptr<IPower> power_hal_aidl_;
- std::shared_ptr<IPowerExt> power_hal_ext_aidl_;
- std::mutex lock_;
};
class ThermalHelper {
public:
- explicit ThermalHelper(const NotificationCallback &cb);
+ ThermalHelper(const NotificationCallback &cb);
~ThermalHelper() = default;
bool fillTemperatures(hidl_vec<Temperature_1_0> *temperatures) const;
- bool fillCurrentTemperatures(bool filterType, bool filterCallback, TemperatureType_2_0 type,
+ bool fillCurrentTemperatures(bool filterType, TemperatureType_2_0 type,
hidl_vec<Temperature_2_0> *temperatures) const;
bool fillTemperatureThresholds(bool filterType, TemperatureType_2_0 type,
hidl_vec<TemperatureThreshold> *thresholds) const;
@@ -127,104 +95,40 @@
bool isInitializedOk() const { return is_initialized_; }
// Read the temperature of a single sensor.
- bool readTemperature(std::string_view sensor_name, Temperature_1_0 *out,
- bool is_virtual_sensor = false) const;
+ bool readTemperature(std::string_view sensor_name, Temperature_1_0 *out) const;
bool readTemperature(
std::string_view sensor_name, Temperature_2_0 *out,
- std::pair<ThrottlingSeverity, ThrottlingSeverity> *throtting_status = nullptr,
- bool is_virtual_sensor = false) const;
+ std::pair<ThrottlingSeverity, ThrottlingSeverity> *throtting_status = nullptr) const;
bool readTemperatureThreshold(std::string_view sensor_name, TemperatureThreshold *out) const;
// Read the value of a single cooling device.
bool readCoolingDevice(std::string_view cooling_device, CoolingDevice_2_0 *out) const;
// Get SensorInfo Map
- const std::unordered_map<std::string, SensorInfo> &GetSensorInfoMap() const {
- return sensor_info_map_;
- }
- // Get CdevInfo Map
- const std::unordered_map<std::string, CdevInfo> &GetCdevInfoMap() const {
- return cooling_device_info_map_;
- }
- // Get PowerRailInfo Map
- const std::unordered_map<std::string, PowerRailInfo> &GetPowerRailInfoMap() const {
- return power_rail_info_map_;
- }
- // Get SensorStatus Map
- const std::unordered_map<std::string, SensorStatus> &GetSensorStatusMap() const {
- std::shared_lock<std::shared_mutex> _lock(sensor_status_map_mutex_);
- return sensor_status_map_;
- }
- // Get CdevStatus Map
- const std::unordered_map<std::string, CdevRequestStatus> &GetCdevStatusMap() const {
- std::shared_lock<std::shared_mutex> _lock(cdev_status_map_mutex_);
- return cdev_status_map_;
- }
- // Get ThrottlingRelease Map
- const std::unordered_map<std::string, CdevReleaseStatus> &GetThrottlingReleaseMap() const {
- return power_files_.GetThrottlingReleaseMap();
- }
-
- // Get PowerStatus Map
- const std::unordered_map<std::string, PowerStatusMap> &GetPowerStatusMap() const {
- return power_files_.GetPowerStatusMap();
- }
-
- void sendPowerExtHint(const Temperature_2_0 &t);
- bool isAidlPowerHalExist() { return power_hal_service_.isAidlPowerHalExist(); }
- bool isPowerHalConnected() { return power_hal_service_.isPowerHalConnected(); }
- bool isPowerHalExtConnected() { return power_hal_service_.isPowerHalExtConnected(); }
+ const std::map<std::string, SensorInfo> &GetSensorInfoMap() const { return sensor_info_map_; }
private:
- bool initializeSensorMap(const std::unordered_map<std::string, std::string> &path_map);
- bool initializeCoolingDevices(const std::unordered_map<std::string, std::string> &path_map);
- void setMinTimeout(SensorInfo *sensor_info);
- void initializeTrip(const std::unordered_map<std::string, std::string> &path_map,
- std::set<std::string> *monitored_sensors, bool thermal_genl_enabled);
+ bool initializeSensorMap(const std::map<std::string, std::string> &path_map);
+ bool initializeCoolingDevices(const std::map<std::string, std::string> &path_map);
+ bool initializeTrip(const std::map<std::string, std::string> &path_map);
- // For thermal_watcher_'s polling thread, return the sleep interval
- std::chrono::milliseconds thermalWatcherCallbackFunc(
- const std::set<std::string> &uevent_sensors);
+ // For thermal_watcher_'s polling thread
+ bool thermalWatcherCallbackFunc(const std::set<std::string> &uevent_sensors);
// Return hot and cold severity status as std::pair
std::pair<ThrottlingSeverity, ThrottlingSeverity> getSeverityFromThresholds(
const ThrottlingArray &hot_thresholds, const ThrottlingArray &cold_thresholds,
const ThrottlingArray &hot_hysteresis, const ThrottlingArray &cold_hysteresis,
ThrottlingSeverity prev_hot_severity, ThrottlingSeverity prev_cold_severity,
float value) const;
- bool checkVirtualSensor(std::string_view sensor_name, std::string *temp) const;
- // Return the target state of PID algorithm
- size_t getTargetStateOfPID(const SensorInfo &sensor_info, const SensorStatus &sensor_status);
- // Return the power budget which is computed by PID algorithm
- float pidPowerCalculator(const Temperature_2_0 &temp, const SensorInfo &sensor_info,
- SensorStatus *sensor_status,
- const std::chrono::milliseconds time_elapsed_ms, size_t target_state);
- bool connectToPowerHal();
- void updateSupportedPowerHints();
- bool requestCdevByPower(std::string_view sensor_name, SensorStatus *sensor_status,
- const SensorInfo &sensor_info, float total_power_budget,
- size_t target_state);
- void requestCdevBySeverity(std::string_view sensor_name, SensorStatus *sensor_status,
- const SensorInfo &sensor_info);
- void computeCoolingDevicesRequest(std::string_view sensor_name, const SensorInfo &sensor_info,
- const SensorStatus &sensor_status,
- std::vector<std::string> *cooling_devices_to_update);
- void updateCoolingDevices(const std::vector<std::string> &cooling_devices_to_update);
sp<ThermalWatcher> thermal_watcher_;
- PowerFiles power_files_;
ThermalFiles thermal_sensors_;
ThermalFiles cooling_devices_;
bool is_initialized_;
const NotificationCallback cb_;
- std::unordered_map<std::string, CdevInfo> cooling_device_info_map_;
- std::unordered_map<std::string, SensorInfo> sensor_info_map_;
- std::unordered_map<std::string, PowerRailInfo> power_rail_info_map_;
- std::unordered_map<std::string, std::map<ThrottlingSeverity, ThrottlingSeverity>>
- supported_powerhint_map_;
- PowerHalService power_hal_service_;
+ const std::map<std::string, CoolingType> cooling_device_info_map_;
+ const std::map<std::string, SensorInfo> sensor_info_map_;
mutable std::shared_mutex sensor_status_map_mutex_;
- std::unordered_map<std::string, SensorStatus> sensor_status_map_;
- mutable std::shared_mutex cdev_status_map_mutex_;
- std::unordered_map<std::string, CdevRequestStatus> cdev_status_map_;
+ std::map<std::string, SensorStatus> sensor_status_map_;
};
} // namespace implementation
@@ -232,3 +136,5 @@
} // namespace thermal
} // namespace hardware
} // namespace android
+
+#endif // THERMAL_THERMAL_HELPER_H__
diff --git a/thermal/utils/config_parser.cpp b/thermal/utils/config_parser.cpp
index 6216dd7..d74fd49 100644
--- a/thermal/utils/config_parser.cpp
+++ b/thermal/utils/config_parser.cpp
@@ -15,10 +15,9 @@
*/
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/properties.h>
#include <android-base/strings.h>
#include <cmath>
-#include <unordered_set>
+#include <set>
#include <json/reader.h>
#include <json/value.h>
@@ -31,8 +30,6 @@
namespace V2_0 {
namespace implementation {
-constexpr std::string_view kPowerLinkDisabledProperty("vendor.disable.thermal.powerlink");
-
using ::android::hardware::hidl_enum_range;
using ::android::hardware::thermal::V2_0::toString;
using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType;
@@ -60,103 +57,27 @@
}
}
-int getIntFromValue(const Json::Value &value) {
- if (value.isString()) {
- return (value.asString() == "max") ? std::numeric_limits<int>::max()
- : std::stoul(value.asString());
- } else {
- return value.asInt();
- }
-}
-
-bool getIntFromJsonValues(const Json::Value &values, CdevArray *out, bool inc_check,
- bool dec_check) {
- CdevArray ret;
-
- if (inc_check && dec_check) {
- LOG(ERROR) << "Cannot enable inc_check and dec_check at the same time";
- return false;
- }
-
- if (values.size() != kThrottlingSeverityCount) {
- LOG(ERROR) << "Values size is invalid";
- return false;
- } else {
- int last;
- for (Json::Value::ArrayIndex i = 0; i < kThrottlingSeverityCount; ++i) {
- ret[i] = getIntFromValue(values[i]);
- if (inc_check && ret[i] < last) {
- LOG(FATAL) << "Invalid array[" << i << "]" << ret[i] << " min=" << last;
- return false;
- }
- if (dec_check && ret[i] > last) {
- LOG(FATAL) << "Invalid array[" << i << "]" << ret[i] << " max=" << last;
- return false;
- }
- last = ret[i];
- LOG(INFO) << "[" << i << "]: " << ret[i];
- }
- }
-
- *out = ret;
- return true;
-}
-
-bool getFloatFromJsonValues(const Json::Value &values, ThrottlingArray *out, bool inc_check,
- bool dec_check) {
- ThrottlingArray ret;
-
- if (inc_check && dec_check) {
- LOG(ERROR) << "Cannot enable inc_check and dec_check at the same time";
- return false;
- }
-
- if (values.size() != kThrottlingSeverityCount) {
- LOG(ERROR) << "Values size is invalid";
- return false;
- } else {
- float last = std::nanf("");
- for (Json::Value::ArrayIndex i = 0; i < kThrottlingSeverityCount; ++i) {
- ret[i] = getFloatFromValue(values[i]);
- if (inc_check && !std::isnan(last) && !std::isnan(ret[i]) && ret[i] < last) {
- LOG(FATAL) << "Invalid array[" << i << "]" << ret[i] << " min=" << last;
- return false;
- }
- if (dec_check && !std::isnan(last) && !std::isnan(ret[i]) && ret[i] > last) {
- LOG(FATAL) << "Invalid array[" << i << "]" << ret[i] << " max=" << last;
- return false;
- }
- last = std::isnan(ret[i]) ? last : ret[i];
- LOG(INFO) << "[" << i << "]: " << ret[i];
- }
- }
-
- *out = ret;
- return true;
-}
} // namespace
-std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path) {
+std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path) {
std::string json_doc;
- std::unordered_map<std::string, SensorInfo> sensors_parsed;
+ std::map<std::string, SensorInfo> sensors_parsed;
if (!android::base::ReadFileToString(config_path.data(), &json_doc)) {
LOG(ERROR) << "Failed to read JSON config from " << config_path;
return sensors_parsed;
}
Json::Value root;
- Json::CharReaderBuilder builder;
- std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
- std::string errorMessage;
+ Json::Reader reader;
- if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) {
- LOG(ERROR) << "Failed to parse JSON config: " << errorMessage;
+ if (!reader.parse(json_doc, root)) {
+ LOG(ERROR) << "Failed to parse JSON config";
return sensors_parsed;
}
Json::Value sensors = root["Sensors"];
std::size_t total_parsed = 0;
- std::unordered_set<std::string> sensors_name_parsed;
+ std::set<std::string> sensors_name_parsed;
for (Json::Value::ArrayIndex i = 0; i < sensors.size(); ++i) {
const std::string &name = sensors[i]["Name"].asString();
@@ -186,24 +107,6 @@
return sensors_parsed;
}
- bool send_cb = false;
- if (sensors[i]["Monitor"].empty() || !sensors[i]["Monitor"].isBool()) {
- LOG(INFO) << "Failed to read Sensor[" << name << "]'s Monitor, set to 'false'";
- } else if (sensors[i]["Monitor"].asBool()) {
- send_cb = true;
- }
- LOG(INFO) << "Sensor[" << name << "]'s SendCallback: " << std::boolalpha << send_cb
- << std::noboolalpha;
-
- bool send_powerhint = false;
- if (sensors[i]["SendPowerHint"].empty() || !sensors[i]["SendPowerHint"].isBool()) {
- LOG(INFO) << "Failed to read Sensor[" << name << "]'s SendPowerHint, set to 'false'";
- } else if (sensors[i]["SendPowerHint"].asBool()) {
- send_powerhint = true;
- }
- LOG(INFO) << "Sensor[" << name << "]'s SendPowerHint: " << std::boolalpha << send_powerhint
- << std::noboolalpha;
-
std::array<float, kThrottlingSeverityCount> hot_thresholds;
hot_thresholds.fill(NAN);
std::array<float, kThrottlingSeverityCount> cold_thresholds;
@@ -212,18 +115,7 @@
hot_hysteresis.fill(0.0);
std::array<float, kThrottlingSeverityCount> cold_hysteresis;
cold_hysteresis.fill(0.0);
- std::vector<std::string> linked_sensors;
- std::vector<float> coefficients;
- float offset = 0;
- std::string trigger_sensor;
- FormulaOption formula = FormulaOption::COUNT_THRESHOLD;
- bool is_virtual_sensor = false;
- if (sensors[i]["VirtualSensor"].empty() || !sensors[i]["VirtualSensor"].isBool()) {
- LOG(INFO) << "Failed to read Sensor[" << name << "]'s VirtualSensor, set to 'false'";
- } else {
- is_virtual_sensor = sensors[i]["VirtualSensor"].asBool();
- }
Json::Value values = sensors[i]["HotThreshold"];
if (values.size() != kThrottlingSeverityCount) {
LOG(ERROR) << "Invalid "
@@ -309,63 +201,6 @@
}
}
- if (is_virtual_sensor) {
- values = sensors[i]["Combination"];
- if (values.size()) {
- linked_sensors.reserve(values.size());
- for (Json::Value::ArrayIndex j = 0; j < values.size(); ++j) {
- linked_sensors.emplace_back(values[j].asString());
- LOG(INFO) << "Sensor[" << name << "]'s combination[" << j
- << "]: " << linked_sensors[j];
- }
- } else {
- sensors_parsed.clear();
- return sensors_parsed;
- }
-
- values = sensors[i]["Coefficient"];
- if (values.size()) {
- coefficients.reserve(values.size());
- for (Json::Value::ArrayIndex j = 0; j < values.size(); ++j) {
- coefficients.emplace_back(getFloatFromValue(values[j]));
- LOG(INFO) << "Sensor[" << name << "]'s coefficient[" << j
- << "]: " << coefficients[j];
- }
- } else {
- sensors_parsed.clear();
- return sensors_parsed;
- }
-
- if (!sensors[i]["Offset"].empty()) {
- offset = sensors[i]["Offset"].asFloat();
- }
-
- if (linked_sensors.size() != coefficients.size()) {
- sensors_parsed.clear();
- return sensors_parsed;
- }
-
- trigger_sensor = sensors[i]["TriggerSensor"].asString();
- if (sensors[i]["Formula"].asString().compare("COUNT_THRESHOLD") == 0) {
- formula = FormulaOption::COUNT_THRESHOLD;
- } else if (sensors[i]["Formula"].asString().compare("WEIGHTED_AVG") == 0) {
- formula = FormulaOption::WEIGHTED_AVG;
- } else if (sensors[i]["Formula"].asString().compare("MAXIMUM") == 0) {
- formula = FormulaOption::MAXIMUM;
- } else if (sensors[i]["Formula"].asString().compare("MINIMUM") == 0) {
- formula = FormulaOption::MINIMUM;
- } else {
- sensors_parsed.clear();
- return sensors_parsed;
- }
- }
-
- std::string temp_path;
- if (!sensors[i]["TempPath"].empty()) {
- temp_path = sensors[i]["TempPath"].asString();
- LOG(INFO) << "Sensor[" << name << "]'s TempPath: " << temp_path;
- }
-
float vr_threshold = NAN;
vr_threshold = getFloatFromValue(sensors[i]["VrThreshold"]);
LOG(INFO) << "Sensor[" << name << "]'s VrThreshold: " << vr_threshold;
@@ -373,287 +208,14 @@
float multiplier = sensors[i]["Multiplier"].asFloat();
LOG(INFO) << "Sensor[" << name << "]'s Multiplier: " << multiplier;
- std::chrono::milliseconds polling_delay;
- if (sensors[i]["PollingDelay"].empty()) {
- polling_delay = kUeventPollTimeoutMs;
+ bool is_monitor = false;
+ if (sensors[i]["Monitor"].empty() || !sensors[i]["Monitor"].isBool()) {
+ LOG(INFO) << "Failed to read Sensor[" << name << "]'s Monitor, set to 'false'";
} else {
- polling_delay = std::chrono::milliseconds(getIntFromValue(sensors[i]["PollingDelay"]));
+ is_monitor = sensors[i]["Monitor"].asBool();
}
- LOG(INFO) << "Sensor[" << name << "]'s Polling delay: " << polling_delay.count();
-
- std::chrono::milliseconds passive_delay;
- if (sensors[i]["PassiveDelay"].empty()) {
- passive_delay = kMinPollIntervalMs;
- } else {
- passive_delay = std::chrono::milliseconds(getIntFromValue(sensors[i]["PassiveDelay"]));
- }
- LOG(INFO) << "Sensor[" << name << "]'s Passive delay: " << passive_delay.count();
-
- bool support_pid = false;
- std::array<float, kThrottlingSeverityCount> k_po;
- k_po.fill(0.0);
- std::array<float, kThrottlingSeverityCount> k_pu;
- k_pu.fill(0.0);
- std::array<float, kThrottlingSeverityCount> k_i;
- k_i.fill(0.0);
- std::array<float, kThrottlingSeverityCount> k_d;
- k_d.fill(0.0);
- std::array<float, kThrottlingSeverityCount> i_max;
- i_max.fill(NAN);
- std::array<float, kThrottlingSeverityCount> max_alloc_power;
- max_alloc_power.fill(NAN);
- std::array<float, kThrottlingSeverityCount> min_alloc_power;
- min_alloc_power.fill(NAN);
- std::array<float, kThrottlingSeverityCount> s_power;
- s_power.fill(NAN);
- std::array<float, kThrottlingSeverityCount> i_cutoff;
- i_cutoff.fill(NAN);
-
- // Parse PID parameters
- if (!sensors[i]["PIDInfo"].empty()) {
- LOG(INFO) << "Start to parse"
- << " Sensor[" << name << "]'s K_Po";
- if (sensors[i]["PIDInfo"]["K_Po"].empty() ||
- !getFloatFromJsonValues(sensors[i]["PIDInfo"]["K_Po"], &k_po, false, false)) {
- LOG(ERROR) << "Sensor[" << name << "]: Failed to parse K_Po";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- LOG(INFO) << "Start to parse"
- << " Sensor[" << name << "]'s K_Pu";
- if (sensors[i]["PIDInfo"]["K_Pu"].empty() ||
- !getFloatFromJsonValues(sensors[i]["PIDInfo"]["K_Pu"], &k_pu, false, false)) {
- LOG(ERROR) << "Sensor[" << name << "]: Failed to parse K_Pu";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- LOG(INFO) << "Start to parse"
- << " Sensor[" << name << "]'s K_I";
- if (sensors[i]["PIDInfo"]["K_I"].empty() ||
- !getFloatFromJsonValues(sensors[i]["PIDInfo"]["K_I"], &k_i, false, false)) {
- LOG(INFO) << "Sensor[" << name << "]: Failed to parse K_I";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- LOG(INFO) << "Start to parse"
- << " Sensor[" << name << "]'s K_D";
- if (sensors[i]["PIDInfo"]["K_D"].empty() ||
- !getFloatFromJsonValues(sensors[i]["PIDInfo"]["K_D"], &k_d, false, false)) {
- LOG(ERROR) << "Sensor[" << name << "]: Failed to parse K_D";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- LOG(INFO) << "Start to parse"
- << " Sensor[" << name << "]'s I_Max";
- if (sensors[i]["PIDInfo"]["I_Max"].empty() ||
- !getFloatFromJsonValues(sensors[i]["PIDInfo"]["I_Max"], &i_max, false, false)) {
- LOG(ERROR) << "Sensor[" << name << "]: Failed to parse I_Max";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- LOG(INFO) << "Start to parse"
- << " Sensor[" << name << "]'s MaxAllocPower";
- if (sensors[i]["PIDInfo"]["MaxAllocPower"].empty() ||
- !getFloatFromJsonValues(sensors[i]["PIDInfo"]["MaxAllocPower"], &max_alloc_power,
- false, true)) {
- LOG(ERROR) << "Sensor[" << name << "]: Failed to parse MaxAllocPower";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- LOG(INFO) << "Start to parse"
- << " Sensor[" << name << "]'s MinAllocPower";
- if (sensors[i]["PIDInfo"]["MinAllocPower"].empty() ||
- !getFloatFromJsonValues(sensors[i]["PIDInfo"]["MinAllocPower"], &min_alloc_power,
- false, true)) {
- LOG(ERROR) << "Sensor[" << name << "]: Failed to parse MinAllocPower";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- LOG(INFO) << "Start to parse"
- << " Sensor[" << name << "]'s S_Power";
- if (sensors[i]["PIDInfo"]["S_Power"].empty() ||
- !getFloatFromJsonValues(sensors[i]["PIDInfo"]["S_Power"], &s_power, false, true)) {
- LOG(ERROR) << "Sensor[" << name << "]: Failed to parse S_Power";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- LOG(INFO) << "Start to parse"
- << " Sensor[" << name << "]'s I_Cutoff";
- if (sensors[i]["PIDInfo"]["I_Cutoff"].empty() ||
- !getFloatFromJsonValues(sensors[i]["PIDInfo"]["I_Cutoff"], &i_cutoff, false,
- false)) {
- LOG(ERROR) << "Sensor[" << name << "]: Failed to parse I_Cutoff";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- // Confirm we have at least one valid PID combination
- bool valid_pid_combination = false;
- for (Json::Value::ArrayIndex j = 0; j < kThrottlingSeverityCount; ++j) {
- if (!std::isnan(s_power[j])) {
- if (std::isnan(k_po[j]) || std::isnan(k_pu[j]) || std::isnan(k_i[j]) ||
- std::isnan(k_d[j]) || std::isnan(i_max[j]) ||
- std::isnan(max_alloc_power[j]) || std::isnan(min_alloc_power[j]) ||
- std::isnan(i_cutoff[j])) {
- valid_pid_combination = false;
- break;
- } else {
- valid_pid_combination = true;
- }
- }
- }
- if (!valid_pid_combination) {
- LOG(ERROR) << "Sensor[" << name << "]: Invalid PID parameters combinations";
- sensors_parsed.clear();
- return sensors_parsed;
- } else {
- support_pid = true;
- }
- }
-
- // Parse binded cooling device
- bool support_hard_limit = false;
- std::unordered_map<std::string, BindedCdevInfo> binded_cdev_info_map;
- values = sensors[i]["BindedCdevInfo"];
- for (Json::Value::ArrayIndex j = 0; j < values.size(); ++j) {
- Json::Value sub_values;
- const std::string &cdev_name = values[j]["CdevRequest"].asString();
- ThrottlingArray cdev_weight_for_pid;
- cdev_weight_for_pid.fill(NAN);
- CdevArray cdev_ceiling;
- cdev_ceiling.fill(std::numeric_limits<int>::max());
- if (support_pid) {
- if (!values[j]["CdevWeightForPID"].empty()) {
- LOG(INFO) << "Sensor[" << name << "]: Star to parse " << cdev_name
- << "'s CdevWeightForPID";
- if (!getFloatFromJsonValues(values[j]["CdevWeightForPID"], &cdev_weight_for_pid,
- false, false)) {
- LOG(ERROR) << "Failed to parse CdevWeightForPID";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- }
- if (!values[j]["CdevCeiling"].empty()) {
- LOG(INFO) << "Sensor[" << name
- << "]: Start to parse CdevCeiling: " << cdev_name;
- if (!getIntFromJsonValues(values[j]["CdevCeiling"], &cdev_ceiling, false,
- false)) {
- LOG(ERROR) << "Failed to parse CdevCeiling";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- }
- }
- CdevArray limit_info;
- limit_info.fill(0);
- ThrottlingArray power_thresholds;
- power_thresholds.fill(NAN);
-
- ReleaseLogic release_logic = ReleaseLogic::NONE;
-
- sub_values = values[j]["LimitInfo"];
- if (sub_values.size()) {
- LOG(INFO) << "Sensor[" << name << "]: Start to parse LimitInfo: " << cdev_name;
- if (!getIntFromJsonValues(sub_values, &limit_info, false, false)) {
- LOG(ERROR) << "Failed to parse LimitInfo";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- support_hard_limit = true;
- }
-
- // Parse linked power info
- bool is_power_data_invalid = false;
- std::string power_rail;
- bool high_power_check = false;
- bool throttling_with_power_link = false;
- CdevArray cdev_floor_with_power_link;
- cdev_floor_with_power_link.fill(0);
-
- const bool power_link_disabled =
- android::base::GetBoolProperty(kPowerLinkDisabledProperty.data(), false);
- if (!power_link_disabled) {
- power_rail = values[j]["BindedPowerRail"].asString();
-
- if (values[j]["HighPowerCheck"].asBool()) {
- high_power_check = true;
- }
- LOG(INFO) << "Highpowercheck: " << std::boolalpha << high_power_check;
-
- if (values[j]["ThrottlingWithPowerLink"].asBool()) {
- throttling_with_power_link = true;
- }
- LOG(INFO) << "ThrottlingwithPowerLink: " << std::boolalpha
- << throttling_with_power_link;
-
- sub_values = values[j]["CdevFloorWithPowerLink"];
- if (sub_values.size()) {
- LOG(INFO) << "Sensor[" << name << "]: Start to parse " << cdev_name
- << "'s CdevFloorWithPowerLink";
- if (!getIntFromJsonValues(sub_values, &cdev_floor_with_power_link, false,
- false)) {
- LOG(ERROR) << "Failed to parse CdevFloor";
- is_power_data_invalid = true;
- }
- }
- sub_values = values[j]["PowerThreshold"];
- if (sub_values.size()) {
- LOG(INFO) << "Sensor[" << name << "]: Start to parse " << cdev_name
- << "'s PowerThreshold";
- if (!getFloatFromJsonValues(sub_values, &power_thresholds, false, false)) {
- LOG(ERROR) << "Failed to parse power thresholds";
- is_power_data_invalid = true;
- }
-
- if (values[j]["ReleaseLogic"].asString() == "INCREASE") {
- release_logic = ReleaseLogic::INCREASE;
- LOG(INFO) << "Release logic: INCREASE";
- } else if (values[j]["ReleaseLogic"].asString() == "DECREASE") {
- release_logic = ReleaseLogic::DECREASE;
- LOG(INFO) << "Release logic: DECREASE";
- } else if (values[j]["ReleaseLogic"].asString() == "STEPWISE") {
- release_logic = ReleaseLogic::STEPWISE;
- LOG(INFO) << "Release logic: STEPWISE";
- } else if (values[j]["ReleaseLogic"].asString() == "RELEASE_TO_FLOOR") {
- release_logic = ReleaseLogic::RELEASE_TO_FLOOR;
- LOG(INFO) << "Release logic: RELEASE_TO_FLOOR";
- } else {
- LOG(ERROR) << "Release logic is invalid";
- is_power_data_invalid = true;
- }
-
- if (is_power_data_invalid) {
- LOG(ERROR) << cdev_name << "'s power rail " << power_rail << " is invalid";
- sensors_parsed.clear();
- return sensors_parsed;
- }
- }
- }
-
- binded_cdev_info_map[cdev_name] = {
- .limit_info = limit_info,
- .power_thresholds = power_thresholds,
- .release_logic = release_logic,
- .high_power_check = high_power_check,
- .throttling_with_power_link = throttling_with_power_link,
- .cdev_weight_for_pid = cdev_weight_for_pid,
- .cdev_ceiling = cdev_ceiling,
- .cdev_floor_with_power_link = cdev_floor_with_power_link,
- .power_rail = power_rail,
- };
- }
-
- bool is_monitor = (send_cb | send_powerhint | support_pid | support_hard_limit);
- LOG(INFO) << "Sensor[" << name << "]'s Monitor: " << std::boolalpha << is_monitor;
-
- std::unique_ptr<VirtualSensorInfo> virtual_sensor_info;
- if (is_virtual_sensor) {
- virtual_sensor_info.reset(new VirtualSensorInfo{linked_sensors, coefficients, offset,
- trigger_sensor, formula});
- }
-
- std::unique_ptr<ThrottlingInfo> throttling_info(
- new ThrottlingInfo{k_po, k_pu, k_i, k_d, i_max, max_alloc_power, min_alloc_power,
- s_power, i_cutoff, binded_cdev_info_map});
+ LOG(INFO) << "Sensor[" << name << "]'s Monitor: " << std::boolalpha << is_monitor
+ << std::noboolalpha;
sensors_parsed[name] = {
.type = sensor_type,
@@ -661,18 +223,10 @@
.cold_thresholds = cold_thresholds,
.hot_hysteresis = hot_hysteresis,
.cold_hysteresis = cold_hysteresis,
- .temp_path = temp_path,
.vr_threshold = vr_threshold,
.multiplier = multiplier,
- .polling_delay = polling_delay,
- .passive_delay = passive_delay,
- .send_cb = send_cb,
- .send_powerhint = send_powerhint,
.is_monitor = is_monitor,
- .virtual_sensor_info = std::move(virtual_sensor_info),
- .throttling_info = std::move(throttling_info),
};
-
++total_parsed;
}
@@ -680,27 +234,25 @@
return sensors_parsed;
}
-std::unordered_map<std::string, CdevInfo> ParseCoolingDevice(std::string_view config_path) {
+std::map<std::string, CoolingType> ParseCoolingDevice(std::string_view config_path) {
std::string json_doc;
- std::unordered_map<std::string, CdevInfo> cooling_devices_parsed;
+ std::map<std::string, CoolingType> cooling_devices_parsed;
if (!android::base::ReadFileToString(config_path.data(), &json_doc)) {
LOG(ERROR) << "Failed to read JSON config from " << config_path;
return cooling_devices_parsed;
}
Json::Value root;
- Json::CharReaderBuilder builder;
- std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
- std::string errorMessage;
+ Json::Reader reader;
- if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) {
+ if (!reader.parse(json_doc, root)) {
LOG(ERROR) << "Failed to parse JSON config";
return cooling_devices_parsed;
}
Json::Value cooling_devices = root["CoolingDevices"];
std::size_t total_parsed = 0;
- std::unordered_set<std::string> cooling_devices_name_parsed;
+ std::set<std::string> cooling_devices_name_parsed;
for (Json::Value::ArrayIndex i = 0; i < cooling_devices.size(); ++i) {
const std::string &name = cooling_devices[i]["Name"].asString();
@@ -730,35 +282,8 @@
return cooling_devices_parsed;
}
- const std::string &read_path = cooling_devices[i]["ReadPath"].asString();
- LOG(INFO) << "Cdev Read Path: " << (read_path.empty() ? "default" : read_path);
+ cooling_devices_parsed[name] = cooling_device_type;
- const std::string &write_path = cooling_devices[i]["WritePath"].asString();
- LOG(INFO) << "Cdev Write Path: " << (write_path.empty() ? "default" : write_path);
-
- std::vector<float> state2power;
- Json::Value values = cooling_devices[i]["State2Power"];
- if (values.size()) {
- state2power.reserve(values.size());
- for (Json::Value::ArrayIndex j = 0; j < values.size(); ++j) {
- state2power.emplace_back(getFloatFromValue(values[j]));
- LOG(INFO) << "Cooling device[" << name << "]'s Power2State[" << j
- << "]: " << state2power[j];
- }
- } else {
- LOG(INFO) << "CoolingDevice[" << i << "]'s Name: " << name
- << " does not support Power2State";
- }
-
- const std::string &power_rail = cooling_devices[i]["PowerRail"].asString();
- LOG(INFO) << "Cooling device power rail : " << power_rail;
-
- cooling_devices_parsed[name] = {
- .type = cooling_device_type,
- .read_path = read_path,
- .write_path = write_path,
- .state2power = state2power,
- };
++total_parsed;
}
@@ -766,139 +291,6 @@
return cooling_devices_parsed;
}
-std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_view config_path) {
- std::string json_doc;
- std::unordered_map<std::string, PowerRailInfo> power_rails_parsed;
- if (!android::base::ReadFileToString(config_path.data(), &json_doc)) {
- LOG(ERROR) << "Failed to read JSON config from " << config_path;
- return power_rails_parsed;
- }
-
- Json::Value root;
- Json::CharReaderBuilder builder;
- std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
- std::string errorMessage;
-
- if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) {
- LOG(ERROR) << "Failed to parse JSON config";
- return power_rails_parsed;
- }
-
- Json::Value power_rails = root["PowerRails"];
- std::size_t total_parsed = 0;
- std::unordered_set<std::string> power_rails_name_parsed;
-
- for (Json::Value::ArrayIndex i = 0; i < power_rails.size(); ++i) {
- const std::string &name = power_rails[i]["Name"].asString();
- LOG(INFO) << "PowerRail[" << i << "]'s Name: " << name;
- if (name.empty()) {
- LOG(ERROR) << "Failed to read "
- << "PowerRail[" << i << "]'s Name";
- power_rails_parsed.clear();
- return power_rails_parsed;
- }
-
- std::string rail;
- if (power_rails[i]["Rail"].empty()) {
- rail = name;
- } else {
- rail = power_rails[i]["Rail"].asString();
- }
- LOG(INFO) << "PowerRail[" << i << "]'s Rail: " << rail;
-
- std::vector<std::string> linked_power_rails;
- std::vector<float> coefficients;
- float offset = 0;
- FormulaOption formula = FormulaOption::COUNT_THRESHOLD;
- bool is_virtual_power_rail = false;
- Json::Value values;
- int power_sample_count = 0;
- std::chrono::milliseconds power_sample_delay;
-
- if (!power_rails[i]["VirtualRails"].empty() && power_rails[i]["VirtualRails"].isBool()) {
- is_virtual_power_rail = power_rails[i]["VirtualRails"].asBool();
- LOG(INFO) << "PowerRails[" << name << "]'s VirtualRail, set to 'true'";
- }
-
- if (is_virtual_power_rail) {
- values = power_rails[i]["Combination"];
- if (values.size()) {
- linked_power_rails.reserve(values.size());
- for (Json::Value::ArrayIndex j = 0; j < values.size(); ++j) {
- linked_power_rails.emplace_back(values[j].asString());
- LOG(INFO) << "PowerRail[" << name << "]'s combination[" << j
- << "]: " << linked_power_rails[j];
- }
- } else {
- power_rails_parsed.clear();
- return power_rails_parsed;
- }
-
- values = power_rails[i]["Coefficient"];
- if (values.size()) {
- coefficients.reserve(values.size());
- for (Json::Value::ArrayIndex j = 0; j < values.size(); ++j) {
- coefficients.emplace_back(getFloatFromValue(values[j]));
- LOG(INFO) << "PowerRail[" << name << "]'s coefficient[" << j
- << "]: " << coefficients[j];
- }
- } else {
- power_rails_parsed.clear();
- return power_rails_parsed;
- }
-
- if (!power_rails[i]["Offset"].empty()) {
- offset = power_rails[i]["Offset"].asFloat();
- }
-
- if (linked_power_rails.size() != coefficients.size()) {
- power_rails_parsed.clear();
- return power_rails_parsed;
- }
-
- if (power_rails[i]["Formula"].asString().compare("COUNT_THRESHOLD") == 0) {
- formula = FormulaOption::COUNT_THRESHOLD;
- } else if (power_rails[i]["Formula"].asString().compare("WEIGHTED_AVG") == 0) {
- formula = FormulaOption::WEIGHTED_AVG;
- } else if (power_rails[i]["Formula"].asString().compare("MAXIMUM") == 0) {
- formula = FormulaOption::MAXIMUM;
- } else if (power_rails[i]["Formula"].asString().compare("MINIMUM") == 0) {
- formula = FormulaOption::MINIMUM;
- } else {
- power_rails_parsed.clear();
- return power_rails_parsed;
- }
- }
-
- std::unique_ptr<VirtualPowerRailInfo> virtual_power_rail_info;
- if (is_virtual_power_rail) {
- virtual_power_rail_info.reset(
- new VirtualPowerRailInfo{linked_power_rails, coefficients, offset, formula});
- }
-
- power_sample_count = power_rails[i]["PowerSampleCount"].asInt();
- LOG(INFO) << "Power sample Count: " << power_sample_count;
-
- if (!power_rails[i]["PowerSampleDelay"]) {
- power_sample_delay = std::chrono::milliseconds::max();
- } else {
- power_sample_delay =
- std::chrono::milliseconds(getIntFromValue(power_rails[i]["PowerSampleDelay"]));
- }
-
- power_rails_parsed[name] = {
- .rail = rail,
- .power_sample_count = power_sample_count,
- .power_sample_delay = power_sample_delay,
- .virtual_power_rail_info = std::move(virtual_power_rail_info),
- };
- ++total_parsed;
- }
-
- LOG(INFO) << total_parsed << " PowerRails parsed successfully";
- return power_rails_parsed;
-}
-
} // namespace implementation
} // namespace V2_0
} // namespace thermal
diff --git a/thermal/utils/config_parser.h b/thermal/utils/config_parser.h
index db941c9..fe43594 100644
--- a/thermal/utils/config_parser.h
+++ b/thermal/utils/config_parser.h
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-#pragma once
+#ifndef THERMAL_UTILS_CONFIG_PARSER_H__
+#define THERMAL_UTILS_CONFIG_PARSER_H__
+#include <map>
#include <string>
-#include <unordered_map>
#include <android/hardware/thermal/2.0/IThermal.h>
@@ -28,73 +29,12 @@
namespace implementation {
using ::android::hardware::hidl_enum_range;
-using CoolingType_2_0 = ::android::hardware::thermal::V2_0::CoolingType;
+using ::android::hardware::thermal::V2_0::CoolingType;
using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType;
using ::android::hardware::thermal::V2_0::ThrottlingSeverity;
constexpr size_t kThrottlingSeverityCount = std::distance(
hidl_enum_range<ThrottlingSeverity>().begin(), hidl_enum_range<ThrottlingSeverity>().end());
using ThrottlingArray = std::array<float, static_cast<size_t>(kThrottlingSeverityCount)>;
-using CdevArray = std::array<int, static_cast<size_t>(kThrottlingSeverityCount)>;
-constexpr std::chrono::milliseconds kMinPollIntervalMs = std::chrono::milliseconds(2000);
-constexpr std::chrono::milliseconds kUeventPollTimeoutMs = std::chrono::milliseconds(300000);
-
-enum FormulaOption : uint32_t {
- COUNT_THRESHOLD = 0,
- WEIGHTED_AVG,
- MAXIMUM,
- MINIMUM,
-};
-
-struct VirtualSensorInfo {
- std::vector<std::string> linked_sensors;
- std::vector<float> coefficients;
- float offset;
- std::string trigger_sensor;
- FormulaOption formula;
-};
-
-struct VirtualPowerRailInfo {
- std::vector<std::string> linked_power_rails;
- std::vector<float> coefficients;
- float offset;
- FormulaOption formula;
-};
-
-// The method when the ODPM power is lower than threshold
-enum ReleaseLogic : uint32_t {
- INCREASE = 0, // Increase throttling by step
- DECREASE, // Decrease throttling by step
- STEPWISE, // Support both increase and decrease logix
- RELEASE_TO_FLOOR, // Release throttling to floor directly
- NONE,
-};
-
-struct BindedCdevInfo {
- CdevArray limit_info;
- ThrottlingArray power_thresholds;
- ReleaseLogic release_logic;
- ThrottlingArray cdev_weight_for_pid;
- CdevArray cdev_ceiling;
- CdevArray cdev_floor_with_power_link;
- std::string power_rail;
- // The flag for activate release logic when power is higher than power threshold
- bool high_power_check;
- // The flag for only triggering throttling until all power samples are collected
- bool throttling_with_power_link;
-};
-
-struct ThrottlingInfo {
- ThrottlingArray k_po;
- ThrottlingArray k_pu;
- ThrottlingArray k_i;
- ThrottlingArray k_d;
- ThrottlingArray i_max;
- ThrottlingArray max_alloc_power;
- ThrottlingArray min_alloc_power;
- ThrottlingArray s_power;
- ThrottlingArray i_cutoff;
- std::unordered_map<std::string, BindedCdevInfo> binded_cdev_info_map;
-};
struct SensorInfo {
TemperatureType_2_0 type;
@@ -102,38 +42,18 @@
ThrottlingArray cold_thresholds;
ThrottlingArray hot_hysteresis;
ThrottlingArray cold_hysteresis;
- std::string temp_path;
float vr_threshold;
float multiplier;
- std::chrono::milliseconds polling_delay;
- std::chrono::milliseconds passive_delay;
- bool send_cb;
- bool send_powerhint;
bool is_monitor;
- std::unique_ptr<VirtualSensorInfo> virtual_sensor_info;
- std::unique_ptr<ThrottlingInfo> throttling_info;
};
-struct CdevInfo {
- CoolingType_2_0 type;
- std::string read_path;
- std::string write_path;
- std::vector<float> state2power;
- int max_state;
-};
-struct PowerRailInfo {
- std::string rail;
- int power_sample_count;
- std::chrono::milliseconds power_sample_delay;
- std::unique_ptr<VirtualPowerRailInfo> virtual_power_rail_info;
-};
-
-std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path);
-std::unordered_map<std::string, CdevInfo> ParseCoolingDevice(std::string_view config_path);
-std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_view config_path);
+std::map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path);
+std::map<std::string, CoolingType> ParseCoolingDevice(std::string_view config_path);
} // namespace implementation
} // namespace V2_0
} // namespace thermal
} // namespace hardware
} // namespace android
+
+#endif // THERMAL_UTILS_CONFIG_PARSER_H__
diff --git a/thermal/utils/power_files.cpp b/thermal/utils/power_files.cpp
deleted file mode 100644
index b91061a..0000000
--- a/thermal/utils/power_files.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-#include <dirent.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include "power_files.h"
-
-namespace android {
-namespace hardware {
-namespace thermal {
-namespace V2_0 {
-namespace implementation {
-
-constexpr std::string_view kDeviceType("iio:device");
-constexpr std::string_view kIioRootDir("/sys/bus/iio/devices");
-constexpr std::string_view kEnergyValueNode("energy_value");
-
-using android::base::ReadFileToString;
-using android::base::StringPrintf;
-
-void PowerFiles::setPowerDataToDefault(std::string_view sensor_name) {
- std::unique_lock<std::shared_mutex> _lock(throttling_release_map_mutex_);
- if (!throttling_release_map_.count(sensor_name.data()) ||
- !power_status_map_.count(sensor_name.data())) {
- return;
- }
-
- auto &cdev_release_map = throttling_release_map_.at(sensor_name.data());
- PowerSample power_sample = {};
-
- for (auto &power_status_pair : power_status_map_.at(sensor_name.data())) {
- for (size_t i = 0; i < power_status_pair.second.power_history.size(); ++i) {
- for (size_t j = 0; j < power_status_pair.second.power_history[i].size(); ++j) {
- power_status_pair.second.power_history[i].pop();
- power_status_pair.second.power_history[i].emplace(power_sample);
- }
- }
- power_status_pair.second.last_updated_avg_power = NAN;
- }
-
- for (auto &cdev_release_pair : cdev_release_map) {
- cdev_release_pair.second.release_step = 0;
- }
-}
-
-int PowerFiles::getReleaseStep(std::string_view sensor_name, std::string_view cdev_name) {
- int release_step = 0;
- std::shared_lock<std::shared_mutex> _lock(throttling_release_map_mutex_);
-
- if (throttling_release_map_.count(sensor_name.data()) &&
- throttling_release_map_[sensor_name.data()].count(cdev_name.data())) {
- release_step = throttling_release_map_[sensor_name.data()][cdev_name.data()].release_step;
- }
-
- return release_step;
-}
-
-bool PowerFiles::registerPowerRailsToWatch(std::string_view sensor_name, std::string_view cdev_name,
- const BindedCdevInfo &binded_cdev_info,
- const CdevInfo &cdev_info,
- const PowerRailInfo &power_rail_info) {
- std::vector<std::queue<PowerSample>> power_history;
- PowerSample power_sample = {
- .energy_counter = 0,
- .duration = 0,
- };
-
- if (throttling_release_map_.count(sensor_name.data()) &&
- throttling_release_map_[sensor_name.data()].count(binded_cdev_info.power_rail)) {
- return true;
- }
-
- if (!energy_info_map_.size() && !updateEnergyValues()) {
- LOG(ERROR) << "Faield to update energy info";
- return false;
- }
-
- if (power_rail_info.virtual_power_rail_info != nullptr &&
- power_rail_info.virtual_power_rail_info->linked_power_rails.size()) {
- for (size_t i = 0; i < power_rail_info.virtual_power_rail_info->linked_power_rails.size();
- ++i) {
- if (energy_info_map_.count(
- power_rail_info.virtual_power_rail_info->linked_power_rails[i])) {
- power_history.emplace_back(std::queue<PowerSample>());
- for (int j = 0; j < power_rail_info.power_sample_count; j++) {
- power_history[i].emplace(power_sample);
- }
- }
- }
- } else {
- if (energy_info_map_.count(power_rail_info.rail)) {
- power_history.emplace_back(std::queue<PowerSample>());
- for (int j = 0; j < power_rail_info.power_sample_count; j++) {
- power_history[0].emplace(power_sample);
- }
- }
- }
-
- if (power_history.size()) {
- throttling_release_map_[sensor_name.data()][cdev_name.data()] = {
- .release_step = 0,
- .max_release_step = cdev_info.max_state,
- };
- power_status_map_[sensor_name.data()][binded_cdev_info.power_rail] = {
- .power_history = power_history,
- .time_remaining = power_rail_info.power_sample_delay,
- .last_updated_avg_power = NAN,
- };
- } else {
- return false;
- }
-
- LOG(INFO) << "Sensor " << sensor_name.data() << " successfully registers power rail "
- << binded_cdev_info.power_rail << " for cooling device " << cdev_name.data();
- return true;
-}
-
-bool PowerFiles::findEnergySourceToWatch(void) {
- std::string devicePath;
-
- if (energy_path_set_.size()) {
- return true;
- }
-
- std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(kIioRootDir.data()), closedir);
- if (!dir) {
- PLOG(ERROR) << "Error opening directory" << kIioRootDir;
- return false;
- }
-
- // Find any iio:devices that support energy_value
- while (struct dirent *ent = readdir(dir.get())) {
- std::string devTypeDir = ent->d_name;
- if (devTypeDir.find(kDeviceType) != std::string::npos) {
- devicePath = StringPrintf("%s/%s", kIioRootDir.data(), devTypeDir.data());
- std::string deviceEnergyContent;
-
- if (!ReadFileToString(StringPrintf("%s/%s", devicePath.data(), kEnergyValueNode.data()),
- &deviceEnergyContent)) {
- } else if (deviceEnergyContent.size()) {
- energy_path_set_.emplace(
- StringPrintf("%s/%s", devicePath.data(), kEnergyValueNode.data()));
- }
- }
- }
-
- if (!energy_path_set_.size()) {
- return false;
- }
-
- return true;
-}
-
-void PowerFiles::clearEnergyInfoMap(void) {
- energy_info_map_.clear();
-}
-
-bool PowerFiles::updateEnergyValues(void) {
- std::string deviceEnergyContent;
- std::string deviceEnergyContents;
- std::string line;
-
- for (const auto &path : energy_path_set_) {
- if (!android::base::ReadFileToString(path, &deviceEnergyContent)) {
- LOG(ERROR) << "Failed to read energy content from " << path;
- return false;
- } else {
- deviceEnergyContents.append(deviceEnergyContent);
- }
- }
-
- std::istringstream energyData(deviceEnergyContents);
-
- clearEnergyInfoMap();
- while (std::getline(energyData, line)) {
- /* Read rail energy */
- uint64_t energy_counter = 0;
- uint64_t duration = 0;
-
- /* Format example: CH3(T=358356)[S2M_VDD_CPUCL2], 761330 */
- auto start_pos = line.find("T=");
- auto end_pos = line.find(')');
- if (start_pos != std::string::npos) {
- duration =
- strtoul(line.substr(start_pos + 2, end_pos - start_pos - 2).c_str(), NULL, 10);
- } else {
- continue;
- }
-
- start_pos = line.find(")[");
- end_pos = line.find(']');
- std::string railName;
- if (start_pos != std::string::npos) {
- railName = line.substr(start_pos + 2, end_pos - start_pos - 2);
- } else {
- continue;
- }
-
- start_pos = line.find("],");
- if (start_pos != std::string::npos) {
- energy_counter = strtoul(line.substr(start_pos + 2).c_str(), NULL, 10);
- } else {
- continue;
- }
-
- energy_info_map_[railName] = {
- .energy_counter = energy_counter,
- .duration = duration,
- };
- }
-
- return true;
-}
-
-bool PowerFiles::getAveragePower(std::string_view power_rail,
- std::queue<PowerSample> *power_history, bool power_sample_update,
- float *avg_power) {
- const auto curr_sample = energy_info_map_.at(power_rail.data());
- bool ret = true;
-
- const auto last_sample = power_history->front();
- const auto duration = curr_sample.duration - last_sample.duration;
- const auto deltaEnergy = curr_sample.energy_counter - last_sample.energy_counter;
-
- if (!last_sample.duration) {
- LOG(VERBOSE) << "Power rail " << power_rail.data() << ": the last energy timestamp is zero";
- } else if (duration <= 0 || deltaEnergy < 0) {
- LOG(ERROR) << "Power rail " << power_rail.data() << " is invalid: duration = " << duration
- << ", deltaEnergy = " << deltaEnergy;
-
- ret = false;
- } else {
- *avg_power = static_cast<float>(deltaEnergy) / static_cast<float>(duration);
- LOG(VERBOSE) << "Power rail " << power_rail.data() << ", avg power = " << *avg_power
- << ", duration = " << duration << ", deltaEnergy = " << deltaEnergy;
- }
-
- if (power_sample_update) {
- power_history->pop();
- power_history->push(curr_sample);
- }
-
- return ret;
-}
-
-bool PowerFiles::computeAveragePower(const PowerRailInfo &power_rail_info,
- PowerStatus *power_status, bool power_sample_update,
- float *avg_power) {
- bool ret = true;
-
- float avg_power_val = -1;
- float offset = power_rail_info.virtual_power_rail_info->offset;
- for (size_t i = 0; i < power_rail_info.virtual_power_rail_info->linked_power_rails.size();
- i++) {
- float coefficient = power_rail_info.virtual_power_rail_info->coefficients[i];
- float avg_power_number = -1;
- if (!getAveragePower(power_rail_info.virtual_power_rail_info->linked_power_rails[i],
- &power_status->power_history[i], power_sample_update,
- &avg_power_number)) {
- ret = false;
- continue;
- } else if (avg_power_number < 0) {
- continue;
- }
- switch (power_rail_info.virtual_power_rail_info->formula) {
- case FormulaOption::COUNT_THRESHOLD:
- if ((coefficient < 0 && avg_power_number < -coefficient) ||
- (coefficient >= 0 && avg_power_number >= coefficient))
- avg_power_val += 1;
- break;
- case FormulaOption::WEIGHTED_AVG:
- avg_power_val += avg_power_number * coefficient;
- break;
- case FormulaOption::MAXIMUM:
- if (i == 0)
- avg_power_val = std::numeric_limits<float>::lowest();
- if (avg_power_number * coefficient > avg_power_val)
- avg_power_val = avg_power_number * coefficient;
- break;
- case FormulaOption::MINIMUM:
- if (i == 0)
- avg_power_val = std::numeric_limits<float>::max();
- if (avg_power_number * coefficient < avg_power_val)
- avg_power_val = avg_power_number * coefficient;
- break;
- default:
- break;
- }
- }
- if (avg_power_val >= 0) {
- avg_power_val = avg_power_val + offset;
- }
-
- *avg_power = avg_power_val;
- return ret;
-}
-
-bool PowerFiles::throttlingReleaseUpdate(std::string_view sensor_name, std::string_view cdev_name,
- const ThrottlingSeverity severity,
- const std::chrono::milliseconds time_elapsed_ms,
- const BindedCdevInfo &binded_cdev_info,
- const PowerRailInfo &power_rail_info,
- bool power_sample_update, bool severity_changed) {
- std::unique_lock<std::shared_mutex> _lock(throttling_release_map_mutex_);
- float avg_power = -1;
-
- if (!throttling_release_map_.count(sensor_name.data()) ||
- !throttling_release_map_[sensor_name.data()].count(cdev_name.data()) ||
- !power_status_map_.count(sensor_name.data()) ||
- !power_status_map_[sensor_name.data()].count(binded_cdev_info.power_rail)) {
- return false;
- }
-
- auto &release_status = throttling_release_map_[sensor_name.data()].at(cdev_name.data());
- auto &power_status = power_status_map_[sensor_name.data()].at(binded_cdev_info.power_rail);
-
- if (power_sample_update) {
- if (time_elapsed_ms > power_status.time_remaining) {
- power_status.time_remaining = power_rail_info.power_sample_delay;
- } else {
- power_status.time_remaining = power_status.time_remaining - time_elapsed_ms;
- LOG(VERBOSE) << "Power rail " << binded_cdev_info.power_rail
- << " : timeout remaining = " << power_status.time_remaining.count();
- if (!severity_changed) {
- return true;
- } else {
- // get the cached average power when thermal severity is changed
- power_sample_update = false;
- }
- }
- } else if (!severity_changed &&
- power_status.time_remaining != power_rail_info.power_sample_delay) {
- return false;
- }
-
- if (!energy_info_map_.size() && !updateEnergyValues()) {
- LOG(ERROR) << "Failed to update energy values";
- release_status.release_step = 0;
- return false;
- }
-
- if (!power_sample_update && !std::isnan(power_status.last_updated_avg_power)) {
- avg_power = power_status.last_updated_avg_power;
- } else {
- // Return false if we cannot get the average power of the target power rail
- if (!((power_rail_info.virtual_power_rail_info == nullptr)
- ? getAveragePower(binded_cdev_info.power_rail, &power_status.power_history[0],
- power_sample_update, &avg_power)
- : computeAveragePower(power_rail_info, &power_status, power_sample_update,
- &avg_power))) {
- release_status.release_step = 0;
- if (binded_cdev_info.throttling_with_power_link) {
- release_status.release_step = release_status.max_release_step;
- }
- return false;
- } else if (avg_power < 0) {
- if (binded_cdev_info.throttling_with_power_link) {
- release_status.release_step = release_status.max_release_step;
- }
- return true;
- }
- }
-
- power_status.last_updated_avg_power = avg_power;
- bool is_over_budget = true;
- if (!binded_cdev_info.high_power_check) {
- if (avg_power < binded_cdev_info.power_thresholds[static_cast<int>(severity)]) {
- is_over_budget = false;
- }
- } else {
- if (avg_power > binded_cdev_info.power_thresholds[static_cast<int>(severity)]) {
- is_over_budget = false;
- }
- }
- LOG(INFO) << "Power rail " << binded_cdev_info.power_rail << ": power threshold = "
- << binded_cdev_info.power_thresholds[static_cast<int>(severity)]
- << ", avg power = " << avg_power;
-
- switch (binded_cdev_info.release_logic) {
- case ReleaseLogic::INCREASE:
- if (!is_over_budget) {
- if (std::abs(release_status.release_step) <
- static_cast<int>(release_status.max_release_step)) {
- release_status.release_step--;
- }
- } else {
- release_status.release_step = 0;
- }
- break;
- case ReleaseLogic::DECREASE:
- if (!is_over_budget) {
- if (release_status.release_step <
- static_cast<int>(release_status.max_release_step)) {
- release_status.release_step++;
- }
- } else {
- release_status.release_step = 0;
- }
- break;
- case ReleaseLogic::STEPWISE:
- if (!is_over_budget) {
- if (release_status.release_step <
- static_cast<int>(release_status.max_release_step)) {
- release_status.release_step++;
- }
- } else {
- if (std::abs(release_status.release_step) <
- static_cast<int>(release_status.max_release_step)) {
- release_status.release_step--;
- }
- }
- break;
- case ReleaseLogic::RELEASE_TO_FLOOR:
- release_status.release_step = is_over_budget ? 0 : release_status.max_release_step;
- break;
- case ReleaseLogic::NONE:
- default:
- break;
- }
- return true;
-}
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace thermal
-} // namespace hardware
-} // namespace android
diff --git a/thermal/utils/power_files.h b/thermal/utils/power_files.h
deleted file mode 100644
index 6207ba5..0000000
--- a/thermal/utils/power_files.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2021 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 <queue>
-#include <shared_mutex>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-
-#include "config_parser.h"
-
-namespace android {
-namespace hardware {
-namespace thermal {
-namespace V2_0 {
-namespace implementation {
-
-struct PowerSample {
- uint64_t energy_counter;
- uint64_t duration;
-};
-
-struct ReleaseStatus {
- int release_step;
- int max_release_step;
-};
-
-struct PowerStatus {
- std::chrono::milliseconds time_remaining;
- // A vector to record the queues of power sample history.
- std::vector<std::queue<PowerSample>> power_history;
- float last_updated_avg_power;
-};
-
-using CdevReleaseStatus = std::unordered_map<std::string, ReleaseStatus>;
-using PowerStatusMap = std::unordered_map<std::string, PowerStatus>;
-
-// A helper class for monitoring power rails.
-class PowerFiles {
- public:
- PowerFiles() = default;
- ~PowerFiles() = default;
- // Disallow copy and assign.
- PowerFiles(const PowerFiles &) = delete;
- void operator=(const PowerFiles &) = delete;
-
- // Register a map for the throttling release decision of target power rail
- // Return false if the power_rail is not supported.
- bool registerPowerRailsToWatch(std::string_view sensor_name, std::string_view cdev_name,
- const BindedCdevInfo &binded_cdev_info,
- const CdevInfo &cdev_info, const PowerRailInfo &power_rail_info);
-
- // Find the energy source path, return false if no energy source found.
- bool findEnergySourceToWatch(void);
-
- // Clear the data of energy_info_map_.
- void clearEnergyInfoMap(void);
-
- // Update energy value to energy_info_map_, return false if the value is failed to update.
- bool updateEnergyValues(void);
-
- bool getAveragePower(std::string_view power_rail, std::queue<PowerSample> *power_history,
- bool power_sample_update, float *avg_power);
- bool computeAveragePower(const PowerRailInfo &power_rail_info, PowerStatus *power_status,
- bool power_sample_update, float *avg_power);
-
- // Update the throttling release status according to the average power, return true if power
- // rail is updated.
- bool throttlingReleaseUpdate(std::string_view sensor_name, std::string_view cdev_name,
- const ThrottlingSeverity severity,
- const std::chrono::milliseconds time_elapsed_ms,
- const BindedCdevInfo &binded_cdev_info,
- const PowerRailInfo &power_rail_info, bool power_sample_update,
- bool severity_changed);
-
- // Get the throttling release status for the targer power rail which is binded in specific
- // sensor.
- int getReleaseStep(std::string_view sensor_name, std::string_view cdev_name);
-
- // Clear the data of throttling_release_map_.
- void setPowerDataToDefault(std::string_view sensor_name);
-
- // Get throttling release status map
- const std::unordered_map<std::string, CdevReleaseStatus> &GetThrottlingReleaseMap() const {
- std::shared_lock<std::shared_mutex> _lock(throttling_release_map_mutex_);
- return throttling_release_map_;
- }
-
- // Get Power status map
- const std::unordered_map<std::string, PowerStatusMap> &GetPowerStatusMap() const {
- std::shared_lock<std::shared_mutex> _lock(power_status_map_mutex_);
- return power_status_map_;
- }
-
- private:
- // The map to record the energy info for each power rail.
- std::unordered_map<std::string, PowerSample> energy_info_map_;
- // The map to record the throttling release status for each thermal sensor.
- std::unordered_map<std::string, CdevReleaseStatus> throttling_release_map_;
- mutable std::shared_mutex throttling_release_map_mutex_;
- // The map to record the power data for each thermal sensor.
- std::unordered_map<std::string, PowerStatusMap> power_status_map_;
- mutable std::shared_mutex power_status_map_mutex_;
- // The set to store the energy source paths
- std::unordered_set<std::string> energy_path_set_;
-};
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace thermal
-} // namespace hardware
-} // namespace android
diff --git a/thermal/utils/thermal_files.cpp b/thermal/utils/thermal_files.cpp
index e5eb6be..c394816 100644
--- a/thermal/utils/thermal_files.cpp
+++ b/thermal/utils/thermal_files.cpp
@@ -19,7 +19,6 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include "thermal_files.h"
@@ -46,7 +45,6 @@
std::string file_path = getThermalFilePath(std::string_view(thermal_name));
*data = "";
if (file_path.empty()) {
- PLOG(WARNING) << "Failed to find " << thermal_name << "'s path";
return false;
}
@@ -60,18 +58,6 @@
return true;
}
-bool ThermalFiles::writeCdevFile(std::string_view cdev_name, std::string_view data) {
- std::string file_path =
- getThermalFilePath(android::base::StringPrintf("%s_%s", cdev_name.data(), "w"));
-
- if (!android::base::WriteStringToFile(data.data(), file_path)) {
- PLOG(WARNING) << "Failed to write cdev: " << cdev_name << " to " << data.data();
- return false;
- }
-
- return true;
-}
-
} // namespace implementation
} // namespace V2_0
} // namespace thermal
diff --git a/thermal/utils/thermal_files.h b/thermal/utils/thermal_files.h
index 0c0a852..d2c86dd 100644
--- a/thermal/utils/thermal_files.h
+++ b/thermal/utils/thermal_files.h
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#pragma once
+#ifndef THERMAL_UTILS_THERMAL_FILES_H_
+#define THERMAL_UTILS_THERMAL_FILES_H_
#include <string>
#include <unordered_map>
@@ -39,7 +40,6 @@
// data to empty and return false. If the thermal_name is found and its content
// is read, this function will fill in data accordingly then return true.
bool readThermalFile(std::string_view thermal_name, std::string *data) const;
- bool writeCdevFile(std::string_view thermal_name, std::string_view data);
size_t getNumThermalFiles() const { return thermal_name_to_path_map_.size(); }
private:
@@ -51,3 +51,5 @@
} // namespace thermal
} // namespace hardware
} // namespace android
+
+#endif // THERMAL_UTILS_THERMAL_FILES_H_
diff --git a/thermal/utils/thermal_watcher.cpp b/thermal/utils/thermal_watcher.cpp
index 9c1f96b..31a89a0 100644
--- a/thermal/utils/thermal_watcher.cpp
+++ b/thermal/utils/thermal_watcher.cpp
@@ -15,11 +15,6 @@
*/
#include <cutils/uevent.h>
#include <dirent.h>
-#include <linux/genetlink.h>
-#include <linux/netlink.h>
-#include <linux/thermal.h>
-#include <netlink/genl/ctrl.h>
-#include <netlink/genl/genl.h>
#include <sys/inotify.h>
#include <sys/resource.h>
#include <sys/types.h>
@@ -28,10 +23,8 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
#include <android-base/strings.h>
-#include "thermal-helper.h"
#include "thermal_watcher.h"
namespace android {
@@ -40,360 +33,27 @@
namespace V2_0 {
namespace implementation {
-namespace {
+using std::chrono_literals::operator""ms;
-static int nlErrorHandle(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
- int *ret = reinterpret_cast<int *>(arg);
- *ret = err->error;
- LOG(ERROR) << __func__ << "nl_groups: " << nla->nl_groups << ", nl_pid: " << nla->nl_pid;
-
- return NL_STOP;
-}
-
-static int nlFinishHandle(struct nl_msg *msg, void *arg) {
- int *ret = reinterpret_cast<int *>(arg);
- *ret = 1;
- struct nlmsghdr *nlh = nlmsg_hdr(msg);
-
- LOG(VERBOSE) << __func__ << ": nlmsg type: " << nlh->nlmsg_type;
-
- return NL_OK;
-}
-
-static int nlAckHandle(struct nl_msg *msg, void *arg) {
- int *ret = reinterpret_cast<int *>(arg);
- *ret = 1;
- struct nlmsghdr *nlh = nlmsg_hdr(msg);
-
- LOG(VERBOSE) << __func__ << ": nlmsg type: " << nlh->nlmsg_type;
-
- return NL_OK;
-}
-
-static int nlSeqCheckHandle(struct nl_msg *msg, void *arg) {
- int *ret = reinterpret_cast<int *>(arg);
- *ret = 1;
- struct nlmsghdr *nlh = nlmsg_hdr(msg);
-
- LOG(VERBOSE) << __func__ << ": nlmsg type: " << nlh->nlmsg_type;
-
- return NL_OK;
-}
-
-struct HandlerArgs {
- const char *group;
- int id;
-};
-
-static int nlSendMsg(struct nl_sock *sock, struct nl_msg *msg,
- int (*rx_handler)(struct nl_msg *, void *), void *data) {
- int err, done = 0;
-
- std::unique_ptr<nl_cb, decltype(&nl_cb_put)> cb(nl_cb_alloc(NL_CB_DEFAULT), nl_cb_put);
-
- err = nl_send_auto_complete(sock, msg);
- if (err < 0)
- return err;
-
- err = 0;
- nl_cb_err(cb.get(), NL_CB_CUSTOM, nlErrorHandle, &err);
- nl_cb_set(cb.get(), NL_CB_FINISH, NL_CB_CUSTOM, nlFinishHandle, &done);
- nl_cb_set(cb.get(), NL_CB_ACK, NL_CB_CUSTOM, nlAckHandle, &done);
-
- if (rx_handler != NULL)
- nl_cb_set(cb.get(), NL_CB_VALID, NL_CB_CUSTOM, rx_handler, data);
-
- while (err == 0 && done == 0) nl_recvmsgs(sock, cb.get());
-
- return err;
-}
-
-static int nlFamilyHandle(struct nl_msg *msg, void *arg) {
- struct HandlerArgs *grp = reinterpret_cast<struct HandlerArgs *>(arg);
- struct nlattr *tb[CTRL_ATTR_MAX + 1];
- struct genlmsghdr *gnlh = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
- struct nlattr *mcgrp;
- int rem_mcgrp;
-
- nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
-
- if (!tb[CTRL_ATTR_MCAST_GROUPS]) {
- LOG(ERROR) << __func__ << "Multicast group not found";
- return -1;
- }
-
- nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp) {
- struct nlattr *tb_mcgrp[CTRL_ATTR_MCAST_GRP_MAX + 1];
-
- nla_parse(tb_mcgrp, CTRL_ATTR_MCAST_GRP_MAX, reinterpret_cast<nlattr *>(nla_data(mcgrp)),
- nla_len(mcgrp), NULL);
-
- if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME] || !tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID])
- continue;
-
- if (strncmp(reinterpret_cast<char *>(nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME])),
- grp->group, nla_len(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
- continue;
-
- grp->id = nla_get_u32(tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]);
-
- break;
- }
-
- return 0;
-}
-
-static int nlGetMulticastId(struct nl_sock *sock, const char *family, const char *group) {
- int err = 0, ctrlid;
- struct HandlerArgs grp = {
- .group = group,
- .id = -ENOENT,
- };
-
- std::unique_ptr<nl_msg, decltype(&nlmsg_free)> msg(nlmsg_alloc(), nlmsg_free);
-
- ctrlid = genl_ctrl_resolve(sock, "nlctrl");
-
- genlmsg_put(msg.get(), 0, 0, ctrlid, 0, 0, CTRL_CMD_GETFAMILY, 0);
-
- nla_put_string(msg.get(), CTRL_ATTR_FAMILY_NAME, family);
-
- err = nlSendMsg(sock, msg.get(), nlFamilyHandle, &grp);
- if (err)
- return err;
-
- err = grp.id;
- LOG(INFO) << group << " multicast_id: " << grp.id;
-
- return err;
-}
-
-static bool socketAddMembership(struct nl_sock *sock, const char *group) {
- int mcid = nlGetMulticastId(sock, THERMAL_GENL_FAMILY_NAME, group);
- if (mcid < 0) {
- LOG(ERROR) << "Failed to get multicast id: " << group;
- return false;
- }
-
- if (nl_socket_add_membership(sock, mcid)) {
- LOG(ERROR) << "Failed to add netlink socket membership: " << group;
- return false;
- }
-
- LOG(INFO) << "Added netlink socket membership: " << group;
- return true;
-}
-
-static int handleEvent(struct nl_msg *n, void *arg) {
- struct nlmsghdr *nlh = nlmsg_hdr(n);
- struct genlmsghdr *glh = genlmsg_hdr(nlh);
- struct nlattr *attrs[THERMAL_GENL_ATTR_MAX + 1];
- int *tz_id = reinterpret_cast<int *>(arg);
-
- genlmsg_parse(nlh, 0, attrs, THERMAL_GENL_ATTR_MAX, NULL);
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_UP) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_UP";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
- LOG(INFO) << "Thermal zone trip id: "
- << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_DOWN) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_DOWN";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
- LOG(INFO) << "Thermal zone trip id: "
- << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_GOV_CHANGE) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_GOV_CHANGE";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- if (attrs[THERMAL_GENL_ATTR_GOV_NAME])
- LOG(INFO) << "Governor name: " << nla_get_string(attrs[THERMAL_GENL_ATTR_GOV_NAME]);
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_CREATE) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_CREATE";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- if (attrs[THERMAL_GENL_ATTR_TZ_NAME])
- LOG(INFO) << "Thermal zone name: " << nla_get_string(attrs[THERMAL_GENL_ATTR_TZ_NAME]);
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_DELETE) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_DELETE";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_DISABLE) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_DISABLE";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_ENABLE) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_ENABLE";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_CHANGE) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_CHANGE";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
- LOG(INFO) << "Trip id:: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE])
- LOG(INFO) << "Trip type: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE]);
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP])
- LOG(INFO) << "Trip temp: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP]);
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST])
- LOG(INFO) << "Trip hyst: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST]);
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_ADD) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_ADD";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID])
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
- LOG(INFO) << "Trip id:: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE])
- LOG(INFO) << "Trip type: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE]);
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP])
- LOG(INFO) << "Trip temp: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP]);
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST])
- LOG(INFO) << "Trip hyst: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST]);
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_TZ_TRIP_DELETE) {
- LOG(INFO) << "THERMAL_GENL_EVENT_TZ_TRIP_DELETE";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- if (attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID])
- LOG(INFO) << "Trip id:: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]);
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_CDEV_STATE_UPDATE) {
- LOG(INFO) << "THERMAL_GENL_EVENT_CDEV_STATE_UPDATE";
- if (attrs[THERMAL_GENL_ATTR_CDEV_ID])
- LOG(INFO) << "Cooling device id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]);
- if (attrs[THERMAL_GENL_ATTR_CDEV_CUR_STATE])
- LOG(INFO) << "Cooling device current state: "
- << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_CUR_STATE]);
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_CDEV_ADD) {
- LOG(INFO) << "THERMAL_GENL_EVENT_CDEV_ADD";
- if (attrs[THERMAL_GENL_ATTR_CDEV_NAME])
- LOG(INFO) << "Cooling device name: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_NAME]);
- if (attrs[THERMAL_GENL_ATTR_CDEV_ID])
- LOG(INFO) << "Cooling device id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]);
- if (attrs[THERMAL_GENL_ATTR_CDEV_MAX_STATE])
- LOG(INFO) << "Cooling device max state: "
- << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_MAX_STATE]);
- }
-
- if (glh->cmd == THERMAL_GENL_EVENT_CDEV_DELETE) {
- LOG(INFO) << "THERMAL_GENL_EVENT_CDEV_DELETE";
- if (attrs[THERMAL_GENL_ATTR_CDEV_ID])
- LOG(INFO) << "Cooling device id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]);
- }
-
- if (glh->cmd == THERMAL_GENL_SAMPLING_TEMP) {
- LOG(INFO) << "THERMAL_GENL_SAMPLING_TEMP";
- if (attrs[THERMAL_GENL_ATTR_TZ_ID]) {
- LOG(INFO) << "Thermal zone id: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- *tz_id = nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]);
- }
- if (attrs[THERMAL_GENL_ATTR_TZ_TEMP])
- LOG(INFO) << "Thermal zone temp: " << nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]);
- }
-
- return 0;
-}
-
-} // namespace
-
-void ThermalWatcher::registerFilesToWatch(const std::set<std::string> &sensors_to_watch) {
- LOG(INFO) << "Uevent register file to watch...";
+void ThermalWatcher::registerFilesToWatch(const std::set<std::string> &sensors_to_watch,
+ bool uevent_monitor) {
monitored_sensors_.insert(sensors_to_watch.begin(), sensors_to_watch.end());
-
+ if (!uevent_monitor) {
+ is_polling_ = true;
+ return;
+ }
uevent_fd_.reset((TEMP_FAILURE_RETRY(uevent_open_socket(64 * 1024, true))));
if (uevent_fd_.get() < 0) {
LOG(ERROR) << "failed to open uevent socket";
+ is_polling_ = true;
return;
}
fcntl(uevent_fd_, F_SETFL, O_NONBLOCK);
looper_->addFd(uevent_fd_.get(), 0, Looper::EVENT_INPUT, nullptr, nullptr);
- sleep_ms_ = std::chrono::milliseconds(0);
- last_update_time_ = boot_clock::now();
-}
-
-void ThermalWatcher::registerFilesToWatchNl(const std::set<std::string> &sensors_to_watch) {
- LOG(INFO) << "Thermal genl register file to watch...";
- monitored_sensors_.insert(sensors_to_watch.begin(), sensors_to_watch.end());
-
- sk_thermal = nl_socket_alloc();
- if (!sk_thermal) {
- LOG(ERROR) << "nl_socket_alloc failed";
- return;
- }
-
- if (genl_connect(sk_thermal)) {
- LOG(ERROR) << "genl_connect failed: sk_thermal";
- return;
- }
-
- thermal_genl_fd_.reset(nl_socket_get_fd(sk_thermal));
- if (thermal_genl_fd_.get() < 0) {
- LOG(ERROR) << "Failed to create thermal netlink socket";
- return;
- }
-
- if (!socketAddMembership(sk_thermal, THERMAL_GENL_EVENT_GROUP_NAME)) {
- return;
- }
-
- /*
- * Currently, only the update_temperature() will send thermal genl samlping events
- * from kernel. To avoid thermal-hal busy because samlping events are sent
- * too frequently, ignore thermal genl samlping events until we figure out how to use it.
- *
- if (!socketAddMembership(sk_thermal, THERMAL_GENL_SAMPLING_GROUP_NAME)) {
- return;
- }
- */
-
- fcntl(thermal_genl_fd_, F_SETFL, O_NONBLOCK);
- looper_->addFd(thermal_genl_fd_.get(), 0, Looper::EVENT_INPUT, nullptr, nullptr);
- sleep_ms_ = std::chrono::milliseconds(0);
+ is_polling_ = false;
+ thermal_triggered_ = true;
last_update_time_ = boot_clock::now();
}
@@ -436,10 +96,9 @@
cp = msg;
while (*cp) {
std::string uevent = cp;
- auto findSubSystemThermal = uevent.find("SUBSYSTEM=thermal");
if (!thermal_event) {
- if (!uevent.find("SUBSYSTEM=")) {
- if (findSubSystemThermal != std::string::npos) {
+ if (uevent.find("SUBSYSTEM=") == 0) {
+ if (uevent.find("SUBSYSTEM=thermal") != std::string::npos) {
thermal_event = true;
} else {
break;
@@ -463,64 +122,34 @@
}
}
-// TODO(b/175367921): Consider for potentially adding more type of event in the function
-// instead of just add the sensors to the list.
-void ThermalWatcher::parseGenlink(std::set<std::string> *sensors_set) {
- int err = 0, done = 0, tz_id = -1;
-
- std::unique_ptr<nl_cb, decltype(&nl_cb_put)> cb(nl_cb_alloc(NL_CB_DEFAULT), nl_cb_put);
-
- nl_cb_err(cb.get(), NL_CB_CUSTOM, nlErrorHandle, &err);
- nl_cb_set(cb.get(), NL_CB_FINISH, NL_CB_CUSTOM, nlFinishHandle, &done);
- nl_cb_set(cb.get(), NL_CB_ACK, NL_CB_CUSTOM, nlAckHandle, &done);
- nl_cb_set(cb.get(), NL_CB_SEQ_CHECK, NL_CB_CUSTOM, nlSeqCheckHandle, &done);
- nl_cb_set(cb.get(), NL_CB_VALID, NL_CB_CUSTOM, handleEvent, &tz_id);
-
- while (!done && !err) {
- nl_recvmsgs(sk_thermal, cb.get());
-
- if (tz_id < 0) {
- break;
- }
-
- std::string name;
- if (getThermalZoneTypeById(tz_id, &name) &&
- std::find(monitored_sensors_.begin(), monitored_sensors_.end(), name) !=
- monitored_sensors_.end()) {
- sensors_set->insert(name);
- }
- }
-}
-
void ThermalWatcher::wake() {
looper_->wake();
}
bool ThermalWatcher::threadLoop() {
LOG(VERBOSE) << "ThermalWatcher polling...";
-
+ // Polling interval 2s
+ static constexpr int kMinPollIntervalMs = 2000;
+ // Max uevent timeout 5mins
+ static constexpr int kUeventPollTimeoutMs = 300000;
int fd;
std::set<std::string> sensors;
auto time_elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() -
- last_update_time_);
-
- if (time_elapsed_ms < sleep_ms_ &&
- looper_->pollOnce(sleep_ms_.count(), &fd, nullptr, nullptr) >= 0) {
- if (fd != uevent_fd_.get() && fd != thermal_genl_fd_.get()) {
+ last_update_time_)
+ .count();
+ int timeout = (thermal_triggered_ || is_polling_) ? kMinPollIntervalMs : kUeventPollTimeoutMs;
+ if (time_elapsed_ms < timeout && looper_->pollOnce(timeout, &fd, nullptr, nullptr) >= 0) {
+ if (fd != uevent_fd_.get()) {
return true;
- } else if (fd == thermal_genl_fd_.get()) {
- parseGenlink(&sensors);
- } else if (fd == uevent_fd_.get()) {
- parseUevent(&sensors);
}
+ parseUevent(&sensors);
// Ignore cb_ if uevent is not from monitored sensors
if (sensors.size() == 0) {
return true;
}
}
-
- sleep_ms_ = cb_(sensors);
+ thermal_triggered_ = cb_(sensors);
last_update_time_ = boot_clock::now();
return true;
}
diff --git a/thermal/utils/thermal_watcher.h b/thermal/utils/thermal_watcher.h
index 7f6a44a..f8cd044 100644
--- a/thermal/utils/thermal_watcher.h
+++ b/thermal/utils/thermal_watcher.h
@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-#pragma once
+#ifndef THERMAL_UTILS_THERMAL_WATCHER_H_
+#define THERMAL_UTILS_THERMAL_WATCHER_H_
#include <chrono>
#include <condition_variable>
@@ -40,12 +40,12 @@
using android::base::boot_clock;
using android::base::unique_fd;
-using WatcherCallback = std::function<std::chrono::milliseconds(const std::set<std::string> &name)>;
+using WatcherCallback = std::function<bool(const std::set<std::string> &name)>;
// A helper class for monitoring thermal files changes.
class ThermalWatcher : public ::android::Thread {
public:
- explicit ThermalWatcher(const WatcherCallback &cb)
+ ThermalWatcher(const WatcherCallback &cb)
: Thread(false), cb_(cb), looper_(new Looper(true)) {}
~ThermalWatcher() = default;
@@ -58,10 +58,7 @@
// Give the file watcher a list of files to start watching. This helper
// class will by default wait for modifications to the file with a looper.
// This should be called before starting watcher thread.
- // For monitoring uevents.
- void registerFilesToWatch(const std::set<std::string> &sensors_to_watch);
- // For monitoring thermal genl events.
- void registerFilesToWatchNl(const std::set<std::string> &sensors_to_watch);
+ void registerFilesToWatch(const std::set<std::string> &sensors_to_watch, bool uevent_monitor);
// Wake up the looper thus the worker thread, immediately. This can be called
// in any thread.
void wake();
@@ -76,9 +73,6 @@
// Parse uevent message
void parseUevent(std::set<std::string> *sensor_name);
- // Parse thermal netlink message
- void parseGenlink(std::set<std::string> *sensor_name);
-
// Maps watcher filer descriptor to watched file path.
std::unordered_map<int, std::string> watch_to_file_path_map_;
@@ -92,16 +86,14 @@
// For uevent socket registration.
android::base::unique_fd uevent_fd_;
- // For thermal genl socket registration.
- android::base::unique_fd thermal_genl_fd_;
// Sensor list which monitor flag is enabled.
std::set<std::string> monitored_sensors_;
- // Sleep interval voting result
- std::chrono::milliseconds sleep_ms_;
+ // Flag to point out if any sensor across the first threshold.
+ bool thermal_triggered_;
+ // Flag to point out if device can support uevent notify.
+ bool is_polling_;
// Timestamp for last thermal update
boot_clock::time_point last_update_time_;
- // For thermal genl socket object.
- struct nl_sock *sk_thermal;
};
} // namespace implementation
@@ -109,3 +101,5 @@
} // namespace thermal
} // namespace hardware
} // namespace android
+
+#endif // THERMAL_UTILS_THERMAL_WATCHER_H_
diff --git a/usb/Android.bp b/usb/Android.bp
index 8927c8a..2290918 100644
--- a/usb/Android.bp
+++ b/usb/Android.bp
@@ -14,10 +14,6 @@
* limitations under the License.
*/
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library_static {
name: "libpixelusb",
vendor_available: true,
@@ -26,7 +22,6 @@
srcs: [
"UsbGadgetUtils.cpp",
"MonitorFfs.cpp",
- "UsbOverheatEvent.cpp"
],
cflags: [
@@ -35,38 +30,10 @@
],
shared_libs: [
+ "android.hardware.usb.gadget@1.0",
"libbase",
- "libbinder",
"libcutils",
"libhidlbase",
"libutils",
- "android.hardware.usb.gadget@1.0",
- "android.hardware.thermal@1.0",
- "android.hardware.thermal@2.0",
],
}
-
-cc_fuzz {
- name: "libpixelusb_gadgetutils_fuzzer",
-
- srcs:[
- "UsbGadgetUtils_fuzz.cpp"
- ],
-
- shared_libs: [
- "android.hardware.usb.gadget@1.0",
- "libbase",
- ],
-
- static_libs: [
- "libpixelusb",
- ],
-
- fuzz_config: {
- cc: [
- "pixel-usb-triage@google.com",
- "kyletso@google.com",
- ],
- componentid: 175220,
- },
-}
diff --git a/usb/MonitorFfs.cpp b/usb/MonitorFfs.cpp
index 717e6a7..b84efbc 100644
--- a/usb/MonitorFfs.cpp
+++ b/usb/MonitorFfs.cpp
@@ -150,7 +150,7 @@
}
for (int i = 0; i < nrEvents; i++) {
- ALOGV("event=%u on fd=%d\n", events[i].events, events[i].data.fd);
+ ALOGI("event=%u on fd=%d\n", events[i].events, events[i].data.fd);
if (events[i].data.fd == monitorFfs->mInotifyFd) {
// Process all of the events in buffer returned by read().
diff --git a/usb/UsbGadgetUtils.cpp b/usb/UsbGadgetUtils.cpp
index 4df6215..115bae5 100644
--- a/usb/UsbGadgetUtils.cpp
+++ b/usb/UsbGadgetUtils.cpp
@@ -192,15 +192,8 @@
if ((functions & GadgetFunction::RNDIS) != 0) {
ALOGI("setCurrentUsbFunctions rndis");
- std::string rndisFunction = GetProperty(kVendorRndisConfig, "");
- if (rndisFunction != "") {
- if (linkFunction(rndisFunction.c_str(), (*functionCount)++))
- return Status::ERROR;
- } else {
- // link gsi.rndis for older pixel projects
- if (linkFunction("gsi.rndis", (*functionCount)++))
- return Status::ERROR;
- }
+ if (linkFunction("gsi.rndis", (*functionCount)++))
+ return Status::ERROR;
}
return Status::SUCCESS;
diff --git a/usb/UsbGadgetUtils_fuzz.cpp b/usb/UsbGadgetUtils_fuzz.cpp
deleted file mode 100644
index b79da69..0000000
--- a/usb/UsbGadgetUtils_fuzz.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include <stddef.h>
-#include <stdint.h>
-
-#include "fuzzer/FuzzedDataProvider.h"
-#include "include/pixelusb/UsbGadgetCommon.h"
-
-using ::android::hardware::google::pixel::usb::setVidPid;
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- FuzzedDataProvider fdp(data, size);
-
- std::string vid_str = fdp.ConsumeRandomLengthString(size);
- std::string pid_str = fdp.ConsumeRemainingBytesAsString();
- setVidPid(vid_str.c_str(), pid_str.c_str());
- return 0;
-}
diff --git a/usb/UsbOverheatEvent.cpp b/usb/UsbOverheatEvent.cpp
deleted file mode 100644
index 408a0ad..0000000
--- a/usb/UsbOverheatEvent.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2021 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 LOG_TAG "libPixelUsbOverheat"
-
-#include "include/pixelusb/UsbOverheatEvent.h"
-
-#include <time.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace usb {
-
-// Start monitoring the temperature
-static volatile bool monitorTemperature;
-
-constexpr int kEpollEvents = 10;
-constexpr char kOverheatLock[] = "overheat";
-constexpr char kWakeLockPath[] = "/sys/power/wake_lock";
-constexpr char kWakeUnlockPath[] = "/sys/power/wake_unlock";
-
-int addEpollFdWakeUp(const unique_fd &epfd, const unique_fd &fd) {
- struct epoll_event event;
- int ret;
-
- event.data.fd = fd;
- event.events = EPOLLIN | EPOLLWAKEUP;
-
- ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
- if (ret)
- ALOGE("epoll_ctl error %d", errno);
-
- return ret;
-}
-
-UsbOverheatEvent::UsbOverheatEvent(const ZoneInfo &monitored_zone,
- const std::vector<ZoneInfo> &queried_zones,
- const int &monitor_interval_sec)
- : monitored_zone_(monitored_zone),
- queried_zones_(queried_zones),
- monitor_interval_sec_(monitor_interval_sec),
- lock_(),
- cv_(),
- monitor_() {
- int fd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0);
- if (fd < 0) {
- ALOGE("timerfd_create failed: %d", errno);
- }
-
- unique_fd timerFd(timerfd_create(CLOCK_BOOTTIME_ALARM, 0));
- if (timerFd == -1) {
- ALOGE("timerFd failed to create %d", errno);
- abort();
- }
-
- unique_fd epollFd(epoll_create(2));
- if (epollFd == -1) {
- ALOGE("epoll_fd_ failed to create %d", errno);
- abort();
- }
-
- unique_fd eventFd(eventfd(0, 0));
- if (eventFd == -1) {
- ALOGE("event_fd_ failed to create %d", errno);
- abort();
- }
-
- if (addEpollFdWakeUp(epollFd, timerFd) == -1) {
- ALOGE("Adding timerFd failed");
- abort();
- }
-
- if (addEpollFdWakeUp(epollFd, eventFd) == -1) {
- ALOGE("Adding eventFd failed");
- abort();
- }
-
- epoll_fd_ = move(epollFd);
- timer_fd_ = move(timerFd);
- event_fd_ = move(eventFd);
-
- monitor_ = unique_ptr<thread>(new thread(this->monitorThread, this));
- registerListener();
-}
-
-static int wakelock_cnt = 0;
-static std::mutex wakelock_lock;
-
-static void wakeLockAcquire() {
- lock_guard<mutex> lock(wakelock_lock);
-
- wakelock_cnt++;
- if (wakelock_cnt == 1) {
- ALOGV("Acquire wakelock");
- if (!WriteStringToFile(kOverheatLock, kWakeLockPath)) {
- ALOGE("Failed to acquire wake lock string");
- }
- }
-}
-
-static void wakeLockRelease() {
- lock_guard<mutex> lock(wakelock_lock);
-
- wakelock_cnt--;
- if (wakelock_cnt == 0) {
- ALOGV("Release wakelock");
- if (!WriteStringToFile(kOverheatLock, kWakeUnlockPath)) {
- ALOGE("Failed to acquire wake lock string");
- }
- }
-}
-
-void *UsbOverheatEvent::monitorThread(void *param) {
- UsbOverheatEvent *overheatEvent = (UsbOverheatEvent *)param;
- struct epoll_event events[kEpollEvents];
- struct itimerspec delay = itimerspec();
- std::unique_lock<std::mutex> lk(overheatEvent->lock_);
-
- delay.it_value.tv_sec = overheatEvent->monitor_interval_sec_;
-
- while (true) {
- uint64_t fired;
- float temperature = 0;
- string status;
-
- overheatEvent->cv_.wait(lk, [] { return monitorTemperature; });
-
- for (vector<ZoneInfo>::size_type i = 0; i < overheatEvent->queried_zones_.size(); i++) {
- if (overheatEvent->getCurrentTemperature(overheatEvent->queried_zones_[i].name_,
- &temperature)) {
- if (i == 0)
- overheatEvent->max_overheat_temp_ =
- max(temperature, overheatEvent->max_overheat_temp_);
- status.append(overheatEvent->queried_zones_[i].name_);
- status.append(":");
- status.append(std::to_string(temperature));
- status.append(" ");
- }
- }
- ALOGW("%s", status.c_str());
-
- int ret = timerfd_settime(overheatEvent->timer_fd_, 0, &delay, NULL);
- if (ret < 0) {
- ALOGE("timerfd_settime failed. err:%d", errno);
- return NULL;
- }
-
- wakeLockRelease();
- int nrEvents = epoll_wait(overheatEvent->epoll_fd_, events, kEpollEvents, -1);
- wakeLockAcquire();
- if (nrEvents <= 0) {
- ALOGE("nrEvents negative skipping");
- continue;
- }
-
- for (int i = 0; i < nrEvents; i++) {
- ALOGV("event=%u on fd=%d\n", events[i].events, events[i].data.fd);
-
- if (events[i].data.fd == overheatEvent->timer_fd_) {
- int numRead = read(overheatEvent->timer_fd_, &fired, sizeof(fired));
- if (numRead != sizeof(fired)) {
- ALOGV("numRead incorrect");
- }
- if (fired != 1) {
- ALOGV("Fired not set to 1");
- }
- } else {
- read(overheatEvent->event_fd_, &fired, sizeof(fired));
- }
- }
- }
-
- return NULL;
-}
-
-bool UsbOverheatEvent::registerListener() {
- ALOGV("UsbOverheatEvent::registerListener");
- sp<IServiceManager> sm = IServiceManager::getService();
- if (sm == NULL) {
- ALOGE("Hardware service manager is not running");
- return false;
- }
- Return<bool> result = sm->registerForNotifications(IThermal::descriptor, "", this);
- if (result.isOk()) {
- return true;
- }
- ALOGE("Failed to register for hardware service manager notifications: %s",
- result.description().c_str());
- return false;
-}
-
-bool UsbOverheatEvent::startRecording() {
- lock_guard<mutex> lock(lock_);
-
- // Bail out if temperature was being monitored previously
- if (monitorTemperature)
- return true;
-
- wakeLockAcquire();
- monitorTemperature = true;
- cv_.notify_all();
- return true;
-}
-
-bool UsbOverheatEvent::stopRecording() {
- // <flag> value does not have any significance here
- uint64_t flag = 100;
- unsigned long ret;
-
- // Bail out if temperature was not being monitored previously
- if (!monitorTemperature)
- return true;
-
- wakeLockRelease();
- monitorTemperature = false;
- ret = TEMP_FAILURE_RETRY(write(event_fd_, &flag, sizeof(flag)));
- if (ret < 0) {
- ALOGE("Error writing eventfd errno=%d", errno);
- }
-
- return true;
-}
-
-bool UsbOverheatEvent::getCurrentTemperature(const string &name, float *temp) {
- ThermalStatus thermal_status;
- hidl_vec<Temperature> thermal_temperatures;
-
- if (thermal_service_ == NULL)
- return false;
-
- auto ret = thermal_service_->getCurrentTemperatures(
- false, TemperatureType::USB_PORT,
- [&](ThermalStatus status, hidl_vec<Temperature> temperatures) {
- thermal_status = status;
- thermal_temperatures = temperatures;
- });
-
- if (ret.isOk() && thermal_status.code == ThermalStatusCode::SUCCESS) {
- for (auto temperature : thermal_temperatures) {
- if (temperature.name == name) {
- *temp = temperature.value;
- return true;
- }
- }
- }
- return false;
-}
-
-float UsbOverheatEvent::getMaxOverheatTemperature() {
- return max_overheat_temp_;
-}
-
-Return<void> UsbOverheatEvent::onRegistration(const hidl_string & /*fully_qualified_name*/,
- const hidl_string & /*instance_name*/,
- bool /*pre_existing*/) {
- ThermalStatus thermal_status;
-
- thermal_service_ = IThermal::getService();
- if (thermal_service_ == NULL) {
- ALOGE("Unable to get Themal Service");
- return Void();
- }
-
- auto ret = thermal_service_->registerThermalChangedCallback(
- this, true, monitored_zone_.type_,
- [&](ThermalStatus status) { thermal_status = status; });
-
- if (!ret.isOk() || thermal_status.code != ThermalStatusCode::SUCCESS) {
- ALOGE("failed to register thermal changed callback!");
- }
-
- return Void();
-}
-
-Return<void> UsbOverheatEvent::notifyThrottling(const Temperature &temperature) {
- ALOGV("notifyThrottling '%s' T=%2.2f throttlingStatus=%d", temperature.name.c_str(),
- temperature.value, temperature.throttlingStatus);
- if (temperature.type == monitored_zone_.type_) {
- if (temperature.throttlingStatus >= monitored_zone_.severity_) {
- startRecording();
- } else {
- stopRecording();
- }
- }
- return Void();
-}
-
-ZoneInfo::ZoneInfo(const TemperatureType &type, const string &name,
- const ThrottlingSeverity &severity)
- : type_(type), name_(name), severity_(severity) {}
-} // namespace usb
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/usb/include/pixelusb/UsbGadgetCommon.h b/usb/include/pixelusb/UsbGadgetCommon.h
index 964a1d6..88b2fa5 100644
--- a/usb/include/pixelusb/UsbGadgetCommon.h
+++ b/usb/include/pixelusb/UsbGadgetCommon.h
@@ -57,7 +57,6 @@
constexpr char kBuildType[] = "ro.build.type";
constexpr char kPersistentVendorConfig[] = "persist.vendor.usb.usbradio.config";
constexpr char kVendorConfig[] = "vendor.usb.config";
-constexpr char kVendorRndisConfig[] = "vendor.usb.rndis.config";
#define GADGET_PATH "/config/usb_gadget/g1/"
#define PULLUP_PATH GADGET_PATH "UDC"
diff --git a/usb/include/pixelusb/UsbOverheatEvent.h b/usb/include/pixelusb/UsbOverheatEvent.h
deleted file mode 100644
index ac8b6b0..0000000
--- a/usb/include/pixelusb/UsbOverheatEvent.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#ifndef HARDWARE_GOOGLE_PIXEL_USB_USBOVERHEATEVENT_H
-#define HARDWARE_GOOGLE_PIXEL_USB_USBOVERHEATEVENT_H
-
-#include <android-base/file.h>
-#include <android-base/properties.h>
-#include <android-base/unique_fd.h>
-#include <android/hardware/thermal/2.0/IThermal.h>
-#include <android/hardware/thermal/2.0/IThermalChangedCallback.h>
-#include <android/hardware/thermal/2.0/types.h>
-#include <android/hidl/manager/1.0/IServiceManager.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/timerfd.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <utils/Log.h>
-
-#include <condition_variable>
-#include <mutex>
-#include <string>
-#include <thread>
-#include <vector>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace usb {
-
-using ::android::base::unique_fd;
-using ::android::base::WriteStringToFile;
-
-using ::android::hardware::thermal::V1_0::ThermalStatus;
-using ::android::hardware::thermal::V1_0::ThermalStatusCode;
-using ::android::hardware::thermal::V2_0::IThermal;
-using ::android::hardware::thermal::V2_0::IThermalChangedCallback;
-using ::android::hardware::thermal::V2_0::Temperature;
-using ::android::hardware::thermal::V2_0::TemperatureType;
-using ::android::hardware::thermal::V2_0::ThrottlingSeverity;
-
-using ::android::hidl::manager::V1_0::IServiceManager;
-using ::android::hidl::manager::V1_0::IServiceNotification;
-
-using ::std::lock_guard;
-using ::std::max;
-using ::std::move;
-using ::std::mutex;
-using ::std::string;
-using ::std::thread;
-using ::std::unique_ptr;
-using ::std::vector;
-
-class ZoneInfo {
- public:
- // Type of the thermal sensor
- TemperatureType type_;
- // Name of the thermal sensor
- string name_;
- // Throttling severity when monitor_ is started for polling temperature
- ThrottlingSeverity severity_;
- ZoneInfo(const TemperatureType &type, const string &name, const ThrottlingSeverity &severity);
-};
-
-class UsbOverheatEvent : public IServiceNotification, public IThermalChangedCallback {
- private:
- // To wake up thread to record max temperature
- unique_fd timer_fd_;
- // Pools on timer_fd_
- unique_fd epoll_fd_;
- // To wake up the thread when waiting on TimerFd
- unique_fd event_fd_;
- // Thermal zone for monitoring Throttling event
- ZoneInfo monitored_zone_;
- // Info of thermal zones that are queried during polling.
- // ATM Suez UsbPortOverheatEvent can only report one of the values though.
- // Therefore the first one in the list will be used for
- // getCurrentTemperature and max_overheat_temp_.
- vector<ZoneInfo> queried_zones_;
- // Sampling interval for monitoring the temperature
- int monitor_interval_sec_;
- // protects the CV.
- std::mutex lock_;
- // Thread waits here when mRecordMaxTemp is false
- std::condition_variable cv_;
- // Thread object that executes the ep monitoring logic
- unique_ptr<thread> monitor_;
- // Maximum overheat temperature recorded
- float max_overheat_temp_;
- // Reference to thermal service
- ::android::sp<IThermal> thermal_service_;
- // Thread that polls temperature to record max temp
- static void *monitorThread(void *param);
- // Register service notification listener
- bool registerListener();
- // Thermal ServiceNotification listener
- Return<void> onRegistration(const hidl_string & /*fully_qualified_name*/,
- const hidl_string & /*instance_name*/,
- bool /*pre_existing*/) override;
- // Thermal service callback
- Return<void> notifyThrottling(const Temperature &temperature) override;
-
- public:
- UsbOverheatEvent(const ZoneInfo &monitored_zone, const std::vector<ZoneInfo> &queried_zones,
- const int &monitor_interval_sec);
- // Start monitoring thermal zone for maximum temperature
- bool startRecording();
- // Stop monitoring thermal zone
- bool stopRecording();
- // Enquire current USB temperature
- bool getCurrentTemperature(const string &name, float *temp);
- // Query Max overheat temperature
- float getMaxOverheatTemperature();
-};
-
-} // namespace usb
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-#endif
diff --git a/vibrator/Android.bp b/vibrator/Android.bp
index 2d6d4d4..fd8c8c1 100644
--- a/vibrator/Android.bp
+++ b/vibrator/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_defaults {
name: "PixelVibratorDefaults",
relative_install_path: "hw",
@@ -37,7 +33,7 @@
name: "PixelVibratorBinaryDefaults",
defaults: ["PixelVibratorDefaults"],
shared_libs: [
- "android.hardware.vibrator-V2-ndk_platform",
+ "android.hardware.vibrator-ndk_platform",
],
}
@@ -45,7 +41,7 @@
name: "PixelVibratorTestDefaults",
defaults: ["PixelVibratorDefaults"],
static_libs: [
- "android.hardware.vibrator-V2-ndk_platform",
+ "android.hardware.vibrator-ndk_platform",
],
test_suites: ["device-tests"],
require_root: true,
diff --git a/vibrator/OWNERS b/vibrator/OWNERS
index 29ca5a3..928c9ff 100644
--- a/vibrator/OWNERS
+++ b/vibrator/OWNERS
@@ -1,3 +1,3 @@
chasewu@google.com
-leungv@google.com
+eliptus@google.com
michaelwr@google.com
diff --git a/vibrator/common/Android.bp b/vibrator/common/Android.bp
index 04fbc4d..d40e7a9 100644
--- a/vibrator/common/Android.bp
+++ b/vibrator/common/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library {
name: "PixelVibratorCommon",
srcs: [
diff --git a/vibrator/common/HardwareBase.cpp b/vibrator/common/HardwareBase.cpp
index 8e07e99..d87806d 100644
--- a/vibrator/common/HardwareBase.cpp
+++ b/vibrator/common/HardwareBase.cpp
@@ -16,12 +16,12 @@
#include "HardwareBase.h"
-#include <cutils/properties.h>
-#include <log/log.h>
-
#include <fstream>
#include <sstream>
+#include <cutils/properties.h>
+#include <log/log.h>
+
#include "utils.h"
namespace aidl {
diff --git a/vibrator/common/HardwareBase.h b/vibrator/common/HardwareBase.h
index 7612fb3..fb5acab 100644
--- a/vibrator/common/HardwareBase.h
+++ b/vibrator/common/HardwareBase.h
@@ -82,7 +82,6 @@
NamesMap mNames;
Records mRecords{RECORDS_SIZE};
std::mutex mRecordsMutex;
- std::mutex mIoMutex;
};
#define HWAPI_RECORD(args...) HwApiBase::record(__FUNCTION__, ##args)
@@ -96,7 +95,6 @@
template <typename T>
bool HwApiBase::get(T *value, std::istream *stream) {
ATRACE_NAME("HwApi::get");
- std::scoped_lock ioLock{mIoMutex};
bool ret;
stream->seekg(0);
*stream >> *value;
@@ -112,7 +110,6 @@
bool HwApiBase::set(const T &value, std::ostream *stream) {
ATRACE_NAME("HwApi::set");
using utils::operator<<;
- std::scoped_lock ioLock{mIoMutex};
bool ret;
*stream << value << std::endl;
if (!(ret = !!*stream)) {
diff --git a/vibrator/common/TEST_MAPPING b/vibrator/common/TEST_MAPPING
new file mode 100644
index 0000000..3c77ebc
--- /dev/null
+++ b/vibrator/common/TEST_MAPPING
@@ -0,0 +1,14 @@
+{
+ "postsubmit": [
+ {
+ "name": "VibratorHalIntegrationBenchmark"
+ },
+ // TODO(b/137256707): Consolidate with above.
+ {
+ "name": "VibratorHalIntegrationBenchmark",
+ "keywords": [
+ "primary-device"
+ ]
+ }
+ ]
+}
diff --git a/vibrator/common/bench/Android.bp b/vibrator/common/bench/Android.bp
new file mode 100644
index 0000000..641b73a
--- /dev/null
+++ b/vibrator/common/bench/Android.bp
@@ -0,0 +1,32 @@
+//
+// Copyright (C) 2019 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.
+
+cc_benchmark {
+ name: "VibratorHalIntegrationBenchmark",
+ defaults: ["hidl_defaults"],
+ srcs: [
+ "benchmark.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.vibrator@1.0",
+ "android.hardware.vibrator@1.1",
+ "android.hardware.vibrator@1.2",
+ "android.hardware.vibrator@1.3",
+ "libhardware",
+ "libhidlbase",
+ "libutils",
+ ],
+ test_suites: ["device-tests"],
+}
diff --git a/vibrator/common/bench/benchmark.cpp b/vibrator/common/bench/benchmark.cpp
new file mode 100644
index 0000000..5886934
--- /dev/null
+++ b/vibrator/common/bench/benchmark.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include "benchmark/benchmark.h"
+
+#include <android/hardware/vibrator/1.3/IVibrator.h>
+
+using ::android::sp;
+using ::android::hardware::hidl_enum_range;
+using ::android::hardware::Return;
+using ::android::hardware::details::hidl_enum_values;
+using ::benchmark::Counter;
+using ::benchmark::Fixture;
+using ::benchmark::kMicrosecond;
+using ::benchmark::State;
+using ::benchmark::internal::Benchmark;
+using ::std::chrono::duration;
+using ::std::chrono::duration_cast;
+using ::std::chrono::high_resolution_clock;
+
+namespace V1_0 = ::android::hardware::vibrator::V1_0;
+namespace V1_1 = ::android::hardware::vibrator::V1_1;
+namespace V1_2 = ::android::hardware::vibrator::V1_2;
+namespace V1_3 = ::android::hardware::vibrator::V1_3;
+
+template <typename I>
+class VibratorBench : public Fixture {
+ public:
+ void SetUp(State & /*state*/) override { mVibrator = I::getService(); }
+
+ void TearDown(State & /*state*/) override {
+ if (!mVibrator) {
+ return;
+ }
+ mVibrator->off();
+ }
+
+ static void DefaultConfig(Benchmark *b) { b->Unit(kMicrosecond); }
+
+ static void DefaultArgs(Benchmark * /*b*/) {
+ // none
+ }
+
+ protected:
+ auto getOtherArg(const State &state, std::size_t index) const { return state.range(index + 0); }
+
+ protected:
+ sp<I> mVibrator;
+};
+
+enum class EmptyEnum : uint32_t;
+template <>
+inline constexpr std::array<EmptyEnum, 0> hidl_enum_values<EmptyEnum> = {};
+
+template <typename T, typename U>
+std::set<T> difference(const hidl_enum_range<T> &t, const hidl_enum_range<U> &u) {
+ class Compare {
+ public:
+ bool operator()(const T &a, const U &b) { return a < static_cast<T>(b); }
+ bool operator()(const U &a, const T &b) { return static_cast<T>(a) < b; }
+ };
+ std::set<T> ret;
+
+ std::set_difference(t.begin(), t.end(), u.begin(), u.end(),
+ std::insert_iterator<decltype(ret)>(ret, ret.begin()), Compare());
+
+ return ret;
+}
+
+template <typename I, typename E1, typename E2 = EmptyEnum>
+class VibratorEffectsBench : public VibratorBench<I> {
+ public:
+ using Effect = E1;
+ using EffectStrength = V1_0::EffectStrength;
+ using Status = V1_0::Status;
+
+ public:
+ static void DefaultArgs(Benchmark *b) {
+ b->ArgNames({"Effect", "Strength"});
+ for (const auto &effect : difference(hidl_enum_range<E1>(), hidl_enum_range<E2>())) {
+ for (const auto &strength : hidl_enum_range<EffectStrength>()) {
+ b->Args({static_cast<long>(effect), static_cast<long>(strength)});
+ }
+ }
+ }
+
+ void performBench(State *state, Return<void> (I::*performApi)(Effect, EffectStrength,
+ typename I::perform_cb)) {
+ auto effect = getEffect(*state);
+ auto strength = getStrength(*state);
+ bool supported = true;
+
+ (*this->mVibrator.*performApi)(effect, strength, [&](Status status, uint32_t /*lengthMs*/) {
+ if (status == Status::UNSUPPORTED_OPERATION) {
+ supported = false;
+ }
+ });
+
+ if (!supported) {
+ return;
+ }
+
+ for (auto _ : *state) {
+ state->ResumeTiming();
+ (*this->mVibrator.*performApi)(effect, strength,
+ [](Status /*status*/, uint32_t /*lengthMs*/) {});
+ state->PauseTiming();
+ this->mVibrator->off();
+ }
+ }
+
+ protected:
+ auto getEffect(const State &state) const {
+ return static_cast<Effect>(this->getOtherArg(state, 0));
+ }
+
+ auto getStrength(const State &state) const {
+ return static_cast<EffectStrength>(this->getOtherArg(state, 1));
+ }
+};
+
+#define BENCHMARK_WRAPPER(fixt, test, code) \
+ BENCHMARK_DEFINE_F(fixt, test) \
+ /* NOLINTNEXTLINE */ \
+ (State & state) { \
+ if (!mVibrator) { \
+ return; \
+ } \
+ \
+ code \
+ } \
+ BENCHMARK_REGISTER_F(fixt, test)->Apply(fixt::DefaultConfig)->Apply(fixt::DefaultArgs)
+
+using VibratorBench_V1_0 = VibratorBench<V1_0::IVibrator>;
+
+BENCHMARK_WRAPPER(VibratorBench_V1_0, on, {
+ uint32_t ms = UINT32_MAX;
+
+ for (auto _ : state) {
+ state.ResumeTiming();
+ mVibrator->on(ms);
+ state.PauseTiming();
+ mVibrator->off();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench_V1_0, off, {
+ uint32_t ms = UINT32_MAX;
+
+ for (auto _ : state) {
+ state.PauseTiming();
+ mVibrator->on(ms);
+ state.ResumeTiming();
+ mVibrator->off();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench_V1_0, supportsAmplitudeControl, {
+ for (auto _ : state) {
+ mVibrator->supportsAmplitudeControl();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench_V1_0, setAmplitude, {
+ uint8_t amplitude = UINT8_MAX;
+
+ if (!mVibrator->supportsAmplitudeControl()) {
+ return;
+ }
+
+ mVibrator->on(UINT32_MAX);
+
+ for (auto _ : state) {
+ mVibrator->setAmplitude(amplitude);
+ }
+
+ mVibrator->off();
+});
+
+using VibratorEffectsBench_V1_0 = VibratorEffectsBench<V1_0::IVibrator, V1_0::Effect>;
+
+BENCHMARK_WRAPPER(VibratorEffectsBench_V1_0, perform,
+ { performBench(&state, &V1_0::IVibrator::perform); });
+
+using VibratorEffectsBench_V1_1 =
+ VibratorEffectsBench<V1_1::IVibrator, V1_1::Effect_1_1, V1_0::Effect>;
+
+BENCHMARK_WRAPPER(VibratorEffectsBench_V1_1, perform_1_1,
+ { performBench(&state, &V1_1::IVibrator::perform_1_1); });
+
+using VibratorEffectsBench_V1_2 =
+ VibratorEffectsBench<V1_2::IVibrator, V1_2::Effect, V1_1::Effect_1_1>;
+
+BENCHMARK_WRAPPER(VibratorEffectsBench_V1_2, perform_1_2,
+ { performBench(&state, &V1_2::IVibrator::perform_1_2); });
+
+using VibratorBench_V1_3 = VibratorBench<V1_3::IVibrator>;
+
+BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalControl, {
+ for (auto _ : state) {
+ mVibrator->supportsExternalControl();
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalControl, {
+ bool enable = true;
+
+ if (!mVibrator->supportsExternalControl()) {
+ return;
+ }
+
+ for (auto _ : state) {
+ state.ResumeTiming();
+ mVibrator->setExternalControl(enable);
+ state.PauseTiming();
+ mVibrator->setExternalControl(false);
+ }
+});
+
+BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalAmplitudeControl, {
+ if (!mVibrator->supportsExternalControl()) {
+ return;
+ }
+
+ mVibrator->setExternalControl(true);
+
+ for (auto _ : state) {
+ mVibrator->supportsAmplitudeControl();
+ }
+
+ mVibrator->setExternalControl(false);
+});
+
+BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalAmplitude, {
+ uint8_t amplitude = UINT8_MAX;
+
+ if (!mVibrator->supportsExternalControl()) {
+ return;
+ }
+
+ mVibrator->setExternalControl(true);
+
+ if (!mVibrator->supportsAmplitudeControl()) {
+ return;
+ }
+
+ for (auto _ : state) {
+ mVibrator->setAmplitude(amplitude);
+ }
+
+ mVibrator->setExternalControl(false);
+});
+
+using VibratorEffectsBench_V1_3 = VibratorEffectsBench<V1_3::IVibrator, V1_3::Effect, V1_2::Effect>;
+
+BENCHMARK_WRAPPER(VibratorEffectsBench_V1_3, perform_1_3,
+ { performBench(&state, &V1_3::IVibrator::perform_1_3); });
+
+BENCHMARK_MAIN();
diff --git a/vibrator/cs40l25/Android.bp b/vibrator/cs40l25/Android.bp
index 6db96f4..1beca23 100644
--- a/vibrator/cs40l25/Android.bp
+++ b/vibrator/cs40l25/Android.bp
@@ -13,19 +13,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_defaults {
name: "android.hardware.vibrator-defaults.cs40l25",
cflags: [
"-DATRACE_TAG=(ATRACE_TAG_VIBRATOR | ATRACE_TAG_HAL)",
"-DLOG_TAG=\"android.hardware.vibrator-cs40l25\"",
],
- shared_libs: [
- "libbinder",
- ],
}
cc_defaults {
@@ -42,23 +35,13 @@
"PixelVibratorTestDefaults",
"android.hardware.vibrator-defaults.cs40l25",
],
- shared_libs: ["android.hardware.vibrator-impl.cs40l25"],
- include_dirs: [
- "external/tinyalsa/include",
- ],
+ static_libs: ["android.hardware.vibrator-impl.cs40l25"],
}
-cc_library_shared {
+cc_library {
name: "android.hardware.vibrator-impl.cs40l25",
defaults: ["VibratorHalCs40l25BinaryDefaults"],
srcs: ["Vibrator.cpp"],
- include_dirs: [
- "external/tinyalsa/include",
- ],
- shared_libs: [
- "libcutils",
- "libtinyalsa",
- ],
export_include_dirs: ["."],
vendor_available: true,
visibility: [":__subpackages__"],
@@ -70,31 +53,6 @@
init_rc: ["android.hardware.vibrator-service.cs40l25.rc"],
vintf_fragments: ["android.hardware.vibrator-service.cs40l25.xml"],
srcs: ["service.cpp"],
- include_dirs: [
- "external/tinyalsa/include"
- ],
- shared_libs: [
- "android.hardware.vibrator-impl.cs40l25",
- "libcutils",
- "libtinyalsa",
- ],
- proprietary: true,
-}
-
-cc_binary {
- name: "android.hardware.vibrator-service.cs40l25-dual",
- defaults: ["VibratorHalCs40l25BinaryDefaults"],
- init_rc: ["android.hardware.vibrator-service.cs40l25-dual.rc"],
- vintf_fragments: ["android.hardware.vibrator-service.cs40l25-dual.xml"],
- srcs: ["service.cpp"],
- include_dirs: [
- "external/tinyalsa/include"
- ],
- shared_libs: [
- "android.hardware.vibrator-impl.cs40l25",
- "libcutils",
- "libtinyalsa",
- ],
- cflags: ["-DVIBRATOR_NAME=\"dual\""],
+ static_libs: ["android.hardware.vibrator-impl.cs40l25"],
proprietary: true,
}
diff --git a/vibrator/cs40l25/Hardware.h b/vibrator/cs40l25/Hardware.h
index d1883e5..81936ed 100644
--- a/vibrator/cs40l25/Hardware.h
+++ b/vibrator/cs40l25/Hardware.h
@@ -27,7 +27,6 @@
public:
HwApi() {
open("device/f0_stored", &mF0);
- open("device/f0_offset", &mF0Offset);
open("device/redc_stored", &mRedc);
open("device/q_stored", &mQ);
open("activate", &mActivate);
@@ -45,13 +44,9 @@
open("device/gpio1_rise_dig_scale", &mGpioRiseScale);
open("device/vibe_state", &mVibeState);
open("device/num_waves", &mEffectCount);
- open("device/clab_enable", &mClabEnable);
- open("device/available_pwle_segments", &mAvailablePwleSegments);
- open("device/pwle", &mPwle);
}
bool setF0(uint32_t value) override { return set(value, &mF0); }
- bool setF0Offset(uint32_t value) override { return set(value, &mF0Offset); }
bool setRedc(uint32_t value) override { return set(value, &mRedc); }
bool setQ(uint32_t value) override { return set(value, &mQ); }
bool setActivate(bool value) override { return set(value, &mActivate); }
@@ -72,15 +67,10 @@
bool setGpioRiseIndex(uint32_t value) override { return set(value, &mGpioRiseIndex); }
bool setGpioRiseScale(uint32_t value) override { return set(value, &mGpioRiseScale); }
bool pollVibeState(bool value) override { return poll(value, &mVibeState); }
- bool setClabEnable(bool value) override { return set(value, &mClabEnable); }
- bool getAvailablePwleSegments(uint32_t *value) override { return get(value, &mAvailablePwleSegments); }
- bool hasPwle() override { return has(mPwle); }
- bool setPwle(std::string value) override { return set(value, &mPwle); }
void debug(int fd) override { HwApiBase::debug(fd); }
private:
std::ofstream mF0;
- std::ofstream mF0Offset;
std::ofstream mRedc;
std::ofstream mQ;
std::ofstream mActivate;
@@ -98,49 +88,27 @@
std::ofstream mGpioRiseIndex;
std::ofstream mGpioRiseScale;
std::ifstream mVibeState;
- std::ofstream mClabEnable;
- std::ifstream mAvailablePwleSegments;
- std::ofstream mPwle;
};
class HwCal : public Vibrator::HwCal, private HwCalBase {
private:
- static constexpr char VERSION[] = "version";
static constexpr char F0_CONFIG[] = "f0_measured";
static constexpr char REDC_CONFIG[] = "redc_measured";
static constexpr char Q_CONFIG[] = "q_measured";
static constexpr char Q_INDEX[] = "q_index";
static constexpr char VOLTAGES_CONFIG[] = "v_levels";
- static constexpr char TICK_VOLTAGES_CONFIG[] = "v_tick";
- static constexpr char CLICK_VOLTAGES_CONFIG[] = "v_click";
- static constexpr char LONG_VOLTAGES_CONFIG[] = "v_long";
static constexpr uint32_t Q_FLOAT_TO_FIXED = 1 << 16;
static constexpr float Q_INDEX_TO_FLOAT = 1.5f;
static constexpr uint32_t Q_INDEX_TO_FIXED = Q_INDEX_TO_FLOAT * Q_FLOAT_TO_FIXED;
static constexpr uint32_t Q_INDEX_OFFSET = 2.0f * Q_FLOAT_TO_FIXED;
- static constexpr uint32_t VERSION_DEFAULT = 1;
- static constexpr int32_t DEFAULT_FREQUENCY_SHIFT = 0;
static constexpr uint32_t Q_DEFAULT = 15.5 * Q_FLOAT_TO_FIXED;
static constexpr std::array<uint32_t, 6> V_LEVELS_DEFAULT = {60, 70, 80, 90, 100, 76};
- static constexpr std::array<uint32_t, 2> V_TICK_DEFAULT = {10, 70};
- static constexpr std::array<uint32_t, 2> V_CTICK_DEFAULT = {10, 70};
- static constexpr std::array<uint32_t, 2> V_LONG_DEFAULT = {10, 70};
public:
HwCal() {}
- bool getVersion(uint32_t *value) override {
- if (getPersist(VERSION, value)) {
- return true;
- }
- *value = VERSION_DEFAULT;
- return true;
- }
- bool getLongFrequencyShift(int32_t *value) override {
- return getProperty("long.frequency.shift", value, DEFAULT_FREQUENCY_SHIFT);
- }
bool getF0(uint32_t *value) override { return getPersist(F0_CONFIG, value); }
bool getRedc(uint32_t *value) override { return getPersist(REDC_CONFIG, value); }
bool getQ(uint32_t *value) override {
@@ -161,27 +129,6 @@
*value = V_LEVELS_DEFAULT;
return true;
}
- bool getTickVolLevels(std::array<uint32_t, 2> *value) override {
- if (getPersist(TICK_VOLTAGES_CONFIG, value)) {
- return true;
- }
- *value = V_TICK_DEFAULT;
- return true;
- }
- bool getClickVolLevels(std::array<uint32_t, 2> *value) override {
- if (getPersist(CLICK_VOLTAGES_CONFIG, value)) {
- return true;
- }
- *value = V_CTICK_DEFAULT;
- return true;
- }
- bool getLongVolLevels(std::array<uint32_t, 2> *value) override {
- if (getPersist(LONG_VOLTAGES_CONFIG, value)) {
- return true;
- }
- *value = V_LONG_DEFAULT;
- return true;
- }
void debug(int fd) override { HwCalBase::debug(fd); }
};
diff --git a/vibrator/cs40l25/Vibrator.cpp b/vibrator/cs40l25/Vibrator.cpp
index 826a28d..df8cbf0 100644
--- a/vibrator/cs40l25/Vibrator.cpp
+++ b/vibrator/cs40l25/Vibrator.cpp
@@ -14,28 +14,24 @@
* limitations under the License.
*/
+
#include "Vibrator.h"
#include <hardware/hardware.h>
#include <hardware/vibrator.h>
#include <log/log.h>
-#include <stdio.h>
#include <utils/Trace.h>
#include <cinttypes>
#include <cmath>
#include <fstream>
#include <iostream>
-#include <map>
#include <sstream>
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#endif
-#define PROC_SND_PCM "/proc/asound/pcm"
-#define HAPTIC_PCM_DEVICE_SYMBOL "haptic nohost playback"
-
namespace aidl {
namespace android {
namespace hardware {
@@ -54,15 +50,11 @@
static constexpr uint32_t WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX = 3 + BASE_CONTINUOUS_EFFECT_OFFSET;
static constexpr uint32_t WAVEFORM_CLICK_INDEX = 2;
-static constexpr uint32_t WAVEFORM_THUD_INDEX = 4;
-static constexpr uint32_t WAVEFORM_SPIN_INDEX = 5;
static constexpr uint32_t WAVEFORM_QUICK_RISE_INDEX = 6;
static constexpr uint32_t WAVEFORM_SLOW_RISE_INDEX = 7;
static constexpr uint32_t WAVEFORM_QUICK_FALL_INDEX = 8;
static constexpr uint32_t WAVEFORM_LIGHT_TICK_INDEX = 9;
-static constexpr uint32_t WAVEFORM_LOW_TICK_INDEX = 10;
-static constexpr uint32_t WAVEFORM_UNSAVED_TRIGGER_QUEUE_INDEX = 65529;
static constexpr uint32_t WAVEFORM_TRIGGER_QUEUE_INDEX = 65534;
static constexpr uint32_t VOLTAGE_GLOBAL_SCALE_LEVEL = 5;
@@ -79,84 +71,12 @@
static constexpr int32_t COMPOSE_DELAY_MAX_MS = 10000;
static constexpr int32_t COMPOSE_SIZE_MAX = 127;
-static constexpr int32_t COMPOSE_PWLE_SIZE_MAX_DEFAULT = 127;
-
-
-// Measured resonant frequency, f0_measured, is represented by Q10.14 fixed
-// point format on cs40l2x devices. The expression to calculate f0 is:
-// f0 = f0_measured / 2^Q14_BIT_SHIFT
-// See the LRA Calibration Support documentation for more details.
-static constexpr int32_t Q14_BIT_SHIFT = 14;
-
-// Measured Q factor, q_measured, is represented by Q8.16 fixed
-// point format on cs40l2x devices. The expression to calculate q is:
-// q = q_measured / 2^Q16_BIT_SHIFT
-// See the LRA Calibration Support documentation for more details.
-static constexpr int32_t Q16_BIT_SHIFT = 16;
-
-static constexpr int32_t COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS = 16383;
-static constexpr float PWLE_LEVEL_MIN = 0.0;
-static constexpr float PWLE_LEVEL_MAX = 1.0;
-static constexpr float CS40L2X_PWLE_LEVEL_MAX = 0.999511;
-static constexpr float PWLE_FREQUENCY_RESOLUTION_HZ = 0.25;
-static constexpr float PWLE_FREQUENCY_MIN_HZ = 0.25;
-static constexpr float PWLE_FREQUENCY_MAX_HZ = 1023.75;
-static constexpr float PWLE_BW_MAP_SIZE =
- 1 + ((PWLE_FREQUENCY_MAX_HZ - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ);
-
-static struct pcm_config haptic_nohost_config = {
- .channels = 1,
- .rate = 48000,
- .period_size = 80,
- .period_count = 2,
- .format = PCM_FORMAT_S16_LE,
-};
static uint8_t amplitudeToScale(float amplitude, float maximum) {
return std::round((-20 * std::log10(amplitude / static_cast<float>(maximum))) /
(AMP_ATTENUATE_STEP_SIZE));
}
-// Discrete points of frequency:max_level pairs as recommended by the document
-// [R4O6] Max. Allowable Chirp Levels (go/r4o6-max-chirp-levels) around resonant frequency
-static std::map<float, float> discretePwleMaxLevels = {{120.0, 0.4}, {130.0, 0.31}, {140.0, 0.14},
- {145.0, 0.09}, {150.0, 0.15}, {160.0, 0.35},
- {170.0, 0.4}};
-
-// Initialize all limits to 0.4 according to the document [R4O6] Max. Allowable Chirp Levels
-// (go/r4o6-max-chirp-levels)
-std::vector<float> pwleMaxLevelLimitMap(PWLE_BW_MAP_SIZE, 0.4);
-
-void Vibrator::createPwleMaxLevelLimitMap() {
- int32_t capabilities;
- Vibrator::getCapabilities(&capabilities);
- if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
- std::map<float, float>::iterator itr0, itr1;
-
- itr0 = discretePwleMaxLevels.begin();
- itr1 = std::next(itr0, 1);
-
- while (itr1 != discretePwleMaxLevels.end()) {
- float x0 = itr0->first;
- float y0 = itr0->second;
- float x1 = itr1->first;
- float y1 = itr1->second;
- float pwleMaxLevelLimitMapIdx =
- (itr0->first - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ;
-
- for (float xp = x0; xp < (x1 + PWLE_FREQUENCY_RESOLUTION_HZ);
- xp += PWLE_FREQUENCY_RESOLUTION_HZ) {
- float yp = y0 + ((y1 - y0) / (x1 - x0)) * (xp - x0);
-
- pwleMaxLevelLimitMap[pwleMaxLevelLimitMapIdx++] = yp;
- }
-
- itr0++;
- itr1++;
- }
- }
-}
-
enum class AlwaysOnId : uint32_t {
GPIO_RISE,
GPIO_FALL,
@@ -164,10 +84,9 @@
Vibrator::Vibrator(std::unique_ptr<HwApi> hwapi, std::unique_ptr<HwCal> hwcal)
: mHwApi(std::move(hwapi)), mHwCal(std::move(hwcal)), mAsyncHandle(std::async([] {})) {
- int32_t longFreqencyShift;
- uint32_t calVer;
uint32_t caldata;
uint32_t effectCount;
+ std::array<uint32_t, 6> volLevels;
if (!mHwApi->setState(true)) {
ALOGE("Failed to set state (%d): %s", errno, strerror(errno));
@@ -183,37 +102,18 @@
mHwApi->setQ(caldata);
}
- mHwCal->getLongFrequencyShift(&longFreqencyShift);
- if (longFreqencyShift > 0) {
- mF0Offset = longFreqencyShift * std::pow(2, 14);
- } else if (longFreqencyShift < 0) {
- mF0Offset = std::pow(2, 24) - std::abs(longFreqencyShift) * std::pow(2, 14);
- } else {
- mF0Offset = 0;
- }
-
- mHwCal->getVersion(&calVer);
- if (calVer == 1) {
- std::array<uint32_t, 6> volLevels;
- mHwCal->getVolLevels(&volLevels);
- /*
- * Given voltage levels for two intensities, assuming a linear function,
- * solve for 'f(0)' in 'v = f(i) = a + b * i' (i.e 'v0 - (v1 - v0) / ((i1 - i0) / i0)').
- */
- mClickEffectVol[0] = std::max(std::lround(volLevels[WAVEFORM_EFFECT_0_20_LEVEL] -
- (volLevels[WAVEFORM_EFFECT_1_00_LEVEL] -
- volLevels[WAVEFORM_EFFECT_0_20_LEVEL]) /
- 4.0f),
- static_cast<long>(WAVEFORM_EFFECT_LEVEL_MINIMUM));
- mClickEffectVol[1] = volLevels[WAVEFORM_EFFECT_1_00_LEVEL];
- mTickEffectVol = mClickEffectVol;
- mLongEffectVol[0] = 0;
- mLongEffectVol[1] = volLevels[VOLTAGE_GLOBAL_SCALE_LEVEL];
- } else {
- mHwCal->getTickVolLevels(&mTickEffectVol);
- mHwCal->getClickVolLevels(&mClickEffectVol);
- mHwCal->getLongVolLevels(&mLongEffectVol);
- }
+ mHwCal->getVolLevels(&volLevels);
+ /*
+ * Given voltage levels for two intensities, assuming a linear function,
+ * solve for 'f(0)' in 'v = f(i) = a + b * i' (i.e 'v0 - (v1 - v0) / ((i1 - i0) / i0)').
+ */
+ mEffectVolMin = std::max(std::lround(volLevels[WAVEFORM_EFFECT_0_20_LEVEL] -
+ (volLevels[WAVEFORM_EFFECT_1_00_LEVEL] -
+ volLevels[WAVEFORM_EFFECT_0_20_LEVEL]) /
+ 4.0f),
+ static_cast<long>(WAVEFORM_EFFECT_LEVEL_MINIMUM));
+ mEffectVolMax = volLevels[WAVEFORM_EFFECT_1_00_LEVEL];
+ mGlobalVolMax = volLevels[VOLTAGE_GLOBAL_SCALE_LEVEL];
mHwApi->getEffectCount(&effectCount);
mEffectDurations.resize(effectCount);
@@ -224,33 +124,18 @@
mEffectDurations[effectIndex] = std::ceil(effectDuration / EFFECT_FREQUENCY_KHZ);
}
}
-
- mHwApi->setClabEnable(true);
-
- if (!(getPwleCompositionSizeMax(&compositionSizeMax).isOk())) {
- ALOGE("Failed to get pwle composition size max, using default size: %d",
- COMPOSE_PWLE_SIZE_MAX_DEFAULT);
- compositionSizeMax = COMPOSE_PWLE_SIZE_MAX_DEFAULT;
- }
-
- createPwleMaxLevelLimitMap();
- mIsUnderExternalControl = false;
}
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) {
ATRACE_NAME("Vibrator::getCapabilities");
int32_t ret = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
- IVibrator::CAP_COMPOSE_EFFECTS | IVibrator::CAP_ALWAYS_ON_CONTROL |
- IVibrator::CAP_GET_RESONANT_FREQUENCY | IVibrator::CAP_GET_Q_FACTOR;
+ IVibrator::CAP_COMPOSE_EFFECTS | IVibrator::CAP_ALWAYS_ON_CONTROL;
if (mHwApi->hasEffectScale()) {
ret |= IVibrator::CAP_AMPLITUDE_CONTROL;
}
- if (mHwApi->hasAspEnable() || hasHapticAlsaDevice()) {
+ if (mHwApi->hasAspEnable()) {
ret |= IVibrator::CAP_EXTERNAL_CONTROL;
}
- if (mHwApi->hasPwle()) {
- ret |= IVibrator::CAP_FREQUENCY_CONTROL | IVibrator::CAP_COMPOSE_PWLE_EFFECTS;
- }
*_aidl_return = ret;
return ndk::ScopedAStatus::ok();
}
@@ -258,7 +143,6 @@
ndk::ScopedAStatus Vibrator::off() {
ATRACE_NAME("Vibrator::off");
setGlobalAmplitude(false);
- mHwApi->setF0Offset(0);
if (!mHwApi->setActivate(0)) {
ALOGE("Failed to turn vibrator off (%d): %s", errno, strerror(errno));
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
@@ -276,7 +160,6 @@
timeoutMs += MAX_COLD_START_LATENCY_MS;
}
setGlobalAmplitude(true);
- mHwApi->setF0Offset(mF0Offset);
return on(timeoutMs, index, callback);
}
@@ -310,41 +193,10 @@
ATRACE_NAME("Vibrator::setExternalControl");
setGlobalAmplitude(enabled);
- if (isUnderExternalControl() == enabled) {
- if (enabled) {
- ALOGE("Restart the external process.");
- if (mHasHapticAlsaDevice) {
- if (!enableHapticPcmAmp(&mHapticPcm, !enabled, mCard, mDevice)) {
- ALOGE("Failed to %s haptic pcm device: %d", (enabled ? "enable" : "disable"),
- mDevice);
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- }
- if (mHwApi->hasAspEnable()) {
- if (!mHwApi->setAspEnable(!enabled)) {
- ALOGE("Failed to set external control (%d): %s", errno, strerror(errno));
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- }
- } else {
- ALOGE("The external control is already disabled.");
- return ndk::ScopedAStatus::ok();
- }
+ if (!mHwApi->setAspEnable(enabled)) {
+ ALOGE("Failed to set external control (%d): %s", errno, strerror(errno));
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
- if (mHasHapticAlsaDevice) {
- if (!enableHapticPcmAmp(&mHapticPcm, enabled, mCard, mDevice)) {
- ALOGE("Failed to %s haptic pcm device: %d", (enabled ? "enable" : "disable"), mDevice);
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- }
- if (mHwApi->hasAspEnable()) {
- if (!mHwApi->setAspEnable(enabled)) {
- ALOGE("Failed to set external control (%d): %s", errno, strerror(errno));
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- }
-
- mIsUnderExternalControl = enabled;
return ndk::ScopedAStatus::ok();
}
@@ -363,10 +215,8 @@
ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector<CompositePrimitive> *supported) {
*supported = {
CompositePrimitive::NOOP, CompositePrimitive::CLICK,
- CompositePrimitive::THUD, CompositePrimitive::SPIN,
CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
CompositePrimitive::QUICK_FALL, CompositePrimitive::LIGHT_TICK,
- CompositePrimitive::LOW_TICK,
};
return ndk::ScopedAStatus::ok();
}
@@ -420,7 +270,7 @@
return status;
}
- effectBuilder << effectIndex << "." << intensityToVolLevel(e.scale, effectIndex) << ",";
+ effectBuilder << effectIndex << "." << intensityToVolLevel(e.scale) << ",";
}
}
@@ -437,11 +287,6 @@
ndk::ScopedAStatus Vibrator::on(uint32_t timeoutMs, uint32_t effectIndex,
const std::shared_ptr<IVibratorCallback> &callback) {
- if (isUnderExternalControl()) {
- setExternalControl(false);
- ALOGE("Device is under external control mode. Force to disable it to prevent chip hang "
- "problem.");
- }
if (mAsyncHandle.wait_for(ASYNC_COMPLETION_TIMEOUT) != std::future_status::ready) {
ALOGE("Previous vibration pending.");
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
@@ -468,7 +313,7 @@
}
ndk::ScopedAStatus Vibrator::setGlobalAmplitude(bool set) {
- uint8_t amplitude = set ? mLongEffectVol[1] : VOLTAGE_SCALE_MAX;
+ uint8_t amplitude = set ? mGlobalVolMax : VOLTAGE_SCALE_MAX;
int32_t scale = amplitudeToScale(amplitude, VOLTAGE_SCALE_MAX);
if (!mHwApi->setGlobalScale(scale)) {
@@ -524,271 +369,10 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-ndk::ScopedAStatus Vibrator::getResonantFrequency(float *resonantFreqHz) {
- uint32_t caldata;
- if (!mHwCal->getF0(&caldata)) {
- ALOGE("Failed to get resonant frequency (%d): %s", errno, strerror(errno));
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- *resonantFreqHz = static_cast<float>(caldata) / (1 << Q14_BIT_SHIFT);
-
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus Vibrator::getQFactor(float *qFactor) {
- uint32_t caldata;
- if (!mHwCal->getQ(&caldata)) {
- ALOGE("Failed to get q factor (%d): %s", errno, strerror(errno));
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- *qFactor = static_cast<float>(caldata) / (1 << Q16_BIT_SHIFT);
-
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus Vibrator::getFrequencyResolution(float *freqResolutionHz) {
- int32_t capabilities;
- Vibrator::getCapabilities(&capabilities);
- if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
- *freqResolutionHz = PWLE_FREQUENCY_RESOLUTION_HZ;
- return ndk::ScopedAStatus::ok();
- } else {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-}
-
-ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float *freqMinimumHz) {
- int32_t capabilities;
- Vibrator::getCapabilities(&capabilities);
- if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
- *freqMinimumHz = PWLE_FREQUENCY_MIN_HZ;
- return ndk::ScopedAStatus::ok();
- } else {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-}
-
-ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) {
- // TODO(b/170919640): complete implementation
- int32_t capabilities;
- Vibrator::getCapabilities(&capabilities);
- if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
- std::vector<float> bandwidthAmplitudeMap(PWLE_BW_MAP_SIZE, 1.0);
- *_aidl_return = bandwidthAmplitudeMap;
- return ndk::ScopedAStatus::ok();
- } else {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-}
-
-ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t *durationMs) {
- int32_t capabilities;
- Vibrator::getCapabilities(&capabilities);
- if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
- *durationMs = COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS;
- return ndk::ScopedAStatus::ok();
- } else {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-}
-
-ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t *maxSize) {
- int32_t capabilities;
- Vibrator::getCapabilities(&capabilities);
- if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
- uint32_t segments;
- if (!mHwApi->getAvailablePwleSegments(&segments)) {
- ALOGE("Failed to get availablePwleSegments (%d): %s", errno, strerror(errno));
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- *maxSize = segments;
- return ndk::ScopedAStatus::ok();
- } else {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-}
-
-ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector<Braking> *supported) {
- int32_t capabilities;
- Vibrator::getCapabilities(&capabilities);
- if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
- *supported = {
- Braking::NONE,
- Braking::CLAB,
- };
- return ndk::ScopedAStatus::ok();
- } else {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-}
-
-ndk::ScopedAStatus Vibrator::setPwle(const std::string &pwleQueue) {
- if (!mHwApi->setPwle(pwleQueue)) {
- ALOGE("Failed to write \"%s\" to pwle (%d): %s", pwleQueue.c_str(), errno, strerror(errno));
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
-
- return ndk::ScopedAStatus::ok();
-}
-
-static void resetPreviousEndAmplitudeEndFrequency(float &prevEndAmplitude,
- float &prevEndFrequency) {
- const float reset = -1.0;
- prevEndAmplitude = reset;
- prevEndFrequency = reset;
-}
-
-static void incrementIndex(int &index) {
- index += 1;
-}
-
-static void constructActiveDefaults(std::ostringstream &pwleBuilder, const int &segmentIdx) {
- pwleBuilder << ",C" << segmentIdx << ":1";
- pwleBuilder << ",B" << segmentIdx << ":0";
- pwleBuilder << ",AR" << segmentIdx << ":0";
- pwleBuilder << ",V" << segmentIdx << ":0";
-}
-
-static void constructActiveSegment(std::ostringstream &pwleBuilder, const int &segmentIdx,
- int duration, float amplitude, float frequency) {
- pwleBuilder << ",T" << segmentIdx << ":" << duration;
- pwleBuilder << ",L" << segmentIdx << ":" << amplitude;
- pwleBuilder << ",F" << segmentIdx << ":" << frequency;
- constructActiveDefaults(pwleBuilder, segmentIdx);
-}
-
-static void constructBrakingSegment(std::ostringstream &pwleBuilder, const int &segmentIdx,
- int duration, Braking brakingType) {
- pwleBuilder << ",T" << segmentIdx << ":" << duration;
- pwleBuilder << ",L" << segmentIdx << ":" << 0;
- pwleBuilder << ",F" << segmentIdx << ":" << PWLE_FREQUENCY_MIN_HZ;
- pwleBuilder << ",C" << segmentIdx << ":0";
- pwleBuilder << ",B" << segmentIdx << ":"
- << static_cast<std::underlying_type<Braking>::type>(brakingType);
- pwleBuilder << ",AR" << segmentIdx << ":0";
- pwleBuilder << ",V" << segmentIdx << ":0";
-}
-
-ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle> &composite,
- const std::shared_ptr<IVibratorCallback> &callback) {
- ATRACE_NAME("Vibrator::composePwle");
- std::ostringstream pwleBuilder;
- std::string pwleQueue;
-
- if (composite.size() <= 0 || composite.size() > compositionSizeMax) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
-
- float prevEndAmplitude;
- float prevEndFrequency;
- resetPreviousEndAmplitudeEndFrequency(prevEndAmplitude, prevEndFrequency);
-
- int segmentIdx = 0;
- uint32_t totalDuration = 0;
-
- pwleBuilder << "S:0,WF:4,RP:0,WT:0";
-
- for (auto &e : composite) {
- switch (e.getTag()) {
- case PrimitivePwle::active: {
- auto active = e.get<PrimitivePwle::active>();
- if (active.duration < 0 ||
- active.duration > COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
- if (active.startAmplitude < PWLE_LEVEL_MIN ||
- active.startAmplitude > PWLE_LEVEL_MAX ||
- active.endAmplitude < PWLE_LEVEL_MIN || active.endAmplitude > PWLE_LEVEL_MAX) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
- if (active.startAmplitude > CS40L2X_PWLE_LEVEL_MAX) {
- active.startAmplitude = CS40L2X_PWLE_LEVEL_MAX;
- }
- if (active.endAmplitude > CS40L2X_PWLE_LEVEL_MAX) {
- active.endAmplitude = CS40L2X_PWLE_LEVEL_MAX;
- }
-
- if (active.startFrequency < PWLE_FREQUENCY_MIN_HZ ||
- active.startFrequency > PWLE_FREQUENCY_MAX_HZ ||
- active.endFrequency < PWLE_FREQUENCY_MIN_HZ ||
- active.endFrequency > PWLE_FREQUENCY_MAX_HZ) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
-
- // clip to the hard limit on input level from pwleMaxLevelLimitMap
- float maxLevelLimit =
- pwleMaxLevelLimitMap[active.startFrequency / PWLE_FREQUENCY_RESOLUTION_HZ - 1];
- if (active.startAmplitude > maxLevelLimit) {
- active.startAmplitude = maxLevelLimit;
- }
- maxLevelLimit =
- pwleMaxLevelLimitMap[active.endFrequency / PWLE_FREQUENCY_RESOLUTION_HZ - 1];
- if (active.endAmplitude > maxLevelLimit) {
- active.endAmplitude = maxLevelLimit;
- }
-
- if (!((active.startAmplitude == prevEndAmplitude) &&
- (active.startFrequency == prevEndFrequency))) {
- constructActiveSegment(pwleBuilder, segmentIdx, 0, active.startAmplitude,
- active.startFrequency);
- incrementIndex(segmentIdx);
- }
-
- constructActiveSegment(pwleBuilder, segmentIdx, active.duration,
- active.endAmplitude, active.endFrequency);
- incrementIndex(segmentIdx);
-
- prevEndAmplitude = active.endAmplitude;
- prevEndFrequency = active.endFrequency;
- totalDuration += active.duration;
- break;
- }
- case PrimitivePwle::braking: {
- auto braking = e.get<PrimitivePwle::braking>();
- if (braking.braking > Braking::CLAB) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
- if (braking.duration > COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
-
- constructBrakingSegment(pwleBuilder, segmentIdx, 0, braking.braking);
- incrementIndex(segmentIdx);
-
- constructBrakingSegment(pwleBuilder, segmentIdx, braking.duration, braking.braking);
- incrementIndex(segmentIdx);
-
- resetPreviousEndAmplitudeEndFrequency(prevEndAmplitude, prevEndFrequency);
- totalDuration += braking.duration;
- break;
- }
- }
- }
-
- pwleQueue = pwleBuilder.str();
- ALOGD("composePwle queue: (%s)", pwleQueue.c_str());
-
- ndk::ScopedAStatus status = setPwle(pwleQueue);
- if (!status.isOk()) {
- ALOGE("Failed to write pwle queue");
- return status;
- }
-
- setEffectAmplitude(VOLTAGE_SCALE_MAX, VOLTAGE_SCALE_MAX);
- mHwApi->setEffectIndex(WAVEFORM_UNSAVED_TRIGGER_QUEUE_INDEX);
-
- totalDuration += MAX_COLD_START_LATENCY_MS;
- mHwApi->setDuration(MAX_TIME_MS);
-
- mHwApi->setActivate(1);
-
- mAsyncHandle = std::async(&Vibrator::waitForComplete, this, callback);
-
- return ndk::ScopedAStatus::ok();
-}
-
bool Vibrator::isUnderExternalControl() {
- return mIsUnderExternalControl;
+ bool isAspEnabled;
+ mHwApi->getAspEnable(&isAspEnabled);
+ return isAspEnabled;
}
binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
@@ -802,15 +386,10 @@
dprintf(fd, "AIDL:\n");
- dprintf(fd, " F0 Offset: %" PRIu32 "\n", mF0Offset);
-
dprintf(fd, " Voltage Levels:\n");
- dprintf(fd, " Tick Effect Min: %" PRIu32 " Max: %" PRIu32 "\n",
- mTickEffectVol[0], mTickEffectVol[1]);
- dprintf(fd, " Click Effect Min: %" PRIu32 " Max: %" PRIu32 "\n",
- mClickEffectVol[0], mClickEffectVol[1]);
- dprintf(fd, " Long Effect Min: %" PRIu32 " Max: %" PRIu32 "\n",
- mLongEffectVol[0], mLongEffectVol[1]);
+ dprintf(fd, " Effect Min: %" PRIu32 "\n", mEffectVolMin);
+ dprintf(fd, " Effect Max: %" PRIu32 "\n", mEffectVolMax);
+ dprintf(fd, " Global Max: %" PRIu32 "\n", mGlobalVolMax);
dprintf(fd, " Effect Durations:");
for (auto d : mEffectDurations) {
@@ -873,7 +452,7 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
- volLevel = intensityToVolLevel(intensity, effectIndex);
+ volLevel = intensityToVolLevel(intensity);
timeMs = mEffectDurations[effectIndex] + MAX_COLD_START_LATENCY_MS;
*outEffectIndex = effectIndex;
@@ -941,12 +520,6 @@
case CompositePrimitive::CLICK:
effectIndex = WAVEFORM_CLICK_INDEX;
break;
- case CompositePrimitive::THUD:
- effectIndex = WAVEFORM_THUD_INDEX;
- break;
- case CompositePrimitive::SPIN:
- effectIndex = WAVEFORM_SPIN_INDEX;
- break;
case CompositePrimitive::QUICK_RISE:
effectIndex = WAVEFORM_QUICK_RISE_INDEX;
break;
@@ -959,9 +532,6 @@
case CompositePrimitive::LIGHT_TICK:
effectIndex = WAVEFORM_LIGHT_TICK_INDEX;
break;
- case CompositePrimitive::LOW_TICK:
- effectIndex = WAVEFORM_LOW_TICK_INDEX;
- break;
default:
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
@@ -1048,108 +618,8 @@
}
}
-uint32_t Vibrator::intensityToVolLevel(float intensity, uint32_t effectIndex) {
-
- uint32_t volLevel;
- auto calc = [](float intst, std::array<uint32_t, 2> v) -> uint32_t {
- return std::lround(intst * (v[1] - v[0])) + v[0]; };
-
- switch (effectIndex) {
- case WAVEFORM_LIGHT_TICK_INDEX:
- volLevel = calc(intensity, mTickEffectVol);
- break;
- case WAVEFORM_QUICK_RISE_INDEX:
- // fall-through
- case WAVEFORM_QUICK_FALL_INDEX:
- volLevel = calc(intensity, mLongEffectVol);
- break;
- case WAVEFORM_CLICK_INDEX:
- // fall-through
- case WAVEFORM_THUD_INDEX:
- // fall-through
- case WAVEFORM_SPIN_INDEX:
- // fall-through
- case WAVEFORM_SLOW_RISE_INDEX:
- // fall-through
- default:
- volLevel = calc(intensity, mClickEffectVol);
- break;
- }
-
- return volLevel;
-}
-
-bool Vibrator::findHapticAlsaDevice(int *card, int *device) {
- std::string line;
- std::ifstream myfile(PROC_SND_PCM);
- if (myfile.is_open()) {
- while (getline(myfile, line)) {
- if (line.find(HAPTIC_PCM_DEVICE_SYMBOL) != std::string::npos) {
- std::stringstream ss(line);
- std::string currentToken;
- std::getline(ss, currentToken, ':');
- sscanf(currentToken.c_str(), "%d-%d", card, device);
- return true;
- }
- }
- myfile.close();
- } else {
- ALOGE("Failed to read file: %s", PROC_SND_PCM);
- }
- return false;
-}
-
-bool Vibrator::hasHapticAlsaDevice() {
- // We need to call findHapticAlsaDevice once only. Calling in the
- // constructor is too early in the boot process and the pcm file contents
- // are empty. Hence we make the call here once only right before we need to.
- static bool configHapticAlsaDeviceDone = false;
- if (!configHapticAlsaDeviceDone) {
- if (findHapticAlsaDevice(&mCard, &mDevice)) {
- mHasHapticAlsaDevice = true;
- configHapticAlsaDeviceDone = true;
- } else {
- ALOGE("Haptic ALSA device not supported");
- }
- }
- return mHasHapticAlsaDevice;
-}
-
-bool Vibrator::enableHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device) {
- int ret = 0;
-
- if (enable) {
- *haptic_pcm = pcm_open(card, device, PCM_OUT, &haptic_nohost_config);
- if (!pcm_is_ready(*haptic_pcm)) {
- ALOGE("cannot open pcm_out driver: %s", pcm_get_error(*haptic_pcm));
- goto fail;
- }
-
- ret = pcm_prepare(*haptic_pcm);
- if (ret < 0) {
- ALOGE("cannot prepare haptic_pcm: %s", pcm_get_error(*haptic_pcm));
- goto fail;
- }
-
- ret = pcm_start(*haptic_pcm);
- if (ret < 0) {
- ALOGE("cannot start haptic_pcm: %s", pcm_get_error(*haptic_pcm));
- goto fail;
- }
-
- return true;
- } else {
- if (*haptic_pcm) {
- pcm_close(*haptic_pcm);
- *haptic_pcm = NULL;
- }
- return true;
- }
-
-fail:
- pcm_close(*haptic_pcm);
- *haptic_pcm = NULL;
- return false;
+uint32_t Vibrator::intensityToVolLevel(float intensity) {
+ return std::lround(intensity * (mEffectVolMax - mEffectVolMin)) + mEffectVolMin;
}
} // namespace vibrator
diff --git a/vibrator/cs40l25/Vibrator.h b/vibrator/cs40l25/Vibrator.h
index 08a115e..3d15406 100644
--- a/vibrator/cs40l25/Vibrator.h
+++ b/vibrator/cs40l25/Vibrator.h
@@ -16,7 +16,6 @@
#pragma once
#include <aidl/android/hardware/vibrator/BnVibrator.h>
-#include <tinyalsa/asoundlib.h>
#include <array>
#include <fstream>
@@ -36,8 +35,6 @@
// Stores the LRA resonant frequency to be used for PWLE playback
// and click compensation.
virtual bool setF0(uint32_t value) = 0;
- // Stores the frequency offset for long vibrations.
- virtual bool setF0Offset(uint32_t value) = 0;
// Stores the LRA series resistance to be used for click
// compensation.
virtual bool setRedc(uint32_t value) = 0;
@@ -92,15 +89,6 @@
// Blocks until vibrator reaches desired state
// (true = enabled, false = disabled).
virtual bool pollVibeState(bool value) = 0;
- // Enables/disables closed-loop active braking.
- virtual bool setClabEnable(bool value) = 0;
- // Reports the number of available PWLE segments.
- virtual bool getAvailablePwleSegments(uint32_t *value) = 0;
- // Reports whether piecewise-linear envelope for waveforms is supported.
- virtual bool hasPwle() = 0;
- // Specifies piecewise-linear specifications to generate complex
- // waveforms.
- virtual bool setPwle(std::string value) = 0;
// Emit diagnostic information to the given file.
virtual void debug(int fd) = 0;
};
@@ -109,8 +97,6 @@
class HwCal {
public:
virtual ~HwCal() = default;
- // Obtain the calibration version
- virtual bool getVersion(uint32_t *value) = 0;
// Obtains the LRA resonant frequency to be used for PWLE playback
// and click compensation.
virtual bool getF0(uint32_t *value) = 0;
@@ -120,16 +106,9 @@
// Obtains the LRA Q factor to be used for Q-dependent waveform
// selection.
virtual bool getQ(uint32_t *value) = 0;
- // Obtains frequency shift for long vibrations.
- virtual bool getLongFrequencyShift(int32_t *value) = 0;
// Obtains the discreet voltage levels to be applied for the various
// waveforms, in units of 1%.
virtual bool getVolLevels(std::array<uint32_t, 6> *value) = 0;
- // Obtains the v0/v1(min/max) voltage levels to be applied for
- // tick/click/long in units of 1%.
- virtual bool getTickVolLevels(std::array<uint32_t, 2> *value) = 0;
- virtual bool getClickVolLevels(std::array<uint32_t, 2> *value) = 0;
- virtual bool getLongVolLevels(std::array<uint32_t, 2> *value) = 0;
// Emit diagnostic information to the given file.
virtual void debug(int fd) = 0;
};
@@ -157,16 +136,6 @@
ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect> *_aidl_return) override;
ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override;
ndk::ScopedAStatus alwaysOnDisable(int32_t id) override;
- ndk::ScopedAStatus getResonantFrequency(float *resonantFreqHz) override;
- ndk::ScopedAStatus getQFactor(float *qFactor) override;
- ndk::ScopedAStatus getFrequencyResolution(float *freqResolutionHz) override;
- ndk::ScopedAStatus getFrequencyMinimum(float *freqMinimumHz) override;
- ndk::ScopedAStatus getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) override;
- ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t *durationMs) override;
- ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t *maxSize) override;
- ndk::ScopedAStatus getSupportedBraking(std::vector<Braking> *supported) override;
- ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle> &composite,
- const std::shared_ptr<IVibratorCallback> &callback) override;
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
@@ -192,29 +161,17 @@
ndk::ScopedAStatus performEffect(uint32_t effectIndex, uint32_t volLevel,
const std::string *effectQueue,
const std::shared_ptr<IVibratorCallback> &callback);
- ndk::ScopedAStatus setPwle(const std::string &pwleQueue);
bool isUnderExternalControl();
void waitForComplete(std::shared_ptr<IVibratorCallback> &&callback);
- uint32_t intensityToVolLevel(float intensity, uint32_t effectIndex);
- bool findHapticAlsaDevice(int *card, int *device);
- bool hasHapticAlsaDevice();
- bool enableHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device);
- void createPwleMaxLevelLimitMap();
+ uint32_t intensityToVolLevel(float intensity);
std::unique_ptr<HwApi> mHwApi;
std::unique_ptr<HwCal> mHwCal;
- uint32_t mF0Offset;
- std::array<uint32_t, 2> mTickEffectVol;
- std::array<uint32_t, 2> mClickEffectVol;
- std::array<uint32_t, 2> mLongEffectVol;
+ uint32_t mEffectVolMin;
+ uint32_t mEffectVolMax;
+ uint32_t mGlobalVolMax;
std::vector<uint32_t> mEffectDurations;
std::future<void> mAsyncHandle;
- int32_t compositionSizeMax;
- struct pcm *mHapticPcm;
- int mCard;
- int mDevice;
- bool mHasHapticAlsaDevice;
- bool mIsUnderExternalControl;
};
} // namespace vibrator
diff --git a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25-dual.rc b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25-dual.rc
deleted file mode 100644
index 7e9ff68..0000000
--- a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25-dual.rc
+++ /dev/null
@@ -1,74 +0,0 @@
-on boot
- wait /sys/class/leds/vibrator_1/device
-
- mkdir /mnt/vendor/persist/haptics 0770 system system
- chmod 770 /mnt/vendor/persist/haptics
- chmod 440 /mnt/vendor/persist/haptics/cs40l25a_dual.cal
- chown system system /mnt/vendor/persist/haptics
- chown system system /mnt/vendor/persist/haptics/cs40l25a_dual.cal
-
- chown system system /sys/class/leds/vibrator_1/activate
- chown system system /sys/class/leds/vibrator_1/brightness
- chown system system /sys/class/leds/vibrator_1/duration
- chown system system /sys/class/leds/vibrator_1/state
-
- chown system system /sys/class/leds/vibrator_1/device/asp_enable
- chown system system /sys/class/leds/vibrator_1/device/clab_enable
- chown system system /sys/class/leds/vibrator_1/device/comp_enable
- chown system system /sys/class/leds/vibrator_1/device/cp_dig_scale
- chown system system /sys/class/leds/vibrator_1/device/cp_trigger_duration
- chown system system /sys/class/leds/vibrator_1/device/cp_trigger_index
- chown system system /sys/class/leds/vibrator_1/device/cp_trigger_q_sub
- chown system system /sys/class/leds/vibrator_1/device/cp_trigger_queue
- chown system system /sys/class/leds/vibrator_1/device/dig_scale
- chown system system /sys/class/leds/vibrator_1/device/exc_enable
- chown system system /sys/class/leds/vibrator_1/device/f0_stored
- chown system system /sys/class/leds/vibrator_1/device/f0_offset
- chown system system /sys/class/leds/vibrator_1/device/fw_rev
- chown system system /sys/class/leds/vibrator_1/device/gpio1_enable
- chown system system /sys/class/leds/vibrator_1/device/gpio1_fall_dig_scale
- chown system system /sys/class/leds/vibrator_1/device/gpio1_fall_index
- chown system system /sys/class/leds/vibrator_1/device/gpio1_rise_dig_scale
- chown system system /sys/class/leds/vibrator_1/device/gpio1_rise_index
- chown system system /sys/class/leds/vibrator_1/device/gpio_event
- chown system system /sys/class/leds/vibrator_1/device/gpio_trigger
- chown system system /sys/class/leds/vibrator_1/device/heartbeat
- chown system system /sys/class/leds/vibrator_1/device/hw_reset
- chown system system /sys/class/leds/vibrator_1/device/num_waves
- chown system system /sys/class/leds/vibrator_1/device/q_stored
- chown system system /sys/class/leds/vibrator_1/device/redc_comp_enable
- chown system system /sys/class/leds/vibrator_1/device/redc_stored
- chown system system /sys/class/leds/vibrator_1/device/standby_timeout
- chown system system /sys/class/leds/vibrator_1/device/vbatt_max
- chown system system /sys/class/leds/vibrator_1/device/vbatt_min
- chown system system /sys/class/leds/vibrator_1/device/vibe_state
-
- enable vendor.vibrator.cs40l25-dual
-
-service vendor.vibrator.cs40l25-dual /vendor/bin/hw/android.hardware.vibrator-service.cs40l25-dual
- class hal
- user system
- group system
-
- setenv PROPERTY_PREFIX ro.vendor.vibrator.hal.
- setenv CALIBRATION_FILEPATH /mnt/vendor/persist/haptics/cs40l25a_dual.cal
-
- setenv HWAPI_PATH_PREFIX /sys/class/leds/vibrator_1/
- setenv HWAPI_DEBUG_PATHS "
- device/asp_enable
- device/clab_enable
- device/f0_stored
- device/f0_offset
- device/fw_rev
- device/gpio1_fall_dig_scale
- device/gpio1_fall_index
- device/gpio1_rise_dig_scale
- device/gpio1_rise_index
- device/heartbeat
- device/num_waves
- device/q_stored
- device/redc_stored
- state
- "
-
- disabled
diff --git a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25-dual.xml b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25-dual.xml
deleted file mode 100644
index 1bd3e7e..0000000
--- a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25-dual.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<manifest version="1.0" type="device">
- <hal format="aidl">
- <name>android.hardware.vibrator</name>
- <version>2</version>
- <fqname>IVibrator/dual</fqname>
- </hal>
-</manifest>
diff --git a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc
index 3f28d81..5508313 100644
--- a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc
+++ b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.rc
@@ -1,5 +1,4 @@
-on boot
- wait /sys/class/leds/vibrator/device
+on early-boot
mkdir /mnt/vendor/persist/haptics 0770 system system
chmod 770 /mnt/vendor/persist/haptics
@@ -7,14 +6,7 @@
chown system system /mnt/vendor/persist/haptics
chown system system /mnt/vendor/persist/haptics/cs40l25a.cal
- chown system system /sys/class/leds/vibrator/activate
- chown system system /sys/class/leds/vibrator/brightness
- chown system system /sys/class/leds/vibrator/duration
- chown system system /sys/class/leds/vibrator/state
-
chown system system /sys/class/leds/vibrator/device/asp_enable
- chown system system /sys/class/leds/vibrator/device/available_pwle_segments
- chown system system /sys/class/leds/vibrator/device/clab_enable
chown system system /sys/class/leds/vibrator/device/comp_enable
chown system system /sys/class/leds/vibrator/device/cp_dig_scale
chown system system /sys/class/leds/vibrator/device/cp_trigger_duration
@@ -24,7 +16,6 @@
chown system system /sys/class/leds/vibrator/device/dig_scale
chown system system /sys/class/leds/vibrator/device/exc_enable
chown system system /sys/class/leds/vibrator/device/f0_stored
- chown system system /sys/class/leds/vibrator/device/f0_offset
chown system system /sys/class/leds/vibrator/device/fw_rev
chown system system /sys/class/leds/vibrator/device/gpio1_fall_dig_scale
chown system system /sys/class/leds/vibrator/device/gpio1_fall_index
@@ -33,7 +24,6 @@
chown system system /sys/class/leds/vibrator/device/heartbeat
chown system system /sys/class/leds/vibrator/device/hw_reset
chown system system /sys/class/leds/vibrator/device/num_waves
- chown system system /sys/class/leds/vibrator/device/pwle
chown system system /sys/class/leds/vibrator/device/q_stored
chown system system /sys/class/leds/vibrator/device/redc_comp_enable
chown system system /sys/class/leds/vibrator/device/redc_stored
@@ -42,23 +32,18 @@
chown system system /sys/class/leds/vibrator/device/vbatt_min
chown system system /sys/class/leds/vibrator/device/vibe_state
- enable vendor.vibrator.cs40l25
-
service vendor.vibrator.cs40l25 /vendor/bin/hw/android.hardware.vibrator-service.cs40l25
class hal
user system
group system
- setenv PROPERTY_PREFIX ro.vendor.vibrator.hal.
+ setenv PROPERTY_PREFIX ro.vibrator.hal.
setenv CALIBRATION_FILEPATH /mnt/vendor/persist/haptics/cs40l25a.cal
setenv HWAPI_PATH_PREFIX /sys/class/leds/vibrator/
setenv HWAPI_DEBUG_PATHS "
device/asp_enable
- device/available_pwle_segments
- device/clab_enable
device/f0_stored
- device/f0_offset
device/fw_rev
device/gpio1_fall_dig_scale
device/gpio1_fall_index
@@ -66,10 +51,7 @@
device/gpio1_rise_index
device/heartbeat
device/num_waves
- device/pwle
device/q_stored
device/redc_stored
state
"
-
- disabled
diff --git a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.xml b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.xml
index 4db8f8c..49b11ec 100644
--- a/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.xml
+++ b/vibrator/cs40l25/android.hardware.vibrator-service.cs40l25.xml
@@ -1,7 +1,6 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.vibrator</name>
- <version>2</version>
<fqname>IVibrator/default</fqname>
</hal>
</manifest>
diff --git a/vibrator/cs40l25/bench/Android.bp b/vibrator/cs40l25/bench/Android.bp
index 110fea8..87a9dc0 100644
--- a/vibrator/cs40l25/bench/Android.bp
+++ b/vibrator/cs40l25/bench/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_benchmark {
name: "VibratorHalCs40l25Benchmark",
defaults: ["VibratorHalCs40l25TestDefaults"],
diff --git a/vibrator/cs40l25/device-stereo.mk b/vibrator/cs40l25/device-stereo.mk
deleted file mode 100644
index fe69b63..0000000
--- a/vibrator/cs40l25/device-stereo.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-PRODUCT_PACKAGES += \
- android.hardware.vibrator-service.cs40l25 \
- android.hardware.vibrator-service.cs40l25-dual \
-
-BOARD_SEPOLICY_DIRS += \
- hardware/google/pixel-sepolicy/vibrator/common \
- hardware/google/pixel-sepolicy/vibrator/cs40l25 \
diff --git a/vibrator/cs40l25/device.mk b/vibrator/cs40l25/device.mk
index 61b95d5..8dbf019 100644
--- a/vibrator/cs40l25/device.mk
+++ b/vibrator/cs40l25/device.mk
@@ -1,6 +1,9 @@
PRODUCT_PACKAGES += \
android.hardware.vibrator-service.cs40l25 \
+PRODUCT_PACKAGES_DEBUG += \
+ diag-vibrator \
+
BOARD_SEPOLICY_DIRS += \
hardware/google/pixel-sepolicy/vibrator/common \
hardware/google/pixel-sepolicy/vibrator/cs40l25 \
diff --git a/vibrator/cs40l25/diag/Android.bp b/vibrator/cs40l25/diag/Android.bp
new file mode 100644
index 0000000..acd8632
--- /dev/null
+++ b/vibrator/cs40l25/diag/Android.bp
@@ -0,0 +1,20 @@
+//
+// 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.
+
+sh_binary {
+ name: "diag-vibrator",
+ src: "diag-vibrator.sh",
+ vendor: true,
+}
diff --git a/vibrator/cs40l25/diag/diag-vibrator.sh b/vibrator/cs40l25/diag/diag-vibrator.sh
new file mode 100644
index 0000000..30dca9d
--- /dev/null
+++ b/vibrator/cs40l25/diag/diag-vibrator.sh
@@ -0,0 +1,64 @@
+#!/vendor/bin/sh
+
+set -e
+
+do_id()
+{
+ cat /sys/class/leds/vibrator/device/modalias | sed 's/^i2c://g'
+}
+
+do_ping()
+{
+ test "$(do_id)" == "cs40l25a"
+}
+
+do_enable()
+{
+ /system/bin/idlcli vibrator on "${@}"
+}
+
+do_disable()
+{
+ /system/bin/idlcli vibrator off
+}
+
+do_state()
+{
+ local state="$(cat /sys/class/leds/vibrator/device/vibe_state)"
+ if [[ "${state}" == "0" ]]
+ then
+ echo "stopped"
+ else
+ echo "running"
+ fi
+}
+
+do_dump()
+{
+ local loc="$(basename /sys/class/leds/vibrator/device/driver/*-0043)"
+ cat /sys/kernel/debug/regmap/${loc}/registers
+}
+
+do_help()
+{
+ local name="$(basename "${0}")"
+ echo "Usage:"
+ echo " ${name} id - Prints controller ID"
+ echo " ${name} ping - Verifies probe succedded"
+ echo " ${name} enable <ms> - Enables vibrator for <ms> milliseconds"
+ echo " ${name} disable - Disables vibrator."
+ echo " ${name} state - Returns 'stopped' or 'running' state."
+ echo " ${name} dump - Dumps memory mapped registers."
+}
+
+if [[ "${#}" -gt "0" ]]
+then
+ cmd="do_${1}" && shift
+fi
+
+if ! typeset -f "${cmd}" >/dev/null
+then
+ cmd="do_help"
+fi
+
+exec "${cmd}" "${@}"
diff --git a/vibrator/cs40l25/service.cpp b/vibrator/cs40l25/service.cpp
index 977e026..01a99c9 100644
--- a/vibrator/cs40l25/service.cpp
+++ b/vibrator/cs40l25/service.cpp
@@ -13,43 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include <android/binder_manager.h>
-#include <android/binder_process.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <log/log.h>
-
#include "Hardware.h"
#include "Vibrator.h"
-using ::aidl::android::hardware::vibrator::HwApi;
-using ::aidl::android::hardware::vibrator::HwCal;
-using ::aidl::android::hardware::vibrator::Vibrator;
-using ::android::defaultServiceManager;
-using ::android::ProcessState;
-using ::android::sp;
-using ::android::String16;
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <log/log.h>
-#if !defined(VIBRATOR_NAME)
-#define VIBRATOR_NAME "default"
-#endif
+using aidl::android::hardware::vibrator::HwApi;
+using aidl::android::hardware::vibrator::HwCal;
+using aidl::android::hardware::vibrator::Vibrator;
int main() {
- auto svc = ndk::SharedRefBase::make<Vibrator>(std::make_unique<HwApi>(),
- std::make_unique<HwCal>());
- const auto svcName = std::string() + svc->descriptor + "/" + VIBRATOR_NAME;
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ std::shared_ptr<Vibrator> vib = ndk::SharedRefBase::make<Vibrator>(std::make_unique<HwApi>(),
+ std::make_unique<HwCal>());
- ProcessState::initWithDriver("/dev/vndbinder");
-
- auto svcBinder = svc->asBinder();
- binder_status_t status = AServiceManager_addService(svcBinder.get(), svcName.c_str());
+ const std::string instance = std::string() + Vibrator::descriptor + "/default";
+ binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str());
LOG_ALWAYS_FATAL_IF(status != STATUS_OK);
- ProcessState::self()->setThreadPoolMaxThreadCount(1);
- ProcessState::self()->startThreadPool();
-
- ABinderProcess_setThreadPoolMaxThreadCount(0);
ABinderProcess_joinThreadPool();
-
return EXIT_FAILURE; // should not reach
}
diff --git a/vibrator/cs40l25/tests/Android.bp b/vibrator/cs40l25/tests/Android.bp
index 438df06..7acdece 100644
--- a/vibrator/cs40l25/tests/Android.bp
+++ b/vibrator/cs40l25/tests/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_test {
name: "VibratorHalCs40l25TestSuite",
defaults: ["VibratorHalCs40l25TestDefaults"],
diff --git a/vibrator/cs40l25/tests/mocks.h b/vibrator/cs40l25/tests/mocks.h
index 2c69e27..f0fd27a 100644
--- a/vibrator/cs40l25/tests/mocks.h
+++ b/vibrator/cs40l25/tests/mocks.h
@@ -24,7 +24,6 @@
public:
MOCK_METHOD0(destructor, void());
MOCK_METHOD1(setF0, bool(uint32_t value));
- MOCK_METHOD1(setF0Offset, bool(uint32_t value));
MOCK_METHOD1(setRedc, bool(uint32_t value));
MOCK_METHOD1(setQ, bool(uint32_t value));
MOCK_METHOD1(setActivate, bool(bool value));
@@ -45,10 +44,6 @@
MOCK_METHOD1(setGpioRiseIndex, bool(uint32_t value));
MOCK_METHOD1(setGpioRiseScale, bool(uint32_t value));
MOCK_METHOD1(pollVibeState, bool(bool value));
- MOCK_METHOD1(setClabEnable, bool(bool value));
- MOCK_METHOD1(getAvailablePwleSegments, bool(uint32_t *value));
- MOCK_METHOD0(hasPwle, bool());
- MOCK_METHOD1(setPwle, bool(std::string value));
MOCK_METHOD1(debug, void(int fd));
~MockApi() override { destructor(); };
@@ -57,15 +52,10 @@
class MockCal : public ::aidl::android::hardware::vibrator::Vibrator::HwCal {
public:
MOCK_METHOD0(destructor, void());
- MOCK_METHOD1(getVersion, bool(uint32_t *value));
MOCK_METHOD1(getF0, bool(uint32_t *value));
MOCK_METHOD1(getRedc, bool(uint32_t *value));
MOCK_METHOD1(getQ, bool(uint32_t *value));
- MOCK_METHOD1(getLongFrequencyShift, bool(int32_t *value));
MOCK_METHOD1(getVolLevels, bool(std::array<uint32_t, 6> *value));
- MOCK_METHOD1(getTickVolLevels, bool(std::array<uint32_t, 2> *value));
- MOCK_METHOD1(getClickVolLevels, bool(std::array<uint32_t, 2> *value));
- MOCK_METHOD1(getLongVolLevels, bool(std::array<uint32_t, 2> *value));
MOCK_METHOD1(debug, void(int fd));
~MockCal() override { destructor(); };
diff --git a/vibrator/cs40l25/tests/test-hwapi.cpp b/vibrator/cs40l25/tests/test-hwapi.cpp
index 7f2ae01..597bf75 100644
--- a/vibrator/cs40l25/tests/test-hwapi.cpp
+++ b/vibrator/cs40l25/tests/test-hwapi.cpp
@@ -53,8 +53,6 @@
"device/gpio1_rise_index",
"device/gpio1_rise_dig_scale",
"device/num_waves",
- "device/available_pwle_segments",
- "device/pwle",
};
public:
@@ -159,7 +157,6 @@
ValuesIn({
HasTest::MakeParam("device/cp_dig_scale", &Vibrator::HwApi::hasEffectScale),
HasTest::MakeParam("device/asp_enable", &Vibrator::HwApi::hasAspEnable),
- HasTest::MakeParam("device/pwle", &Vibrator::HwApi::hasPwle),
}),
HasTest::PrintParam);
@@ -235,8 +232,6 @@
&Vibrator::HwApi::getEffectCount),
GetUint32Test::MakeParam("device/cp_trigger_duration",
&Vibrator::HwApi::getEffectDuration),
- GetUint32Test::MakeParam("device/available_pwle_segments",
- &Vibrator::HwApi::getAvailablePwleSegments),
}),
GetUint32Test::PrintParam);
@@ -347,8 +342,6 @@
ValuesIn({
SetStringTest::MakeParam("device/cp_trigger_queue",
&Vibrator::HwApi::setEffectQueue),
- SetStringTest::MakeParam("device/pwle",
- &Vibrator::HwApi::setPwle),
}),
SetStringTest::PrintParam);
diff --git a/vibrator/cs40l25/tests/test-vibrator.cpp b/vibrator/cs40l25/tests/test-vibrator.cpp
index 3b083c1..1217cc2 100644
--- a/vibrator/cs40l25/tests/test-vibrator.cpp
+++ b/vibrator/cs40l25/tests/test-vibrator.cpp
@@ -66,7 +66,6 @@
// Constants With Arbitrary Values
-static constexpr uint32_t CAL_VERSION = 1;
static constexpr std::array<EffectLevel, 6> V_LEVELS{40, 50, 60, 70, 80, 90};
static constexpr std::array<EffectDuration, 10> EFFECT_DURATIONS{0, 0, 15, 0, 50,
100, 150, 200, 250, 8};
@@ -177,9 +176,6 @@
ON_CALL(*mMockCal, destructor()).WillByDefault(Assign(&mMockCal, nullptr));
- ON_CALL(*mMockCal, getVersion(_))
- .WillByDefault(DoAll(SetArgPointee<0>(CAL_VERSION), Return(true)));
-
ON_CALL(*mMockCal, getVolLevels(_))
.WillByDefault(DoAll(SetArgPointee<0>(V_LEVELS), Return(true)));
@@ -269,7 +265,6 @@
uint32_t f0Val = std::rand();
uint32_t redcVal = std::rand();
uint32_t qVal = std::rand();
- uint32_t calVer;
Expectation volGet;
Sequence f0Seq, redcSeq, qSeq, volSeq, durSeq;
@@ -294,13 +289,8 @@
.InSequence(qSeq)
.WillOnce(DoAll(SetArgPointee<0>(qVal), Return(true)));
EXPECT_CALL(*mMockApi, setQ(qVal)).InSequence(qSeq).WillOnce(Return(true));
- if (mMockCal->getVersion(&calVer) == 1) {
- volGet = EXPECT_CALL(*mMockCal, getVolLevels(_)).WillOnce(DoDefault());
- } else {
- volGet = EXPECT_CALL(*mMockCal, getTickVolLevels(_)).WillOnce(DoDefault());
- volGet = EXPECT_CALL(*mMockCal, getClickVolLevels(_)).WillOnce(DoDefault());
- volGet = EXPECT_CALL(*mMockCal, getLongVolLevels(_)).WillOnce(DoDefault());
- }
+
+ volGet = EXPECT_CALL(*mMockCal, getVolLevels(_)).WillOnce(DoDefault());
EXPECT_CALL(*mMockApi, setState(true)).WillOnce(Return(true));
EXPECT_CALL(*mMockApi, getEffectCount(_)).InSequence(durSeq).WillOnce(DoDefault());
@@ -537,7 +527,6 @@
const std::vector<PrimitiveParam> kPrimitiveParams = {
{CompositePrimitive::NOOP, 0}, {CompositePrimitive::CLICK, 2},
- {CompositePrimitive::THUD, 4}, {CompositePrimitive::SPIN, 5},
{CompositePrimitive::QUICK_RISE, 6}, {CompositePrimitive::SLOW_RISE, 7},
{CompositePrimitive::QUICK_FALL, 8},
};
@@ -597,23 +586,18 @@
const std::vector<ComposeParam> kComposeParams = {
{"click", {{0, CompositePrimitive::CLICK, 1.0f}}, Queue(QueueEffect(2, Level(1.0f)), 0)},
- {"thud", {{1, CompositePrimitive::THUD, 0.8f}}, Queue(1, QueueEffect(4, Level(0.8f)), 0)},
- {"spin", {{2, CompositePrimitive::SPIN, 0.6f}}, Queue(2, QueueEffect(5, Level(0.6f)), 0)},
{"quick_rise",
{{3, CompositePrimitive::QUICK_RISE, 0.4f}},
- Queue(3, QueueEffect(6, 0.4f * V_LEVELS[5]), 0)},
+ Queue(3, QueueEffect(6, Level(0.4f)), 0)},
{"slow_rise",
{{4, CompositePrimitive::SLOW_RISE, 0.0f}},
Queue(4, QueueEffect(7, Level(0.0f)), 0)},
{"quick_fall",
{{5, CompositePrimitive::QUICK_FALL, 1.0f}},
- Queue(5, QueueEffect(8, 1.0f * V_LEVELS[5]), 0)},
- {"pop",
- {{6, CompositePrimitive::SLOW_RISE, 1.0f}, {50, CompositePrimitive::THUD, 1.0f}},
- Queue(6, QueueEffect(7, Level(1.0f)), 50, QueueEffect(4, Level(1.0f)), 0)},
+ Queue(5, QueueEffect(8, Level(1.0f)), 0)},
{"snap",
{{7, CompositePrimitive::QUICK_RISE, 1.0f}, {0, CompositePrimitive::QUICK_FALL, 1.0f}},
- Queue(7, QueueEffect(6, 1.0f * V_LEVELS[5]), QueueEffect(8, 1.0f * V_LEVELS[5]), 0)},
+ Queue(7, QueueEffect(6, Level(1.0f)), QueueEffect(8, Level(1.0f)), 0)},
};
INSTANTIATE_TEST_CASE_P(VibratorTests, ComposeTest,
diff --git a/vibrator/drv2624/Android.bp b/vibrator/drv2624/Android.bp
index ef792a3..594aaeb 100644
--- a/vibrator/drv2624/Android.bp
+++ b/vibrator/drv2624/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_defaults {
name: "android.hardware.vibrator-defaults.drv2624",
cflags: [
diff --git a/vibrator/drv2624/Hardware.h b/vibrator/drv2624/Hardware.h
index 0588e2b..a07aec7 100644
--- a/vibrator/drv2624/Hardware.h
+++ b/vibrator/drv2624/Hardware.h
@@ -46,8 +46,7 @@
bool setSequencer(std::string value) override { return set(value, &mSequencer); }
bool setScale(uint8_t value) override { return set(value, &mScale); }
bool setCtrlLoop(bool value) override { return set(value, &mCtrlLoop); }
- bool setLpTriggerEffect(uint32_t value) override { return set(value, &mLpTriggerEffect); }
- bool setLpTriggerScale(uint8_t value) override { return set(value, &mLpTriggerScale); }
+ bool setLpTriggerEffect(uint32_t value) override { return set(value, &mLpTrigger); }
bool setLraWaveShape(uint32_t value) override { return set(value, &mLraWaveShape); }
bool setOdClamp(uint32_t value) override { return set(value, &mOdClamp); }
void debug(int fd) override { HwApiBase::debug(fd); }
@@ -64,8 +63,7 @@
open("device/set_sequencer", &mSequencer);
open("device/scale", &mScale);
open("device/ctrl_loop", &mCtrlLoop);
- open("device/lp_trigger_effect", &mLpTriggerEffect);
- open("device/lp_trigger_scale", &mLpTriggerScale);
+ open("device/lp_trigger_effect", &mLpTrigger);
open("device/lra_wave_shape", &mLraWaveShape);
open("device/od_clamp", &mOdClamp);
}
@@ -81,8 +79,7 @@
std::ofstream mSequencer;
std::ofstream mScale;
std::ofstream mCtrlLoop;
- std::ofstream mLpTriggerEffect;
- std::ofstream mLpTriggerScale;
+ std::ofstream mLpTrigger;
std::ofstream mLraWaveShape;
std::ofstream mOdClamp;
};
diff --git a/vibrator/drv2624/Vibrator.cpp b/vibrator/drv2624/Vibrator.cpp
index 213fc67..9e8683b 100644
--- a/vibrator/drv2624/Vibrator.cpp
+++ b/vibrator/drv2624/Vibrator.cpp
@@ -41,25 +41,21 @@
static constexpr char WAVEFORM_MODE[] = "waveform";
// Use effect #1 in the waveform library for CLICK effect
-static constexpr uint8_t WAVEFORM_CLICK_EFFECT_INDEX = 1;
+static constexpr char WAVEFORM_CLICK_EFFECT_SEQ[] = "1 0";
// Use effect #2 in the waveform library for TICK effect
-static constexpr char WAVEFORM_TICK_EFFECT_INDEX = 2;
+static constexpr char WAVEFORM_TICK_EFFECT_SEQ[] = "2 0";
// Use effect #3 in the waveform library for DOUBLE_CLICK effect
-static constexpr char WAVEFORM_DOUBLE_CLICK_EFFECT_INDEX = 3;
+static constexpr char WAVEFORM_DOUBLE_CLICK_EFFECT_SEQ[] = "3 0";
// Use effect #4 in the waveform library for HEAVY_CLICK effect
-static constexpr char WAVEFORM_HEAVY_CLICK_EFFECT_INDEX = 4;
+static constexpr char WAVEFORM_HEAVY_CLICK_EFFECT_SEQ[] = "4 0";
static std::uint32_t freqPeriodFormula(std::uint32_t in) {
return 1000000000 / (24615 * in);
}
-static float freqPeriodFormulaFloat(std::uint32_t in) {
- return static_cast<float>(1000000000) / static_cast<float>(24615 * in);
-}
-
using utils::toUnderlying;
Vibrator::Vibrator(std::unique_ptr<HwApi> hwapi, std::unique_ptr<HwCal> hwcal)
@@ -109,11 +105,17 @@
mHwCal->getTickDuration(&mTickDuration);
mHwCal->getDoubleClickDuration(&mDoubleClickDuration);
mHwCal->getHeavyClickDuration(&mHeavyClickDuration);
+
+ // This enables effect #1 from the waveform library to be triggered by SLPI
+ // while the AP is in suspend mode
+ if (!mHwApi->setLpTriggerEffect(1)) {
+ ALOGW("Failed to set LP trigger mode (%d): %s", errno, strerror(errno));
+ }
}
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) {
ATRACE_NAME("Vibrator::getCapabilities");
- int32_t ret = IVibrator::CAP_ALWAYS_ON_CONTROL | IVibrator::CAP_GET_RESONANT_FREQUENCY;
+ int32_t ret = 0;
if (mHwApi->hasRtpInput()) {
ret |= IVibrator::CAP_AMPLITUDE_CONTROL;
}
@@ -272,46 +274,35 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Vibrator::getEffectDetails(Effect effect, uint8_t *outIndex,
- uint32_t *outTimeMs) {
- switch (effect) {
- case Effect::TEXTURE_TICK:
- *outIndex = WAVEFORM_TICK_EFFECT_INDEX;
- *outTimeMs = mTickDuration;
- break;
- case Effect::CLICK:
- *outIndex = WAVEFORM_CLICK_EFFECT_INDEX;
- *outTimeMs = mClickDuration;
- break;
- case Effect::DOUBLE_CLICK:
- *outIndex = WAVEFORM_DOUBLE_CLICK_EFFECT_INDEX;
- *outTimeMs = mDoubleClickDuration;
- break;
- case Effect::TICK:
- *outIndex = WAVEFORM_TICK_EFFECT_INDEX;
- *outTimeMs = mTickDuration;
- break;
- case Effect::HEAVY_CLICK:
- *outIndex = WAVEFORM_HEAVY_CLICK_EFFECT_INDEX;
- *outTimeMs = mHeavyClickDuration;
- break;
- default:
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-
- return ndk::ScopedAStatus::ok();
-}
-
ndk::ScopedAStatus Vibrator::performEffect(Effect effect, EffectStrength strength,
int32_t *outTimeMs) {
ndk::ScopedAStatus status;
- uint8_t index;
- uint32_t timeMS;
+ uint32_t timeMS = 0;
uint8_t scale;
- status = getEffectDetails(effect, &index, &timeMS);
- if (!status.isOk()) {
- return status;
+ switch (effect) {
+ case Effect::TEXTURE_TICK:
+ mHwApi->setSequencer(WAVEFORM_TICK_EFFECT_SEQ);
+ timeMS = mTickDuration;
+ break;
+ case Effect::CLICK:
+ mHwApi->setSequencer(WAVEFORM_CLICK_EFFECT_SEQ);
+ timeMS = mClickDuration;
+ break;
+ case Effect::DOUBLE_CLICK:
+ mHwApi->setSequencer(WAVEFORM_DOUBLE_CLICK_EFFECT_SEQ);
+ timeMS = mDoubleClickDuration;
+ break;
+ case Effect::TICK:
+ mHwApi->setSequencer(WAVEFORM_TICK_EFFECT_SEQ);
+ timeMS = mTickDuration;
+ break;
+ case Effect::HEAVY_CLICK:
+ mHwApi->setSequencer(WAVEFORM_HEAVY_CLICK_EFFECT_SEQ);
+ timeMS = mHeavyClickDuration;
+ break;
+ default:
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
status = convertEffectStrength(strength, &scale);
@@ -319,7 +310,6 @@
return status;
}
- mHwApi->setSequencer(std::to_string(index) + " 0");
mHwApi->setScale(scale);
status = on(timeMS, WAVEFORM_MODE, mEffectConfig);
if (!status.isOk()) {
@@ -331,52 +321,16 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect> *_aidl_return) {
- *_aidl_return = {
- Effect::CLICK, Effect::DOUBLE_CLICK, Effect::TICK,
- Effect::HEAVY_CLICK, Effect::TEXTURE_TICK,
- };
- return ndk::ScopedAStatus::ok();
+ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect> * /*_aidl_return*/) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
- if (id != 0) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-
- ndk::ScopedAStatus status;
- uint8_t index;
- uint32_t timeMs;
- uint8_t scale;
-
- status = getEffectDetails(effect, &index, &timeMs);
- if (!status.isOk()) {
- return status;
- }
-
- status = convertEffectStrength(strength, &scale);
- if (!status.isOk()) {
- return status;
- }
-
- if (!mHwApi->setLpTriggerEffect(index)) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
-
- if (!mHwApi->setLpTriggerScale(scale)) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
-
- return ndk::ScopedAStatus::ok();
+ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t /*id*/, Effect /*effect*/,
+ EffectStrength /*strength*/) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t id) {
- if (id != 0) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- }
-
- mHwApi->setLpTriggerEffect(0);
-
- return ndk::ScopedAStatus::ok();
+ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t /*id*/) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t * /*maxDelayMs*/) {
@@ -402,49 +356,6 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-ndk::ScopedAStatus Vibrator::getResonantFrequency(float *resonantFreqHz) {
- uint32_t lraPeriod;
- if(!mHwCal->getLraPeriod(&lraPeriod)) {
- ALOGE("Failed to get resonant frequency (%d): %s", errno, strerror(errno));
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- *resonantFreqHz = freqPeriodFormulaFloat(lraPeriod);
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus Vibrator::getQFactor(float * /*qFactor*/) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus Vibrator::getFrequencyResolution(float * /*freqResolutionHz*/) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float * /*freqMinimumHz*/) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector<float> * /*_aidl_return*/) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t * /*durationMs*/) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t * /*maxSize*/) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector<Braking> * /*supported*/) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
-ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle> & /*composite*/,
- const std::shared_ptr<IVibratorCallback> & /*callback*/) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
-}
-
} // namespace vibrator
} // namespace hardware
} // namespace android
diff --git a/vibrator/drv2624/Vibrator.h b/vibrator/drv2624/Vibrator.h
index 5f81ee3..971014d 100644
--- a/vibrator/drv2624/Vibrator.h
+++ b/vibrator/drv2624/Vibrator.h
@@ -70,9 +70,6 @@
// 0 - Disabled
// 1+ - Waveform Index
virtual bool setLpTriggerEffect(uint32_t value) = 0;
- // Specifies scale to be used in low-power trigger mode.
- // See setScale().
- virtual bool setLpTriggerScale(uint8_t value) = 0;
// Specifies which shape to use for driving the LRA when in open loop
// mode.
// 0 - Square Wave
@@ -155,23 +152,12 @@
ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect> *_aidl_return) override;
ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override;
ndk::ScopedAStatus alwaysOnDisable(int32_t id) override;
- ndk::ScopedAStatus getResonantFrequency(float *resonantFreqHz) override;
- ndk::ScopedAStatus getQFactor(float *qFactor) override;
- ndk::ScopedAStatus getFrequencyResolution(float *freqResolutionHz) override;
- ndk::ScopedAStatus getFrequencyMinimum(float *freqMinimumHz) override;
- ndk::ScopedAStatus getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) override;
- ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t *durationMs) override;
- ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t *maxSize) override;
- ndk::ScopedAStatus getSupportedBraking(std::vector<Braking> *supported) override;
- ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle> &composite,
- const std::shared_ptr<IVibratorCallback> &callback) override;
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
private:
ndk::ScopedAStatus on(uint32_t timeoutMs, const char mode[],
const std::unique_ptr<VibrationConfig> &config);
- ndk::ScopedAStatus getEffectDetails(Effect effect, uint8_t *outIndex, uint32_t *outTimeMs);
ndk::ScopedAStatus performEffect(Effect effect, EffectStrength strength, int32_t *outTimeMs);
std::unique_ptr<HwApi> mHwApi;
diff --git a/vibrator/drv2624/android.hardware.vibrator-service.drv2624.rc b/vibrator/drv2624/android.hardware.vibrator-service.drv2624.rc
index d7ced06..fe3e548 100644
--- a/vibrator/drv2624/android.hardware.vibrator-service.drv2624.rc
+++ b/vibrator/drv2624/android.hardware.vibrator-service.drv2624.rc
@@ -1,48 +1,15 @@
-on boot
- wait /sys/class/leds/vibrator/device
-
- mkdir /mnt/vendor/persist/haptics 0770 system system
- chmod 770 /mnt/vendor/persist/haptics
- chmod 440 /mnt/vendor/persist/haptics/drv2624.cal
- chown system system /mnt/vendor/persist/haptics
- chown system system /mnt/vendor/persist/haptics/drv2624.cal
-
- write /sys/class/leds/vibrator/trigger transient
- chown system system /sys/class/leds/vibrator/activate
- chown system system /sys/class/leds/vibrator/brightness
- chown system system /sys/class/leds/vibrator/duration
- chown system system /sys/class/leds/vibrator/state
-
- chown system system /sys/class/leds/vibrator/device/autocal
- chown system system /sys/class/leds/vibrator/device/autocal_result
- chown system system /sys/class/leds/vibrator/device/ctrl_loop
- chown system system /sys/class/leds/vibrator/device/lp_trigger_effect
- chown system system /sys/class/leds/vibrator/device/lp_trigger_scale
- chown system system /sys/class/leds/vibrator/device/lra_wave_shape
- chown system system /sys/class/leds/vibrator/device/mode
- chown system system /sys/class/leds/vibrator/device/od_clamp
- chown system system /sys/class/leds/vibrator/device/ol_lra_period
- chown system system /sys/class/leds/vibrator/device/rtp_input
- chown system system /sys/class/leds/vibrator/device/scale
- chown system system /sys/class/leds/vibrator/device/set_sequencer
-
- enable vendor.vibrator.drv2624
-
service vendor.vibrator.drv2624 /vendor/bin/hw/android.hardware.vibrator-service.drv2624
class hal
user system
group system
- setenv PROPERTY_PREFIX ro.vendor.vibrator.hal.
+ setenv PROPERTY_PREFIX ro.vibrator.hal.
setenv CALIBRATION_FILEPATH /persist/haptics/drv2624.cal
setenv HWAPI_PATH_PREFIX /sys/class/leds/vibrator/
setenv HWAPI_DEBUG_PATHS "
device/autocal
device/lp_trigger_effect
- device/lp_trigger_scale
device/ol_lra_period
state
"
-
- disabled
diff --git a/vibrator/drv2624/android.hardware.vibrator-service.drv2624.xml b/vibrator/drv2624/android.hardware.vibrator-service.drv2624.xml
index 4db8f8c..49b11ec 100644
--- a/vibrator/drv2624/android.hardware.vibrator-service.drv2624.xml
+++ b/vibrator/drv2624/android.hardware.vibrator-service.drv2624.xml
@@ -1,7 +1,6 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.vibrator</name>
- <version>2</version>
<fqname>IVibrator/default</fqname>
</hal>
</manifest>
diff --git a/vibrator/drv2624/apex/Android.bp b/vibrator/drv2624/apex/Android.bp
deleted file mode 100644
index 016a793..0000000
--- a/vibrator/drv2624/apex/Android.bp
+++ /dev/null
@@ -1,59 +0,0 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-apex {
- name: "com.android.vibrator.drv2624",
- manifest: "apex_manifest.json",
- key: "com.android.vibrator.drv2624.key",
- certificate: ":com.android.vibrator.drv2624.certificate",
- file_contexts: "file_contexts",
- use_vndk_as_stable: true,
- updatable: false,
-
- // install the apex in /vendor/apex
- proprietary: true,
-
- // BEGIN of apex payloads
- // /bin
- binaries: [
- "android.hardware.vibrator-service.drv2624",
- ],
- // /etc
- prebuilts: [
- "com.android.vibrator.drv2624.rc",
- ],
- // END of apex payloads
-
- // BEGIN of companion files to be installed if this module is installed
- // init script, which is installed in /vendor/etc.
- // Note that init scripts in an apex can contain only "service" sections.
- // The following init script contains "on" section to enable the service.
- init_rc: [
- "com.android.vibrator.drv2624.enable.rc",
- ],
-
- // vintf manifest fragments, which is installed in /vendor/etc/vintf.
- // TODO(b/130058564): should we put vintf framgments within the apex?
- vintf_fragments: [
- "com.android.vibrator.drv2624.xml",
- ],
- // END of companion filse
-}
-
-apex_key {
- name: "com.android.vibrator.drv2624.key",
- public_key: "com.android.vibrator.drv2624.pubkey",
- private_key: "com.android.vibrator.drv2624.pem",
-}
-
-android_app_certificate {
- name: "com.android.vibrator.drv2624.certificate",
- certificate: "com.android.vibrator.drv2624",
-}
-
-prebuilt_etc {
- name: "com.android.vibrator.drv2624.rc",
- src: "com.android.vibrator.drv2624.rc",
- installable: false,
-}
diff --git a/vibrator/drv2624/apex/apex_manifest.json b/vibrator/drv2624/apex/apex_manifest.json
deleted file mode 100644
index ac8af3a..0000000
--- a/vibrator/drv2624/apex/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.vibrator.drv2624",
- "version": 1
-}
diff --git a/vibrator/drv2624/apex/com.android.vibrator.drv2624.enable.rc b/vibrator/drv2624/apex/com.android.vibrator.drv2624.enable.rc
deleted file mode 100644
index d9b79f0..0000000
--- a/vibrator/drv2624/apex/com.android.vibrator.drv2624.enable.rc
+++ /dev/null
@@ -1,29 +0,0 @@
-on boot
- wait /sys/class/leds/vibrator/device
-
- mkdir /mnt/vendor/persist/haptics 0770 system system
- chmod 770 /mnt/vendor/persist/haptics
- chmod 440 /mnt/vendor/persist/haptics/drv2624.cal
- chown system system /mnt/vendor/persist/haptics
- chown system system /mnt/vendor/persist/haptics/drv2624.cal
-
- write /sys/class/leds/vibrator/trigger transient
- chown system system /sys/class/leds/vibrator/activate
- chown system system /sys/class/leds/vibrator/brightness
- chown system system /sys/class/leds/vibrator/duration
- chown system system /sys/class/leds/vibrator/state
-
- chown system system /sys/class/leds/vibrator/device/autocal
- chown system system /sys/class/leds/vibrator/device/autocal_result
- chown system system /sys/class/leds/vibrator/device/ctrl_loop
- chown system system /sys/class/leds/vibrator/device/lp_trigger_effect
- chown system system /sys/class/leds/vibrator/device/lp_trigger_scale
- chown system system /sys/class/leds/vibrator/device/lra_wave_shape
- chown system system /sys/class/leds/vibrator/device/mode
- chown system system /sys/class/leds/vibrator/device/od_clamp
- chown system system /sys/class/leds/vibrator/device/ol_lra_period
- chown system system /sys/class/leds/vibrator/device/rtp_input
- chown system system /sys/class/leds/vibrator/device/scale
- chown system system /sys/class/leds/vibrator/device/set_sequencer
-
- enable vendor.vibrator.drv2624
diff --git a/vibrator/drv2624/apex/com.android.vibrator.drv2624.pem b/vibrator/drv2624/apex/com.android.vibrator.drv2624.pem
deleted file mode 100644
index 012ed8f..0000000
--- a/vibrator/drv2624/apex/com.android.vibrator.drv2624.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKQIBAAKCAgEApQRSXBZAOcDNbSYwIOIEsONVxMzd0lAUeOkFc/vRRfxMFtDy
-vh1rpxZzcSyaUj+Hx82yNDaVTkXFSHhBlupeRffnZU1Nf2n9q3g9dUDC7cSF2mj0
-xXgKkTHV8aWqmM68Gy1dUyRehUtMxF+QbpGPuN1Cq9n3mYIwuAjoXnrchtV31aco
-WgGmMZi6V2MwlzKDQ7XYL0ZY7cAHXQwo07pcqBXJujvJjaW+O9m9aY6Mx9Qoe/Vh
-NQUMV5jKtQAxhvvu57hOa2ExzoEyCq0xao2Bu+ynvoSKl+4ibVqufILEGwG6Uplz
-/l5R2KqHNXeLg3lyESmh1ACjj+PI4yszNqcY0I+jb7vkiY7SdEF6ZLklk/BoT+Bv
-BPgdjahDb1trAv6+uEwA5Ybglegt2HwaA30Y5v7+8Q3JFBhL2g3gRBN3LCy0w5aQ
-/vcp6UhLU/SZWvshmO46S2R1Sj5CvgTvZun46vKpSmwDuJwwJZ8sJydnynTtghN1
-zrapxUVF5fkY8ZjmeI8PLmQnbdsDZaXQpYte6DmLTuafazYyr/KbmxqeMTd7h2qz
-xOR8VbErATmwqxvh4xt3hZVeTzmfncAkMBPOlYTEVW7nvjk7x1q5TUT1a+6ByEbU
-9Ynk708u/xeVwKwwL010ITecZGWUQ9uR1QlLmeaQRZsCXehn9IXcbf02qNcCAwEA
-AQKCAgAF0kk1hnNtliepGhfIkTCpLNvxvWh16u1N9qqClPelCGmGxIhLvK33jwsz
-iudGz4byvYbz4JkT0dJL5DIsKMh6n2xCXp/FRu/0BKHmaQp3aN9v/RPlg36b8K4j
-gDysd16bdtY8AKR0/1sN8nEd9XSkiOm5Nk9N0xH07BuGeb8d4pn/p4383uIGDeVE
-//LO4rFOyjN+N3UbrhKUbcFi9sgeBea/8ywBGz/CzMOp3aWJxypGdTmgrTTqQjGk
-gQU+RdT/x7i8gQlIx7YEOmfr4mIZRxgD2JkrEvOT+Ab/zX0tlroD//Xfm2Q3yIxM
-jpMVaEtl35od6Ifco6SKnxOHcg2l/2aHR+DvFgrj8Ed1SH0hWqP2Mj+raY/ZNCwQ
-23vnQ5kCD5M2vb8hMT/Zx2MPixIK/I1CW73GX9hdDXHLP8Mt5Lhx3Z4vR1Pj6p8w
-tPV+GCfmwMJ3u5eyBLeOHkOHnFktQWXNCG9pnH62GHxF8As8cgWr9FGTm7RY6tx/
-tbzDu7dPQSaikVxpOA6Xu/a0zYfibiXKZGjb9AFv+62HQaZ1lz05WTtDk95EgJn/
-LwZTmsFBALUABrghS1VAMV8NOeNw8fithdc3HpKz9nc+hkV3o3hbxsbqsPz6/7Bv
-FdTtE+bLkkmCFIj9yFtZ0Qa8VF1LJ/+JNlQJ1Rjw3kSV3SZ1wQKCAQEA15pC5w4q
-g55Bk+9ECfslpWkI8wVTYcvlZdMjVTcDMJBqK4RzJM+c0SdwSEhWOTGRWafC821L
-FqdblziPYF7XmymT0FducDmBcg3EWW+RkFKpaZu5YRU9juz8jjsHyLOmAc5+3jBu
-IHAKH4oFifpEuNfBUgwpLGq8V+wCZ+kMBhrmPeZhCMxR7M9kkToJmoiDOHXK7GMf
-/AcnLlAHvxnUkS/BpabiVT06Eyy2dvZQ3dkxx5VW+bQrgLBKgy4uztku0F739oSd
-ewseiuq0t+4iPwL9VvdjwM8JpNnFtPUZ/Y1exBHpW24xJsr3USpNSy2ZtG4UUiye
-QEaUeuetKRd/XQKCAQEAw++h72NUhv+3MuzWSCTpckUp5MqBne4j1AOrvezUdK8B
-4eUowRWFAaZnZqkMQRIRmAaxF6+0AqsJx2ROqKOpniELq6UXcjbpVJFYOexT3UzX
-hyRGDEvwvHKschfRadHvniK4QuzAv+wceSubYRAD0uG2yotQzZKs4+StSPDXWOFj
-UWSgLkrg+NqPacyPEfq3mk4l1nFnCNp7zIsHfW5M9bUehaWZIhZRxugrpOLPDMa5
-9/rnVMhBdONrTsLIeSXOoZ06M6esD3usOb/eziL6vo3vWd1oKazuAaX4BvHS4ZWV
-9AEuVTJfYvqp88FKRz0OqzEeCHmbNnBwEzXYjanpwwKCAQEAyknwj73Y4dkwik6q
-NfswXTxpqyrKCy41tA4gTqnpEj3Nf7ssFdO9vPgV/5vvWoZJbCddYOyg0UaBRydI
-TxFtliWyjH4cHqu16n9ERO3LU/BbB72Wd6JoOZvdcs2sBgGYtoU6v9oM2d6FgQYN
-IGJy7ENzHTpPv17+DDhiIYClSW0freBkFs8t5tTH9QLRU+7Vv7m1hYmTzvIfLvLj
-8ceYjAiU1on4PiXOQYNoR8HgKebJMAvMqUkEsB+4KdDBFk7r/5G7cc8HuxS5uXlx
-ykliVGDHtjszmwomcEfrmleF5UIpMinkG2cOMumolrzr/KdyWboW0usOKByQ36hT
-7gQf+QKCAQEArtQqbPz3lkGjyLfU96if+ItIN1KOV0n/BBWGb8BbTgY+Kr8cHzVB
-adh+GPcr7P/fXQRTjiwD9gGBhz20hfsKxQL9c9mqUwo2JnROAdkid6syAO7X5e74
-zl2QC3m/LKnbIgIe4fB4iId4XJIRYYk1sDwgqxemMNf4lpwcFqJ3tGHgCec8mjHM
-DaCPKLsSydspanDiiDbF1fuFTVycgUojN3a11lCNlAHQVCgjkUujreXAWEmzkk3h
-QhgOTse0s4yNlF1DaoXpHCOg6CKQ/uPtUow5DrllURJxiFz8M84g+ZJMq91F51U8
-EYhSjyJgUbJkXVJFVxCS8v9esXVxVe5PmwKCAQAUS3vbNjb1s6pf8GQiYaI0C8o5
-7yz//kSQvlIjFbU95wysKYTeHQ5GTCdSNWt3qJYqAfSNK2/YiTzLTmieCDlijriK
-WkbrisAvkwK3yB5Zg5FLORUhTuBJdJXW6fay11gCCqpQTmEHKeTeK8UNEViTdt5H
-HvAedLO9pPh1TS0l6f0rbrLWc+MVuAmnuywuJZk9+yPcXpnKpv61BYyTaADsyjgS
-XJ/wPKbAk7n6RgFMEOvCtkfRdpf5+CoS7lz5mVdgSa4FRpIaZGji1wHbSoLgmZnl
-7jDIwKFsVNg5YHCmHtU4XlgcPlt1SRgcrCeu16GSHAcRr3arIYi8Sc0Y0BQO
------END RSA PRIVATE KEY-----
diff --git a/vibrator/drv2624/apex/com.android.vibrator.drv2624.pk8 b/vibrator/drv2624/apex/com.android.vibrator.drv2624.pk8
deleted file mode 100644
index 1e94187..0000000
--- a/vibrator/drv2624/apex/com.android.vibrator.drv2624.pk8
+++ /dev/null
Binary files differ
diff --git a/vibrator/drv2624/apex/com.android.vibrator.drv2624.pubkey b/vibrator/drv2624/apex/com.android.vibrator.drv2624.pubkey
deleted file mode 100644
index 479a868..0000000
--- a/vibrator/drv2624/apex/com.android.vibrator.drv2624.pubkey
+++ /dev/null
Binary files differ
diff --git a/vibrator/drv2624/apex/com.android.vibrator.drv2624.rc b/vibrator/drv2624/apex/com.android.vibrator.drv2624.rc
deleted file mode 100644
index df4e3e9..0000000
--- a/vibrator/drv2624/apex/com.android.vibrator.drv2624.rc
+++ /dev/null
@@ -1,18 +0,0 @@
-service vendor.vibrator.drv2624 /apex/com.android.vibrator.drv2624/bin/hw/android.hardware.vibrator-service.drv2624
- class hal
- user system
- group system
-
- setenv PROPERTY_PREFIX ro.vendor.vibrator.hal.
- setenv CALIBRATION_FILEPATH /persist/haptics/drv2624.cal
-
- setenv HWAPI_PATH_PREFIX /sys/class/leds/vibrator/
- setenv HWAPI_DEBUG_PATHS "
- device/autocal
- device/lp_trigger_effect
- device/lp_trigger_scale
- device/ol_lra_period
- state
- "
-
- disabled
diff --git a/vibrator/drv2624/apex/com.android.vibrator.drv2624.x509.pem b/vibrator/drv2624/apex/com.android.vibrator.drv2624.x509.pem
deleted file mode 100644
index e1d9cac..0000000
--- a/vibrator/drv2624/apex/com.android.vibrator.drv2624.x509.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF6TCCA9GgAwIBAgIUS+fMQCRvkowd4LpTC7T24ObLaNowDQYJKoZIhvcNAQEL
-BQAwgYIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMCAXDTIwMDYx
-NTA4MDYxMloYDzQ3NTgwNTEyMDgwNjEyWjCBgjELMAkGA1UEBhMCVVMxEzARBgNV
-BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoM
-B0FuZHJvaWQxEDAOBgNVBAsMB0FuZHJvaWQxIjAgBgkqhkiG9w0BCQEWE2FuZHJv
-aWRAYW5kcm9pZC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDn
-GbaLjkQDnLq8sjgGjKYBo5G/y7AeiL2wM7zLZSP5tYlQ1Ulj4AZx1xu2A3zneVBo
-gd/RtEz3n+P/iA7GYkgq42iT8LeQhAZKC2AfbfywzkaVUgW5yyEPwliPmVUDN8aa
-JlDJ+kgYvzRbqwtJcowMgls6EmxTRgzF1B7tZZJ2BGhDe38pyLx/yiM+lnyLaGUp
-yZM8m8Uc3CoWtINZfw28QKPhCnJ0Hsl3HahElEvwWrxEYwwNCZfjteq+jbgdbewh
-QjunbM1gXsqFVH4pPdrRD5m/tq54mNA1w2Br1gosPQ6WOAsTwB+F7dRGadXvJV1r
-h6mg9ESvB9GmEeM6ybDJXUbrpWD2CddX7pWIjlUjY7gvKoqUeS/fY/wl5uCfbqFB
-LdXZQGqFVbYkvhWtjCuAH9oN+mHkzF9iEF7Fo6ap63Vd/r5ZAdsnJioyO2E0vabn
-5rSg9dtvrnIUxPUqsq0FKKx471ZKC2Ps8TkAHHiE01o38R0HvPSp39C/3IZBggsu
-Z3kA4Y28Q1EFvZfInbZH/pUsOIU25T3Y7qMfHFAaqcGsMFw9baP/3UW0rH7mIv6A
-LbJ0fHPoXyi/e2BBcP8gOXGRkfC1QKWVIji/oJVuo08sFXZmo1BPC7ffmHDpLHtn
-njuiuUi8vRRyp25nyiafcWTEtEGSmS+rbV1BZafgzwIDAQABo1MwUTAdBgNVHQ4E
-FgQUZoKnKb+Z7+U5VUnsZDMvkOwq3OgwHwYDVR0jBBgwFoAUZoKnKb+Z7+U5VUns
-ZDMvkOwq3OgwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAWhpx
-aMf5OU+UqIQ0oNfJMsKD3naxwvjNtxEbVdXZLXOWXZjMYbT1uzfx245/l8KPjj4z
-RVGu7mWBFAoNRyWxibC8vfX9UlWfDTOfJv4S3tp7xvStvNEmZpdfa7YSQ1PqcJyw
-oPmwNw6+Py1F6pgjtq7Adv+5v692zbTLurkGiAEz6FW5tf4tQb+nY8awTcu9Qx+M
-bous4Mjv8D+biM2jePsvGso/3wVViL40MWOsHDJP4nreygmlkCiariVwVkarEmdH
-dZ6vJ/T+vs1hPkkhxg3oNoXr2ZOaqi8Yt4wkJTnlcyUDEyhINj60YTW4FdDGdUaJ
-iUx8+1o1x6Y8KwgLBxwJX2HQlm79Tws7IxM+b6ZbJeWn8QHckuREtwmzLF7uvC3n
-p33w+tsx6NvSPIIQXfTKjij13lJ8ou5s8a0cr6lWe8dJlY46GeIXESdLlrGF47y5
-kKc+Bm6wiH4BJFO1B/j0T6miM6RCOVE/K4Z3SUPl5XfG3pnOBiMjxxuV6m8GCG11
-qRRhqycW+r2UW+aIQdyrr5N3CWb4EPKPtHWMnXsCmEuuLXTTBi/9XIeJdlt5jsEI
-Hh19bQoVVGwnrDeyKkEsTgeOhs7+2nZ6az/8C7gxkGlZ3fQu5w1wg6G5TqIr3XNW
-8rWXShiHxat5sB1c3ON8X4ZukajREniUSOXhzic=
------END CERTIFICATE-----
diff --git a/vibrator/drv2624/apex/com.android.vibrator.drv2624.xml b/vibrator/drv2624/apex/com.android.vibrator.drv2624.xml
deleted file mode 100644
index 4db8f8c..0000000
--- a/vibrator/drv2624/apex/com.android.vibrator.drv2624.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<manifest version="1.0" type="device">
- <hal format="aidl">
- <name>android.hardware.vibrator</name>
- <version>2</version>
- <fqname>IVibrator/default</fqname>
- </hal>
-</manifest>
diff --git a/vibrator/drv2624/apex/file_contexts b/vibrator/drv2624/apex/file_contexts
deleted file mode 100644
index 5be98ec..0000000
--- a/vibrator/drv2624/apex/file_contexts
+++ /dev/null
@@ -1,2 +0,0 @@
-(/.*)? u:object_r:vendor_file:s0
-/bin/hw/android\.hardware\.vibrator-service\.drv2624 u:object_r:hal_vibrator_default_exec:s0
\ No newline at end of file
diff --git a/vibrator/drv2624/apex/key.pem b/vibrator/drv2624/apex/key.pem
deleted file mode 100644
index b582099..0000000
--- a/vibrator/drv2624/apex/key.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDnGbaLjkQDnLq8
-sjgGjKYBo5G/y7AeiL2wM7zLZSP5tYlQ1Ulj4AZx1xu2A3zneVBogd/RtEz3n+P/
-iA7GYkgq42iT8LeQhAZKC2AfbfywzkaVUgW5yyEPwliPmVUDN8aaJlDJ+kgYvzRb
-qwtJcowMgls6EmxTRgzF1B7tZZJ2BGhDe38pyLx/yiM+lnyLaGUpyZM8m8Uc3CoW
-tINZfw28QKPhCnJ0Hsl3HahElEvwWrxEYwwNCZfjteq+jbgdbewhQjunbM1gXsqF
-VH4pPdrRD5m/tq54mNA1w2Br1gosPQ6WOAsTwB+F7dRGadXvJV1rh6mg9ESvB9Gm
-EeM6ybDJXUbrpWD2CddX7pWIjlUjY7gvKoqUeS/fY/wl5uCfbqFBLdXZQGqFVbYk
-vhWtjCuAH9oN+mHkzF9iEF7Fo6ap63Vd/r5ZAdsnJioyO2E0vabn5rSg9dtvrnIU
-xPUqsq0FKKx471ZKC2Ps8TkAHHiE01o38R0HvPSp39C/3IZBggsuZ3kA4Y28Q1EF
-vZfInbZH/pUsOIU25T3Y7qMfHFAaqcGsMFw9baP/3UW0rH7mIv6ALbJ0fHPoXyi/
-e2BBcP8gOXGRkfC1QKWVIji/oJVuo08sFXZmo1BPC7ffmHDpLHtnnjuiuUi8vRRy
-p25nyiafcWTEtEGSmS+rbV1BZafgzwIDAQABAoICAGALcq9bR+8MYxtrIheuuotx
-1HAWkjKOd+9UAUGy3hm4lcIPcnncsDD9ylmB55Y39/AHEeMQgPBk9hfMDv/p9r5E
-VsEtSMz54bdCNQe66Ur9353NQe3ueuYWykGb4xX8R0DnbaoTp4UJahQy6PT0czn7
-rzhaUcTmFwbc2qGlFhKQUFjDaZ0O/TBK7Qzk9AvoLisIyHVm86vD4IYhLXmzcRzs
-7G7prZmO9gHYRIeD7m+M9jOhym9crlCH2XCqa3tnpLxJz4sMj+peWuLAs9ImD9vV
-FPv1S1t5fwbpFRicEwxBr99EmW3y6eb6ab992tiR+dpnvlrTSfxITpwrUPmsuxia
-nWXbMoCuLmW4PypZpNPYawB6lRafCtjIY0Kxs3owvBnOQIhdKx5Ls8N8pRonjXfn
-J/CzrxPSua6z8GaYtBs03O/QPhiXrblKUxEHfTcAVt5EBE3Ke5V+7Rlew9rD6AIF
-m8sgOZocQ/NS6f65ZyvE0ju6RKwNd2EBTy+v5UqopPOnLcgpWEUw4e2tyOJ4fI8G
-5h/NllaxfwOsgnKxakw4a3FUHCRMCt5HqvGIDb8VL+fH6c+XXUDlyFoKY6JbxxBx
-kmsSdJkebpkWFn9i2DRGfAVzH0Ux9ohEeC2Ixmr21q88GeRCQ4fWd2KVeotY8egJ
-SE5hcO7qu52fiJdmtBYhAoIBAQD9t1tFzyOLSy7kiuF5lXmgUODbTgn/5263Hduk
-ifwcqIsWsK/NeyeaEUuxBLiKoAc9xQOVkQuBTwKxffvihYL355kI0yKSnsS5OEKT
-bOl0IYXkfjZz3jbxSKjojce4DxNiWzB10RWEfJ67HNDrPjmiS3Jj6CnE8X8UirLN
-udznNneq6R1nZ25upcR0bN3bDerf9jZIfcMAnBipyTzRLw3Hfn2gdPy3X4nXdp9/
-mhnBn0KyyDb+FfGOsYEvV5foDGuSuS5gf7AledLm1BRQ/YKVFgmuvePIxIoz098G
-PVDbdGs3GDvem0ptpBzjpGPYevTuN1CxJXEcifpZYP2Y7HL/AoIBAQDpLj4UZKlK
-y8YGOgllax/GSlumjDRqXMWS9HYksUOSIFBCMHaNNcUAUlxSn19NZetDSbRUtUIO
-XE/w6Lc/MP/q7v7WfU1yAW8yxXwszBI9VO9QYOa3oCc0fFOyjE9sBI3DhLKxP9s6
-f6hNRoyHoi3UTJVnwdlHBCF98kmO6oVZ+OM/uIH9X8YUcJ5xGT6a7Yt4mJAS/fKc
-l2azfqfS3occXr33cCUknomuKU04tKVnRlLiIQgRdACUW2LtYTjH6tFeWXOkfPOF
-Nn8zkVtcJ4JZIVifY8uP36cTpSkeZazZ0sYgM/gCtbKn3yhs51xT0lyhdTVJJevS
-ZgUJqc7m4CIxAoIBAQDunzLC12ywp4d0/4HM3l7D/w1cdWtGOZ6Rrw1TFUv+kC4w
-qwDNm5TFfJrZ5HzENHpbCB603vQZK/x2fu0WQUfKbRIrkJglmhmfsmA7U+XFiXnq
-SyJfm5HFIPdrsV0zqUor6WQMixdXwfVwOkvr1FxUXe06NbKDPjatVT2R68rt0vZ9
-0j4LcOYWPuYkMff+/Hn5JhIr38w1mJpBpbkDbOPiyv7QmPbOaJa2BSVB1+d9iZIr
-n87I7k6ATEYaBqIiZvwNxQjvTWiX9pn662AoRCY6nb2BkarYurDYyd4qeiTAIiBs
-cuhsF1XLBNz+5S/a/Nm76l6EHZjipIrG4UfiOhB1AoIBAC2oAD+99efPPla5xl01
-PGN267sQeLLat1SuyPMmQjS6XvyWwJ+lh40okysaSW6+JfJm3Ag59VUafgyNhFO7
-JGC7quoUXrWT0lH+mPGsg2W+25zBXGtX0FVWgozTLDnaKme9878A4cvycuGujpWA
-C7klxZsrOX/OL0CZ0A1LnhCfyt8PIWSa/A3Ef0Flz/xFxqk2Nf+B+Z7vhgxfID0J
-lSrY4hkwvBUPdaXEMHqJ5Fj0TAY6sXm5XOOvgQ85mgSK1bPDkAEE9il/IijWrSy+
-D6ej/9Y1lAX3pJ8UF5j8D3wW6PQlOMpPCUwVRbUNF+bRqZFzgZtw8Vug3humQ/yw
-pgECggEAY9Hp381730ISZitEAPQzV9sMj3W/BMSb9JVcS/b995hsmTtu5LO2s6Pb
-MGDYpOZHlbdyGWRGd9VhJpoagf2YMn9Gl0cERPvmY74aJmZ3O23T+gDU2C0dRy6o
-cCv3mKn6QAyy5EpBs6kgHarMDGUX39lB5z6iqn2/rwqqxqGzVonn2vKxZ3cqNpdV
-SztAqFQic46s31KtHQOSxYpBioq3iIKtHzrPMjyoyNsLC+4OG5BkbR8YHLK6uM5v
-4SCutgeR6pE5IQCD08S/WsLOOyve5HF/fNU9O+yrxHLoH9oMxNA4K+SUv2LeifQh
-zCK8JO9WGOwvH9n0F+pgYXEo4OtjMA==
------END PRIVATE KEY-----
diff --git a/vibrator/drv2624/bench/Android.bp b/vibrator/drv2624/bench/Android.bp
index e2d68da..6227dc5 100644
--- a/vibrator/drv2624/bench/Android.bp
+++ b/vibrator/drv2624/bench/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_benchmark {
name: "VibratorHalDrv2624Benchmark",
defaults: ["VibratorHalDrv2624TestDefaults"],
diff --git a/vibrator/drv2624/bench/benchmark.cpp b/vibrator/drv2624/bench/benchmark.cpp
index 24b6764..7a425b3 100644
--- a/vibrator/drv2624/bench/benchmark.cpp
+++ b/vibrator/drv2624/bench/benchmark.cpp
@@ -42,7 +42,6 @@
"device/scale",
"device/ctrl_loop",
"device/lp_trigger_effect",
- "device/lp_trigger_scale",
"device/lra_wave_shape",
"device/od_clamp",
};
diff --git a/vibrator/drv2624/device.mk b/vibrator/drv2624/device.mk
index c2719b5..1a3e184 100644
--- a/vibrator/drv2624/device.mk
+++ b/vibrator/drv2624/device.mk
@@ -1,6 +1,5 @@
PRODUCT_PACKAGES += \
- com.android.vibrator.drv2624 \
+ android.hardware.vibrator-service.drv2624 \
BOARD_SEPOLICY_DIRS += \
- hardware/google/pixel-sepolicy/vibrator/common \
hardware/google/pixel-sepolicy/vibrator/drv2624 \
diff --git a/vibrator/drv2624/tests/Android.bp b/vibrator/drv2624/tests/Android.bp
index 8f392a1..4c85740 100644
--- a/vibrator/drv2624/tests/Android.bp
+++ b/vibrator/drv2624/tests/Android.bp
@@ -13,10 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_test {
name: "VibratorHalDrv2624TestSuite",
defaults: ["VibratorHalDrv2624TestDefaults"],
diff --git a/vibrator/drv2624/tests/mocks.h b/vibrator/drv2624/tests/mocks.h
index b4d06d1..bbb4408 100644
--- a/vibrator/drv2624/tests/mocks.h
+++ b/vibrator/drv2624/tests/mocks.h
@@ -33,7 +33,6 @@
MOCK_METHOD1(setScale, bool(uint8_t value));
MOCK_METHOD1(setCtrlLoop, bool(bool value));
MOCK_METHOD1(setLpTriggerEffect, bool(uint32_t value));
- MOCK_METHOD1(setLpTriggerScale, bool(uint8_t value));
MOCK_METHOD1(setLraWaveShape, bool(uint32_t value));
MOCK_METHOD1(setOdClamp, bool(uint32_t value));
MOCK_METHOD1(debug, void(int fd));
diff --git a/vibrator/drv2624/tests/test-hwapi.cpp b/vibrator/drv2624/tests/test-hwapi.cpp
index af2b2f7..b58e02b 100644
--- a/vibrator/drv2624/tests/test-hwapi.cpp
+++ b/vibrator/drv2624/tests/test-hwapi.cpp
@@ -47,7 +47,6 @@
"device/scale",
"device/ctrl_loop",
"device/lp_trigger_effect",
- "device/lp_trigger_scale",
"device/lra_wave_shape",
"device/od_clamp",
};
@@ -320,8 +319,6 @@
INSTANTIATE_TEST_CASE_P(HwApiTests, SetUint8Test,
ValuesIn({
SetUint8Test::MakeParam("device/scale", &Vibrator::HwApi::setScale),
- SetUint8Test::MakeParam("device/lp_trigger_scale",
- &Vibrator::HwApi::setLpTriggerScale),
}),
SetUint8Test::PrintParam);
diff --git a/vibrator/drv2624/tests/test-vibrator.cpp b/vibrator/drv2624/tests/test-vibrator.cpp
index b64e493..2b952ce 100644
--- a/vibrator/drv2624/tests/test-vibrator.cpp
+++ b/vibrator/drv2624/tests/test-vibrator.cpp
@@ -38,7 +38,6 @@
using ::testing::Exactly;
using ::testing::ExpectationSet;
using ::testing::Mock;
-using ::testing::Range;
using ::testing::Return;
using ::testing::Sequence;
using ::testing::SetArgPointee;
@@ -51,21 +50,21 @@
// Constants With Prescribed Values
static const std::map<EffectTuple, EffectSequence> EFFECT_SEQUENCES{
- {{Effect::CLICK, EffectStrength::LIGHT}, {1, 2}},
- {{Effect::CLICK, EffectStrength::MEDIUM}, {1, 0}},
- {{Effect::CLICK, EffectStrength::STRONG}, {1, 0}},
- {{Effect::TICK, EffectStrength::LIGHT}, {2, 2}},
- {{Effect::TICK, EffectStrength::MEDIUM}, {2, 0}},
- {{Effect::TICK, EffectStrength::STRONG}, {2, 0}},
- {{Effect::DOUBLE_CLICK, EffectStrength::LIGHT}, {3, 2}},
- {{Effect::DOUBLE_CLICK, EffectStrength::MEDIUM}, {3, 0}},
- {{Effect::DOUBLE_CLICK, EffectStrength::STRONG}, {3, 0}},
- {{Effect::HEAVY_CLICK, EffectStrength::LIGHT}, {4, 2}},
- {{Effect::HEAVY_CLICK, EffectStrength::MEDIUM}, {4, 0}},
- {{Effect::HEAVY_CLICK, EffectStrength::STRONG}, {4, 0}},
- {{Effect::TEXTURE_TICK, EffectStrength::LIGHT}, {2, 2}},
- {{Effect::TEXTURE_TICK, EffectStrength::MEDIUM}, {2, 0}},
- {{Effect::TEXTURE_TICK, EffectStrength::STRONG}, {2, 0}},
+ {{Effect::CLICK, EffectStrength::LIGHT}, {"1 0", 2}},
+ {{Effect::CLICK, EffectStrength::MEDIUM}, {"1 0", 0}},
+ {{Effect::CLICK, EffectStrength::STRONG}, {"1 0", 0}},
+ {{Effect::TICK, EffectStrength::LIGHT}, {"2 0", 2}},
+ {{Effect::TICK, EffectStrength::MEDIUM}, {"2 0", 0}},
+ {{Effect::TICK, EffectStrength::STRONG}, {"2 0", 0}},
+ {{Effect::DOUBLE_CLICK, EffectStrength::LIGHT}, {"3 0", 2}},
+ {{Effect::DOUBLE_CLICK, EffectStrength::MEDIUM}, {"3 0", 0}},
+ {{Effect::DOUBLE_CLICK, EffectStrength::STRONG}, {"3 0", 0}},
+ {{Effect::HEAVY_CLICK, EffectStrength::LIGHT}, {"4 0", 2}},
+ {{Effect::HEAVY_CLICK, EffectStrength::MEDIUM}, {"4 0", 0}},
+ {{Effect::HEAVY_CLICK, EffectStrength::STRONG}, {"4 0", 0}},
+ {{Effect::TEXTURE_TICK, EffectStrength::LIGHT}, {"2 0", 2}},
+ {{Effect::TEXTURE_TICK, EffectStrength::MEDIUM}, {"2 0", 0}},
+ {{Effect::TEXTURE_TICK, EffectStrength::STRONG}, {"2 0", 0}},
};
static uint32_t freqPeriodFormula(uint32_t in) {
@@ -212,7 +211,6 @@
EXPECT_CALL(*mMockApi, setScale(_)).Times(times);
EXPECT_CALL(*mMockApi, setCtrlLoop(_)).Times(times);
EXPECT_CALL(*mMockApi, setLpTriggerEffect(_)).Times(times);
- EXPECT_CALL(*mMockApi, setLpTriggerScale(_)).Times(times);
EXPECT_CALL(*mMockApi, setLraWaveShape(_)).Times(times);
EXPECT_CALL(*mMockApi, setOdClamp(_)).Times(times);
EXPECT_CALL(*mMockApi, debug(_)).Times(times);
@@ -289,6 +287,8 @@
EXPECT_CALL(*mMockCal, getDoubleClickDuration(_)).WillOnce(DoDefault());
EXPECT_CALL(*mMockCal, getHeavyClickDuration(_)).WillOnce(DoDefault());
+ EXPECT_CALL(*mMockApi, setLpTriggerEffect(1)).WillOnce(Return(true));
+
createVibrator(std::move(mockapi), std::move(mockcal), false);
}
@@ -406,7 +406,7 @@
EffectDuration duration;
if (seqIter != EFFECT_SEQUENCES.end() && durIter != mEffectDurations.end()) {
- auto sequence = std::to_string(std::get<0>(seqIter->second)) + " 0";
+ auto sequence = std::get<0>(seqIter->second);
auto scale = std::get<1>(seqIter->second);
ExpectationSet e;
@@ -439,27 +439,6 @@
}
}
-TEST_P(EffectsTest, alwaysOnEnable) {
- auto tuple = getEffectTuple();
- auto effect = std::get<0>(tuple);
- auto strength = std::get<1>(tuple);
- auto seqIter = EFFECT_SEQUENCES.find(tuple);
- bool supported = (seqIter != EFFECT_SEQUENCES.end());
-
- if (supported) {
- auto [index, scale] = seqIter->second;
- EXPECT_CALL(*mMockApi, setLpTriggerEffect(index)).WillOnce(Return(true));
- EXPECT_CALL(*mMockApi, setLpTriggerScale(scale)).WillOnce(Return(true));
- }
-
- ndk::ScopedAStatus status = mVibrator->alwaysOnEnable(0, effect, strength);
- if (supported) {
- EXPECT_EQ(EX_NONE, status.getExceptionCode());
- } else {
- EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
- }
-}
-
INSTANTIATE_TEST_CASE_P(VibratorTests, EffectsTest,
Combine(ValuesIn({false, true}),
Combine(ValuesIn(ndk::enum_range<Effect>().begin(),
@@ -468,47 +447,6 @@
ndk::enum_range<EffectStrength>().end()))),
EffectsTest::PrintParam);
-class AlwaysOnTest : public VibratorTestTemplate<int32_t> {
- public:
- static auto GetId(ParamType param) { return GetOtherParam<0>(param); }
-
- static auto PrintParam(const TestParamInfo<ParamType> &info) {
- return std::to_string(GetId(info.param));
- }
-
- protected:
- auto getId() const { return GetId(GetParam()); }
-};
-
-TEST_P(AlwaysOnTest, alwaysOnEnable) {
- auto id = getId();
- auto seqIter = EFFECT_SEQUENCES.begin();
-
- std::advance(seqIter, std::rand() % EFFECT_SEQUENCES.size());
-
- auto effect = std::get<0>(seqIter->first);
- auto strength = std::get<1>(seqIter->first);
- auto [index, scale] = seqIter->second;
-
- EXPECT_CALL(*mMockApi, setLpTriggerEffect(index)).WillOnce(Return(true));
- EXPECT_CALL(*mMockApi, setLpTriggerScale(scale)).WillOnce(Return(true));
-
- ndk::ScopedAStatus status = mVibrator->alwaysOnEnable(id, effect, strength);
- EXPECT_EQ(EX_NONE, status.getExceptionCode());
-}
-
-TEST_P(AlwaysOnTest, alwaysOnDisable) {
- auto id = getId();
-
- EXPECT_CALL(*mMockApi, setLpTriggerEffect(0)).WillOnce(Return(true));
-
- ndk::ScopedAStatus status = mVibrator->alwaysOnDisable(id);
- EXPECT_EQ(EX_NONE, status.getExceptionCode());
-}
-
-INSTANTIATE_TEST_CASE_P(VibratorTests, AlwaysOnTest, Combine(ValuesIn({false, true}), Range(0, 0)),
- AlwaysOnTest::PrintParam);
-
} // namespace vibrator
} // namespace hardware
} // namespace android
diff --git a/vibrator/drv2624/tests/types.h b/vibrator/drv2624/tests/types.h
index 103678d..6ff21a6 100644
--- a/vibrator/drv2624/tests/types.h
+++ b/vibrator/drv2624/tests/types.h
@@ -20,7 +20,7 @@
using EffectAmplitude = float;
using EffectDuration = uint32_t;
-using EffectSequence = std::tuple<uint32_t, uint8_t>;
+using EffectSequence = std::tuple<std::string, uint8_t>;
using EffectTuple = std::tuple<::aidl::android::hardware::vibrator::Effect,
::aidl::android::hardware::vibrator::EffectStrength>;