Compare commits
111 commits
thirteen/u
...
fifteen/st
Author | SHA1 | Date | |
---|---|---|---|
|
c71e73fb4b | ||
3bb5ab71db | |||
142cf9c159 | |||
45c1db8716 | |||
24c0c2e411 | |||
|
ba9abb88a4 | ||
|
fd2697235e | ||
16255e2c1e | |||
894299a3b4 | |||
|
6db1bd45fb | ||
|
54098687d1 | ||
|
feaa34a9d5 | ||
|
648cf6451a | ||
|
784b8cb14c | ||
|
7854c1db20 | ||
|
ab20f0362a | ||
|
ef8a21ebbc | ||
|
9aa2340907 | ||
|
ab20e80753 | ||
|
c4e5b44832 | ||
|
09f92402a8 | ||
|
18bebf746a | ||
|
402db86450 | ||
|
39c7f048b3 | ||
|
5a4fd4769b | ||
|
f8a8af5f66 | ||
|
d1f19a49d1 | ||
|
a1d525bfe9 | ||
|
ed5b514c7b | ||
|
5b0a6d5403 | ||
|
084d6ce9a3 | ||
|
6552a4f8b7 | ||
|
16ac982064 | ||
|
14225579e3 | ||
|
1bd130e635 | ||
|
07f15593bf | ||
|
fda7743839 | ||
|
7e941406e3 | ||
|
1a15183e39 | ||
|
9b31e5251a | ||
|
3a0bf13a01 | ||
|
30b957083e | ||
|
caf58ea362 | ||
6b9dbfe85a | |||
|
a6aa3f0e32 | ||
6b3e5c5a10 | |||
f8a78253fe | |||
|
8803ff0740 | ||
|
2549bc87d0 | ||
|
c20eba7afa | ||
|
72a3c37dc1 | ||
|
7f627da9f6 | ||
|
f7d3923f07 | ||
|
d9a4ac54df | ||
|
854c54400c | ||
|
51b24b16b4 | ||
|
22156aae16 | ||
|
bc8800d6dc | ||
|
e4c27418ef | ||
|
60d42efd08 | ||
|
20869d2170 | ||
|
e4fb9c52d3 | ||
b2a12a6340 | |||
|
81e3fa278b | ||
|
c7fb8c20d2 | ||
|
17e45ddf64 | ||
|
a4b84e2a40 | ||
|
791b9834e0 | ||
|
0a16af1ebf | ||
|
52286472cf | ||
|
b77a2922a2 | ||
|
96c04024e2 | ||
|
907d7e8b6c | ||
|
198d911563 | ||
|
b0294cf40d | ||
5d41efd453 | |||
|
a7bcd58d98 | ||
|
6654f22da7 | ||
|
f422cc4545 | ||
|
27ef678a6b | ||
|
549291d79f | ||
|
da66a65c9e | ||
|
3f2c340233 | ||
|
df268abe1a | ||
|
ddbd3a0222 | ||
|
945488d2a5 | ||
|
63c205630e | ||
|
e1cc9860f7 | ||
|
30efc06094 | ||
|
29f1905334 | ||
|
deca8b38a0 | ||
|
860fcdd319 | ||
|
59eb184cd4 | ||
|
05959f652a | ||
|
ef2362021f | ||
|
2a7017fc7a | ||
|
ade32dd8dd | ||
|
97763d6310 | ||
|
7bd37cdae4 | ||
|
f5a3af4e1e | ||
|
493734f9b0 | ||
|
44971233da | ||
|
fee8733f29 | ||
|
5814309579 | ||
|
2682cc4543 | ||
|
4dd1fed383 | ||
|
d4b624fda4 | ||
|
ad52c6db78 | ||
|
28095d1e8a | ||
|
8343044e5d | ||
|
7fd8dc1c2c |
109 changed files with 843 additions and 185397 deletions
13
Android.mk
13
Android.mk
|
@ -9,6 +9,19 @@ LOCAL_PATH := $(call my-dir)
|
|||
ifneq ($(filter kunlun2 kunlun2_row jd2019,$(TARGET_DEVICE)),)
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
|
||||
LPFLASH := $(HOST_OUT_EXECUTABLES)/lpflash$(HOST_EXECUTABLE_SUFFIX)
|
||||
INSTALLED_SUPERIMAGE_DUMMY_TARGET := $(PRODUCT_OUT)/super_dummy.img
|
||||
|
||||
$(INSTALLED_SUPERIMAGE_DUMMY_TARGET): $(PRODUCT_OUT)/super_empty.img $(LPFLASH)
|
||||
$(call pretty,"Target dummy super image: $@")
|
||||
$(hide) touch $@
|
||||
$(hide) $(LPFLASH) $@ $(PRODUCT_OUT)/super_empty.img
|
||||
|
||||
.PHONY: super_dummyimage
|
||||
super_dummyimage: $(INSTALLED_SUPERIMAGE_DUMMY_TARGET)
|
||||
|
||||
INSTALLED_RADIOIMAGE_TARGET += $(INSTALLED_SUPERIMAGE_DUMMY_TARGET)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# Create symbolic links for msadp
|
||||
|
|
|
@ -4,21 +4,22 @@ COMMON_PATH := device/lenovo/sdm710-common
|
|||
|
||||
# Architecture
|
||||
TARGET_ARCH := arm64
|
||||
TARGET_ARCH_VARIANT := armv8-2a
|
||||
TARGET_ARCH_VARIANT := armv8-a
|
||||
TARGET_CPU_ABI := arm64-v8a
|
||||
TARGET_CPU_ABI2 :=
|
||||
TARGET_CPU_VARIANT := generic
|
||||
TARGET_CPU_VARIANT_RUNTIME := cortex-a75
|
||||
TARGET_CPU_VARIANT_RUNTIME := kryo385
|
||||
|
||||
TARGET_2ND_ARCH := arm
|
||||
TARGET_2ND_ARCH_VARIANT := armv8-a
|
||||
TARGET_2ND_CPU_ABI := armeabi-v7a
|
||||
TARGET_2ND_CPU_ABI2 := armeabi
|
||||
TARGET_2ND_CPU_VARIANT := generic
|
||||
TARGET_2ND_CPU_VARIANT_RUNTIME := cortex-a75
|
||||
TARGET_2ND_CPU_VARIANT_RUNTIME := kryo385
|
||||
|
||||
BUILD_BROKEN_DUP_RULES := true
|
||||
BUILD_BROKEN_ELF_PREBUILT_PRODUCT_COPY_FILES := true
|
||||
BUILD_BROKEN_INCORRECT_PARTITION_IMAGES := true
|
||||
|
||||
# Bootloader
|
||||
TARGET_BOOTLOADER_BOARD_NAME := sdm710
|
||||
|
@ -40,16 +41,15 @@ BOARD_KERNEL_CMDLINE := \
|
|||
service_locator.enable=1 \
|
||||
androidboot.configfs=true \
|
||||
androidboot.usbcontroller=a600000.dwc3 \
|
||||
swiotlb=1 \
|
||||
loop.max_part=7 \
|
||||
kpti=off
|
||||
BOARD_KERNEL_CMDLINE += androidboot.android_dt_dir=/non-existent androidboot.boot_devices=soc/7c4000.sdhci
|
||||
BOARD_KERNEL_BASE := 0x00000000
|
||||
BOARD_KERNEL_PAGESIZE := 4096
|
||||
BOARD_KERNEL_TAGS_OFFSET := 0x00000100
|
||||
BOARD_RAMDISK_OFFSET := 0x01000000
|
||||
BOARD_KERNEL_IMAGE_NAME := Image.gz-dtb
|
||||
BOARD_KERNEL_SEPARATED_DTBO := true
|
||||
BOARD_RAMDISK_USE_LZ4 := true
|
||||
TARGET_KERNEL_ARCH := arm64
|
||||
TARGET_KERNEL_SOURCE := kernel/lenovo/sdm710
|
||||
TARGET_KERNEL_VERSION := 4.9
|
||||
|
@ -58,7 +58,6 @@ TARGET_KERNEL_VERSION := 4.9
|
|||
TARGET_PROVIDES_AUDIO_EXTNS := true
|
||||
|
||||
# Camera
|
||||
MALLOC_SVELTE := true
|
||||
MALLOC_SVELTE_FOR_LIBC32 := true
|
||||
|
||||
# Display
|
||||
|
@ -68,6 +67,7 @@ TARGET_HAS_WIDE_COLOR_DISPLAY := true
|
|||
TARGET_USES_GRALLOC1 := true
|
||||
TARGET_USES_HWC2 := true
|
||||
TARGET_USES_ION := true
|
||||
TARGET_TAP_TO_WAKE_NODE := /sys/class/touch/tp_dev/gesture_on
|
||||
|
||||
# Filesystem
|
||||
TARGET_FS_CONFIG_GEN := $(COMMON_PATH)/config.fs
|
||||
|
@ -79,6 +79,10 @@ BOARD_HAS_QCA_FM_SOC := "cherokee"
|
|||
# HIDL
|
||||
DEVICE_MANIFEST_FILE := $(COMMON_PATH)/manifest.xml
|
||||
DEVICE_MATRIX_FILE := $(COMMON_PATH)/compatibility_matrix.xml
|
||||
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE += \
|
||||
hardware/qcom-caf/common/vendor_framework_compatibility_matrix.xml \
|
||||
$(COMMON_PATH)/framework_compatibility_matrix.xml \
|
||||
vendor/lineage/config/device_framework_matrix.xml
|
||||
|
||||
# Partitions
|
||||
BOARD_BOOTIMAGE_PARTITION_SIZE := 67108864
|
||||
|
@ -86,17 +90,37 @@ BOARD_DTBOIMG_PARTITION_SIZE := 25165824
|
|||
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 67108864
|
||||
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
|
||||
BOARD_CACHEIMAGE_PARTITION_SIZE := 268435456
|
||||
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 3758096384
|
||||
BOARD_VENDORIMAGE_PARTITION_SIZE := 1073741824
|
||||
BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
|
||||
BOARD_ODMIMAGE_FILE_SYSTEM_TYPE := ext4
|
||||
BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE := ext4
|
||||
BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE := ext4
|
||||
BOARD_FLASH_BLOCK_SIZE := 262144
|
||||
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
|
||||
TARGET_USERIMAGES_USE_EXT4 := true
|
||||
|
||||
# Dynamic partitions
|
||||
BOARD_USES_METADATA_PARTITION := true
|
||||
|
||||
BOARD_SUPER_PARTITION_BLOCK_DEVICES := vendor system
|
||||
BOARD_SUPER_PARTITION_METADATA_DEVICE := system
|
||||
|
||||
-include vendor/lineage/config/BoardConfigReservedSize.mk
|
||||
BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := 1073741824
|
||||
BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := 5368709120
|
||||
BOARD_SUPER_PARTITION_SIZE := $(shell expr $(BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE) + $(BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE) )
|
||||
|
||||
BOARD_SUPER_PARTITION_GROUPS := lenovo710_dynpart
|
||||
BOARD_LENOVO710_DYNPART_SIZE := $(shell expr $(BOARD_SUPER_PARTITION_SIZE) - 4194304 )
|
||||
BOARD_LENOVO710_DYNPART_PARTITION_LIST := odm product system system_ext vendor
|
||||
|
||||
TARGET_COPY_OUT_ODM := odm
|
||||
TARGET_COPY_OUT_PRODUCT := product
|
||||
TARGET_COPY_OUT_SYSTEM_EXT := system_ext
|
||||
|
||||
# Properties
|
||||
TARGET_ODM_PROP += $(COMMON_PATH)/odm.prop
|
||||
TARGET_PRODUCT_PROP += $(COMMON_PATH)/product.prop
|
||||
TARGET_SYSTEM_EXT_PROP += $(COMMON_PATH)/system_ext.prop
|
||||
TARGET_SYSTEM_PROP += $(COMMON_PATH)/system.prop
|
||||
TARGET_VENDOR_PROP += $(COMMON_PATH)/vendor.prop
|
||||
|
||||
# Root
|
||||
|
@ -107,7 +131,8 @@ BOARD_ROOT_EXTRA_SYMLINKS := \
|
|||
/vendor/firmware_mnt:/firmware
|
||||
|
||||
# Recovery
|
||||
TARGET_RECOVERY_FSTAB := $(COMMON_PATH)/rootdir/etc/recovery.fstab
|
||||
TARGET_RECOVERY_PIXEL_FORMAT := BGRA_8888
|
||||
TARGET_RECOVERY_FSTAB := $(COMMON_PATH)/rootdir/etc/fstab.qcom
|
||||
|
||||
# Releasetools
|
||||
TARGET_RELEASETOOLS_EXTENSIONS := $(COMMON_PATH)
|
||||
|
@ -118,8 +143,12 @@ OVERRIDE_RS_DRIVER := libRSDriver_adreno.so
|
|||
# RIL
|
||||
ENABLE_VENDOR_RIL_SERVICE := true
|
||||
|
||||
# Security patch level
|
||||
VENDOR_SECURITY_PATCH := 2020-03-01
|
||||
|
||||
# Sepolicy
|
||||
include device/qcom/sepolicy_vndr-legacy-um/SEPolicy.mk
|
||||
TARGET_USES_LOGDUMP_AS_METADATA := true
|
||||
include device/qcom/sepolicy_vndr/SEPolicy.mk
|
||||
|
||||
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS += $(COMMON_PATH)/sepolicy/private
|
||||
BOARD_VENDOR_SEPOLICY_DIRS += $(COMMON_PATH)/sepolicy/vendor
|
||||
|
@ -157,4 +186,4 @@ WPA_SUPPLICANT_VERSION := VER_0_8_X
|
|||
TARGET_SEC_FP_HAS_FINGERPRINT_GESTURES := true
|
||||
|
||||
# Inherit from the proprietary version
|
||||
-include vendor/lenovo/sdm710-common/BoardConfigVendor.mk
|
||||
include vendor/lenovo/sdm710-common/BoardConfigVendor.mk
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
{
|
||||
"repository": "kernel_lenovo_sdm710",
|
||||
"target_path": "kernel/lenovo/sdm710",
|
||||
"branch": "thirteen"
|
||||
"branch": "fourteen"
|
||||
},
|
||||
{
|
||||
"remote": "pixel-devices-blobs",
|
||||
"repository": "vendor_lenovo_sdm710-common",
|
||||
"target_path": "vendor/lenovo/sdm710-common",
|
||||
"branch": "thirteen"
|
||||
"branch": "fourteen"
|
||||
},
|
||||
{
|
||||
"remote": "pixel-devices-blobs",
|
||||
"repository": "vendor_lenovo-firmware",
|
||||
"target_path": "vendor/lenovo-firmware",
|
||||
"branch": "thirteen"
|
||||
"branch": "fourteen"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<compatibility-matrix version="1.0" type="device">
|
||||
<compatibility-matrix version="2.0" type="device">
|
||||
<hal format="hidl" optional="false">
|
||||
<name>android.frameworks.schedulerservice</name>
|
||||
<version>1.0</version>
|
||||
|
|
20
configs/flash_super_dummy.sh
Normal file
20
configs/flash_super_dummy.sh
Normal file
|
@ -0,0 +1,20 @@
|
|||
#!/system/bin/sh
|
||||
#
|
||||
# Copyright (C) 2021 The LineageOS Project
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
SUPER="/dev/block/by-name/system"
|
||||
|
||||
mkdir /tmp/super-mnt
|
||||
|
||||
mount $SUPER /tmp/super-mnt 2>/dev/null
|
||||
|
||||
if [ "$?" = "0" ]; then
|
||||
echo "Detected stock /system in super partition, flashing super_dummy.img!"
|
||||
umount /tmp/super-mnt
|
||||
dd if=/tmp/super_dummy.img of=$SUPER
|
||||
fi
|
||||
|
||||
rmdir /tmp/super-mnt
|
|
@ -58,6 +58,7 @@ It allows additional grants on top of privapp-permissions-platform.xml
|
|||
<privapp-permissions package="com.qualcomm.wfd.service">
|
||||
<permission name="android.permission.READ_FRAME_BUFFER"/>
|
||||
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
|
||||
<permission name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"/>
|
||||
</privapp-permissions>
|
||||
|
||||
<privapp-permissions package="org.codeaurora.ims">
|
||||
|
@ -72,4 +73,13 @@ It allows additional grants on top of privapp-permissions-platform.xml
|
|||
<privapp-permissions package="com.skyhook.blp">
|
||||
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
|
||||
</privapp-permissions>
|
||||
|
||||
<privapp-permissions package="com.android.phone">
|
||||
<permission name="android.permission.READ_PHONE_STATE"/>
|
||||
</privapp-permissions>
|
||||
|
||||
<privapp-permissions package="com.android.cellbroadcastreceiver.module">
|
||||
<permission name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<permission name="android.permission.READ_PHONE_STATE"/>
|
||||
</privapp-permissions>
|
||||
</permissions>
|
||||
|
|
|
@ -61,7 +61,10 @@ fi
|
|||
function blob_fixup() {
|
||||
case "${1}" in
|
||||
vendor/etc/seccomp_policy/vendor.qti.hardware.dsp.policy)
|
||||
echo 'madvise: 1' >> ${2}
|
||||
echo 'madvise: 1' >> "${2}"
|
||||
;;
|
||||
vendor/lib/libwvhidl.so)
|
||||
"${PATCHELF}" --replace-needed "libcrypto.so" "libcrypto-v33.so" "${2}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
|
100
framework_compatibility_matrix.xml
Normal file
100
framework_compatibility_matrix.xml
Normal file
|
@ -0,0 +1,100 @@
|
|||
<compatibility-matrix version="2.0" type="framework">
|
||||
<hal format="hidl" optional="true">
|
||||
<name>android.hardware.light</name>
|
||||
<version>2.0</version>
|
||||
<interface>
|
||||
<name>ILight</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="true">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>IVibrator</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl">
|
||||
<name>com.qualcomm.qti.ant</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>IAntHci</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="true">
|
||||
<name>vendor.qti.imsrtpservice</name>
|
||||
<version>2.0-1</version>
|
||||
<version>3.0</version>
|
||||
<interface>
|
||||
<name>IRTPService</name>
|
||||
<instance>imsrtpservice</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.wifi</name>
|
||||
<interface>
|
||||
<name>IWifi</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.cas</name>
|
||||
<interface>
|
||||
<name>IMediaCasService</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.drm</name>
|
||||
<interface>
|
||||
<name>IDrmFactory</name>
|
||||
<instance>clearkey</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.power</name>
|
||||
<interface>
|
||||
<name>IPower</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="true">
|
||||
<name>android.hardware.usb</name>
|
||||
<version>1.0-3</version>
|
||||
<interface>
|
||||
<name>IUsb</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<interface>
|
||||
<name>IVibrator</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.wifi</name>
|
||||
<interface>
|
||||
<name>IWifi</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.wifi.hostapd</name>
|
||||
<interface>
|
||||
<name>IHostapd</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.wifi.supplicant</name>
|
||||
<interface>
|
||||
<name>ISupplicant</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</compatibility-matrix>
|
21
manifest.xml
21
manifest.xml
|
@ -1,4 +1,4 @@
|
|||
<manifest version="1.0" type="device" target-level="4">
|
||||
<manifest version="1.0" type="device" target-level="5">
|
||||
<hal format="hidl">
|
||||
<name>android.hardware.audio</name>
|
||||
<transport>hwbinder</transport>
|
||||
|
@ -19,16 +19,6 @@
|
|||
</interface>
|
||||
<fqname>@6.0::IEffectsFactory/default</fqname>
|
||||
</hal>
|
||||
<hal format="hidl">
|
||||
<name>android.hardware.biometrics.fingerprint</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>2.1</version>
|
||||
<interface>
|
||||
<name>IBiometricsFingerprint</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
<fqname>@2.1::IBiometricsFingerprint/default</fqname>
|
||||
</hal>
|
||||
<hal format="hidl">
|
||||
<name>android.hardware.bluetooth</name>
|
||||
<transport>hwbinder</transport>
|
||||
|
@ -641,12 +631,13 @@
|
|||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl">
|
||||
<name>android.hardware.health</name>
|
||||
<name>vendor.qti.hardware.data.iwlan</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>2.1</version>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>IHealth</name>
|
||||
<instance>default</instance>
|
||||
<name>IIWlan</name>
|
||||
<instance>slot1</instance>
|
||||
<instance>slot2</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
|
@ -315,11 +315,6 @@
|
|||
<item>35</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- Vibrator pattern for a very short but reliable vibration for soft keyboard tap -->
|
||||
<integer-array name="config_keyboardTapVibePattern">
|
||||
<item>40</item>
|
||||
</integer-array>
|
||||
|
||||
<!-- Default list of files pinned by the Pinner Service -->
|
||||
<string-array translatable="false" name="config_defaultPinnerServiceFiles">
|
||||
<item>"/system/framework/framework.jar"</item>
|
||||
|
@ -390,7 +385,7 @@
|
|||
<string ...>M -5,0 L -5,10 L 5,10 L 5,0 Z @dp</string>
|
||||
@see https://www.w3.org/TR/SVG/paths.html#PathData
|
||||
-->
|
||||
<string translatable="false" name="config_mainBuiltInDisplayCutout">M -80,0 L -80,80 L 80,80 L 80,0 Z</string>
|
||||
<string translatable="false" name="config_mainBuiltInDisplayCutout">M -100,0 L -40,82 L 40,82 L 100,0 Z</string>
|
||||
|
||||
<!-- Height of the status bar -->
|
||||
<dimen name="status_bar_height">88.0px</dimen>
|
||||
|
@ -404,14 +399,6 @@
|
|||
The default is false. -->
|
||||
<bool name="config_lidControlsSleep">true</bool>
|
||||
|
||||
<!-- List of biometric sensors on the device, in decreasing strength. Consumed by AuthService
|
||||
when registering authenticators with BiometricService. Format must be ID:Modality:Strength,
|
||||
where: IDs are unique per device, Modality as defined in BiometricAuthenticator.java,
|
||||
and Strength as defined in Authenticators.java -->
|
||||
<string-array name="config_biometric_sensors" translatable="false" >
|
||||
<item>0:2:15</item> <!-- ID0:Fingerprint:Strong -->
|
||||
</string-array>
|
||||
|
||||
<!-- SQLite -->
|
||||
<string name="db_default_journal_mode">MEMORY</string>
|
||||
<string name="db_default_sync_mode">OFF</string>
|
||||
|
@ -432,9 +419,6 @@
|
|||
2: gestures only for back, home and overview -->
|
||||
<integer name="config_navBarInteractionMode">2</integer>
|
||||
|
||||
<!-- Specify if the fingerprint hardware support gestures-->
|
||||
<bool name="config_fingerprintSupportsGestures">true</bool>
|
||||
|
||||
<!-- Enable system navigation keys. -->
|
||||
<bool name="config_supportSystemNavigationKeys">true</bool>
|
||||
|
||||
|
@ -500,9 +484,15 @@
|
|||
<!-- Whether to show the Preference for Adaptive connectivity -->
|
||||
<bool name="config_show_adaptive_connectivity">false</bool>
|
||||
|
||||
<!-- Display low battery warning when battery level dips to this value -->
|
||||
<integer name="config_lowBatteryWarningLevel">15</integer>
|
||||
<!-- Enable Night display, which requires HWC 2.0. -->
|
||||
<bool name="config_nightDisplayAvailable">true</bool>
|
||||
|
||||
<!-- See AmbientSensor.AmbientColorTemperatureSensor. The ambient color temperature sensor name. -->
|
||||
<string name="config_displayWhiteBalanceColorTemperatureSensorName">com.google.sensor.color</string>
|
||||
<!-- Boolean indicating whether the HWC setColorTransform function can be performed efficiently
|
||||
in hardware. -->
|
||||
<bool name="config_setColorTransformAccelerated">true</bool>
|
||||
|
||||
<!-- Enables or disables fading edges when marquee is enabled in TextView.
|
||||
Off by default, since the framebuffer readback used to implement the
|
||||
fading edges is prohibitively expensive on most GPUs. -->
|
||||
<bool name="config_ui_enableFadingMarquee">true</bool>
|
||||
</resources>
|
||||
|
|
|
@ -30,9 +30,5 @@
|
|||
|
||||
<!-- Update battery info every second when device is charging -->
|
||||
<bool name="config_alternateFastchargeInfoUpdate">true</bool>
|
||||
|
||||
<!-- Whether to show estimate in QS header. Default to false in case there's not enough
|
||||
space -->
|
||||
<bool name="config_showBatteryEstimateQSBH">true</bool>
|
||||
</resources>
|
||||
|
||||
|
|
|
@ -16,4 +16,7 @@
|
|||
<!-- To enable display touch sensitivity switch -->
|
||||
<bool name="config_show_touch_sensitivity">false</bool>
|
||||
|
||||
<!-- Whether to enable Lineage Fast Charge Prefernece -->
|
||||
<bool name="config_lineageFastChargeSupported">true</bool>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
LOCAL_PACKAGE_NAME := LenovoPocketMode
|
||||
LOCAL_CERTIFICATE := platform
|
||||
LOCAL_PRIVATE_PLATFORM_APIS := true
|
||||
LOCAL_PRIVILEGED_MODULE := true
|
||||
|
||||
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
|
||||
|
||||
include $(BUILD_PACKAGE)
|
|
@ -1,45 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The CyanogenMod Project
|
||||
Copyright (C) 2017-2018 The LineageOS 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.lineageos.pocketmode"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0"
|
||||
android:sharedUserId="android.uid.system">
|
||||
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="27" />
|
||||
|
||||
<application
|
||||
android:label="LenovoPocketMode"
|
||||
android:persistent="true">
|
||||
|
||||
<receiver android:name=".BootCompletedReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service android:name=".PocketModeService"
|
||||
android:permission="PocketModeService">
|
||||
</service>
|
||||
|
||||
</application>
|
||||
</manifest>
|
|
@ -1,3 +0,0 @@
|
|||
-keep class org.lineageos.pocketmode.* {
|
||||
*;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* 2017 The LineageOS 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 org.lineageos.pocketmode;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
public class BootCompletedReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String TAG = "LenovoPocketMode";
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d(TAG, "Starting");
|
||||
context.startServiceAsUser(new Intent(context, PocketModeService.class),
|
||||
UserHandle.CURRENT);
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* 2017 The LineageOS 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 org.lineageos.pocketmode;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
public class PocketModeService extends Service {
|
||||
private static final String TAG = "PocketModeService";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private ProximitySensor mProximitySensor;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
if (DEBUG) Log.d(TAG, "Creating service");
|
||||
mProximitySensor = new ProximitySensor(this);
|
||||
|
||||
IntentFilter screenStateFilter = new IntentFilter();
|
||||
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
screenStateFilter.addAction(Intent.ACTION_USER_PRESENT);
|
||||
registerReceiver(mScreenStateReceiver, screenStateFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (DEBUG) Log.d(TAG, "Starting service");
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (DEBUG) Log.d(TAG, "Destroying service");
|
||||
this.unregisterReceiver(mScreenStateReceiver);
|
||||
mProximitySensor.disable();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void onDeviceUnlocked() {
|
||||
if (DEBUG) Log.d(TAG, "Device unlocked");
|
||||
mProximitySensor.disable();
|
||||
}
|
||||
|
||||
private void onDisplayOff() {
|
||||
if (DEBUG) Log.d(TAG, "Display off");
|
||||
mProximitySensor.enable();
|
||||
}
|
||||
|
||||
private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
|
||||
onDeviceUnlocked();
|
||||
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
onDisplayOff();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* 2017-2019 The LineageOS 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 org.lineageos.pocketmode;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.FileUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class ProximitySensor implements SensorEventListener {
|
||||
private static final String TAG = "PocketModeProximity";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private ExecutorService mExecutorService;
|
||||
private Context mContext;
|
||||
private Sensor mSensor;
|
||||
private SensorManager mSensorManager;
|
||||
|
||||
public ProximitySensor(Context context) {
|
||||
mContext = context;
|
||||
mSensorManager = mContext.getSystemService(SensorManager.class);
|
||||
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
||||
mExecutorService = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
private Future<?> submit(Runnable runnable) {
|
||||
return mExecutorService.submit(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
/* Empty */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
/* Empty */
|
||||
}
|
||||
|
||||
protected void enable() {
|
||||
if (DEBUG) Log.d(TAG, "Enabling");
|
||||
submit(() -> {
|
||||
mSensorManager.registerListener(this, mSensor,
|
||||
SensorManager.SENSOR_DELAY_NORMAL);
|
||||
});
|
||||
}
|
||||
|
||||
protected void disable() {
|
||||
if (DEBUG) Log.d(TAG, "Disabling");
|
||||
submit(() -> {
|
||||
mSensorManager.unregisterListener(this, mSensor);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
|
||||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libdisppower-lenovo-sdm710",
|
||||
proprietary: true,
|
||||
srcs: [
|
||||
"disp-power/DisplayLowPower.cpp",
|
||||
"disp-power/InteractionHandler.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libperfmgr",
|
||||
"libutils",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libadaptivecpu-lenovo-sdm710",
|
||||
proprietary: true,
|
||||
vendor: true,
|
||||
srcs: [
|
||||
"adaptivecpu/AdaptiveCpu.cpp",
|
||||
"adaptivecpu/AdaptiveCpuConfig.cpp",
|
||||
"adaptivecpu/AdaptiveCpuStats.cpp",
|
||||
"adaptivecpu/CpuFrequencyReader.cpp",
|
||||
"adaptivecpu/CpuLoadReaderProcStat.cpp",
|
||||
"adaptivecpu/CpuLoadReaderSysDevices.cpp",
|
||||
"adaptivecpu/Device.cpp",
|
||||
"adaptivecpu/KernelCpuFeatureReader.cpp",
|
||||
"adaptivecpu/Model.cpp",
|
||||
"adaptivecpu/RealFilesystem.cpp",
|
||||
"adaptivecpu/ThrottleDecision.cpp",
|
||||
"adaptivecpu/TimeSource.cpp",
|
||||
"adaptivecpu/WorkDurationProcessor.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.power-V3-ndk",
|
||||
"libbase",
|
||||
"liblog",
|
||||
"libperfmgr",
|
||||
"libutils",
|
||||
"libcutils",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "libadaptivecpu_test-lenovo-sdm710",
|
||||
proprietary: true,
|
||||
vendor: true,
|
||||
srcs: [
|
||||
"adaptivecpu/tests/AdaptiveCpuConfigTest.cpp",
|
||||
"adaptivecpu/tests/AdaptiveCpuStatsTest.cpp",
|
||||
"adaptivecpu/tests/CpuFrequencyReaderTest.cpp",
|
||||
"adaptivecpu/tests/CpuLoadReaderProcStatTest.cpp",
|
||||
"adaptivecpu/tests/CpuLoadReaderSysDevicesTest.cpp",
|
||||
"adaptivecpu/tests/KernelCpuFeatureReaderTest.cpp",
|
||||
"adaptivecpu/tests/ModelTest.cpp",
|
||||
"adaptivecpu/tests/WorkDurationProcessorTest.cpp",
|
||||
],
|
||||
static_libs: [
|
||||
"libadaptivecpu-lenovo-sdm710",
|
||||
"libgmock",
|
||||
"android.hardware.power-V3-ndk",
|
||||
],
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libbase",
|
||||
"libcutils",
|
||||
],
|
||||
test_suites: ["device-tests"],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.power-service.lenovo-sdm710-libperfmgr",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["aidl/android.hardware.power-service.lenovo-sdm710-libperfmgr.rc"],
|
||||
vintf_fragments: ["aidl/android.hardware.power-service.lenovo-sdm710.xml"],
|
||||
vendor: true,
|
||||
shared_libs: [
|
||||
"android.hardware.power-V3-ndk",
|
||||
"libadaptivecpu-lenovo-sdm710",
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libbinder_ndk",
|
||||
"libdisppower-lenovo-sdm710",
|
||||
"libperfmgr",
|
||||
"libprocessgroup",
|
||||
"pixel-power-ext-V1-ndk",
|
||||
],
|
||||
srcs: [
|
||||
"aidl/service.cpp",
|
||||
"aidl/Power.cpp",
|
||||
"aidl/PowerExt.cpp",
|
||||
"aidl/PowerHintSession.cpp",
|
||||
"aidl/PowerSessionManager.cpp",
|
||||
],
|
||||
}
|
54
power-libperfmgr/Android.mk
Normal file
54
power-libperfmgr/Android.mk
Normal file
|
@ -0,0 +1,54 @@
|
|||
#
|
||||
# Copyright (C) 2021 The LineageOS 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.
|
||||
#
|
||||
ifneq (,$(findstring hardware/google/interfaces, $(PRODUCT_SOONG_NAMESPACES)))
|
||||
ifneq (,$(findstring hardware/google/pixel, $(PRODUCT_SOONG_NAMESPACES)))
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
android.hardware.power-V2-ndk \
|
||||
libbase \
|
||||
libbinder_ndk \
|
||||
libcutils \
|
||||
libdl \
|
||||
liblog \
|
||||
libperfmgr \
|
||||
libprocessgroup \
|
||||
libutils \
|
||||
pixel-power-ext-V1-ndk
|
||||
LOCAL_SRC_FILES := \
|
||||
service.cpp \
|
||||
InteractionHandler.cpp \
|
||||
Power.cpp \
|
||||
PowerExt.cpp \
|
||||
PowerHintSession.cpp \
|
||||
PowerSessionManager.cpp
|
||||
LOCAL_CFLAGS := -Wno-unused-parameter -Wno-unused-variable
|
||||
ifneq ($(TARGET_POWERHAL_MODE_EXT),)
|
||||
LOCAL_CFLAGS += -DMODE_EXT
|
||||
LOCAL_SRC_FILES += ../../../../$(TARGET_POWERHAL_MODE_EXT)
|
||||
endif
|
||||
ifneq ($(TARGET_TAP_TO_WAKE_NODE),)
|
||||
LOCAL_CFLAGS += -DTAP_TO_WAKE_NODE=\"$(TARGET_TAP_TO_WAKE_NODE)\"
|
||||
endif
|
||||
LOCAL_MODULE := android.hardware.power-service.xiaomi-libperfmgr
|
||||
LOCAL_INIT_RC := android.hardware.power-service.xiaomi-libperfmgr.rc
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
LOCAL_VINTF_FRAGMENTS := android.hardware.power-service.xiaomi.xml
|
||||
include $(BUILD_EXECUTABLE)
|
||||
endif
|
||||
endif
|
|
@ -13,12 +13,9 @@
|
|||
* 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)
|
||||
|
||||
#define LOG_TAG "powerhal-libperfmgr"
|
||||
#include "InteractionHandler.h"
|
||||
|
||||
#include <android-base/properties.h>
|
||||
#include <fcntl.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
|
@ -28,24 +25,18 @@
|
|||
#include <unistd.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#define MAX_LENGTH 64
|
||||
|
||||
#define MSINSEC 1000L
|
||||
#define NSINMS 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",
|
||||
|
@ -58,14 +49,12 @@ 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) {
|
||||
|
@ -76,77 +65,58 @@ static int FbIdleOpen(void) {
|
|||
ALOGE("Unable to open fb idle state path (%d)", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
InteractionHandler::InteractionHandler()
|
||||
: mState(INTERACTION_STATE_UNINITIALIZED), mDurationMs(0) {}
|
||||
|
||||
InteractionHandler::~InteractionHandler() {
|
||||
Exit();
|
||||
}
|
||||
|
||||
bool InteractionHandler::Init() {
|
||||
std::lock_guard<std::mutex> lk(mLock);
|
||||
|
||||
if (mState != INTERACTION_STATE_UNINITIALIZED)
|
||||
return true;
|
||||
|
||||
int fd = FbIdleOpen();
|
||||
if (fd < 0)
|
||||
return false;
|
||||
mIdleFd = fd;
|
||||
|
||||
mEventFd = eventfd(0, EFD_NONBLOCK);
|
||||
if (mEventFd < 0) {
|
||||
ALOGE("Unable to create event fd (%d)", errno);
|
||||
close(mIdleFd);
|
||||
return false;
|
||||
}
|
||||
|
||||
mState = INTERACTION_STATE_IDLE;
|
||||
mThread = std::unique_ptr<std::thread>(new std::thread(&InteractionHandler::Routine, this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InteractionHandler::Exit() {
|
||||
std::unique_lock<std::mutex> lk(mLock);
|
||||
if (mState == INTERACTION_STATE_UNINITIALIZED)
|
||||
return;
|
||||
|
||||
AbortWaitLocked();
|
||||
mState = INTERACTION_STATE_UNINITIALIZED;
|
||||
lk.unlock();
|
||||
|
||||
mCond.notify_all();
|
||||
mThread->join();
|
||||
|
||||
close(mEventFd);
|
||||
close(mIdleFd);
|
||||
}
|
||||
|
||||
void InteractionHandler::PerfLock() {
|
||||
ALOGV("%s: acquiring perf lock", __func__);
|
||||
if (!HintManager::GetInstance()->DoHint("INTERACTION")) {
|
||||
ALOGE("%s: do hint INTERACTION failed", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionHandler::PerfRel() {
|
||||
ALOGV("%s: releasing perf lock", __func__);
|
||||
if (!HintManager::GetInstance()->EndHint("INTERACTION")) {
|
||||
ALOGE("%s: end hint INTERACTION failed", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionHandler::Acquire(int32_t duration) {
|
||||
ATRACE_CALL();
|
||||
|
||||
std::lock_guard<std::mutex> lk(mLock);
|
||||
|
||||
int inputDuration = duration + kDurationOffsetMs;
|
||||
int finalDuration;
|
||||
if (inputDuration > kMaxDurationMs)
|
||||
|
@ -155,7 +125,6 @@ void InteractionHandler::Acquire(int32_t duration) {
|
|||
finalDuration = inputDuration;
|
||||
else
|
||||
finalDuration = kMinDurationMs;
|
||||
|
||||
// Fallback to do boost directly
|
||||
// 1) override property is set OR
|
||||
// 2) InteractionHandler not initialized
|
||||
|
@ -163,7 +132,6 @@ void InteractionHandler::Acquire(int32_t duration) {
|
|||
HintManager::GetInstance()->DoHint("INTERACTION", std::chrono::milliseconds(finalDuration));
|
||||
return;
|
||||
}
|
||||
|
||||
struct timespec cur_timespec;
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_timespec);
|
||||
if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) {
|
||||
|
@ -178,18 +146,14 @@ void InteractionHandler::Acquire(int32_t duration) {
|
|||
}
|
||||
mLastTimespec = cur_timespec;
|
||||
mDurationMs = finalDuration;
|
||||
|
||||
ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration);
|
||||
|
||||
if (mState == INTERACTION_STATE_WAITING)
|
||||
AbortWaitLocked();
|
||||
else if (mState == INTERACTION_STATE_IDLE)
|
||||
PerfLock();
|
||||
|
||||
mState = INTERACTION_STATE_INTERACTION;
|
||||
mCond.notify_one();
|
||||
}
|
||||
|
||||
void InteractionHandler::Release() {
|
||||
std::lock_guard<std::mutex> lk(mLock);
|
||||
if (mState == INTERACTION_STATE_WAITING) {
|
||||
|
@ -200,11 +164,9 @@ void InteractionHandler::Release() {
|
|||
// clear any wait aborts pending in event fd
|
||||
uint64_t val;
|
||||
ssize_t ret = read(mEventFd, &val, sizeof(val));
|
||||
|
||||
ALOGW_IF(ret < 0, "%s: failed to clear eventfd (%zd, %d)", __func__, ret, errno);
|
||||
}
|
||||
}
|
||||
|
||||
// should be called while locked
|
||||
void InteractionHandler::AbortWaitLocked() {
|
||||
uint64_t val = 1;
|
||||
|
@ -212,21 +174,16 @@ void InteractionHandler::AbortWaitLocked() {
|
|||
if (ret != sizeof(val))
|
||||
ALOGW("Unable to write to event fd (%zd)", ret);
|
||||
}
|
||||
|
||||
void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) {
|
||||
char data[MAX_LENGTH];
|
||||
ssize_t ret;
|
||||
struct pollfd pfd[2];
|
||||
|
||||
ATRACE_CALL();
|
||||
|
||||
ALOGV("%s: wait:%d timeout:%d", __func__, wait_ms, timeout_ms);
|
||||
|
||||
pfd[0].fd = mEventFd;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = mIdleFd;
|
||||
pfd[1].events = POLLPRI | POLLERR;
|
||||
|
||||
ret = poll(pfd, 1, wait_ms);
|
||||
if (ret > 0) {
|
||||
ALOGV("%s: wait aborted", __func__);
|
||||
|
@ -235,18 +192,15 @@ void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) {
|
|||
ALOGE("%s: error in poll while waiting", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = pread(mIdleFd, data, sizeof(data), 0);
|
||||
if (!ret) {
|
||||
ALOGE("%s: Unexpected EOF!", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strncmp(data, "idle", 4)) {
|
||||
ALOGV("%s: already idle", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = poll(pfd, 2, timeout_ms);
|
||||
if (ret < 0)
|
||||
ALOGE("%s: Error on waiting for idle (%zd)", __func__, ret);
|
||||
|
@ -257,11 +211,9 @@ void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) {
|
|||
else if (pfd[1].revents)
|
||||
ALOGV("%s: idle detected", __func__);
|
||||
}
|
||||
|
||||
void InteractionHandler::Routine() {
|
||||
pthread_setname_np(pthread_self(), "DispIdle");
|
||||
std::unique_lock<std::mutex> lk(mLock, std::defer_lock);
|
||||
|
||||
while (true) {
|
||||
lk.lock();
|
||||
mCond.wait(lk, [&] { return mState != INTERACTION_STATE_IDLE; });
|
||||
|
@ -269,12 +221,10 @@ void InteractionHandler::Routine() {
|
|||
return;
|
||||
mState = INTERACTION_STATE_WAITING;
|
||||
lk.unlock();
|
||||
|
||||
WaitForIdle(kWaitMs, mDurationMs);
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
|
@ -13,29 +13,24 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
enum InteractionState {
|
||||
INTERACTION_STATE_UNINITIALIZED,
|
||||
INTERACTION_STATE_IDLE,
|
||||
INTERACTION_STATE_INTERACTION,
|
||||
INTERACTION_STATE_WAITING,
|
||||
};
|
||||
|
||||
class InteractionHandler {
|
||||
public:
|
||||
InteractionHandler();
|
||||
|
@ -43,16 +38,13 @@ class InteractionHandler {
|
|||
bool Init();
|
||||
void Exit();
|
||||
void Acquire(int32_t duration);
|
||||
|
||||
private:
|
||||
void Release();
|
||||
void WaitForIdle(int32_t wait_ms, int32_t timeout_ms);
|
||||
void AbortWaitLocked();
|
||||
void Routine();
|
||||
|
||||
void PerfLock();
|
||||
void PerfRel();
|
||||
|
||||
enum InteractionState mState;
|
||||
int mIdleFd;
|
||||
int mEventFd;
|
||||
|
@ -62,7 +54,6 @@ class InteractionHandler {
|
|||
std::mutex mLock;
|
||||
std::condition_variable mCond;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
|
@ -13,11 +13,8 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "powerhal-libperfmgr"
|
||||
|
||||
#include "Power.h"
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
|
@ -25,35 +22,29 @@
|
|||
#include <android-base/strings.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "PowerHintSession.h"
|
||||
#include "PowerSessionManager.h"
|
||||
#include "disp-power/DisplayLowPower.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using ::aidl::google::hardware::power::impl::pixel::PowerHintSession;
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
#ifdef MODE_EXT
|
||||
extern bool isDeviceSpecificModeSupported(Mode type, bool* _aidl_return);
|
||||
extern bool setDeviceSpecificMode(Mode type, bool enabled);
|
||||
#endif
|
||||
constexpr char kPowerHalStateProp[] = "vendor.powerhal.state";
|
||||
constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio";
|
||||
constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering";
|
||||
|
||||
Power::Power(std::shared_ptr<DisplayLowPower> dlpw, std::shared_ptr<AdaptiveCpu> adaptiveCpu)
|
||||
: mDisplayLowPower(dlpw),
|
||||
mAdaptiveCpu(adaptiveCpu),
|
||||
mInteractionHandler(nullptr),
|
||||
Power::Power()
|
||||
: mInteractionHandler(nullptr),
|
||||
mSustainedPerfModeOn(false) {
|
||||
mInteractionHandler = std::make_unique<InteractionHandler>();
|
||||
mInteractionHandler->Init();
|
||||
|
||||
std::string state = ::android::base::GetProperty(kPowerHalStateProp, "");
|
||||
if (state == "SUSTAINED_PERFORMANCE") {
|
||||
LOG(INFO) << "Initialize with SUSTAINED_PERFORMANCE on";
|
||||
|
@ -62,60 +53,34 @@ Power::Power(std::shared_ptr<DisplayLowPower> dlpw, std::shared_ptr<AdaptiveCpu>
|
|||
} else {
|
||||
LOG(INFO) << "Initialize PowerHAL";
|
||||
}
|
||||
|
||||
state = ::android::base::GetProperty(kPowerHalAudioProp, "");
|
||||
if (state == "AUDIO_STREAMING_LOW_LATENCY") {
|
||||
LOG(INFO) << "Initialize with AUDIO_LOW_LATENCY on";
|
||||
HintManager::GetInstance()->DoHint(state);
|
||||
}
|
||||
|
||||
state = ::android::base::GetProperty(kPowerHalRenderingProp, "");
|
||||
if (state == "EXPENSIVE_RENDERING") {
|
||||
LOG(INFO) << "Initialize with EXPENSIVE_RENDERING on";
|
||||
HintManager::GetInstance()->DoHint("EXPENSIVE_RENDERING");
|
||||
}
|
||||
}
|
||||
|
||||
static int sysfs_write(const char *path, const char *s)
|
||||
{
|
||||
char buf[80];
|
||||
int len;
|
||||
int ret = 0;
|
||||
int fd = open(path, O_WRONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
strerror_r(errno, buf, sizeof(buf));
|
||||
ALOGE("Error opening %s: %s\n", path, buf);
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
len = write(fd, s, strlen(s));
|
||||
if (len < 0) {
|
||||
strerror_r(errno, buf, sizeof(buf));
|
||||
ALOGE("Error writing to %s: %s\n", path, buf);
|
||||
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
|
||||
LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled;
|
||||
if (HintManager::GetInstance()->GetAdpfProfile() &&
|
||||
HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) {
|
||||
PowerSessionManager::getInstance()->updateHintMode(toString(type), enabled);
|
||||
}
|
||||
switch (type) {
|
||||
case Mode::DOUBLE_TAP_TO_WAKE:
|
||||
{
|
||||
sysfs_write("/sys/class/touch/tp_dev/gesture_on", enabled ? "1" : "0");
|
||||
#ifdef MODE_EXT
|
||||
if (setDeviceSpecificMode(type, enabled)) {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
#endif
|
||||
switch (type) {
|
||||
#ifdef TAP_TO_WAKE_NODE
|
||||
case Mode::DOUBLE_TAP_TO_WAKE:
|
||||
::android::base::WriteStringToFile(enabled ? "1" : "0", TAP_TO_WAKE_NODE, true);
|
||||
break;
|
||||
case Mode::LOW_POWER:
|
||||
break;
|
||||
#endif
|
||||
case Mode::SUSTAINED_PERFORMANCE:
|
||||
if (enabled) {
|
||||
HintManager::GetInstance()->DoHint("SUSTAINED_PERFORMANCE");
|
||||
|
@ -127,6 +92,10 @@ ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
|
|||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
#ifndef TAP_TO_WAKE_NODE
|
||||
case Mode::DOUBLE_TAP_TO_WAKE:
|
||||
[[fallthrough]];
|
||||
#endif
|
||||
case Mode::FIXED_PERFORMANCE:
|
||||
[[fallthrough]];
|
||||
case Mode::EXPENSIVE_RENDERING:
|
||||
|
@ -139,8 +108,6 @@ ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
|
|||
[[fallthrough]];
|
||||
case Mode::AUDIO_STREAMING_LOW_LATENCY:
|
||||
[[fallthrough]];
|
||||
case Mode::GAME_LOADING:
|
||||
[[fallthrough]];
|
||||
default:
|
||||
if (enabled) {
|
||||
HintManager::GetInstance()->DoHint(toString(type));
|
||||
|
@ -149,21 +116,24 @@ ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::isModeSupported(Mode type, bool *_aidl_return) {
|
||||
#ifdef MODE_EXT
|
||||
if (isDeviceSpecificModeSupported(type, _aidl_return)) {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
#endif
|
||||
bool supported = HintManager::GetInstance()->IsHintSupported(toString(type));
|
||||
// LOW_POWER and DOUBLE_TAP_TO_WAKE handled insides PowerHAL specifically
|
||||
if (type == Mode::LOW_POWER || type == Mode::DOUBLE_TAP_TO_WAKE) {
|
||||
#ifdef TAP_TO_WAKE_NODE
|
||||
if (type == Mode::DOUBLE_TAP_TO_WAKE) {
|
||||
supported = true;
|
||||
}
|
||||
#endif
|
||||
LOG(INFO) << "Power mode " << toString(type) << " isModeSupported: " << supported;
|
||||
*_aidl_return = supported;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
|
||||
LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs;
|
||||
if (HintManager::GetInstance()->GetAdpfProfile() &&
|
||||
|
@ -197,21 +167,17 @@ ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool *_aidl_return) {
|
||||
bool supported = HintManager::GetInstance()->IsHintSupported(toString(type));
|
||||
LOG(INFO) << "Power boost " << toString(type) << " isBoostSupported: " << supported;
|
||||
*_aidl_return = supported;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
constexpr const char *boolToString(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
binder_status_t Power::dump(int fd, const char **, uint32_t) {
|
||||
std::string buf(::android::base::StringPrintf(
|
||||
"HintManager Running: %s\n"
|
||||
|
@ -221,14 +187,12 @@ binder_status_t Power::dump(int fd, const char **, uint32_t) {
|
|||
// Dump nodes through libperfmgr
|
||||
HintManager::GetInstance()->DumpToFd(fd);
|
||||
PowerSessionManager::getInstance()->dumpToFd(fd);
|
||||
mAdaptiveCpu->DumpToFd(fd);
|
||||
if (!::android::base::WriteStringToFd(buf, fd)) {
|
||||
PLOG(ERROR) << "Failed to dump state to fd";
|
||||
}
|
||||
fsync(fd);
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::createHintSession(int32_t tgid, int32_t uid,
|
||||
const std::vector<int32_t> &threadIds,
|
||||
int64_t durationNanos,
|
||||
|
@ -244,11 +208,10 @@ ndk::ScopedAStatus Power::createHintSession(int32_t tgid, int32_t uid,
|
|||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
std::shared_ptr<IPowerHintSession> session = ndk::SharedRefBase::make<PowerHintSession>(
|
||||
mAdaptiveCpu, tgid, uid, threadIds, durationNanos);
|
||||
tgid, uid, threadIds, durationNanos);
|
||||
*_aidl_return = session;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t *outNanoseconds) {
|
||||
*outNanoseconds = HintManager::GetInstance()->GetAdpfProfile()
|
||||
? HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs
|
||||
|
@ -256,10 +219,8 @@ ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t *outNanoseconds) {
|
|||
if (*outNanoseconds <= 0) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
|
@ -13,33 +13,24 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/power/BnPower.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include "adaptivecpu/AdaptiveCpu.h"
|
||||
#include "disp-power/DisplayLowPower.h"
|
||||
#include "disp-power/InteractionHandler.h"
|
||||
|
||||
#include "InteractionHandler.h"
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using ::aidl::android::hardware::power::Boost;
|
||||
using ::aidl::android::hardware::power::IPowerHintSession;
|
||||
using ::aidl::android::hardware::power::Mode;
|
||||
|
||||
class Power : public ::aidl::android::hardware::power::BnPower {
|
||||
public:
|
||||
Power(std::shared_ptr<DisplayLowPower> dlpw, std::shared_ptr<AdaptiveCpu> adaptiveCpu);
|
||||
Power();
|
||||
ndk::ScopedAStatus setMode(Mode type, bool enabled) override;
|
||||
ndk::ScopedAStatus isModeSupported(Mode type, bool *_aidl_return) override;
|
||||
ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override;
|
||||
|
@ -50,14 +41,10 @@ class Power : public ::aidl::android::hardware::power::BnPower {
|
|||
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:
|
||||
std::shared_ptr<DisplayLowPower> mDisplayLowPower;
|
||||
std::shared_ptr<AdaptiveCpu> mAdaptiveCpu;
|
||||
std::unique_ptr<InteractionHandler> mInteractionHandler;
|
||||
std::atomic<bool> mSustainedPerfModeOn;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
|
@ -13,11 +13,8 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.power-service.pixel.ext-libperfmgr"
|
||||
|
||||
#define LOG_TAG "android.hardware.power-service.xiaomi.ext-libperfmgr"
|
||||
#include "PowerExt.h"
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
|
@ -25,23 +22,17 @@
|
|||
#include <android-base/strings.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "PowerSessionManager.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
ndk::ScopedAStatus PowerExt::setMode(const std::string &mode, bool enabled) {
|
||||
LOG(DEBUG) << "PowerExt setMode: " << mode << " to: " << enabled;
|
||||
|
||||
if (enabled) {
|
||||
HintManager::GetInstance()->DoHint(mode);
|
||||
} else {
|
||||
|
@ -51,29 +42,20 @@ ndk::ScopedAStatus PowerExt::setMode(const std::string &mode, bool enabled) {
|
|||
HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) {
|
||||
PowerSessionManager::getInstance()->updateHintMode(mode, enabled);
|
||||
}
|
||||
|
||||
if (mode == AdaptiveCpu::HINT_NAME) {
|
||||
LOG(DEBUG) << "AdaptiveCpu intercepted hint";
|
||||
mAdaptiveCpu->HintReceived(enabled);
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerExt::isModeSupported(const std::string &mode, bool *_aidl_return) {
|
||||
bool supported = HintManager::GetInstance()->IsHintSupported(mode);
|
||||
LOG(INFO) << "PowerExt mode " << mode << " isModeSupported: " << supported;
|
||||
*_aidl_return = supported;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerExt::setBoost(const std::string &boost, int32_t durationMs) {
|
||||
LOG(DEBUG) << "PowerExt setBoost: " << boost << " duration: " << durationMs;
|
||||
if (HintManager::GetInstance()->GetAdpfProfile() &&
|
||||
HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) {
|
||||
PowerSessionManager::getInstance()->updateHintBoost(boost, durationMs);
|
||||
}
|
||||
|
||||
if (durationMs > 0) {
|
||||
HintManager::GetInstance()->DoHint(boost, std::chrono::milliseconds(durationMs));
|
||||
} else if (durationMs == 0) {
|
||||
|
@ -81,17 +63,14 @@ ndk::ScopedAStatus PowerExt::setBoost(const std::string &boost, int32_t duration
|
|||
} else {
|
||||
HintManager::GetInstance()->EndHint(boost);
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerExt::isBoostSupported(const std::string &boost, bool *_aidl_return) {
|
||||
bool supported = HintManager::GetInstance()->IsHintSupported(boost);
|
||||
LOG(INFO) << "PowerExt boost " << boost << " isBoostSupported: " << supported;
|
||||
*_aidl_return = supported;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
|
@ -13,40 +13,27 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/google/hardware/power/extension/pixel/BnPowerExt.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include "adaptivecpu/AdaptiveCpu.h"
|
||||
#include "disp-power/DisplayLowPower.h"
|
||||
|
||||
#include <aidl/google/hardware/power/extension/pixel/BnPowerExt.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
class PowerExt : public ::aidl::google::hardware::power::extension::pixel::BnPowerExt {
|
||||
public:
|
||||
PowerExt(std::shared_ptr<DisplayLowPower> dlpw, std::shared_ptr<AdaptiveCpu> acpu)
|
||||
: mDisplayLowPower(dlpw), mAdaptiveCpu(acpu) {}
|
||||
PowerExt() {}
|
||||
ndk::ScopedAStatus setMode(const std::string &mode, bool enabled) override;
|
||||
ndk::ScopedAStatus isModeSupported(const std::string &mode, bool *_aidl_return) override;
|
||||
ndk::ScopedAStatus setBoost(const std::string &boost, int32_t durationMs) override;
|
||||
ndk::ScopedAStatus isBoostSupported(const std::string &boost, bool *_aidl_return) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<DisplayLowPower> mDisplayLowPower;
|
||||
std::shared_ptr<AdaptiveCpu> mAdaptiveCpu;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
|
@ -13,12 +13,9 @@
|
|||
* 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 "PowerHintSession.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/parsedouble.h>
|
||||
#include <android-base/properties.h>
|
||||
|
@ -28,35 +25,30 @@
|
|||
#include <sys/syscall.h>
|
||||
#include <time.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "PowerSessionManager.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using ::android::base::StringPrintf;
|
||||
using ::android::perfmgr::AdpfConfig;
|
||||
using ::android::perfmgr::HintManager;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::nanoseconds;
|
||||
|
||||
namespace {
|
||||
|
||||
static inline int64_t ns_to_100us(int64_t ns) {
|
||||
return ns / 100000;
|
||||
}
|
||||
|
||||
static int64_t convertWorkDurationToBoostByPid(std::shared_ptr<AdpfConfig> adpfConfig,
|
||||
nanoseconds targetDuration,
|
||||
const std::vector<WorkDuration> &actualDurations,
|
||||
int64_t *integral_error, int64_t *previous_error,
|
||||
const std::string &idstr) {
|
||||
} // namespace
|
||||
int64_t PowerHintSession::convertWorkDurationToBoostByPid(
|
||||
const std::vector<WorkDuration> &actualDurations) {
|
||||
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
|
||||
const nanoseconds &targetDuration = mDescriptor->duration;
|
||||
int64_t &integral_error = mDescriptor->integral_error;
|
||||
int64_t &previous_error = mDescriptor->previous_error;
|
||||
uint64_t samplingWindowP = adpfConfig->mSamplingWindowP;
|
||||
uint64_t samplingWindowI = adpfConfig->mSamplingWindowI;
|
||||
uint64_t samplingWindowD = adpfConfig->mSamplingWindowD;
|
||||
|
@ -80,109 +72,77 @@ static int64_t convertWorkDurationToBoostByPid(std::shared_ptr<AdpfConfig> adpfC
|
|||
// PID control algorithm
|
||||
int64_t error = ns_to_100us(actualDurationNanos - targetDurationNanos);
|
||||
if (i >= d_start) {
|
||||
derivative_sum += error - (*previous_error);
|
||||
derivative_sum += error - previous_error;
|
||||
}
|
||||
if (i >= p_start) {
|
||||
err_sum += error;
|
||||
}
|
||||
if (i >= i_start) {
|
||||
*integral_error = *integral_error + error * dt;
|
||||
*integral_error = std::min(adpfConfig->getPidIHighDivI(), *integral_error);
|
||||
*integral_error = std::max(adpfConfig->getPidILowDivI(), *integral_error);
|
||||
integral_error += error * dt;
|
||||
integral_error = std::min(adpfConfig->getPidIHighDivI(), integral_error);
|
||||
integral_error = std::max(adpfConfig->getPidILowDivI(), integral_error);
|
||||
}
|
||||
*previous_error = error;
|
||||
previous_error = error;
|
||||
}
|
||||
int64_t pOut = static_cast<int64_t>((err_sum > 0 ? adpfConfig->mPidPo : adpfConfig->mPidPu) *
|
||||
err_sum / (length - p_start));
|
||||
int64_t iOut = static_cast<int64_t>(adpfConfig->mPidI * (*integral_error));
|
||||
int64_t iOut = static_cast<int64_t>(adpfConfig->mPidI * integral_error);
|
||||
int64_t dOut =
|
||||
static_cast<int64_t>((derivative_sum > 0 ? adpfConfig->mPidDo : adpfConfig->mPidDu) *
|
||||
derivative_sum / dt / (length - d_start));
|
||||
|
||||
int64_t output = pOut + iOut + dOut;
|
||||
if (ATRACE_ENABLED()) {
|
||||
std::string sz = StringPrintf("adpf.%s-pid.err", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), err_sum / (length - p_start));
|
||||
sz = StringPrintf("adpf.%s-pid.integral", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), *integral_error);
|
||||
sz = StringPrintf("adpf.%s-pid.derivative", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), derivative_sum / dt / (length - d_start));
|
||||
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);
|
||||
traceSessionVal("pid.err", err_sum / (length - p_start));
|
||||
traceSessionVal("pid.integral", integral_error);
|
||||
traceSessionVal("pid.derivative", derivative_sum / dt / (length - d_start));
|
||||
traceSessionVal("pid.pOut", pOut);
|
||||
traceSessionVal("pid.iOut", iOut);
|
||||
traceSessionVal("pid.dOut", dOut);
|
||||
traceSessionVal("pid.output", output);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PowerHintSession::PowerHintSession(std::shared_ptr<AdaptiveCpu> adaptiveCpu, int32_t tgid,
|
||||
int32_t uid, const std::vector<int32_t> &threadIds,
|
||||
int64_t durationNanos)
|
||||
: mAdaptiveCpu(adaptiveCpu) {
|
||||
PowerHintSession::PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds,
|
||||
int64_t durationNanos) {
|
||||
mDescriptor = new AppHintDesc(tgid, uid, threadIds);
|
||||
mDescriptor->duration = std::chrono::nanoseconds(durationNanos);
|
||||
mIdString = StringPrintf("%" PRId32 "-%" PRId32 "-%" PRIxPTR, mDescriptor->tgid,
|
||||
mDescriptor->uid, reinterpret_cast<uintptr_t>(this) & 0xffff);
|
||||
mStaleTimerHandler = sp<StaleTimerHandler>(new StaleTimerHandler(this));
|
||||
mEarlyBoostHandler = sp<EarlyBoostHandler>(new EarlyBoostHandler(this));
|
||||
mPowerManagerHandler = PowerSessionManager::getInstance();
|
||||
mLastUpdatedTime.store(std::chrono::steady_clock::now());
|
||||
mLastStartedTimeNs =
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
(std::chrono::steady_clock::now() - mDescriptor->duration).time_since_epoch())
|
||||
.count();
|
||||
mLastDurationNs = durationNanos;
|
||||
mWorkPeriodNs = durationNanos;
|
||||
|
||||
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());
|
||||
traceSessionVal("target", mDescriptor->duration.count());
|
||||
traceSessionVal("active", mDescriptor->is_active.load());
|
||||
}
|
||||
PowerSessionManager::getInstance()->addPowerSession(this);
|
||||
// init boost
|
||||
setSessionUclampMin(HintManager::GetInstance()->GetAdpfProfile()->mUclampMinInit);
|
||||
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);
|
||||
traceSessionVal("target", 0);
|
||||
traceSessionVal("actl_last", 0);
|
||||
traceSessionVal("active", 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::traceSessionVal(char const *identifier, int64_t val) const {
|
||||
ATRACE_INT(StringPrintf("adpf.%s-%s", mIdString.c_str(), identifier).c_str(), val);
|
||||
}
|
||||
|
||||
bool PowerHintSession::isAppSession() {
|
||||
// Check if uid is in range reserved for applications
|
||||
return mDescriptor->uid >= AID_APP_START;
|
||||
}
|
||||
|
||||
void PowerHintSession::updateUniveralBoostMode() {
|
||||
if (!isAppSession()) {
|
||||
return;
|
||||
}
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string tag = StringPrintf("%s:updateUniveralBoostMode()", getIdString().c_str());
|
||||
const std::string tag = StringPrintf("%s:updateUniveralBoostMode()", mIdString.c_str());
|
||||
ATRACE_BEGIN(tag.c_str());
|
||||
}
|
||||
PowerHintMonitor::getInstance()->getLooper()->sendMessage(mPowerManagerHandler, NULL);
|
||||
|
@ -190,7 +150,14 @@ void PowerHintSession::updateUniveralBoostMode() {
|
|||
ATRACE_END();
|
||||
}
|
||||
}
|
||||
|
||||
void PowerHintSession::tryToSendPowerHint(std::string hint) {
|
||||
if (!mSupportedHints[hint].has_value()) {
|
||||
mSupportedHints[hint] = HintManager::GetInstance()->IsHintSupported(hint);
|
||||
}
|
||||
if (mSupportedHints[hint].value()) {
|
||||
HintManager::GetInstance()->DoHint(hint);
|
||||
}
|
||||
}
|
||||
int PowerHintSession::setSessionUclampMin(int32_t min) {
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mSessionLock);
|
||||
|
@ -200,26 +167,20 @@ int PowerHintSession::setSessionUclampMin(int32_t min) {
|
|||
mStaleTimerHandler->updateTimer();
|
||||
}
|
||||
PowerSessionManager::getInstance()->setUclampMin(this, min);
|
||||
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), min);
|
||||
traceSessionVal("min", min);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PowerHintSession::getUclampMin() {
|
||||
return mDescriptor->current_min;
|
||||
}
|
||||
|
||||
void PowerHintSession::dumpToStream(std::ostream &stream) {
|
||||
stream << "ID.Min.Act.Timeout(" << getIdString();
|
||||
stream << "ID.Min.Act.Timeout(" << mIdString;
|
||||
stream << ", " << mDescriptor->current_min;
|
||||
stream << ", " << mDescriptor->is_active;
|
||||
stream << ", " << isTimeout() << ")";
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerHintSession::pause() {
|
||||
if (mSessionClosed) {
|
||||
ALOGE("Error: session is dead");
|
||||
|
@ -231,14 +192,11 @@ ndk::ScopedAStatus PowerHintSession::pause() {
|
|||
mDescriptor->is_active.store(false);
|
||||
setStale();
|
||||
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());
|
||||
traceSessionVal("active", mDescriptor->is_active.load());
|
||||
}
|
||||
updateUniveralBoostMode();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerHintSession::resume() {
|
||||
if (mSessionClosed) {
|
||||
ALOGE("Error: session is dead");
|
||||
|
@ -250,14 +208,11 @@ ndk::ScopedAStatus PowerHintSession::resume() {
|
|||
// resume boost
|
||||
setSessionUclampMin(mDescriptor->current_min);
|
||||
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());
|
||||
traceSessionVal("active", mDescriptor->is_active.load());
|
||||
}
|
||||
updateUniveralBoostMode();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerHintSession::close() {
|
||||
bool sessionClosedExpectedToBe = false;
|
||||
if (!mSessionClosed.compare_exchange_strong(sessionClosedExpectedToBe, true)) {
|
||||
|
@ -265,18 +220,12 @@ ndk::ScopedAStatus PowerHintSession::close() {
|
|||
}
|
||||
// Remove the session from PowerSessionManager first to avoid racing.
|
||||
PowerSessionManager::getInstance()->removePowerSession(this);
|
||||
setSessionUclampMin(0);
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mSessionLock);
|
||||
mSessionClosed.store(true);
|
||||
}
|
||||
mDescriptor->is_active.store(false);
|
||||
mEarlyBoostHandler->setSessionDead();
|
||||
mStaleTimerHandler->setSessionDead();
|
||||
setSessionUclampMin(0);
|
||||
mDescriptor->is_active.store(false);
|
||||
updateUniveralBoostMode();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerHintSession::updateTargetWorkDuration(int64_t targetDurationNanos) {
|
||||
if (mSessionClosed) {
|
||||
ALOGE("Error: session is dead");
|
||||
|
@ -289,17 +238,12 @@ ndk::ScopedAStatus PowerHintSession::updateTargetWorkDuration(int64_t targetDura
|
|||
targetDurationNanos =
|
||||
targetDurationNanos * HintManager::GetInstance()->GetAdpfProfile()->mTargetTimeFactor;
|
||||
ALOGV("update target duration: %" PRId64 " ns", targetDurationNanos);
|
||||
|
||||
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());
|
||||
traceSessionVal("target", mDescriptor->duration.count());
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerHintSession::reportActualWorkDuration(
|
||||
const std::vector<WorkDuration> &actualDurations) {
|
||||
if (mSessionClosed) {
|
||||
|
@ -322,49 +266,33 @@ ndk::ScopedAStatus PowerHintSession::reportActualWorkDuration(
|
|||
mDescriptor->update_count++;
|
||||
bool isFirstFrame = isTimeout();
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-batch_size", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), actualDurations.size());
|
||||
sz = StringPrintf("adpf.%s-actl_last", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), actualDurations.back().durationNanos);
|
||||
sz = StringPrintf("adpf.%s-target", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), (int64_t)mDescriptor->duration.count());
|
||||
sz = StringPrintf("adpf.%s-hint.count", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), mDescriptor->update_count);
|
||||
sz = StringPrintf("adpf.%s-hint.overtime", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(),
|
||||
traceSessionVal("batch_size", actualDurations.size());
|
||||
traceSessionVal("actl_last", actualDurations.back().durationNanos);
|
||||
traceSessionVal("target", mDescriptor->duration.count());
|
||||
traceSessionVal("hint.count", mDescriptor->update_count);
|
||||
traceSessionVal("hint.overtime",
|
||||
actualDurations.back().durationNanos - mDescriptor->duration.count() > 0);
|
||||
traceSessionVal("session_hint", -1);
|
||||
}
|
||||
|
||||
mLastUpdatedTime.store(std::chrono::steady_clock::now());
|
||||
if (isFirstFrame) {
|
||||
if (isAppSession()) {
|
||||
tryToSendPowerHint("ADPF_FIRST_FRAME");
|
||||
}
|
||||
updateUniveralBoostMode();
|
||||
}
|
||||
|
||||
if (!adpfConfig->mPidOn) {
|
||||
setSessionUclampMin(adpfConfig->mUclampMinHigh);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
int64_t output = convertWorkDurationToBoostByPid(
|
||||
adpfConfig, mDescriptor->duration, actualDurations, &(mDescriptor->integral_error),
|
||||
&(mDescriptor->previous_error), getIdString());
|
||||
|
||||
int64_t output = convertWorkDurationToBoostByPid(actualDurations);
|
||||
/* apply to all the threads in the group */
|
||||
int next_min = std::min(static_cast<int>(adpfConfig->mUclampMinHigh),
|
||||
mDescriptor->current_min + static_cast<int>(output));
|
||||
next_min = std::max(static_cast<int>(adpfConfig->mUclampMinLow), next_min);
|
||||
setSessionUclampMin(next_min);
|
||||
mStaleTimerHandler->updateTimer(getStaleTime());
|
||||
if (HintManager::GetInstance()->GetAdpfProfile()->mEarlyBoostOn) {
|
||||
updateWorkPeriod(actualDurations);
|
||||
mEarlyBoostHandler->updateTimer(getEarlyBoostTime());
|
||||
}
|
||||
|
||||
mAdaptiveCpu->ReportWorkDurations(actualDurations, mDescriptor->duration);
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
std::string AppHintDesc::toString() const {
|
||||
std::string out =
|
||||
StringPrintf("session %" PRIxPTR "\n", reinterpret_cast<uintptr_t>(this) & 0xffff);
|
||||
|
@ -372,7 +300,6 @@ std::string AppHintDesc::toString() const {
|
|||
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) {
|
||||
|
@ -385,121 +312,49 @@ std::string AppHintDesc::toString() const {
|
|||
out.append("]\n");
|
||||
return out;
|
||||
}
|
||||
|
||||
bool PowerHintSession::isActive() {
|
||||
return mDescriptor->is_active.load();
|
||||
}
|
||||
|
||||
bool PowerHintSession::isTimeout() {
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
return now >= getStaleTime();
|
||||
time_point<steady_clock> staleTime =
|
||||
mLastUpdatedTime.load() +
|
||||
nanoseconds(static_cast<int64_t>(
|
||||
mDescriptor->duration.count() *
|
||||
HintManager::GetInstance()->GetAdpfProfile()->mStaleTimeFactor));
|
||||
return now >= staleTime;
|
||||
}
|
||||
|
||||
const std::vector<int> &PowerHintSession::getTidList() const {
|
||||
return mDescriptor->threadIds;
|
||||
}
|
||||
|
||||
void PowerHintSession::setStale() {
|
||||
// Reset to default uclamp value.
|
||||
PowerSessionManager::getInstance()->setUclampMin(this, 0);
|
||||
// Deliver a task to check if all sessions are inactive.
|
||||
updateUniveralBoostMode();
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), 0);
|
||||
traceSessionVal("min", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerHintSession::wakeup() {
|
||||
std::lock_guard<std::mutex> guard(mSessionLock);
|
||||
|
||||
// We only wake up non-paused and stale sessions
|
||||
if (mSessionClosed || !isActive() || !isTimeout())
|
||||
return;
|
||||
if (ATRACE_ENABLED()) {
|
||||
std::string tag = StringPrintf("wakeup.%s(a:%d,s:%d)", getIdString().c_str(), isActive(),
|
||||
isTimeout());
|
||||
ATRACE_NAME(tag.c_str());
|
||||
}
|
||||
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
|
||||
int min = std::max(mDescriptor->current_min, static_cast<int>(adpfConfig->mUclampMinInit));
|
||||
mDescriptor->current_min = min;
|
||||
PowerSessionManager::getInstance()->setUclampMinLocked(this, min);
|
||||
mStaleTimerHandler->updateTimer();
|
||||
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), min);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerHintSession::updateWorkPeriod(const std::vector<WorkDuration> &actualDurations) {
|
||||
if (actualDurations.size() == 0)
|
||||
return;
|
||||
if (actualDurations.size() >= 2) {
|
||||
const WorkDuration &last = actualDurations[actualDurations.size() - 2];
|
||||
mLastStartedTimeNs = last.timeStampNanos - last.durationNanos;
|
||||
}
|
||||
const WorkDuration ¤t = actualDurations.back();
|
||||
int64_t curr_start = current.timeStampNanos - current.durationNanos;
|
||||
int64_t period = curr_start - mLastStartedTimeNs;
|
||||
if (period > 0 && period < mDescriptor->duration.count() * 2) {
|
||||
// Accounting workload period with moving average for the last 10 workload.
|
||||
mWorkPeriodNs = 0.9 * mWorkPeriodNs + 0.1 * period;
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-timer.period", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), mWorkPeriodNs);
|
||||
}
|
||||
}
|
||||
mLastStartedTimeNs = curr_start;
|
||||
mLastDurationNs = current.durationNanos;
|
||||
}
|
||||
|
||||
time_point<steady_clock> PowerHintSession::getEarlyBoostTime() {
|
||||
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
|
||||
int64_t earlyBoostTimeoutNs =
|
||||
(int64_t)mDescriptor->duration.count() * adpfConfig->mEarlyBoostTimeFactor;
|
||||
time_point<steady_clock> nextStartTime =
|
||||
mLastUpdatedTime.load() + nanoseconds(mWorkPeriodNs - mLastDurationNs);
|
||||
return nextStartTime + nanoseconds(earlyBoostTimeoutNs);
|
||||
}
|
||||
|
||||
time_point<steady_clock> PowerHintSession::getStaleTime() {
|
||||
return mLastUpdatedTime.load() +
|
||||
nanoseconds(static_cast<int64_t>(
|
||||
mDescriptor->duration.count() *
|
||||
HintManager::GetInstance()->GetAdpfProfile()->mStaleTimeFactor));
|
||||
}
|
||||
|
||||
void PowerHintSession::StaleTimerHandler::updateTimer() {
|
||||
time_point<steady_clock> staleTime =
|
||||
std::chrono::steady_clock::now() +
|
||||
nanoseconds(static_cast<int64_t>(
|
||||
mSession->mDescriptor->duration.count() *
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
nanoseconds staleDuration = std::chrono::nanoseconds(
|
||||
static_cast<int64_t>(mSession->mDescriptor->duration.count() *
|
||||
HintManager::GetInstance()->GetAdpfProfile()->mStaleTimeFactor));
|
||||
updateTimer(staleTime);
|
||||
}
|
||||
|
||||
void PowerHintSession::StaleTimerHandler::updateTimer(time_point<steady_clock> staleTime) {
|
||||
mStaleTime.store(staleTime);
|
||||
mStaleTime.store(now + staleDuration);
|
||||
int64_t next = static_cast<int64_t>(staleDuration.count());
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mMessageLock);
|
||||
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mStaleTimerHandler);
|
||||
PowerHintMonitor::getInstance()->getLooper()->sendMessage(mSession->mStaleTimerHandler,
|
||||
NULL);
|
||||
PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
|
||||
next, mSession->mStaleTimerHandler, NULL);
|
||||
}
|
||||
mIsMonitoring.store(true);
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = mSession->getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-timer.stale", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), 0);
|
||||
mSession->traceSessionVal("timer.stale", 0);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerHintSession::StaleTimerHandler::handleMessage(const Message &) {
|
||||
std::lock_guard<std::mutex> guard(mClosedLock);
|
||||
if (mIsSessionDead) {
|
||||
return;
|
||||
}
|
||||
|
@ -514,80 +369,19 @@ void PowerHintSession::StaleTimerHandler::handleMessage(const Message &) {
|
|||
next, mSession->mStaleTimerHandler, NULL);
|
||||
} else {
|
||||
mSession->setStale();
|
||||
mIsMonitoring.store(false);
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = mSession->getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-timer.earlyboost", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), 0);
|
||||
mSession->traceSessionVal("session_hint", -1);
|
||||
}
|
||||
}
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = mSession->getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-timer.stale", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), mIsMonitoring ? 0 : 1);
|
||||
mSession->traceSessionVal("timer.stale", next > 0 ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerHintSession::StaleTimerHandler::setSessionDead() {
|
||||
std::lock_guard<std::mutex> guard(mStaleLock);
|
||||
std::lock_guard<std::mutex> guard(mClosedLock);
|
||||
mIsSessionDead = true;
|
||||
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mStaleTimerHandler);
|
||||
}
|
||||
|
||||
void PowerHintSession::EarlyBoostHandler::updateTimer(time_point<steady_clock> boostTime) {
|
||||
mBoostTime.store(boostTime);
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mMessageLock);
|
||||
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mEarlyBoostHandler);
|
||||
PowerHintMonitor::getInstance()->getLooper()->sendMessage(mSession->mEarlyBoostHandler,
|
||||
NULL);
|
||||
}
|
||||
mIsMonitoring.store(true);
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = mSession->getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-timer.earlyboost", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerHintSession::EarlyBoostHandler::handleMessage(const Message &) {
|
||||
std::lock_guard<std::mutex> guard(mBoostLock);
|
||||
if (mIsSessionDead) {
|
||||
return;
|
||||
}
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
int64_t next =
|
||||
static_cast<int64_t>(duration_cast<nanoseconds>(mBoostTime.load() - now).count());
|
||||
if (next > 0) {
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = mSession->getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-timer.earlyboost", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), 1);
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(mMessageLock);
|
||||
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mEarlyBoostHandler);
|
||||
PowerHintMonitor::getInstance()->getLooper()->sendMessageDelayed(
|
||||
next, mSession->mEarlyBoostHandler, NULL);
|
||||
} else {
|
||||
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
|
||||
PowerSessionManager::getInstance()->setUclampMin(mSession, adpfConfig->mUclampMinHigh);
|
||||
mIsMonitoring.store(false);
|
||||
if (ATRACE_ENABLED()) {
|
||||
const std::string idstr = mSession->getIdString();
|
||||
std::string sz = StringPrintf("adpf.%s-min", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), adpfConfig->mUclampMinHigh);
|
||||
sz = StringPrintf("adpf.%s-timer.earlyboost", idstr.c_str());
|
||||
ATRACE_INT(sz.c_str(), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PowerHintSession::EarlyBoostHandler::setSessionDead() {
|
||||
std::lock_guard<std::mutex> guard(mBoostLock);
|
||||
mIsSessionDead = true;
|
||||
PowerHintMonitor::getInstance()->getLooper()->removeMessages(mSession->mEarlyBoostHandler);
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
|
@ -13,26 +13,19 @@
|
|||
* 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>
|
||||
|
||||
#include "adaptivecpu/AdaptiveCpu.h"
|
||||
|
||||
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;
|
||||
|
@ -42,7 +35,6 @@ using std::chrono::milliseconds;
|
|||
using std::chrono::nanoseconds;
|
||||
using std::chrono::steady_clock;
|
||||
using std::chrono::time_point;
|
||||
|
||||
struct AppHintDesc {
|
||||
AppHintDesc(int32_t tgid, int32_t uid, std::vector<int> threadIds)
|
||||
: tgid(tgid),
|
||||
|
@ -67,11 +59,10 @@ struct AppHintDesc {
|
|||
int64_t integral_error;
|
||||
int64_t previous_error;
|
||||
};
|
||||
|
||||
class PowerHintSession : public BnPowerHintSession {
|
||||
public:
|
||||
explicit PowerHintSession(std::shared_ptr<AdaptiveCpu> adaptiveCpu, int32_t tgid, int32_t uid,
|
||||
const std::vector<int32_t> &threadIds, int64_t durationNanos);
|
||||
explicit PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds,
|
||||
int64_t durationNanos);
|
||||
~PowerHintSession();
|
||||
ndk::ScopedAStatus close() override;
|
||||
ndk::ScopedAStatus pause() override;
|
||||
|
@ -81,72 +72,43 @@ class PowerHintSession : public BnPowerHintSession {
|
|||
const std::vector<WorkDuration> &actualDurations) override;
|
||||
bool isActive();
|
||||
bool isTimeout();
|
||||
void wakeup();
|
||||
void setStale();
|
||||
// Is this hint session for a user application
|
||||
bool isAppSession();
|
||||
const std::vector<int> &getTidList() const;
|
||||
int getUclampMin();
|
||||
void dumpToStream(std::ostream &stream);
|
||||
|
||||
void updateWorkPeriod(const std::vector<WorkDuration> &actualDurations);
|
||||
time_point<steady_clock> getEarlyBoostTime();
|
||||
time_point<steady_clock> getStaleTime();
|
||||
|
||||
private:
|
||||
class StaleTimerHandler : public MessageHandler {
|
||||
public:
|
||||
StaleTimerHandler(PowerHintSession *session)
|
||||
: mSession(session), mIsMonitoring(false), mIsSessionDead(false) {}
|
||||
StaleTimerHandler(PowerHintSession *session) : mSession(session), mIsSessionDead(false) {}
|
||||
void updateTimer();
|
||||
void updateTimer(time_point<steady_clock> staleTime);
|
||||
void handleMessage(const Message &message) override;
|
||||
void setSessionDead();
|
||||
|
||||
private:
|
||||
PowerHintSession *mSession;
|
||||
std::mutex mStaleLock;
|
||||
std::mutex mClosedLock;
|
||||
std::mutex mMessageLock;
|
||||
std::atomic<time_point<steady_clock>> mStaleTime;
|
||||
std::atomic<bool> mIsMonitoring;
|
||||
bool mIsSessionDead;
|
||||
};
|
||||
|
||||
class EarlyBoostHandler : public MessageHandler {
|
||||
public:
|
||||
EarlyBoostHandler(PowerHintSession *session)
|
||||
: mSession(session), mIsMonitoring(false), mIsSessionDead(false) {}
|
||||
void updateTimer(time_point<steady_clock> boostTime);
|
||||
void handleMessage(const Message &message) override;
|
||||
void setSessionDead();
|
||||
|
||||
private:
|
||||
PowerHintSession *mSession;
|
||||
std::mutex mBoostLock;
|
||||
std::mutex mMessageLock;
|
||||
std::atomic<time_point<steady_clock>> mBoostTime;
|
||||
std::atomic<bool> mIsMonitoring;
|
||||
bool mIsSessionDead;
|
||||
};
|
||||
|
||||
private:
|
||||
void updateUniveralBoostMode();
|
||||
int setSessionUclampMin(int32_t min);
|
||||
std::string getIdString() const;
|
||||
const std::shared_ptr<AdaptiveCpu> mAdaptiveCpu;
|
||||
void tryToSendPowerHint(std::string hint);
|
||||
int64_t convertWorkDurationToBoostByPid(const std::vector<WorkDuration> &actualDurations);
|
||||
void traceSessionVal(char const *identifier, int64_t val) const;
|
||||
AppHintDesc *mDescriptor = nullptr;
|
||||
sp<StaleTimerHandler> mStaleTimerHandler;
|
||||
sp<EarlyBoostHandler> mEarlyBoostHandler;
|
||||
std::atomic<time_point<steady_clock>> mLastUpdatedTime;
|
||||
sp<MessageHandler> mPowerManagerHandler;
|
||||
std::mutex mSessionLock;
|
||||
std::atomic<bool> mSessionClosed = false;
|
||||
// These 3 variables are for earlyboost work period estimation.
|
||||
int64_t mLastStartedTimeNs;
|
||||
int64_t mLastDurationNs;
|
||||
int64_t mWorkPeriodNs;
|
||||
std::string mIdString;
|
||||
// To cache the status of whether ADPF hints are supported.
|
||||
std::unordered_map<std::string, std::optional<bool>> mSupportedHints;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
|
@ -13,28 +13,23 @@
|
|||
* 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 "PowerSessionManager.h"
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <log/log.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
#include <processgroup/processgroup.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using ::android::perfmgr::AdpfConfig;
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
namespace {
|
||||
/* there is no glibc or bionic wrapper */
|
||||
struct sched_attr {
|
||||
|
@ -49,7 +44,6 @@ struct sched_attr {
|
|||
__u32 sched_util_min;
|
||||
__u32 sched_util_max;
|
||||
};
|
||||
|
||||
static int sched_setattr(int pid, struct sched_attr *attr, unsigned int flags) {
|
||||
if (!HintManager::GetInstance()->GetAdpfProfile()->mUclampMinOn) {
|
||||
ALOGV("PowerSessionManager:%s: skip", __func__);
|
||||
|
@ -57,25 +51,20 @@ static int sched_setattr(int pid, struct sched_attr *attr, unsigned int flags) {
|
|||
}
|
||||
return syscall(__NR_sched_setattr, pid, attr, flags);
|
||||
}
|
||||
|
||||
static void set_uclamp_min(int tid, int min) {
|
||||
static constexpr int32_t kMaxUclampValue = 1024;
|
||||
min = std::max(0, min);
|
||||
min = std::min(min, kMaxUclampValue);
|
||||
|
||||
sched_attr attr = {};
|
||||
attr.size = sizeof(attr);
|
||||
|
||||
attr.sched_flags = (SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP_MIN);
|
||||
attr.sched_util_min = min;
|
||||
|
||||
int ret = sched_setattr(tid, &attr, 0);
|
||||
if (ret) {
|
||||
ALOGW("sched_setattr failed for thread %d, err=%d", tid, errno);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
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) {
|
||||
|
@ -91,27 +80,14 @@ void PowerSessionManager::updateHintMode(const std::string &mode, bool enabled)
|
|||
HintManager::GetInstance()->SetAdpfProfile(mode);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerSessionManager::updateHintBoost(const std::string &boost, int32_t durationMs) {
|
||||
ATRACE_CALL();
|
||||
ALOGV("PowerSessionManager::updateHintBoost: boost: %s, durationMs: %d", boost.c_str(),
|
||||
durationMs);
|
||||
if (boost.compare("DISPLAY_UPDATE_IMMINENT") == 0) {
|
||||
PowerHintMonitor::getInstance()->getLooper()->sendMessage(mWakeupHandler, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerSessionManager::wakeSessions() {
|
||||
std::lock_guard<std::mutex> guard(mLock);
|
||||
for (PowerHintSession *s : mSessions) {
|
||||
s->wakeup();
|
||||
}
|
||||
}
|
||||
|
||||
int PowerSessionManager::getDisplayRefreshRate() {
|
||||
return mDisplayRefreshRate;
|
||||
}
|
||||
|
||||
void PowerSessionManager::addPowerSession(PowerHintSession *session) {
|
||||
std::lock_guard<std::mutex> guard(mLock);
|
||||
for (auto t : session->getTidList()) {
|
||||
|
@ -132,7 +108,6 @@ void PowerSessionManager::addPowerSession(PowerHintSession *session) {
|
|||
}
|
||||
mSessions.insert(session);
|
||||
}
|
||||
|
||||
void PowerSessionManager::removePowerSession(PowerHintSession *session) {
|
||||
std::lock_guard<std::mutex> guard(mLock);
|
||||
for (auto t : session->getTidList()) {
|
||||
|
@ -151,12 +126,10 @@ void PowerSessionManager::removePowerSession(PowerHintSession *session) {
|
|||
}
|
||||
mSessions.erase(session);
|
||||
}
|
||||
|
||||
void PowerSessionManager::setUclampMin(PowerHintSession *session, int val) {
|
||||
std::lock_guard<std::mutex> guard(mLock);
|
||||
setUclampMinLocked(session, val);
|
||||
}
|
||||
|
||||
void PowerSessionManager::setUclampMinLocked(PowerHintSession *session, int val) {
|
||||
for (auto t : session->getTidList()) {
|
||||
// Get thex max uclamp.min across sessions which include the tid.
|
||||
|
@ -169,7 +142,6 @@ void PowerSessionManager::setUclampMinLocked(PowerHintSession *session, int val)
|
|||
set_uclamp_min(t, std::max(val, tidMax));
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<bool> PowerSessionManager::isAnyAppSessionActive() {
|
||||
std::lock_guard<std::mutex> guard(mLock);
|
||||
bool active = false;
|
||||
|
@ -185,10 +157,8 @@ std::optional<bool> PowerSessionManager::isAnyAppSessionActive() {
|
|||
} else {
|
||||
mActive = active;
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
void PowerSessionManager::handleMessage(const Message &) {
|
||||
auto active = isAnyAppSessionActive();
|
||||
if (!active.has_value()) {
|
||||
|
@ -200,11 +170,6 @@ void PowerSessionManager::handleMessage(const Message &) {
|
|||
enableSystemTopAppBoost();
|
||||
}
|
||||
}
|
||||
|
||||
void PowerSessionManager::WakeupHandler::handleMessage(const Message &) {
|
||||
PowerSessionManager::getInstance()->wakeSessions();
|
||||
}
|
||||
|
||||
void PowerSessionManager::dumpToFd(int fd) {
|
||||
std::ostringstream dump_buf;
|
||||
std::lock_guard<std::mutex> guard(mLock);
|
||||
|
@ -226,39 +191,33 @@ void PowerSessionManager::dumpToFd(int fd) {
|
|||
ALOGE("Failed to dump one of session list to fd:%d", fd);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerSessionManager::enableSystemTopAppBoost() {
|
||||
if (HintManager::GetInstance()->IsHintSupported(kDisableBoostHintName)) {
|
||||
ALOGV("PowerSessionManager::enableSystemTopAppBoost!!");
|
||||
HintManager::GetInstance()->EndHint(kDisableBoostHintName);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerSessionManager::disableSystemTopAppBoost() {
|
||||
if (HintManager::GetInstance()->IsHintSupported(kDisableBoostHintName)) {
|
||||
ALOGV("PowerSessionManager::disableSystemTopAppBoost!!");
|
||||
HintManager::GetInstance()->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
|
|
@ -13,34 +13,26 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <android-base/properties.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
#include <utils/Looper.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "PowerHintSession.h"
|
||||
|
||||
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
|
||||
|
@ -54,31 +46,19 @@ class PowerSessionManager : public MessageHandler {
|
|||
void setUclampMinLocked(PowerHintSession *session, int min);
|
||||
void handleMessage(const Message &message) override;
|
||||
void dumpToFd(int fd);
|
||||
|
||||
// Singleton
|
||||
static sp<PowerSessionManager> getInstance() {
|
||||
static sp<PowerSessionManager> instance = new PowerSessionManager();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private:
|
||||
class WakeupHandler : public MessageHandler {
|
||||
public:
|
||||
WakeupHandler() {}
|
||||
void handleMessage(const Message &message) override;
|
||||
};
|
||||
|
||||
private:
|
||||
void wakeSessions();
|
||||
std::optional<bool> isAnyAppSessionActive();
|
||||
void disableSystemTopAppBoost();
|
||||
void enableSystemTopAppBoost();
|
||||
const std::string kDisableBoostHintName;
|
||||
|
||||
std::unordered_set<PowerHintSession *> mSessions; // protected by mLock
|
||||
std::unordered_map<int, int> mTidRefCountMap; // protected by mLock
|
||||
std::unordered_map<int, std::unordered_set<PowerHintSession *>> mTidSessionListMap;
|
||||
sp<WakeupHandler> mWakeupHandler;
|
||||
bool mActive; // protected by mLock
|
||||
/**
|
||||
* mLock to pretect the above data objects opertions.
|
||||
|
@ -90,13 +70,10 @@ class PowerSessionManager : public MessageHandler {
|
|||
: kDisableBoostHintName(::android::base::GetProperty(kPowerHalAdpfDisableTopAppBoost,
|
||||
"ADPF_DISABLE_TA_BOOST")),
|
||||
mActive(false),
|
||||
mDisplayRefreshRate(60) {
|
||||
mWakeupHandler = sp<WakeupHandler>(new WakeupHandler());
|
||||
}
|
||||
mDisplayRefreshRate(60) {}
|
||||
PowerSessionManager(PowerSessionManager const &) = delete;
|
||||
void operator=(PowerSessionManager const &) = delete;
|
||||
};
|
||||
|
||||
class PowerHintMonitor : public Thread {
|
||||
public:
|
||||
void start();
|
||||
|
@ -109,13 +86,11 @@ class PowerHintMonitor : public Thread {
|
|||
}
|
||||
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
|
|
@ -1,233 +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 "powerhal-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "AdaptiveCpu.h"
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
#include <sys/resource.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <deque>
|
||||
#include <numeric>
|
||||
|
||||
#include "CpuLoadReaderSysDevices.h"
|
||||
#include "Model.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
// We pass the previous N ModelInputs to the model, including the most recent ModelInput.
|
||||
constexpr uint32_t kNumHistoricalModelInputs = 3;
|
||||
|
||||
// TODO(b/207662659): Add config for changing between different reader types.
|
||||
AdaptiveCpu::AdaptiveCpu() {}
|
||||
|
||||
bool AdaptiveCpu::IsEnabled() const {
|
||||
return mIsEnabled;
|
||||
}
|
||||
|
||||
void AdaptiveCpu::HintReceived(bool enable) {
|
||||
ATRACE_CALL();
|
||||
LOG(INFO) << "AdaptiveCpu received hint: enable=" << enable;
|
||||
if (enable) {
|
||||
StartThread();
|
||||
} else {
|
||||
SuspendThread();
|
||||
}
|
||||
}
|
||||
|
||||
void AdaptiveCpu::StartThread() {
|
||||
ATRACE_CALL();
|
||||
std::lock_guard lock(mThreadCreationMutex);
|
||||
LOG(INFO) << "Starting AdaptiveCpu thread";
|
||||
mIsEnabled = true;
|
||||
mShouldReloadConfig = true;
|
||||
mLastEnabledHintTime = mTimeSource.GetTime();
|
||||
if (!mLoopThread.joinable()) {
|
||||
mLoopThread = std::thread([&]() {
|
||||
pthread_setname_np(pthread_self(), "AdaptiveCpu");
|
||||
// Parent threads may have higher priorities, so we reset to the default.
|
||||
int ret = setpriority(PRIO_PROCESS, 0, 0);
|
||||
if (ret != 0) {
|
||||
PLOG(ERROR) << "setpriority on AdaptiveCpu thread failed: " << ret;
|
||||
}
|
||||
LOG(INFO) << "Started AdaptiveCpu thread successfully";
|
||||
RunMainLoop();
|
||||
LOG(ERROR) << "AdaptiveCpu thread ended, this should never happen!";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void AdaptiveCpu::SuspendThread() {
|
||||
ATRACE_CALL();
|
||||
LOG(INFO) << "Stopping AdaptiveCpu thread";
|
||||
// This stops the thread from receiving work durations in ReportWorkDurations, which means the
|
||||
// thread blocks indefinitely.
|
||||
mIsEnabled = false;
|
||||
}
|
||||
|
||||
void AdaptiveCpu::ReportWorkDurations(const std::vector<WorkDuration> &workDurations,
|
||||
std::chrono::nanoseconds targetDuration) {
|
||||
ATRACE_CALL();
|
||||
if (!mIsEnabled) {
|
||||
return;
|
||||
}
|
||||
if (!mWorkDurationProcessor.ReportWorkDurations(workDurations, targetDuration)) {
|
||||
mIsEnabled = false;
|
||||
return;
|
||||
}
|
||||
mWorkDurationsAvailableCondition.notify_one();
|
||||
}
|
||||
|
||||
void AdaptiveCpu::WaitForEnabledAndWorkDurations() {
|
||||
ATRACE_CALL();
|
||||
std::unique_lock<std::mutex> lock(mWaitMutex);
|
||||
// TODO(b/188770301) Once the gating logic is implemented, don't block indefinitely.
|
||||
mWorkDurationsAvailableCondition.wait(
|
||||
lock, [&] { return mIsEnabled && mWorkDurationProcessor.HasWorkDurations(); });
|
||||
}
|
||||
|
||||
void AdaptiveCpu::RunMainLoop() {
|
||||
ATRACE_CALL();
|
||||
|
||||
std::deque<ModelInput> historicalModelInputs;
|
||||
ThrottleDecision previousThrottleDecision = ThrottleDecision::NO_THROTTLE;
|
||||
while (true) {
|
||||
ATRACE_NAME("loop");
|
||||
WaitForEnabledAndWorkDurations();
|
||||
|
||||
if (mLastEnabledHintTime + mConfig.enabledHintTimeout < mTimeSource.GetTime()) {
|
||||
LOG(INFO) << "Adaptive CPU hint timed out, last enabled time="
|
||||
<< mLastEnabledHintTime.count() << "ns";
|
||||
mIsEnabled = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mShouldReloadConfig) {
|
||||
if (!AdaptiveCpuConfig::ReadFromSystemProperties(&mConfig)) {
|
||||
mIsEnabled = false;
|
||||
continue;
|
||||
}
|
||||
LOG(INFO) << "Read config: " << mConfig;
|
||||
mShouldReloadConfig = false;
|
||||
}
|
||||
|
||||
ATRACE_BEGIN("compute");
|
||||
mAdaptiveCpuStats.RegisterStartRun();
|
||||
|
||||
if (!mIsInitialized) {
|
||||
if (!mKernelCpuFeatureReader.Init()) {
|
||||
mIsEnabled = false;
|
||||
continue;
|
||||
}
|
||||
mDevice = ReadDevice();
|
||||
mIsInitialized = true;
|
||||
}
|
||||
|
||||
ModelInput modelInput;
|
||||
modelInput.previousThrottleDecision = previousThrottleDecision;
|
||||
|
||||
modelInput.workDurationFeatures = mWorkDurationProcessor.GetFeatures();
|
||||
LOG(VERBOSE) << "Got work durations: count=" << modelInput.workDurationFeatures.numDurations
|
||||
<< ", average=" << modelInput.workDurationFeatures.averageDuration.count()
|
||||
<< "ns";
|
||||
if (modelInput.workDurationFeatures.numDurations == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mKernelCpuFeatureReader.GetRecentCpuFeatures(&modelInput.cpuPolicyAverageFrequencyHz,
|
||||
&modelInput.cpuCoreIdleTimesPercentage)) {
|
||||
mIsEnabled = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
modelInput.LogToAtrace();
|
||||
historicalModelInputs.push_back(modelInput);
|
||||
if (historicalModelInputs.size() > kNumHistoricalModelInputs) {
|
||||
historicalModelInputs.pop_front();
|
||||
}
|
||||
|
||||
const ThrottleDecision throttleDecision = mModel.Run(historicalModelInputs, mConfig);
|
||||
LOG(VERBOSE) << "Model decision: " << static_cast<uint32_t>(throttleDecision);
|
||||
ATRACE_INT("AdaptiveCpu_throttleDecision", static_cast<uint32_t>(throttleDecision));
|
||||
|
||||
{
|
||||
ATRACE_NAME("sendHints");
|
||||
const auto now = mTimeSource.GetTime();
|
||||
// Resend the throttle hints, even if they've not changed, if the previous send is close
|
||||
// to timing out. We define "close to" as half the hint timeout, as we can't guarantee
|
||||
// we will run again before the actual timeout.
|
||||
const bool throttleHintMayTimeout =
|
||||
now - mLastThrottleHintTime > mConfig.hintTimeout / 2;
|
||||
if (throttleDecision != previousThrottleDecision || throttleHintMayTimeout) {
|
||||
ATRACE_NAME("sendNewHints");
|
||||
mLastThrottleHintTime = now;
|
||||
for (const auto &hintName : THROTTLE_DECISION_TO_HINT_NAMES.at(throttleDecision)) {
|
||||
HintManager::GetInstance()->DoHint(hintName, mConfig.hintTimeout);
|
||||
}
|
||||
}
|
||||
if (throttleDecision != previousThrottleDecision) {
|
||||
ATRACE_NAME("endOldHints");
|
||||
for (const auto &hintName :
|
||||
THROTTLE_DECISION_TO_HINT_NAMES.at(previousThrottleDecision)) {
|
||||
HintManager::GetInstance()->EndHint(hintName);
|
||||
}
|
||||
previousThrottleDecision = throttleDecision;
|
||||
}
|
||||
}
|
||||
|
||||
mAdaptiveCpuStats.RegisterSuccessfulRun(previousThrottleDecision, throttleDecision,
|
||||
modelInput.workDurationFeatures, mConfig);
|
||||
ATRACE_END(); // compute
|
||||
{
|
||||
ATRACE_NAME("sleep");
|
||||
std::this_thread::sleep_for(mConfig.iterationSleepDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AdaptiveCpu::DumpToFd(int fd) const {
|
||||
std::stringstream result;
|
||||
result << "========== Begin Adaptive CPU stats ==========\n";
|
||||
result << "Enabled: " << mIsEnabled << "\n";
|
||||
result << "Config: " << mConfig << "\n";
|
||||
mKernelCpuFeatureReader.DumpToStream(result);
|
||||
mAdaptiveCpuStats.DumpToStream(result);
|
||||
result << "========== End Adaptive CPU stats ==========\n";
|
||||
if (!::android::base::WriteStringToFd(result.str(), fd)) {
|
||||
PLOG(ERROR) << "Failed to dump state to fd";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,112 +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 <aidl/android/hardware/power/WorkDuration.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "AdaptiveCpuConfig.h"
|
||||
#include "AdaptiveCpuStats.h"
|
||||
#include "Device.h"
|
||||
#include "KernelCpuFeatureReader.h"
|
||||
#include "Model.h"
|
||||
#include "WorkDurationProcessor.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using std::chrono_literals::operator""ms;
|
||||
using ::aidl::android::hardware::power::WorkDuration;
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
// Applies CPU frequency hints infered by an ML model based on the recent CPU statistics and work
|
||||
// durations.
|
||||
// This class's public members are not synchronised and should not be used from multiple threads,
|
||||
// with the exception of ReportWorkDuration, which can be called from an arbitrary thread.
|
||||
class AdaptiveCpu {
|
||||
public:
|
||||
AdaptiveCpu();
|
||||
|
||||
bool IsEnabled() const;
|
||||
|
||||
// Called when the Adaptive CPU hint is received. This method enables/disables the Adaptive CPU
|
||||
// thread.
|
||||
void HintReceived(bool enable);
|
||||
|
||||
// Reports work durations for processing. This method returns immediately as work durations are
|
||||
// processed asynchonuously.
|
||||
void ReportWorkDurations(const std::vector<WorkDuration> &workDurations,
|
||||
std::chrono::nanoseconds targetDuration);
|
||||
|
||||
// Dump info to a file descriptor. Called when dumping service info.
|
||||
void DumpToFd(int fd) const;
|
||||
|
||||
// When PowerExt receives a hint with this name, HintReceived() is called.
|
||||
static constexpr char HINT_NAME[] = "ADAPTIVE_CPU";
|
||||
|
||||
private:
|
||||
void StartThread();
|
||||
|
||||
void SuspendThread();
|
||||
|
||||
// The main loop of Adaptive CPU, which runs in a separate thread.
|
||||
void RunMainLoop();
|
||||
|
||||
void WaitForEnabledAndWorkDurations();
|
||||
|
||||
Model mModel;
|
||||
WorkDurationProcessor mWorkDurationProcessor;
|
||||
KernelCpuFeatureReader mKernelCpuFeatureReader;
|
||||
AdaptiveCpuStats mAdaptiveCpuStats;
|
||||
const TimeSource mTimeSource;
|
||||
|
||||
// The thread in which work durations are processed.
|
||||
std::thread mLoopThread;
|
||||
|
||||
// Guards against creating multiple threads in the case HintReceived(true) is called on separate
|
||||
// threads simultaneously.
|
||||
std::mutex mThreadCreationMutex;
|
||||
// Used when waiting in WaitForEnabledAndWorkDurations().
|
||||
std::mutex mWaitMutex;
|
||||
|
||||
// A condition variable that will be notified when new work durations arrive.
|
||||
std::condition_variable mWorkDurationsAvailableCondition;
|
||||
|
||||
volatile bool mIsEnabled = false;
|
||||
bool mIsInitialized = false;
|
||||
volatile bool mShouldReloadConfig = false;
|
||||
std::chrono::nanoseconds mLastEnabledHintTime;
|
||||
std::chrono::nanoseconds mLastThrottleHintTime;
|
||||
Device mDevice;
|
||||
AdaptiveCpuConfig mConfig = AdaptiveCpuConfig::DEFAULT;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "AdaptiveCpuConfig.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <inttypes.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using std::chrono_literals::operator""ms;
|
||||
using std::chrono_literals::operator""min;
|
||||
|
||||
constexpr std::string_view kIterationSleepDurationProperty(
|
||||
"debug.adaptivecpu.iteration_sleep_duration_ms");
|
||||
static const std::chrono::milliseconds kIterationSleepDurationMin = 20ms;
|
||||
constexpr std::string_view kHintTimeoutProperty("debug.adaptivecpu.hint_timeout_ms");
|
||||
// "percent" as range is 0-100, while the in-memory is "probability" as range is 0-1.
|
||||
constexpr std::string_view kRandomThrottleDecisionPercentProperty(
|
||||
"debug.adaptivecpu.random_throttle_decision_percent");
|
||||
constexpr std::string_view kRandomThrottleOptionsProperty(
|
||||
"debug.adaptivecpu.random_throttle_options");
|
||||
constexpr std::string_view kEnabledHintTimeoutProperty("debug.adaptivecpu.enabled_hint_timeout_ms");
|
||||
|
||||
bool ParseThrottleDecisions(const std::string &input, std::vector<ThrottleDecision> *output);
|
||||
std::string FormatThrottleDecisions(const std::vector<ThrottleDecision> &throttleDecisions);
|
||||
|
||||
const AdaptiveCpuConfig AdaptiveCpuConfig::DEFAULT{
|
||||
// N.B.: The model will typically be trained with this value set to 25ms. We set it to 1s as
|
||||
// a safety measure, but best performance will be seen at 25ms.
|
||||
.iterationSleepDuration = 1000ms,
|
||||
.hintTimeout = 2000ms,
|
||||
.randomThrottleDecisionProbability = 0,
|
||||
.randomThrottleOptions = {ThrottleDecision::NO_THROTTLE, ThrottleDecision::THROTTLE_50,
|
||||
ThrottleDecision::THROTTLE_60, ThrottleDecision::THROTTLE_70,
|
||||
ThrottleDecision::THROTTLE_80, ThrottleDecision::THROTTLE_90},
|
||||
.enabledHintTimeout = 120min,
|
||||
};
|
||||
|
||||
bool AdaptiveCpuConfig::ReadFromSystemProperties(AdaptiveCpuConfig *output) {
|
||||
ATRACE_CALL();
|
||||
|
||||
output->iterationSleepDuration = std::chrono::milliseconds(
|
||||
::android::base::GetUintProperty<uint32_t>(kIterationSleepDurationProperty.data(),
|
||||
DEFAULT.iterationSleepDuration.count()));
|
||||
output->iterationSleepDuration =
|
||||
std::max(output->iterationSleepDuration, kIterationSleepDurationMin);
|
||||
|
||||
output->hintTimeout = std::chrono::milliseconds(::android::base::GetUintProperty<uint32_t>(
|
||||
kHintTimeoutProperty.data(), DEFAULT.hintTimeout.count()));
|
||||
|
||||
output->randomThrottleDecisionProbability =
|
||||
static_cast<double>(::android::base::GetUintProperty<uint32_t>(
|
||||
kRandomThrottleDecisionPercentProperty.data(),
|
||||
DEFAULT.randomThrottleDecisionProbability * 100)) /
|
||||
100;
|
||||
if (output->randomThrottleDecisionProbability > 1.0) {
|
||||
LOG(ERROR) << "Received bad value for " << kRandomThrottleDecisionPercentProperty << ": "
|
||||
<< output->randomThrottleDecisionProbability;
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string randomThrottleOptionsStr =
|
||||
::android::base::GetProperty(kRandomThrottleOptionsProperty.data(),
|
||||
FormatThrottleDecisions(DEFAULT.randomThrottleOptions));
|
||||
output->randomThrottleOptions.clear();
|
||||
if (!ParseThrottleDecisions(randomThrottleOptionsStr, &output->randomThrottleOptions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
output->enabledHintTimeout =
|
||||
std::chrono::milliseconds(::android::base::GetUintProperty<uint32_t>(
|
||||
kEnabledHintTimeoutProperty.data(), DEFAULT.enabledHintTimeout.count()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AdaptiveCpuConfig::operator==(const AdaptiveCpuConfig &other) const {
|
||||
return iterationSleepDuration == other.iterationSleepDuration &&
|
||||
hintTimeout == other.hintTimeout &&
|
||||
randomThrottleDecisionProbability == other.randomThrottleDecisionProbability &&
|
||||
enabledHintTimeout == other.enabledHintTimeout &&
|
||||
randomThrottleOptions == other.randomThrottleOptions;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const AdaptiveCpuConfig &config) {
|
||||
stream << "AdaptiveCpuConfig(";
|
||||
stream << "iterationSleepDuration=" << config.iterationSleepDuration.count() << "ms, ";
|
||||
stream << "hintTimeout=" << config.hintTimeout.count() << "ms, ";
|
||||
stream << "randomThrottleDecisionProbability=" << config.randomThrottleDecisionProbability
|
||||
<< ", ";
|
||||
stream << "enabledHintTimeout=" << config.enabledHintTimeout.count() << "ms, ";
|
||||
stream << "randomThrottleOptions=[" << FormatThrottleDecisions(config.randomThrottleOptions)
|
||||
<< "]";
|
||||
stream << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
bool ParseThrottleDecisions(const std::string &input, std::vector<ThrottleDecision> *output) {
|
||||
std::stringstream ss(input);
|
||||
while (ss.good()) {
|
||||
std::string throttleDecisionStr;
|
||||
if (std::getline(ss, throttleDecisionStr, ',').fail()) {
|
||||
LOG(ERROR) << "Failed to getline on throttle decisions string: " << input;
|
||||
return false;
|
||||
}
|
||||
uint32_t throttleDecisionInt;
|
||||
int scanEnd;
|
||||
if (std::sscanf(throttleDecisionStr.c_str(), "%" PRIu32 "%n", &throttleDecisionInt,
|
||||
&scanEnd) != 1 ||
|
||||
scanEnd != throttleDecisionStr.size()) {
|
||||
LOG(ERROR) << "Failed to parse as int: str=" << throttleDecisionStr
|
||||
<< ", input=" << input << ", scanEnd=" << scanEnd;
|
||||
return false;
|
||||
}
|
||||
if (throttleDecisionInt < static_cast<uint32_t>(ThrottleDecision::FIRST) ||
|
||||
throttleDecisionInt > static_cast<uint32_t>(ThrottleDecision::LAST)) {
|
||||
LOG(ERROR) << "Failed to parse throttle decision: throttleDecision="
|
||||
<< throttleDecisionInt << ", input=" << input;
|
||||
return false;
|
||||
}
|
||||
output->push_back(static_cast<ThrottleDecision>(throttleDecisionInt));
|
||||
}
|
||||
if (output->empty()) {
|
||||
LOG(ERROR) << "Failed to find any throttle decisions, must have at least one: " << input;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string FormatThrottleDecisions(const std::vector<ThrottleDecision> &throttleDecisions) {
|
||||
std::stringstream ss;
|
||||
for (size_t i = 0; i < throttleDecisions.size(); i++) {
|
||||
ss << static_cast<uint32_t>(throttleDecisions[i]);
|
||||
if (i < throttleDecisions.size() - 1) {
|
||||
ss << ",";
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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 <chrono>
|
||||
#include <iostream>
|
||||
|
||||
#include "ThrottleDecision.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
struct AdaptiveCpuConfig {
|
||||
static bool ReadFromSystemProperties(AdaptiveCpuConfig *output);
|
||||
static const AdaptiveCpuConfig DEFAULT;
|
||||
|
||||
// How long to sleep for between Adaptive CPU runs.
|
||||
std::chrono::milliseconds iterationSleepDuration;
|
||||
// Timeout applied to hints. If Adaptive CPU doesn't receive any frames in this time, CPU
|
||||
// throttling hints are cancelled.
|
||||
std::chrono::milliseconds hintTimeout;
|
||||
// Instead of throttling based on model output, choose a random throttle X% of the time. Must be
|
||||
// between 0 and 1 inclusive.
|
||||
double randomThrottleDecisionProbability;
|
||||
std::vector<ThrottleDecision> randomThrottleOptions;
|
||||
// Setting AdaptiveCpu to enabled only lasts this long. For a continuous run, AdaptiveCpu needs
|
||||
// to receive the enabled hint more frequently than this value.
|
||||
std::chrono::milliseconds enabledHintTimeout;
|
||||
|
||||
bool operator==(const AdaptiveCpuConfig &other) const;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const AdaptiveCpuConfig &config);
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,131 +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 "powerhal-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "AdaptiveCpuStats.h"
|
||||
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include "AdaptiveCpu.h"
|
||||
|
||||
using std::chrono_literals::operator""ns;
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
void AdaptiveCpuStats::RegisterStartRun() {
|
||||
ATRACE_CALL();
|
||||
mNumStartedRuns++;
|
||||
mLastRunStartTime = mTimeSource->GetTime();
|
||||
if (mStartTime == 0ns) {
|
||||
mStartTime = mLastRunStartTime;
|
||||
}
|
||||
}
|
||||
|
||||
void AdaptiveCpuStats::RegisterSuccessfulRun(ThrottleDecision previousThrottleDecision,
|
||||
ThrottleDecision throttleDecision,
|
||||
WorkDurationFeatures workDurationFeatures,
|
||||
const AdaptiveCpuConfig &config) {
|
||||
ATRACE_CALL();
|
||||
mNumSuccessfulRuns++;
|
||||
mNumThrottles[throttleDecision]++;
|
||||
const auto runSuccessTime = mTimeSource->GetTime();
|
||||
mTotalRunDuration += runSuccessTime - mLastRunStartTime;
|
||||
// Don't update previousThrottleDecision entries if we haven't run successfully before.
|
||||
if (mLastRunSuccessTime != 0ns) {
|
||||
mThrottleDurations[previousThrottleDecision] +=
|
||||
std::min(runSuccessTime - mLastRunSuccessTime,
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(config.hintTimeout));
|
||||
mNumDurations[previousThrottleDecision] += workDurationFeatures.numDurations;
|
||||
mNumMissedDeadlines[previousThrottleDecision] += workDurationFeatures.numMissedDeadlines;
|
||||
}
|
||||
mLastRunSuccessTime = runSuccessTime;
|
||||
}
|
||||
|
||||
void AdaptiveCpuStats::DumpToStream(std::ostream &stream) const {
|
||||
stream << "Stats:\n";
|
||||
stream << "- Successful runs / total runs: " << mNumSuccessfulRuns << " / " << mNumStartedRuns
|
||||
<< "\n";
|
||||
stream << "- Total run duration: " << FormatDuration(mTotalRunDuration) << "\n";
|
||||
stream << "- Average run duration: " << FormatDuration(mTotalRunDuration / mNumSuccessfulRuns)
|
||||
<< "\n";
|
||||
stream << "- Running time fraction: "
|
||||
<< static_cast<double>(mTotalRunDuration.count()) /
|
||||
(mTimeSource->GetTime() - mStartTime).count()
|
||||
<< "\n";
|
||||
|
||||
stream << "- Number of throttles:\n";
|
||||
size_t totalNumThrottles = 0;
|
||||
for (const auto &[throttleDecision, numThrottles] : mNumThrottles) {
|
||||
stream << " - " << ThrottleString(throttleDecision) << ": " << numThrottles << "\n";
|
||||
totalNumThrottles += numThrottles;
|
||||
}
|
||||
stream << " - Total: " << totalNumThrottles << "\n";
|
||||
|
||||
stream << "- Time spent throttling:\n";
|
||||
std::chrono::nanoseconds totalThrottleDuration;
|
||||
for (const auto &[throttleDecision, throttleDuration] : mThrottleDurations) {
|
||||
stream << " - " << ThrottleString(throttleDecision) << ": "
|
||||
<< FormatDuration(throttleDuration) << "\n";
|
||||
totalThrottleDuration += throttleDuration;
|
||||
}
|
||||
stream << " - Total: " << FormatDuration(totalThrottleDuration) << "\n";
|
||||
|
||||
stream << "- Missed deadlines per throttle:\n";
|
||||
size_t totalNumDurations = 0;
|
||||
size_t totalNumMissedDeadlines = 0;
|
||||
for (const auto &[throttleDecision, numDurations] : mNumDurations) {
|
||||
const size_t numMissedDeadlines = mNumMissedDeadlines.at(throttleDecision);
|
||||
stream << " - " << ThrottleString(throttleDecision) << ": " << numMissedDeadlines << " / "
|
||||
<< numDurations << " (" << static_cast<double>(numMissedDeadlines) / numDurations
|
||||
<< ")\n";
|
||||
totalNumDurations += numDurations;
|
||||
totalNumMissedDeadlines += numMissedDeadlines;
|
||||
}
|
||||
stream << " - Total: " << totalNumMissedDeadlines << " / " << totalNumDurations << " ("
|
||||
<< static_cast<double>(totalNumMissedDeadlines) / totalNumDurations << ")\n";
|
||||
}
|
||||
|
||||
std::string AdaptiveCpuStats::FormatDuration(std::chrono::nanoseconds duration) {
|
||||
double count = static_cast<double>(duration.count());
|
||||
std::string suffix;
|
||||
if (count < 1000.0) {
|
||||
suffix = "ns";
|
||||
} else if (count < 1000.0 * 1000) {
|
||||
suffix = "us";
|
||||
count /= 1000;
|
||||
} else if (count < 1000.0 * 1000 * 100) {
|
||||
suffix = "ms";
|
||||
count /= 1000 * 1000;
|
||||
} else {
|
||||
suffix = "s";
|
||||
count /= 1000 * 1000 * 1000;
|
||||
}
|
||||
return std::to_string(count) + suffix;
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,73 +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 <ostream>
|
||||
|
||||
#include "AdaptiveCpuConfig.h"
|
||||
#include "ITimeSource.h"
|
||||
#include "Model.h"
|
||||
#include "TimeSource.h"
|
||||
#include "WorkDurationProcessor.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
// Collects statistics about Adaptive CPU.
|
||||
// These are only Used during a dumpsys to improve bug report quality.
|
||||
class AdaptiveCpuStats {
|
||||
public:
|
||||
AdaptiveCpuStats() : mTimeSource(std::make_unique<TimeSource>()) {}
|
||||
AdaptiveCpuStats(std::unique_ptr<ITimeSource> timeSource)
|
||||
: mTimeSource(std::move(timeSource)) {}
|
||||
|
||||
void RegisterStartRun();
|
||||
void RegisterSuccessfulRun(ThrottleDecision previousThrottleDecision,
|
||||
ThrottleDecision throttleDecision,
|
||||
WorkDurationFeatures workDurationFeatures,
|
||||
const AdaptiveCpuConfig &config);
|
||||
void DumpToStream(std::ostream &stream) const;
|
||||
|
||||
private:
|
||||
const std::unique_ptr<ITimeSource> mTimeSource;
|
||||
|
||||
size_t mNumStartedRuns = 0;
|
||||
size_t mNumSuccessfulRuns = 0;
|
||||
std::chrono::nanoseconds mStartTime;
|
||||
std::chrono::nanoseconds mLastRunStartTime;
|
||||
std::chrono::nanoseconds mLastRunSuccessTime;
|
||||
std::chrono::nanoseconds mTotalRunDuration;
|
||||
|
||||
std::map<ThrottleDecision, size_t> mNumThrottles;
|
||||
std::map<ThrottleDecision, std::chrono::nanoseconds> mThrottleDurations;
|
||||
|
||||
std::map<ThrottleDecision, size_t> mNumDurations;
|
||||
std::map<ThrottleDecision, size_t> mNumMissedDeadlines;
|
||||
|
||||
static std::string FormatDuration(std::chrono::nanoseconds duration);
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,149 +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 "powerhal-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "CpuFrequencyReader.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <inttypes.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
using std::chrono_literals::operator""ms;
|
||||
|
||||
constexpr std::string_view kCpuPolicyDirectory("/sys/devices/system/cpu/cpufreq");
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
bool CpuFrequencyReader::Init() {
|
||||
ATRACE_CALL();
|
||||
mCpuPolicyIds.clear();
|
||||
if (!ReadCpuPolicyIds(&mCpuPolicyIds)) {
|
||||
return false;
|
||||
}
|
||||
mPreviousCpuPolicyFrequencies.clear();
|
||||
return ReadCpuPolicyFrequencies(&mPreviousCpuPolicyFrequencies);
|
||||
}
|
||||
|
||||
bool CpuFrequencyReader::GetRecentCpuPolicyFrequencies(
|
||||
std::vector<CpuPolicyAverageFrequency> *result) {
|
||||
ATRACE_CALL();
|
||||
std::map<uint32_t, std::map<uint64_t, std::chrono::milliseconds>> cpuPolicyFrequencies;
|
||||
if (!ReadCpuPolicyFrequencies(&cpuPolicyFrequencies)) {
|
||||
return false;
|
||||
}
|
||||
for (const auto &[policyId, cpuFrequencies] : cpuPolicyFrequencies) {
|
||||
const auto &previousCpuFrequencies = mPreviousCpuPolicyFrequencies.find(policyId);
|
||||
if (previousCpuFrequencies == mPreviousCpuPolicyFrequencies.end()) {
|
||||
LOG(ERROR) << "Couldn't find policy " << policyId << " in previous frequencies";
|
||||
return false;
|
||||
}
|
||||
uint64_t weightedFrequenciesSumHz = 0;
|
||||
std::chrono::milliseconds timeSum = 0ms;
|
||||
for (const auto &[frequencyHz, time] : cpuFrequencies) {
|
||||
const auto &previousCpuFrequency = previousCpuFrequencies->second.find(frequencyHz);
|
||||
if (previousCpuFrequency == previousCpuFrequencies->second.end()) {
|
||||
LOG(ERROR) << "Couldn't find frequency " << frequencyHz
|
||||
<< " in previous frequencies";
|
||||
return false;
|
||||
}
|
||||
const std::chrono::milliseconds recentTime = time - previousCpuFrequency->second;
|
||||
weightedFrequenciesSumHz += frequencyHz * recentTime.count();
|
||||
timeSum += recentTime;
|
||||
}
|
||||
const uint64_t averageFrequencyHz =
|
||||
timeSum != 0ms ? weightedFrequenciesSumHz / timeSum.count() : 0;
|
||||
result->push_back({.policyId = policyId, .averageFrequencyHz = averageFrequencyHz});
|
||||
}
|
||||
mPreviousCpuPolicyFrequencies = cpuPolicyFrequencies;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<uint32_t, std::map<uint64_t, std::chrono::milliseconds>>
|
||||
CpuFrequencyReader::GetPreviousCpuPolicyFrequencies() const {
|
||||
return mPreviousCpuPolicyFrequencies;
|
||||
}
|
||||
|
||||
bool CpuFrequencyReader::ReadCpuPolicyFrequencies(
|
||||
std::map<uint32_t, std::map<uint64_t, std::chrono::milliseconds>> *result) {
|
||||
ATRACE_CALL();
|
||||
for (const uint32_t cpuPolicyId : mCpuPolicyIds) {
|
||||
std::stringstream timeInStatePath;
|
||||
timeInStatePath << "/sys/devices/system/cpu/cpufreq/policy" << cpuPolicyId
|
||||
<< "/stats/time_in_state";
|
||||
std::unique_ptr<std::istream> timeInStateFile;
|
||||
if (!mFilesystem->ReadFileStream(timeInStatePath.str(), &timeInStateFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<uint64_t, std::chrono::milliseconds> cpuFrequencies;
|
||||
std::string timeInStateLine;
|
||||
while (std::getline(*timeInStateFile, timeInStateLine)) {
|
||||
// Time format in time_in_state is 10s of milliseconds:
|
||||
// https://www.kernel.org/doc/Documentation/cpu-freq/cpufreq-stats.txt
|
||||
uint64_t frequencyHz, time10Ms;
|
||||
if (std::sscanf(timeInStateLine.c_str(), "%" PRIu64 " %" PRIu64 "\n", &frequencyHz,
|
||||
&time10Ms) != 2) {
|
||||
LOG(ERROR) << "Failed to parse time_in_state line: " << timeInStateLine;
|
||||
return false;
|
||||
}
|
||||
cpuFrequencies[frequencyHz] = time10Ms * 10ms;
|
||||
}
|
||||
if (cpuFrequencies.size() > 500) {
|
||||
LOG(ERROR) << "Found " << cpuFrequencies.size() << " frequencies for policy "
|
||||
<< cpuPolicyId << ", aborting";
|
||||
return false;
|
||||
}
|
||||
(*result)[cpuPolicyId] = cpuFrequencies;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CpuFrequencyReader::ReadCpuPolicyIds(std::vector<uint32_t> *result) const {
|
||||
ATRACE_CALL();
|
||||
std::vector<std::string> entries;
|
||||
if (!mFilesystem->ListDirectory(kCpuPolicyDirectory.data(), &entries)) {
|
||||
return false;
|
||||
}
|
||||
for (const auto &entry : entries) {
|
||||
uint32_t cpuPolicyId;
|
||||
if (!sscanf(entry.c_str(), "policy%d", &cpuPolicyId)) {
|
||||
continue;
|
||||
}
|
||||
result->push_back(cpuPolicyId);
|
||||
}
|
||||
// Sort the list, so that getRecentCpuPolicyFrequencies always returns frequencies sorted by
|
||||
// policy ID.
|
||||
std::sort(result->begin(), result->end());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,91 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* 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 <chrono>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "IFilesystem.h"
|
||||
#include "RealFilesystem.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
struct CpuPolicyAverageFrequency {
|
||||
const uint32_t policyId;
|
||||
const uint64_t averageFrequencyHz;
|
||||
|
||||
bool operator==(const CpuPolicyAverageFrequency &other) const {
|
||||
return policyId == other.policyId && averageFrequencyHz == other.averageFrequencyHz;
|
||||
}
|
||||
};
|
||||
|
||||
class CpuFrequencyReader {
|
||||
public:
|
||||
CpuFrequencyReader() : mFilesystem(std::make_unique<RealFilesystem>()) {}
|
||||
CpuFrequencyReader(std::unique_ptr<IFilesystem> filesystem)
|
||||
: mFilesystem(std::move(filesystem)) {}
|
||||
|
||||
// Initialize reading, must be done before calling other methods.
|
||||
// Work is not done in constructor as it accesses files.
|
||||
// Returns true on success.
|
||||
bool Init();
|
||||
|
||||
// Gets the average frequency each CPU policy was using, since this method was last called.
|
||||
// Results are returned sorted by policyId.
|
||||
// Returns true on success.
|
||||
bool GetRecentCpuPolicyFrequencies(std::vector<CpuPolicyAverageFrequency> *result);
|
||||
|
||||
// The most recently read frequencies for each CPU policy. See readCpuPolicyFrequencies for type
|
||||
// explanation. Used for dumping to bug reports.
|
||||
std::map<uint32_t, std::map<uint64_t, std::chrono::milliseconds>>
|
||||
GetPreviousCpuPolicyFrequencies() const;
|
||||
|
||||
private:
|
||||
// CPU policy IDs read from /sys. Initialized in #init(). Sorted ascending.
|
||||
std::vector<uint32_t> mCpuPolicyIds;
|
||||
// The CPU frequencies when #getRecentCpuPolicyFrequencies was last called (or #init if it has
|
||||
// not been called yet).
|
||||
// See readCpuPolicyFrequencies for explanation of type.
|
||||
std::map<uint32_t, std::map<uint64_t, std::chrono::milliseconds>> mPreviousCpuPolicyFrequencies;
|
||||
const std::unique_ptr<IFilesystem> mFilesystem;
|
||||
|
||||
// Reads, from the /sys filesystem, the CPU frequencies used by each policy.
|
||||
// - The outer map's key is the CPU policy ID.
|
||||
// - The inner map's key is the CPU frequency in Hz.
|
||||
// - The inner map's value is the time the policy has been running at that frequency, aggregated
|
||||
// since boot.
|
||||
// Returns true on success.
|
||||
bool ReadCpuPolicyFrequencies(
|
||||
std::map<uint32_t, std::map<uint64_t, std::chrono::milliseconds>> *result);
|
||||
|
||||
bool ReadCpuPolicyIds(std::vector<uint32_t> *result) const;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,132 +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 "powerhal-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "CpuLoadReaderProcStat.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <inttypes.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
bool CpuLoadReaderProcStat::Init() {
|
||||
mPreviousCpuTimes.clear();
|
||||
return ReadCpuTimes(&mPreviousCpuTimes);
|
||||
}
|
||||
|
||||
bool CpuLoadReaderProcStat::GetRecentCpuLoads(
|
||||
std::array<double, NUM_CPU_CORES> *cpuCoreIdleTimesPercentage) {
|
||||
ATRACE_CALL();
|
||||
if (cpuCoreIdleTimesPercentage == nullptr) {
|
||||
LOG(ERROR) << "Got nullptr output in getRecentCpuLoads";
|
||||
return false;
|
||||
}
|
||||
std::map<uint32_t, CpuTime> cpuTimes;
|
||||
if (!ReadCpuTimes(&cpuTimes)) {
|
||||
return false;
|
||||
}
|
||||
if (cpuTimes.empty()) {
|
||||
LOG(ERROR) << "Failed to find any CPU times";
|
||||
return false;
|
||||
}
|
||||
for (const auto &[cpuId, cpuTime] : cpuTimes) {
|
||||
const auto previousCpuTime = mPreviousCpuTimes.find(cpuId);
|
||||
if (previousCpuTime == mPreviousCpuTimes.end()) {
|
||||
LOG(ERROR) << "Couldn't find CPU " << cpuId << " in previous CPU times";
|
||||
return false;
|
||||
}
|
||||
const auto recentIdleTimeMs = cpuTime.idleTimeMs - previousCpuTime->second.idleTimeMs;
|
||||
const auto recentTotalTimeMs = cpuTime.totalTimeMs - previousCpuTime->second.totalTimeMs;
|
||||
if (recentIdleTimeMs > recentTotalTimeMs) {
|
||||
LOG(ERROR) << "Found more recent idle time than total time: idle=" << recentIdleTimeMs
|
||||
<< ", total=" << recentTotalTimeMs;
|
||||
return false;
|
||||
}
|
||||
const double idleTimePercentage =
|
||||
static_cast<double>(recentIdleTimeMs) / (recentTotalTimeMs);
|
||||
LOG(VERBOSE) << "Read CPU idle time: cpuId=" << cpuId
|
||||
<< ", idleTimePercentage=" << idleTimePercentage;
|
||||
(*cpuCoreIdleTimesPercentage)[cpuId] = idleTimePercentage;
|
||||
}
|
||||
mPreviousCpuTimes = cpuTimes;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CpuLoadReaderProcStat::ReadCpuTimes(std::map<uint32_t, CpuTime> *result) {
|
||||
ATRACE_CALL();
|
||||
|
||||
std::unique_ptr<std::istream> file;
|
||||
if (!mFilesystem->ReadFileStream("/proc/stat", &file)) {
|
||||
return false;
|
||||
}
|
||||
std::string line;
|
||||
ATRACE_BEGIN("loop");
|
||||
while (std::getline(*file, line)) {
|
||||
ATRACE_NAME("parse");
|
||||
uint32_t cpuId;
|
||||
// Times reported when the CPU is active.
|
||||
uint64_t user, nice, system, irq, softIrq, steal, guest, guestNice;
|
||||
// Times reported when the CPU is idle.
|
||||
uint64_t idle, ioWait;
|
||||
// Order & values taken from `fs/proc/stat.c`.
|
||||
if (std::sscanf(line.c_str(),
|
||||
"cpu%d %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
|
||||
" %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " ",
|
||||
&cpuId, &user, &nice, &system, &idle, &ioWait, &irq, &softIrq, &steal,
|
||||
&guest, &guestNice) != 11) {
|
||||
continue;
|
||||
}
|
||||
uint64_t idleTimeJiffies = idle + ioWait;
|
||||
uint64_t totalTimeJiffies =
|
||||
user + nice + system + irq + softIrq + steal + guest + guestNice + idleTimeJiffies;
|
||||
(*result)[cpuId] = {.idleTimeMs = JiffiesToMs(idleTimeJiffies),
|
||||
.totalTimeMs = JiffiesToMs(totalTimeJiffies)};
|
||||
}
|
||||
ATRACE_END();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CpuLoadReaderProcStat::DumpToStream(std::stringstream &stream) const {
|
||||
stream << "CPU loads from /proc/stat:\n";
|
||||
for (const auto &[cpuId, cpuTime] : mPreviousCpuTimes) {
|
||||
stream << "- CPU=" << cpuId << ", idleTime=" << cpuTime.idleTimeMs
|
||||
<< "ms, totalTime=" << cpuTime.totalTimeMs << "ms\n";
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t CpuLoadReaderProcStat::JiffiesToMs(uint64_t jiffies) {
|
||||
return (jiffies * 1000) / sysconf(_SC_CLK_TCK);
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,63 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* 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 <map>
|
||||
|
||||
#include "ICpuLoadReader.h"
|
||||
#include "IFilesystem.h"
|
||||
#include "RealFilesystem.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
struct CpuTime {
|
||||
uint64_t idleTimeMs;
|
||||
uint64_t totalTimeMs;
|
||||
};
|
||||
|
||||
// Reads CPU idle stats from /proc/stat.
|
||||
class CpuLoadReaderProcStat : public ICpuLoadReader {
|
||||
public:
|
||||
CpuLoadReaderProcStat() : mFilesystem(std::make_unique<RealFilesystem>()) {}
|
||||
CpuLoadReaderProcStat(std::unique_ptr<IFilesystem> filesystem)
|
||||
: mFilesystem(std::move(filesystem)) {}
|
||||
|
||||
bool Init() override;
|
||||
bool GetRecentCpuLoads(std::array<double, NUM_CPU_CORES> *cpuCoreIdleTimesPercentage) override;
|
||||
void DumpToStream(std::stringstream &stream) const override;
|
||||
|
||||
private:
|
||||
std::map<uint32_t, CpuTime> mPreviousCpuTimes;
|
||||
const std::unique_ptr<IFilesystem> mFilesystem;
|
||||
|
||||
bool ReadCpuTimes(std::map<uint32_t, CpuTime> *result);
|
||||
// Converts jiffies to milliseconds. Jiffies is the granularity the kernel reports times in,
|
||||
// including the timings in CPU statistics.
|
||||
static uint64_t JiffiesToMs(uint64_t jiffies);
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,151 +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 "powerhal-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "CpuLoadReaderSysDevices.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <inttypes.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
std::chrono::nanoseconds getKernelTime() {
|
||||
timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return std::chrono::nanoseconds(ts.tv_sec * 1000000000UL + ts.tv_nsec);
|
||||
}
|
||||
|
||||
bool CpuLoadReaderSysDevices::Init() {
|
||||
mIdleStateNames.clear();
|
||||
if (!ReadIdleStateNames(&mIdleStateNames)) {
|
||||
return false;
|
||||
}
|
||||
return ReadCpuTimes(&mPreviousCpuTimes);
|
||||
}
|
||||
|
||||
bool CpuLoadReaderSysDevices::GetRecentCpuLoads(
|
||||
std::array<double, NUM_CPU_CORES> *cpuCoreIdleTimesPercentage) {
|
||||
ATRACE_CALL();
|
||||
if (cpuCoreIdleTimesPercentage == nullptr) {
|
||||
LOG(ERROR) << "Got nullptr output in getRecentCpuLoads";
|
||||
return false;
|
||||
}
|
||||
std::array<CpuTime, NUM_CPU_CORES> cpuTimes;
|
||||
if (!ReadCpuTimes(&cpuTimes)) {
|
||||
return false;
|
||||
}
|
||||
if (cpuTimes.empty()) {
|
||||
LOG(ERROR) << "Failed to find any CPU times";
|
||||
return false;
|
||||
}
|
||||
for (size_t cpuId = 0; cpuId < NUM_CPU_CORES; cpuId++) {
|
||||
const auto cpuTime = cpuTimes[cpuId];
|
||||
const auto previousCpuTime = mPreviousCpuTimes[cpuId];
|
||||
auto recentIdleTime = cpuTime.idleTime - previousCpuTime.idleTime;
|
||||
const auto recentTotalTime = cpuTime.totalTime - previousCpuTime.totalTime;
|
||||
if (recentIdleTime > recentTotalTime) {
|
||||
// This happens occasionally, as we use the idle time from the kernel, and the current
|
||||
// time from userspace.
|
||||
recentIdleTime = recentTotalTime;
|
||||
}
|
||||
const double idleTimePercentage =
|
||||
static_cast<double>(recentIdleTime.count()) / recentTotalTime.count();
|
||||
(*cpuCoreIdleTimesPercentage)[cpuId] = idleTimePercentage;
|
||||
}
|
||||
mPreviousCpuTimes = cpuTimes;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CpuLoadReaderSysDevices::DumpToStream(std::stringstream &stream) const {
|
||||
stream << "CPU loads from /sys/devices/system/cpu/cpuN/cpuidle:\n";
|
||||
for (size_t cpuId = 0; cpuId < NUM_CPU_CORES; cpuId++) {
|
||||
stream << "- CPU=" << cpuId << ", idleTime=" << mPreviousCpuTimes[cpuId].idleTime.count()
|
||||
<< "ms, totalTime=" << mPreviousCpuTimes[cpuId].totalTime.count() << "ms\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool CpuLoadReaderSysDevices::ReadCpuTimes(std::array<CpuTime, NUM_CPU_CORES> *result) const {
|
||||
ATRACE_CALL();
|
||||
const auto totalTime = mTimeSource->GetTime();
|
||||
|
||||
for (size_t cpuId = 0; cpuId < NUM_CPU_CORES; cpuId++) {
|
||||
std::chrono::microseconds idleTime;
|
||||
for (const auto &idleStateName : mIdleStateNames) {
|
||||
std::stringstream cpuIdlePath;
|
||||
cpuIdlePath << "/sys/devices/system/cpu/"
|
||||
<< "cpu" << cpuId << "/cpuidle/" << idleStateName << "/time";
|
||||
std::unique_ptr<std::istream> file;
|
||||
if (!mFilesystem->ReadFileStream(cpuIdlePath.str(), &file)) {
|
||||
return false;
|
||||
}
|
||||
// Times are reported in microseconds:
|
||||
// https://www.kernel.org/doc/Documentation/cpuidle/sysfs.txt
|
||||
std::string idleTimeUs(std::istreambuf_iterator<char>(*file), {});
|
||||
idleTime += std::chrono::microseconds(std::atoi(idleTimeUs.c_str()));
|
||||
}
|
||||
(*result)[cpuId] = {
|
||||
.idleTime = idleTime,
|
||||
.totalTime = std::chrono::duration_cast<std::chrono::microseconds>(totalTime),
|
||||
};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CpuLoadReaderSysDevices::ReadIdleStateNames(std::vector<std::string> *result) const {
|
||||
std::vector<std::string> idleStateNames;
|
||||
if (!mFilesystem->ListDirectory("/sys/devices/system/cpu/cpu0/cpuidle", &idleStateNames)) {
|
||||
return false;
|
||||
}
|
||||
for (const auto &idleStateName : idleStateNames) {
|
||||
if (idleStateName.length() == 0 || idleStateName[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
std::vector<std::string> files;
|
||||
if (!mFilesystem->ListDirectory(
|
||||
std::string("/sys/devices/system/cpu/cpu0/cpuidle/") + idleStateName, &files)) {
|
||||
return false;
|
||||
}
|
||||
if (std::find(files.begin(), files.end(), "time") == files.end()) {
|
||||
continue;
|
||||
}
|
||||
result->push_back(idleStateName);
|
||||
}
|
||||
if (idleStateNames.empty()) {
|
||||
LOG(ERROR) << "Found no idle state names";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,71 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* 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 <chrono>
|
||||
#include <map>
|
||||
|
||||
#include "ICpuLoadReader.h"
|
||||
#include "IFilesystem.h"
|
||||
#include "ITimeSource.h"
|
||||
#include "Model.h"
|
||||
#include "RealFilesystem.h"
|
||||
#include "TimeSource.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
struct CpuTime {
|
||||
std::chrono::microseconds idleTime;
|
||||
std::chrono::microseconds totalTime;
|
||||
};
|
||||
|
||||
// Reads CPU idle stats from /sys/devices/system/cpu/cpuN/cpuidle.
|
||||
class CpuLoadReaderSysDevices : public ICpuLoadReader {
|
||||
public:
|
||||
CpuLoadReaderSysDevices()
|
||||
: mFilesystem(std::make_unique<RealFilesystem>()),
|
||||
mTimeSource(std::make_unique<TimeSource>()) {}
|
||||
CpuLoadReaderSysDevices(std::unique_ptr<IFilesystem> filesystem,
|
||||
std::unique_ptr<ITimeSource> timeSource)
|
||||
: mFilesystem(std::move(filesystem)), mTimeSource(std::move(timeSource)) {}
|
||||
|
||||
bool Init() override;
|
||||
bool GetRecentCpuLoads(std::array<double, NUM_CPU_CORES> *cpuCoreIdleTimesPercentage) override;
|
||||
void DumpToStream(std::stringstream &stream) const override;
|
||||
|
||||
private:
|
||||
const std::unique_ptr<IFilesystem> mFilesystem;
|
||||
const std::unique_ptr<ITimeSource> mTimeSource;
|
||||
|
||||
std::array<CpuTime, NUM_CPU_CORES> mPreviousCpuTimes;
|
||||
std::vector<std::string> mIdleStateNames;
|
||||
|
||||
bool ReadCpuTimes(std::array<CpuTime, NUM_CPU_CORES> *result) const;
|
||||
bool ReadIdleStateNames(std::vector<std::string> *result) const;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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 "Device.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
Device ReadDevice() {
|
||||
ATRACE_CALL();
|
||||
const std::string deviceProperty = ::android::base::GetProperty("ro.product.device", "");
|
||||
Device device;
|
||||
if (deviceProperty == "raven") {
|
||||
device = Device::RAVEN;
|
||||
} else if (deviceProperty == "oriole") {
|
||||
device = Device::ORIOLE;
|
||||
} else {
|
||||
LOG(WARNING) << "Failed to parse device property, setting to UNKNOWN: " << deviceProperty;
|
||||
device = Device::UNKNOWN;
|
||||
}
|
||||
LOG(DEBUG) << "Parsed device: deviceProperty=" << deviceProperty
|
||||
<< ", device=" << static_cast<uint32_t>(device);
|
||||
return device;
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
enum class Device { UNKNOWN = 0, RAVEN = 1, ORIOLE = 2 };
|
||||
|
||||
Device ReadDevice();
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,49 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* 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 <array>
|
||||
#include <sstream>
|
||||
|
||||
#include "Model.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
class ICpuLoadReader {
|
||||
public:
|
||||
// Initialize reading, must be done before calling other methods.
|
||||
// Work is not done in constructor as it accesses files.
|
||||
virtual bool Init() = 0;
|
||||
// Get the load of each CPU, since the last time this method was called.
|
||||
virtual bool GetRecentCpuLoads(
|
||||
std::array<double, NUM_CPU_CORES> *cpuCoreIdleTimesPercentage) = 0;
|
||||
// Dump internal state to a string stream. Used for dumpsys.
|
||||
virtual void DumpToStream(std::stringstream &stream) const = 0;
|
||||
virtual ~ICpuLoadReader() {}
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,49 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* 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 <chrono>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
// Abstracted so we can mock in tests.
|
||||
class IFilesystem {
|
||||
public:
|
||||
virtual ~IFilesystem() {}
|
||||
virtual bool ListDirectory(const std::string &path, std::vector<std::string> *result) const = 0;
|
||||
virtual bool ReadFileStream(const std::string &path,
|
||||
std::unique_ptr<std::istream> *result) const = 0;
|
||||
// Resets the file stream, so that the next read will read from the beginning.
|
||||
// This function exists in IFilesystem rather than using istream::seekg directly. This is
|
||||
// so we can mock this function in tests, allowing us to return different data on reset.
|
||||
virtual bool ResetFileStream(const std::unique_ptr<std::istream> &fileStream) const = 0;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,41 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* 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 <chrono>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
// Abstracted so we can mock in tests.
|
||||
class ITimeSource {
|
||||
public:
|
||||
virtual ~ITimeSource() {}
|
||||
virtual std::chrono::nanoseconds GetTime() const = 0;
|
||||
virtual std::chrono::nanoseconds GetKernelTime() const = 0;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "KernelCpuFeatureReader.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
constexpr std::string_view kKernelFilePath("/proc/vendor_sched/acpu_stats");
|
||||
constexpr size_t kReadBufferSize = sizeof(acpu_stats) * NUM_CPU_CORES;
|
||||
|
||||
bool KernelCpuFeatureReader::Init() {
|
||||
ATRACE_CALL();
|
||||
if (!OpenStatsFile(&mStatsFile)) {
|
||||
return false;
|
||||
}
|
||||
return ReadStats(&mPreviousStats, &mPreviousReadTime);
|
||||
}
|
||||
|
||||
bool KernelCpuFeatureReader::GetRecentCpuFeatures(
|
||||
std::array<double, NUM_CPU_POLICIES> *cpuPolicyAverageFrequencyHz,
|
||||
std::array<double, NUM_CPU_CORES> *cpuCoreIdleTimesPercentage) {
|
||||
ATRACE_CALL();
|
||||
std::array<acpu_stats, NUM_CPU_CORES> stats;
|
||||
std::chrono::nanoseconds readTime;
|
||||
if (!ReadStats(&stats, &readTime)) {
|
||||
return false;
|
||||
}
|
||||
const std::chrono::nanoseconds timeDelta = readTime - mPreviousReadTime;
|
||||
|
||||
for (size_t i = 0; i < NUM_CPU_POLICIES; i++) {
|
||||
// acpu_stats has data per-CPU, but frequency data is equivalent for all CPUs in a policy.
|
||||
// So, we only read the first CPU in each policy.
|
||||
const size_t statsIdx = CPU_POLICY_INDICES[i];
|
||||
if (stats[statsIdx].weighted_sum_freq < mPreviousStats[statsIdx].weighted_sum_freq) {
|
||||
LOG(WARNING) << "New weighted_sum_freq is less than old: new="
|
||||
<< stats[statsIdx].weighted_sum_freq
|
||||
<< ", old=" << mPreviousStats[statsIdx].weighted_sum_freq;
|
||||
mPreviousStats[statsIdx].weighted_sum_freq = stats[statsIdx].weighted_sum_freq;
|
||||
}
|
||||
(*cpuPolicyAverageFrequencyHz)[i] =
|
||||
static_cast<double>(stats[statsIdx].weighted_sum_freq -
|
||||
mPreviousStats[statsIdx].weighted_sum_freq) /
|
||||
timeDelta.count();
|
||||
}
|
||||
for (size_t i = 0; i < NUM_CPU_CORES; i++) {
|
||||
if (stats[i].total_idle_time_ns < mPreviousStats[i].total_idle_time_ns) {
|
||||
LOG(WARNING) << "New total_idle_time_ns is less than old: new="
|
||||
<< stats[i].total_idle_time_ns
|
||||
<< ", old=" << mPreviousStats[i].total_idle_time_ns;
|
||||
mPreviousStats[i].total_idle_time_ns = stats[i].total_idle_time_ns;
|
||||
}
|
||||
(*cpuCoreIdleTimesPercentage)[i] =
|
||||
static_cast<double>(stats[i].total_idle_time_ns -
|
||||
mPreviousStats[i].total_idle_time_ns) /
|
||||
timeDelta.count();
|
||||
}
|
||||
|
||||
mPreviousStats = stats;
|
||||
mPreviousReadTime = readTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KernelCpuFeatureReader::OpenStatsFile(std::unique_ptr<std::istream> *file) {
|
||||
ATRACE_CALL();
|
||||
return mFilesystem->ReadFileStream(kKernelFilePath.data(), file);
|
||||
}
|
||||
|
||||
bool KernelCpuFeatureReader::ReadStats(std::array<acpu_stats, NUM_CPU_CORES> *stats,
|
||||
std::chrono::nanoseconds *readTime) {
|
||||
ATRACE_CALL();
|
||||
*readTime = mTimeSource->GetKernelTime();
|
||||
if (!mFilesystem->ResetFileStream(mStatsFile)) {
|
||||
return false;
|
||||
}
|
||||
char buffer[kReadBufferSize];
|
||||
{
|
||||
ATRACE_NAME("read");
|
||||
if (!mStatsFile->read(buffer, kReadBufferSize).good()) {
|
||||
LOG(ERROR) << "Failed to read stats file";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const size_t bytesRead = mStatsFile->gcount();
|
||||
if (bytesRead != kReadBufferSize) {
|
||||
LOG(ERROR) << "Didn't read full data: expected=" << kReadBufferSize
|
||||
<< ", actual=" << bytesRead;
|
||||
return false;
|
||||
}
|
||||
const auto kernelStructs = reinterpret_cast<acpu_stats *>(buffer);
|
||||
std::copy(kernelStructs, kernelStructs + NUM_CPU_CORES, stats->begin());
|
||||
return true;
|
||||
}
|
||||
|
||||
void KernelCpuFeatureReader::DumpToStream(std::ostream &stream) const {
|
||||
ATRACE_CALL();
|
||||
stream << "CPU features from acpu_stats:\n";
|
||||
for (size_t i = 0; i < NUM_CPU_CORES; i++) {
|
||||
stream << "- CPU " << i << ": weighted_sum_freq=" << mPreviousStats[i].weighted_sum_freq
|
||||
<< ", total_idle_time_ns=" << mPreviousStats[i].total_idle_time_ns << "\n";
|
||||
}
|
||||
stream << "- Last read time: " << mPreviousReadTime.count() << "ns\n";
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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 <array>
|
||||
#include <ostream>
|
||||
|
||||
#include "IFilesystem.h"
|
||||
#include "ITimeSource.h"
|
||||
#include "Model.h"
|
||||
#include "RealFilesystem.h"
|
||||
#include "TimeSource.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
// Kernel <-> Userspace ABI for CPU features. See kernel/sched/acpu.c.
|
||||
// Contains CPU statistics for a single CPU. The kernel reports an `acpu_stats` struct for each CPU
|
||||
// on the system.
|
||||
struct acpu_stats {
|
||||
// Sum of the CPU frequencies that the CPU used, multiplied by how much time was spent in each
|
||||
// frequency. Measured in ns*KHz. E.g.:
|
||||
// 10ns at 100MHz, 2ns at 50MHz = 10*100,000 + 2*50,000 = 1,100,000
|
||||
// This is used to calculate the average frequency the CPU was running at between two times:
|
||||
// (new.weighted_sum_freq - old.weighted_sum_freq) / elapsed_time_ns
|
||||
uint64_t weighted_sum_freq;
|
||||
// The total time (in nanoseconds) that the CPU was idle.
|
||||
// This is ued to calculate the percent of time the CPU was idle between two times:
|
||||
// (new.total_idle_time_ns - old.total_idle_time_ns) / elapsed_time_ns
|
||||
uint64_t total_idle_time_ns;
|
||||
};
|
||||
|
||||
class KernelCpuFeatureReader {
|
||||
public:
|
||||
KernelCpuFeatureReader()
|
||||
: mFilesystem(std::make_unique<RealFilesystem>()),
|
||||
mTimeSource(std::make_unique<TimeSource>()) {}
|
||||
KernelCpuFeatureReader(std::unique_ptr<IFilesystem> filesystem,
|
||||
std::unique_ptr<ITimeSource> timeSource)
|
||||
: mFilesystem(std::move(filesystem)), mTimeSource(std::move(timeSource)) {}
|
||||
|
||||
bool Init();
|
||||
bool GetRecentCpuFeatures(std::array<double, NUM_CPU_POLICIES> *cpuPolicyAverageFrequencyHz,
|
||||
std::array<double, NUM_CPU_CORES> *cpuCoreIdleTimesPercentage);
|
||||
void DumpToStream(std::ostream &stream) const;
|
||||
|
||||
private:
|
||||
const std::unique_ptr<IFilesystem> mFilesystem;
|
||||
const std::unique_ptr<ITimeSource> mTimeSource;
|
||||
// We only open the stats file once and reuse the file descriptor. We find this reduces
|
||||
// ReadStats runtime by 2x.
|
||||
std::unique_ptr<std::istream> mStatsFile;
|
||||
std::array<acpu_stats, NUM_CPU_CORES> mPreviousStats;
|
||||
std::chrono::nanoseconds mPreviousReadTime;
|
||||
bool OpenStatsFile(std::unique_ptr<std::istream> *file);
|
||||
bool ReadStats(std::array<acpu_stats, NUM_CPU_CORES> *stats,
|
||||
std::chrono::nanoseconds *readTime);
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,106 +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 "powerhal-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "Model.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
bool ModelInput::SetCpuFreqiencies(
|
||||
const std::vector<CpuPolicyAverageFrequency> &cpuPolicyAverageFrequencies) {
|
||||
ATRACE_CALL();
|
||||
if (cpuPolicyAverageFrequencies.size() != cpuPolicyAverageFrequencyHz.size()) {
|
||||
LOG(ERROR) << "Received incorrect amount of CPU policy frequencies, expected "
|
||||
<< cpuPolicyAverageFrequencyHz.size() << ", received "
|
||||
<< cpuPolicyAverageFrequencies.size();
|
||||
return false;
|
||||
}
|
||||
int32_t previousPolicyId = -1;
|
||||
for (uint32_t i = 0; i < cpuPolicyAverageFrequencies.size(); i++) {
|
||||
if (previousPolicyId >= static_cast<int32_t>(cpuPolicyAverageFrequencies[i].policyId)) {
|
||||
LOG(ERROR) << "CPU frequencies weren't sorted by policy ID, found " << previousPolicyId
|
||||
<< " " << cpuPolicyAverageFrequencies[i].policyId;
|
||||
return false;
|
||||
}
|
||||
previousPolicyId = cpuPolicyAverageFrequencies[i].policyId;
|
||||
cpuPolicyAverageFrequencyHz[i] = cpuPolicyAverageFrequencies[i].averageFrequencyHz;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModelInput::LogToAtrace() const {
|
||||
if (!ATRACE_ENABLED()) {
|
||||
return;
|
||||
}
|
||||
ATRACE_CALL();
|
||||
for (int i = 0; i < cpuPolicyAverageFrequencyHz.size(); i++) {
|
||||
ATRACE_INT((std::string("ModelInput_frequency_") + std::to_string(i)).c_str(),
|
||||
static_cast<int>(cpuPolicyAverageFrequencyHz[i]));
|
||||
}
|
||||
for (int i = 0; i < cpuCoreIdleTimesPercentage.size(); i++) {
|
||||
ATRACE_INT((std::string("ModelInput_idle_") + std::to_string(i)).c_str(),
|
||||
static_cast<int>(cpuCoreIdleTimesPercentage[i] * 100));
|
||||
}
|
||||
ATRACE_INT("ModelInput_workDurations_averageDurationNs",
|
||||
workDurationFeatures.averageDuration.count());
|
||||
ATRACE_INT("ModelInput_workDurations_maxDurationNs", workDurationFeatures.maxDuration.count());
|
||||
ATRACE_INT("ModelInput_workDurations_numMissedDeadlines",
|
||||
workDurationFeatures.numMissedDeadlines);
|
||||
ATRACE_INT("ModelInput_workDurations_numDurations", workDurationFeatures.numDurations);
|
||||
ATRACE_INT("ModelInput_prevThrottle", (int)previousThrottleDecision);
|
||||
ATRACE_INT("ModelInput_device", static_cast<int>(device));
|
||||
}
|
||||
|
||||
ThrottleDecision Model::Run(const std::deque<ModelInput> &modelInputs,
|
||||
const AdaptiveCpuConfig &config) {
|
||||
ATRACE_CALL();
|
||||
if (config.randomThrottleDecisionProbability > 0 &&
|
||||
mShouldRandomThrottleDistribution(mGenerator) < config.randomThrottleDecisionProbability) {
|
||||
std::uniform_int_distribution<uint32_t> optionDistribution(
|
||||
0, config.randomThrottleOptions.size() - 1);
|
||||
const ThrottleDecision throttleDecision =
|
||||
config.randomThrottleOptions[optionDistribution(mGenerator)];
|
||||
LOG(VERBOSE) << "Randomly overrided throttle decision: "
|
||||
<< static_cast<uint32_t>(throttleDecision);
|
||||
ATRACE_INT("AdaptiveCpu_randomThrottleDecision", static_cast<uint32_t>(throttleDecision));
|
||||
return throttleDecision;
|
||||
}
|
||||
ATRACE_INT("AdaptiveCpu_randomThrottleDecision", -1);
|
||||
return RunDecisionTree(modelInputs);
|
||||
}
|
||||
|
||||
ThrottleDecision Model::RunDecisionTree(const std::deque<ModelInput> &modelInputs
|
||||
__attribute__((unused))) {
|
||||
ATRACE_CALL();
|
||||
#include "models/model.inc"
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,88 +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 <inttypes.h>
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <deque>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include "AdaptiveCpuConfig.h"
|
||||
#include "CpuFrequencyReader.h"
|
||||
#include "Device.h"
|
||||
#include "ThrottleDecision.h"
|
||||
#include "WorkDurationProcessor.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
// Currently Adaptive CPU is targeted to only raven/oriole, so we can hardcode the CPU architecture.
|
||||
// If we extend to other architectures, this will have to vary per-device or be dynamically loaded.
|
||||
constexpr uint32_t NUM_CPU_CORES = 8;
|
||||
constexpr uint32_t NUM_CPU_POLICIES = 3;
|
||||
constexpr std::array<uint32_t, NUM_CPU_POLICIES> CPU_POLICY_INDICES{0, 4, 6};
|
||||
|
||||
struct ModelInput {
|
||||
std::array<double, NUM_CPU_POLICIES> cpuPolicyAverageFrequencyHz;
|
||||
std::array<double, NUM_CPU_CORES> cpuCoreIdleTimesPercentage;
|
||||
WorkDurationFeatures workDurationFeatures;
|
||||
ThrottleDecision previousThrottleDecision;
|
||||
Device device;
|
||||
|
||||
bool SetCpuFreqiencies(
|
||||
const std::vector<CpuPolicyAverageFrequency> &cpuPolicyAverageFrequencies);
|
||||
|
||||
void LogToAtrace() const;
|
||||
|
||||
bool operator==(const ModelInput &other) const {
|
||||
return cpuPolicyAverageFrequencyHz == other.cpuPolicyAverageFrequencyHz &&
|
||||
cpuCoreIdleTimesPercentage == other.cpuCoreIdleTimesPercentage &&
|
||||
workDurationFeatures == other.workDurationFeatures &&
|
||||
previousThrottleDecision == other.previousThrottleDecision;
|
||||
}
|
||||
};
|
||||
|
||||
class Model {
|
||||
public:
|
||||
Model()
|
||||
: mShouldRandomThrottleDistribution(0, 1),
|
||||
mRandomThrottleDistribution(static_cast<uint32_t>(ThrottleDecision::FIRST),
|
||||
static_cast<uint32_t>(ThrottleDecision::LAST)) {}
|
||||
ThrottleDecision Run(const std::deque<ModelInput> &modelInputs,
|
||||
const AdaptiveCpuConfig &config);
|
||||
|
||||
private:
|
||||
std::default_random_engine mGenerator;
|
||||
std::uniform_real_distribution<double> mShouldRandomThrottleDistribution;
|
||||
std::uniform_int_distribution<uint32_t> mRandomThrottleDistribution;
|
||||
|
||||
ThrottleDecision RunDecisionTree(const std::deque<ModelInput> &modelInputs);
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,76 +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 "powerhal-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "RealFilesystem.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <dirent.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <istream>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
bool RealFilesystem::ListDirectory(const std::string &path,
|
||||
std::vector<std::string> *result) const {
|
||||
ATRACE_CALL();
|
||||
// We can't use std::filesystem, see aosp/894015 & b/175635923.
|
||||
auto dir = std::unique_ptr<DIR, decltype(&closedir)>{opendir(path.c_str()), closedir};
|
||||
if (!dir) {
|
||||
LOG(ERROR) << "Failed to open directory " << path;
|
||||
return false;
|
||||
}
|
||||
dirent *entry;
|
||||
while ((entry = readdir(&*dir)) != nullptr) {
|
||||
result->emplace_back(entry->d_name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RealFilesystem::ReadFileStream(const std::string &path,
|
||||
std::unique_ptr<std::istream> *result) const {
|
||||
ATRACE_CALL();
|
||||
*result = std::make_unique<std::ifstream>(path);
|
||||
if ((*result)->fail()) {
|
||||
LOG(ERROR) << "Failed to read file stream: " << path;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RealFilesystem::ResetFileStream(const std::unique_ptr<std::istream> &fileStream) const {
|
||||
if (fileStream->seekg(0).bad()) {
|
||||
LOG(ERROR) << "Failed to reset file stream";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,46 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* 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 <memory>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
#include "IFilesystem.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
class RealFilesystem : public IFilesystem {
|
||||
public:
|
||||
virtual ~RealFilesystem() {}
|
||||
bool ListDirectory(const std::string &path, std::vector<std::string> *result) const override;
|
||||
bool ReadFileStream(const std::string &path,
|
||||
std::unique_ptr<std::istream> *result) const override;
|
||||
bool ResetFileStream(const std::unique_ptr<std::istream> &fileStream) const override;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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 "ThrottleDecision.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
std::string ThrottleString(ThrottleDecision throttleDecision) {
|
||||
switch (throttleDecision) {
|
||||
case ThrottleDecision::NO_THROTTLE:
|
||||
return "NO_THROTTLE";
|
||||
case ThrottleDecision::THROTTLE_60:
|
||||
return "THROTTLE_60";
|
||||
case ThrottleDecision::THROTTLE_70:
|
||||
return "THROTTLE_70";
|
||||
case ThrottleDecision::THROTTLE_80:
|
||||
return "THROTTLE_80";
|
||||
case ThrottleDecision::THROTTLE_90:
|
||||
return "THROTTLE_90";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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 <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
enum class ThrottleDecision {
|
||||
NO_THROTTLE = 0,
|
||||
THROTTLE_50 = 1,
|
||||
THROTTLE_60 = 2,
|
||||
THROTTLE_70 = 3,
|
||||
THROTTLE_80 = 4,
|
||||
THROTTLE_90 = 5,
|
||||
FIRST = NO_THROTTLE,
|
||||
LAST = THROTTLE_90,
|
||||
};
|
||||
|
||||
std::string ThrottleString(ThrottleDecision throttleDecision);
|
||||
|
||||
static const std::unordered_map<ThrottleDecision, std::vector<std::string>>
|
||||
THROTTLE_DECISION_TO_HINT_NAMES = {
|
||||
{ThrottleDecision::NO_THROTTLE, {}},
|
||||
{ThrottleDecision::THROTTLE_50,
|
||||
{"LOW_POWER_LITTLE_CLUSTER_50", "LOW_POWER_MID_CLUSTER_50", "LOW_POWER_CPU_50"}},
|
||||
{ThrottleDecision::THROTTLE_60,
|
||||
{"LOW_POWER_LITTLE_CLUSTER_60", "LOW_POWER_MID_CLUSTER_60", "LOW_POWER_CPU_60"}},
|
||||
{ThrottleDecision::THROTTLE_70,
|
||||
{"LOW_POWER_LITTLE_CLUSTER_70", "LOW_POWER_MID_CLUSTER_70", "LOW_POWER_CPU_70"}},
|
||||
{ThrottleDecision::THROTTLE_80,
|
||||
{"LOW_POWER_LITTLE_CLUSTER_80", "LOW_POWER_MID_CLUSTER_80", "LOW_POWER_CPU_80"}},
|
||||
{ThrottleDecision::THROTTLE_90,
|
||||
{"LOW_POWER_LITTLE_CLUSTER_90", "LOW_POWER_MID_CLUSTER_90", "LOW_POWER_CPU_90"}}};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,48 +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 ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "TimeSource.h"
|
||||
|
||||
#include <utils/Trace.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
std::chrono::nanoseconds TimeSource::GetTime() const {
|
||||
ATRACE_CALL();
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds TimeSource::GetKernelTime() const {
|
||||
ATRACE_CALL();
|
||||
timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return std::chrono::nanoseconds(ts.tv_sec * 1000000000UL + ts.tv_nsec);
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,40 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* 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 "ITimeSource.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
class TimeSource : public ITimeSource {
|
||||
public:
|
||||
~TimeSource() override {}
|
||||
std::chrono::nanoseconds GetTime() const override;
|
||||
std::chrono::nanoseconds GetKernelTime() const override;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,120 +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 "powerhal-adaptivecpu"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include "WorkDurationProcessor.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
using std::chrono_literals::operator""ms;
|
||||
using std::chrono_literals::operator""ns;
|
||||
|
||||
// The standard target duration, based on 60 FPS. Durations submitted with different targets are
|
||||
// normalized against this target. For example, a duration that was at 80% of its target will be
|
||||
// scaled to 0.8 * kNormalTargetDuration.
|
||||
constexpr std::chrono::nanoseconds kNormalTargetDuration = 16666666ns;
|
||||
|
||||
// All durations shorter than this are ignored.
|
||||
constexpr std::chrono::nanoseconds kMinDuration = 0ns;
|
||||
|
||||
// All durations longer than this are ignored.
|
||||
constexpr std::chrono::nanoseconds kMaxDuration = 600 * kNormalTargetDuration;
|
||||
|
||||
// If we haven't processed a lot of batches, stop accepting new ones. In cases where the processing
|
||||
// thread has crashed, but the reporting thread is still reporting, this prevents consuming large
|
||||
// amounts of memory.
|
||||
// TODO(b/213160386): Move to AdaptiveCpuConfig.
|
||||
constexpr size_t kMaxUnprocessedBatches = 1000;
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
bool WorkDurationProcessor::ReportWorkDurations(const std::vector<WorkDuration> &workDurations,
|
||||
std::chrono::nanoseconds targetDuration) {
|
||||
ATRACE_CALL();
|
||||
LOG(VERBOSE) << "Received " << workDurations.size() << " work durations with target "
|
||||
<< targetDuration.count() << "ns";
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
if (mWorkDurationBatches.size() >= kMaxUnprocessedBatches) {
|
||||
LOG(ERROR) << "Adaptive CPU isn't processing work durations fast enough";
|
||||
mWorkDurationBatches.clear();
|
||||
return false;
|
||||
}
|
||||
mWorkDurationBatches.emplace_back(workDurations, targetDuration);
|
||||
return true;
|
||||
}
|
||||
|
||||
WorkDurationFeatures WorkDurationProcessor::GetFeatures() {
|
||||
ATRACE_CALL();
|
||||
|
||||
std::vector<WorkDurationBatch> workDurationBatches;
|
||||
{
|
||||
ATRACE_NAME("lock");
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
mWorkDurationBatches.swap(workDurationBatches);
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds durationsSum = 0ns;
|
||||
std::chrono::nanoseconds maxDuration = 0ns;
|
||||
uint32_t numMissedDeadlines = 0;
|
||||
uint32_t numDurations = 0;
|
||||
for (const WorkDurationBatch &batch : workDurationBatches) {
|
||||
for (const WorkDuration workDuration : batch.workDurations) {
|
||||
std::chrono::nanoseconds duration(workDuration.durationNanos);
|
||||
if (duration < kMinDuration || duration > kMaxDuration) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Normalise the duration and add it to the total.
|
||||
// kMaxDuration * kStandardTarget.count() fits comfortably within int64_t.
|
||||
std::chrono::nanoseconds durationNormalized =
|
||||
(duration * kNormalTargetDuration.count()) / batch.targetDuration.count();
|
||||
durationsSum += durationNormalized;
|
||||
maxDuration = std::max(maxDuration, durationNormalized);
|
||||
if (duration > batch.targetDuration) {
|
||||
++numMissedDeadlines;
|
||||
}
|
||||
++numDurations;
|
||||
}
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds averageDuration = durationsSum / numDurations;
|
||||
return {
|
||||
.averageDuration = averageDuration,
|
||||
.maxDuration = maxDuration,
|
||||
.numMissedDeadlines = numMissedDeadlines,
|
||||
.numDurations = numDurations,
|
||||
};
|
||||
}
|
||||
|
||||
bool WorkDurationProcessor::HasWorkDurations() {
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
return !mWorkDurationBatches.empty();
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,76 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* 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 <aidl/android/hardware/power/WorkDuration.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using ::aidl::android::hardware::power::WorkDuration;
|
||||
|
||||
struct WorkDurationBatch {
|
||||
WorkDurationBatch(const std::vector<WorkDuration> &workDurations,
|
||||
std::chrono::nanoseconds targetDuration)
|
||||
: workDurations(workDurations), targetDuration(targetDuration) {}
|
||||
const std::vector<WorkDuration> workDurations;
|
||||
const std::chrono::nanoseconds targetDuration;
|
||||
};
|
||||
|
||||
struct WorkDurationFeatures {
|
||||
std::chrono::nanoseconds averageDuration;
|
||||
std::chrono::nanoseconds maxDuration;
|
||||
uint32_t numMissedDeadlines;
|
||||
uint32_t numDurations;
|
||||
|
||||
bool operator==(const WorkDurationFeatures &other) const {
|
||||
return averageDuration == other.averageDuration && maxDuration == other.maxDuration &&
|
||||
numMissedDeadlines == other.numMissedDeadlines && numDurations == other.numDurations;
|
||||
}
|
||||
};
|
||||
|
||||
class WorkDurationProcessor {
|
||||
public:
|
||||
bool ReportWorkDurations(const std::vector<WorkDuration> &workDurations,
|
||||
std::chrono::nanoseconds targetDuration);
|
||||
|
||||
WorkDurationFeatures GetFeatures();
|
||||
|
||||
// True if ReportWorkDurations has been called since GetFeatures was last called.
|
||||
bool HasWorkDurations();
|
||||
|
||||
private:
|
||||
// The work durations reported since GetFeatures() was last called.
|
||||
// Ordered from least recent to most recent.
|
||||
std::vector<WorkDurationBatch> mWorkDurationBatches;
|
||||
// Guards reading/writing mWorkDurationBatches.
|
||||
std::mutex mMutex;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1 +0,0 @@
|
|||
exclude_files=.*
|
|
@ -1,4 +0,0 @@
|
|||
benm@google.com
|
||||
miloslav@google.com
|
||||
mishaw@google.com
|
||||
silviavinyes@google.com
|
File diff suppressed because it is too large
Load diff
|
@ -1,131 +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/properties.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "adaptivecpu/AdaptiveCpuConfig.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using std::chrono_literals::operator""ms;
|
||||
using std::chrono_literals::operator""min;
|
||||
|
||||
class AdaptiveCpuConfigTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
android::base::SetProperty("debug.adaptivecpu.iteration_sleep_duration_ms", "");
|
||||
android::base::SetProperty("debug.adaptivecpu.hint_timeout_ms", "");
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_decision_percent", "");
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_options", "");
|
||||
android::base::SetProperty("debug.adaptivecpu.enabled_hint_timeout_ms", "");
|
||||
}
|
||||
};
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, valid) {
|
||||
android::base::SetProperty("debug.adaptivecpu.iteration_sleep_duration_ms", "25");
|
||||
android::base::SetProperty("debug.adaptivecpu.hint_timeout_ms", "500");
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_decision_percent", "25");
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_options", "0,3,4");
|
||||
android::base::SetProperty("debug.adaptivecpu.enabled_hint_timeout_ms", "1000");
|
||||
const AdaptiveCpuConfig expectedConfig{
|
||||
.iterationSleepDuration = 25ms,
|
||||
.hintTimeout = 500ms,
|
||||
.randomThrottleDecisionProbability = 0.25,
|
||||
.enabledHintTimeout = 1000ms,
|
||||
.randomThrottleOptions = {ThrottleDecision::NO_THROTTLE, ThrottleDecision::THROTTLE_70,
|
||||
ThrottleDecision::THROTTLE_80},
|
||||
};
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_TRUE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
ASSERT_EQ(actualConfig, expectedConfig);
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, defaultConfig) {
|
||||
android::base::SetProperty("debug.adaptivecpu.iteration_sleep_duration_ms", "");
|
||||
android::base::SetProperty("debug.adaptivecpu.hint_timeout_ms", "");
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_decision_percent", "");
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_options", "");
|
||||
android::base::SetProperty("debug.adaptivecpu.enabled_hint_timeout_ms", "");
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_TRUE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
ASSERT_EQ(actualConfig, AdaptiveCpuConfig::DEFAULT);
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, iterationSleepDuration_belowMin) {
|
||||
android::base::SetProperty("debug.adaptivecpu.iteration_sleep_duration_ms", "2");
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_TRUE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
ASSERT_EQ(actualConfig.iterationSleepDuration, 20ms);
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, iterationSleepDuration_negative) {
|
||||
android::base::SetProperty("debug.adaptivecpu.iteration_sleep_duration_ms", "-100");
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_TRUE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
ASSERT_EQ(actualConfig.iterationSleepDuration, 1000ms);
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, randomThrottleDecisionProbability_float) {
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_decision_percent", "0.5");
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_TRUE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
ASSERT_EQ(actualConfig.randomThrottleDecisionProbability, 0);
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, randomThrottleDecisionProbability_tooBig) {
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_decision_percent", "101");
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_FALSE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, randomThrottleOptions_invalidThrottle) {
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_options", "0,1,2,9");
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_FALSE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, randomThrottleOptions_wrongDelim) {
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_options", "0,1.2,3");
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_FALSE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, randomThrottleOptions_wrongNumber) {
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_options", "0,1,2a,3");
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_FALSE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuConfigTest, randomThrottleOptions_straySpace) {
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_options", "0,1 ,2,3");
|
||||
AdaptiveCpuConfig actualConfig;
|
||||
ASSERT_FALSE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
android::base::SetProperty("debug.adaptivecpu.random_throttle_options", "0,1,2,3 ");
|
||||
ASSERT_FALSE(AdaptiveCpuConfig::ReadFromSystemProperties(&actualConfig));
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,129 +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 <gtest/gtest.h>
|
||||
|
||||
#include "adaptivecpu/AdaptiveCpuStats.h"
|
||||
#include "mocks.h"
|
||||
|
||||
using testing::HasSubstr;
|
||||
using testing::Return;
|
||||
using std::chrono_literals::operator""ns;
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
TEST(AdaptiveCpuStatsTest, singleRun) {
|
||||
std::unique_ptr<MockTimeSource> timeSource = std::make_unique<MockTimeSource>();
|
||||
|
||||
EXPECT_CALL(*timeSource, GetTime())
|
||||
.Times(3)
|
||||
.WillOnce(Return(1000ns))
|
||||
.WillOnce(Return(1100ns))
|
||||
.WillOnce(Return(1200ns));
|
||||
|
||||
AdaptiveCpuStats stats(std::move(timeSource));
|
||||
stats.RegisterStartRun();
|
||||
stats.RegisterSuccessfulRun(ThrottleDecision::NO_THROTTLE, ThrottleDecision::THROTTLE_60, {},
|
||||
AdaptiveCpuConfig::DEFAULT);
|
||||
|
||||
std::stringstream stream;
|
||||
stats.DumpToStream(stream);
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- Successful runs / total runs: 1 / 1\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- Total run duration: 100.000000ns\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- Average run duration: 100.000000ns\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- Running time fraction: 0.5\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- THROTTLE_60: 1\n"));
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuStatsTest, multipleRuns) {
|
||||
std::unique_ptr<MockTimeSource> timeSource = std::make_unique<MockTimeSource>();
|
||||
|
||||
EXPECT_CALL(*timeSource, GetTime())
|
||||
.Times(9)
|
||||
.WillOnce(Return(1000ns)) // start #1
|
||||
.WillOnce(Return(1100ns)) // success #1
|
||||
.WillOnce(Return(2000ns)) // start #2
|
||||
.WillOnce(Return(2200ns)) // success #2
|
||||
.WillOnce(Return(3000ns)) // start #3
|
||||
.WillOnce(Return(3100ns)) // success #3
|
||||
.WillOnce(Return(4000ns)) // start #4
|
||||
.WillOnce(Return(4800ns)) // success #4
|
||||
.WillOnce(Return(5000ns)); // dump
|
||||
|
||||
AdaptiveCpuStats stats(std::move(timeSource));
|
||||
stats.RegisterStartRun();
|
||||
stats.RegisterSuccessfulRun(ThrottleDecision::NO_THROTTLE, ThrottleDecision::THROTTLE_60,
|
||||
// Ignored, as this is the first call.
|
||||
{.numDurations = 100000, .numMissedDeadlines = 123},
|
||||
AdaptiveCpuConfig::DEFAULT);
|
||||
stats.RegisterStartRun();
|
||||
stats.RegisterSuccessfulRun(ThrottleDecision::THROTTLE_60, ThrottleDecision::THROTTLE_70,
|
||||
{.numDurations = 100, .numMissedDeadlines = 10},
|
||||
AdaptiveCpuConfig::DEFAULT);
|
||||
stats.RegisterStartRun();
|
||||
stats.RegisterSuccessfulRun(ThrottleDecision::THROTTLE_70, ThrottleDecision::THROTTLE_60,
|
||||
{.numDurations = 50, .numMissedDeadlines = 1},
|
||||
AdaptiveCpuConfig::DEFAULT);
|
||||
stats.RegisterStartRun();
|
||||
stats.RegisterSuccessfulRun(ThrottleDecision::THROTTLE_60, ThrottleDecision::THROTTLE_80,
|
||||
{.numDurations = 200, .numMissedDeadlines = 20},
|
||||
AdaptiveCpuConfig::DEFAULT);
|
||||
|
||||
std::stringstream stream;
|
||||
stats.DumpToStream(stream);
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- Successful runs / total runs: 4 / 4\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- Total run duration: 1.200000us\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- Average run duration: 300.000000ns\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- Running time fraction: 0.3\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- THROTTLE_60: 2\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- THROTTLE_70: 1\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- THROTTLE_60: 30 / 300 (0.1)\n"));
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- THROTTLE_70: 1 / 50 (0.02)\n"));
|
||||
}
|
||||
|
||||
TEST(AdaptiveCpuStatsTest, failedRun) {
|
||||
std::unique_ptr<MockTimeSource> timeSource = std::make_unique<MockTimeSource>();
|
||||
|
||||
EXPECT_CALL(*timeSource, GetTime())
|
||||
.Times(4)
|
||||
.WillOnce(Return(1000ns))
|
||||
.WillOnce(Return(1100ns))
|
||||
.WillOnce(Return(1200ns))
|
||||
.WillOnce(Return(1300ns));
|
||||
|
||||
AdaptiveCpuStats stats(std::move(timeSource));
|
||||
stats.RegisterStartRun();
|
||||
stats.RegisterStartRun();
|
||||
stats.RegisterSuccessfulRun(ThrottleDecision::NO_THROTTLE, ThrottleDecision::THROTTLE_60, {},
|
||||
AdaptiveCpuConfig::DEFAULT);
|
||||
|
||||
std::stringstream stream;
|
||||
stats.DumpToStream(stream);
|
||||
EXPECT_THAT(stream.str(), HasSubstr("- Successful runs / total runs: 1 / 2\n"));
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -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 <gtest/gtest.h>
|
||||
|
||||
#include "adaptivecpu/CpuFrequencyReader.h"
|
||||
#include "mocks.h"
|
||||
|
||||
using testing::_;
|
||||
using testing::ByMove;
|
||||
using testing::Return;
|
||||
using std::chrono_literals::operator""ms;
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const CpuPolicyAverageFrequency &frequency) {
|
||||
return stream << "CpuPolicyAverageFrequency(" << frequency.policyId << ", "
|
||||
<< frequency.averageFrequencyHz << ")";
|
||||
}
|
||||
|
||||
TEST(CpuFrequencyReaderTest, cpuPolicyIds) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
EXPECT_CALL(*filesystem, ListDirectory("/sys/devices/system/cpu/cpufreq", _))
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::vector<std::string>{"ignored1", "policy1", "ignored2",
|
||||
"policy5", "policy10", "policybad"};
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*filesystem, ReadFileStream(_, _))
|
||||
.WillRepeatedly([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1 2\n3 4\n");
|
||||
return true;
|
||||
});
|
||||
|
||||
CpuFrequencyReader reader(std::move(filesystem));
|
||||
EXPECT_TRUE(reader.Init());
|
||||
|
||||
std::map<uint32_t, std::map<uint64_t, std::chrono::milliseconds>> expected = {
|
||||
{1, {{1, 20ms}, {3, 40ms}}}, {5, {{1, 20ms}, {3, 40ms}}}, {10, {{1, 20ms}, {3, 40ms}}}};
|
||||
EXPECT_EQ(reader.GetPreviousCpuPolicyFrequencies(), expected);
|
||||
}
|
||||
|
||||
TEST(CpuFrequencyReaderTest, getRecentCpuPolicyFrequencies) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
EXPECT_CALL(*filesystem, ListDirectory("/sys/devices/system/cpu/cpufreq", _))
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::vector<std::string>{"policy1", "policy2"};
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*filesystem,
|
||||
ReadFileStream("/sys/devices/system/cpu/cpufreq/policy1/stats/time_in_state", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1000 5\n2000 4");
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1000 7\n2000 10");
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*filesystem,
|
||||
ReadFileStream("/sys/devices/system/cpu/cpufreq/policy2/stats/time_in_state", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1500 1\n2500 23");
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1500 5\n2500 23");
|
||||
return true;
|
||||
});
|
||||
|
||||
CpuFrequencyReader reader(std::move(filesystem));
|
||||
EXPECT_TRUE(reader.Init());
|
||||
|
||||
std::vector<CpuPolicyAverageFrequency> actual;
|
||||
EXPECT_TRUE(reader.GetRecentCpuPolicyFrequencies(&actual));
|
||||
EXPECT_EQ(actual, std::vector<CpuPolicyAverageFrequency>({
|
||||
{.policyId = 1, .averageFrequencyHz = 1750},
|
||||
{.policyId = 2, .averageFrequencyHz = 1500},
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(CpuFrequencyReaderTest, getRecentCpuPolicyFrequencies_frequenciesChange) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
EXPECT_CALL(*filesystem, ListDirectory("/sys/devices/system/cpu/cpufreq", _))
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::vector<std::string>{"policy1"};
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*filesystem,
|
||||
ReadFileStream("/sys/devices/system/cpu/cpufreq/policy1/stats/time_in_state", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1000 5\n2000 4");
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1000 6\n2001 4");
|
||||
return true;
|
||||
});
|
||||
|
||||
CpuFrequencyReader reader(std::move(filesystem));
|
||||
EXPECT_TRUE(reader.Init());
|
||||
|
||||
std::vector<CpuPolicyAverageFrequency> actual;
|
||||
EXPECT_FALSE(reader.GetRecentCpuPolicyFrequencies(&actual));
|
||||
}
|
||||
|
||||
TEST(CpuFrequencyReaderTest, getRecentCpuPolicyFrequencies_badFormat) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
EXPECT_CALL(*filesystem, ListDirectory("/sys/devices/system/cpu/cpufreq", _))
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::vector<std::string>{"policy1"};
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*filesystem,
|
||||
ReadFileStream("/sys/devices/system/cpu/cpufreq/policy1/stats/time_in_state", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1000 1");
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1000 2\nfoo");
|
||||
return true;
|
||||
});
|
||||
|
||||
CpuFrequencyReader reader(std::move(filesystem));
|
||||
EXPECT_TRUE(reader.Init());
|
||||
|
||||
std::vector<CpuPolicyAverageFrequency> actual;
|
||||
EXPECT_FALSE(reader.GetRecentCpuPolicyFrequencies(&actual));
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,139 +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 <gtest/gtest.h>
|
||||
|
||||
#include "adaptivecpu/CpuLoadReaderProcStat.h"
|
||||
#include "mocks.h"
|
||||
|
||||
#define LOG_TAG "powerhal-adaptivecpu"
|
||||
|
||||
using testing::_;
|
||||
using testing::ByMove;
|
||||
using testing::Return;
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
TEST(CpuLoadReaderProcStatTest, GetRecentCpuLoads) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/proc/stat", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
std::stringstream ss;
|
||||
ss << "bad line\n";
|
||||
ss << "cpu1 100 0 0 50 0 0 0 0 0 0\n";
|
||||
ss << "cpu2 200 0 0 50 0 0 0 0 0 0\n";
|
||||
*result = std::make_unique<std::istringstream>(ss.str());
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
std::stringstream ss;
|
||||
ss << "bad line\n";
|
||||
ss << "cpu1 200 0 0 150 0 0 0 0 0 0\n";
|
||||
ss << "cpu2 500 0 0 150 0 0 0 0 0 0\n";
|
||||
*result = std::make_unique<std::istringstream>(ss.str());
|
||||
return true;
|
||||
});
|
||||
|
||||
CpuLoadReaderProcStat reader(std::move(filesystem));
|
||||
reader.Init();
|
||||
|
||||
std::array<double, NUM_CPU_CORES> actualPercentages;
|
||||
ASSERT_TRUE(reader.GetRecentCpuLoads(&actualPercentages));
|
||||
std::array<double, NUM_CPU_CORES> expectedPercentages({0, 0.5, 0.25, 0, 0, 0, 0, 0});
|
||||
ASSERT_EQ(actualPercentages, expectedPercentages);
|
||||
}
|
||||
|
||||
TEST(CpuLoadReaderProcStatTest, GetRecentCpuLoads_failsWithMissingValues) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/proc/stat", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
std::stringstream ss;
|
||||
ss << "bad line\n";
|
||||
ss << "cpu1 100 0 0 50 0 0 0\n";
|
||||
ss << "cpu2 200 0 0 50 0 0 0\n";
|
||||
*result = std::make_unique<std::istringstream>(ss.str());
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
std::stringstream ss;
|
||||
ss << "bad line\n";
|
||||
ss << "cpu1 200 0 0 150 0 0 0\n";
|
||||
ss << "cpu2 500 0 0 150 0 0 0\n";
|
||||
*result = std::make_unique<std::istringstream>(ss.str());
|
||||
return true;
|
||||
});
|
||||
|
||||
CpuLoadReaderProcStat reader(std::move(filesystem));
|
||||
reader.Init();
|
||||
std::array<double, NUM_CPU_CORES> actualPercentages;
|
||||
ASSERT_FALSE(reader.GetRecentCpuLoads(&actualPercentages));
|
||||
}
|
||||
|
||||
TEST(CpuLoadReaderProcStatTest, GetRecentCpuLoads_failsWithEmptyFile) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/proc/stat", _))
|
||||
.Times(2)
|
||||
.WillRepeatedly([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("");
|
||||
return true;
|
||||
});
|
||||
|
||||
CpuLoadReaderProcStat reader(std::move(filesystem));
|
||||
reader.Init();
|
||||
std::array<double, NUM_CPU_CORES> actualPercentages;
|
||||
ASSERT_FALSE(reader.GetRecentCpuLoads(&actualPercentages));
|
||||
}
|
||||
|
||||
TEST(CpuLoadReaderProcStatTest, GetRecentCpuLoads_failsWithDifferentCpus) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/proc/stat", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
std::stringstream ss;
|
||||
ss << "bad line\n";
|
||||
ss << "cpu1 100 0 0 50 0 0 0 0 0 0\n";
|
||||
ss << "cpu2 200 0 0 50 0 0 0 0 0 0\n";
|
||||
*result = std::make_unique<std::istringstream>(ss.str());
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
std::stringstream ss;
|
||||
ss << "bad line\n";
|
||||
ss << "cpu1 200 0 0 150 0 0 0 0 0 0\n";
|
||||
ss << "cpu3 500 0 0 150 0 0 0 0 0 0\n";
|
||||
*result = std::make_unique<std::istringstream>(ss.str());
|
||||
return true;
|
||||
});
|
||||
|
||||
CpuLoadReaderProcStat reader(std::move(filesystem));
|
||||
reader.Init();
|
||||
std::array<double, NUM_CPU_CORES> actualPercentages;
|
||||
ASSERT_FALSE(reader.GetRecentCpuLoads(&actualPercentages));
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,126 +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 <gtest/gtest.h>
|
||||
|
||||
#include "adaptivecpu/CpuLoadReaderSysDevices.h"
|
||||
#include "mocks.h"
|
||||
|
||||
#define LOG_TAG "powerhal-adaptivecpu"
|
||||
|
||||
using testing::_;
|
||||
using testing::ByMove;
|
||||
using testing::MatchesRegex;
|
||||
using testing::Return;
|
||||
using std::chrono_literals::operator""ms;
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
TEST(CpuLoadReaderSysDevicesTest, GetRecentCpuLoads) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
std::unique_ptr<MockTimeSource> timeSource = std::make_unique<MockTimeSource>();
|
||||
EXPECT_CALL(*filesystem, ListDirectory(MatchesRegex("/sys/devices/system/cpu/cpu0/cpuidle"), _))
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::vector<std::string>{"foo", "bar", "baz"};
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*filesystem,
|
||||
ListDirectory(MatchesRegex("/sys/devices/system/cpu/cpu0/cpuidle/(foo|bar)"), _))
|
||||
.Times(2)
|
||||
.WillRepeatedly([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::vector<std::string>{"abc", "time", "xyz"};
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*filesystem,
|
||||
ListDirectory(MatchesRegex("/sys/devices/system/cpu/cpu0/cpuidle/baz"), _))
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::vector<std::string>{"abc", "xyz"};
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/sys/devices/system/cpu/cpu0/cpuidle/foo/time", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("100");
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("200");
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/sys/devices/system/cpu/cpu0/cpuidle/bar/time", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("500");
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("700");
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/sys/devices/system/cpu/cpu1/cpuidle/foo/time", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1000");
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("1010");
|
||||
return true;
|
||||
});
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/sys/devices/system/cpu/cpu1/cpuidle/bar/time", _))
|
||||
.Times(2)
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("50");
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("70");
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_CALL(*filesystem,
|
||||
ReadFileStream(
|
||||
MatchesRegex("/sys/devices/system/cpu/cpu[2-7]/cpuidle/(foo|bar)/time"), _))
|
||||
.WillRepeatedly([](auto _path __attribute__((unused)), auto result) {
|
||||
*result = std::make_unique<std::istringstream>("0");
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_CALL(*timeSource, GetTime()).Times(2).WillOnce(Return(1ms)).WillOnce(Return(2ms));
|
||||
|
||||
CpuLoadReaderSysDevices reader(std::move(filesystem), std::move(timeSource));
|
||||
ASSERT_TRUE(reader.Init());
|
||||
|
||||
std::array<double, NUM_CPU_CORES> actualPercentage;
|
||||
reader.GetRecentCpuLoads(&actualPercentage);
|
||||
|
||||
std::array<double, NUM_CPU_CORES> expectedPercentage{0.3, 0.03, 0, 0, 0, 0, 0, 0};
|
||||
ASSERT_EQ(actualPercentage, expectedPercentage);
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2022 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 <gtest/gtest.h>
|
||||
|
||||
#include "adaptivecpu/KernelCpuFeatureReader.h"
|
||||
#include "mocks.h"
|
||||
|
||||
using testing::_;
|
||||
using testing::ByMove;
|
||||
using testing::MatchesRegex;
|
||||
using testing::Return;
|
||||
using std::chrono_literals::operator""ns;
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
TEST(KernelCpuFeatureReaderTest, valid) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
std::unique_ptr<MockTimeSource> timeSource = std::make_unique<MockTimeSource>();
|
||||
|
||||
EXPECT_CALL(*timeSource, GetKernelTime())
|
||||
.Times(2)
|
||||
.WillOnce(Return(100ns))
|
||||
.WillOnce(Return(200ns));
|
||||
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/proc/vendor_sched/acpu_stats", _))
|
||||
.WillOnce([](auto path __attribute__((unused)), auto result) {
|
||||
// Empty file, we will populate in ResetFileStream.
|
||||
*result = std::make_unique<std::istringstream>("");
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_CALL(*filesystem, ResetFileStream(_))
|
||||
.Times(2)
|
||||
.WillOnce([](auto &result) {
|
||||
std::array<acpu_stats, NUM_CPU_CORES> acpuStats{{
|
||||
{.weighted_sum_freq = 100, .total_idle_time_ns = 100},
|
||||
{.weighted_sum_freq = 100, .total_idle_time_ns = 100},
|
||||
{.weighted_sum_freq = 100, .total_idle_time_ns = 100},
|
||||
{.weighted_sum_freq = 100, .total_idle_time_ns = 100},
|
||||
{.weighted_sum_freq = 200, .total_idle_time_ns = 200},
|
||||
{.weighted_sum_freq = 200, .total_idle_time_ns = 200},
|
||||
{.weighted_sum_freq = 300, .total_idle_time_ns = 200},
|
||||
{.weighted_sum_freq = 300, .total_idle_time_ns = 200},
|
||||
}};
|
||||
char *bytes = reinterpret_cast<char *>(acpuStats.begin());
|
||||
static_cast<std::istringstream &>(*result).str(
|
||||
std::string(bytes, bytes + sizeof(acpuStats)));
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto &result) {
|
||||
std::array<acpu_stats, NUM_CPU_CORES> acpuStats{{
|
||||
{.weighted_sum_freq = 200, .total_idle_time_ns = 150},
|
||||
{.weighted_sum_freq = 100, .total_idle_time_ns = 150},
|
||||
{.weighted_sum_freq = 100, .total_idle_time_ns = 150},
|
||||
{.weighted_sum_freq = 100, .total_idle_time_ns = 150},
|
||||
{.weighted_sum_freq = 300, .total_idle_time_ns = 300},
|
||||
{.weighted_sum_freq = 200, .total_idle_time_ns = 300},
|
||||
{.weighted_sum_freq = 400, .total_idle_time_ns = 300},
|
||||
{.weighted_sum_freq = 300, .total_idle_time_ns = 300},
|
||||
}};
|
||||
char *bytes = reinterpret_cast<char *>(acpuStats.begin());
|
||||
static_cast<std::istringstream &>(*result).str(
|
||||
std::string(bytes, bytes + sizeof(acpuStats)));
|
||||
return true;
|
||||
});
|
||||
|
||||
KernelCpuFeatureReader reader(std::move(filesystem), std::move(timeSource));
|
||||
ASSERT_TRUE(reader.Init());
|
||||
|
||||
std::array<double, NUM_CPU_POLICIES> cpuPolicyAverageFrequencyHz;
|
||||
std::array<double, NUM_CPU_CORES> cpuCoreIdleTimesPercentage;
|
||||
ASSERT_TRUE(
|
||||
reader.GetRecentCpuFeatures(&cpuPolicyAverageFrequencyHz, &cpuCoreIdleTimesPercentage));
|
||||
std::array<double, NUM_CPU_POLICIES> expectedFrequencies{{1, 1, 1}};
|
||||
std::array<double, NUM_CPU_CORES> expectedIdleTimes{{0.5, 0.5, 0.5, 0.5, 1, 1, 1, 1}};
|
||||
ASSERT_EQ(cpuPolicyAverageFrequencyHz, expectedFrequencies);
|
||||
ASSERT_EQ(cpuCoreIdleTimesPercentage, expectedIdleTimes);
|
||||
}
|
||||
|
||||
TEST(KernelCpuFeatureReaderTest, noFile) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
std::unique_ptr<MockTimeSource> timeSource = std::make_unique<MockTimeSource>();
|
||||
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/proc/vendor_sched/acpu_stats", _))
|
||||
.WillOnce(Return(false));
|
||||
|
||||
KernelCpuFeatureReader reader(std::move(filesystem), std::move(timeSource));
|
||||
ASSERT_FALSE(reader.Init());
|
||||
}
|
||||
|
||||
TEST(KernelCpuFeatureReaderTest, frequencies_capsNegativeDiff) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
std::unique_ptr<MockTimeSource> timeSource = std::make_unique<MockTimeSource>();
|
||||
|
||||
EXPECT_CALL(*timeSource, GetKernelTime())
|
||||
.Times(2)
|
||||
.WillOnce(Return(100ns))
|
||||
.WillOnce(Return(200ns));
|
||||
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/proc/vendor_sched/acpu_stats", _))
|
||||
.WillOnce([](auto path __attribute__((unused)), auto result) {
|
||||
// Empty file, we will populate in ResetFileStream.
|
||||
*result = std::make_unique<std::istringstream>("");
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_CALL(*filesystem, ResetFileStream(_))
|
||||
.Times(2)
|
||||
.WillOnce([](auto &result) {
|
||||
std::array<acpu_stats, NUM_CPU_CORES> acpuStats{{
|
||||
{.weighted_sum_freq = 200, .total_idle_time_ns = 100},
|
||||
}};
|
||||
char *bytes = reinterpret_cast<char *>(acpuStats.begin());
|
||||
static_cast<std::istringstream &>(*result).str(
|
||||
std::string(bytes, bytes + sizeof(acpuStats)));
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto &result) {
|
||||
std::array<acpu_stats, NUM_CPU_CORES> acpuStats{{
|
||||
{.weighted_sum_freq = 100, .total_idle_time_ns = 150},
|
||||
}};
|
||||
char *bytes = reinterpret_cast<char *>(acpuStats.begin());
|
||||
static_cast<std::istringstream &>(*result).str(
|
||||
std::string(bytes, bytes + sizeof(acpuStats)));
|
||||
return true;
|
||||
});
|
||||
|
||||
KernelCpuFeatureReader reader(std::move(filesystem), std::move(timeSource));
|
||||
ASSERT_TRUE(reader.Init());
|
||||
|
||||
std::array<double, NUM_CPU_POLICIES> cpuPolicyAverageFrequencyHz;
|
||||
std::array<double, NUM_CPU_CORES> cpuCoreIdleTimesPercentage;
|
||||
ASSERT_TRUE(
|
||||
reader.GetRecentCpuFeatures(&cpuPolicyAverageFrequencyHz, &cpuCoreIdleTimesPercentage));
|
||||
std::array<double, NUM_CPU_POLICIES> expectedFrequencies{{0}};
|
||||
ASSERT_EQ(cpuPolicyAverageFrequencyHz, expectedFrequencies);
|
||||
}
|
||||
|
||||
TEST(KernelCpuFeatureReaderTest, idleTimes_capsNegativeDiff) {
|
||||
std::unique_ptr<MockFilesystem> filesystem = std::make_unique<MockFilesystem>();
|
||||
std::unique_ptr<MockTimeSource> timeSource = std::make_unique<MockTimeSource>();
|
||||
|
||||
EXPECT_CALL(*timeSource, GetKernelTime())
|
||||
.Times(2)
|
||||
.WillOnce(Return(100ns))
|
||||
.WillOnce(Return(200ns));
|
||||
|
||||
EXPECT_CALL(*filesystem, ReadFileStream("/proc/vendor_sched/acpu_stats", _))
|
||||
.WillOnce([](auto path __attribute__((unused)), auto result) {
|
||||
// Empty file, we will populate in ResetFileStream.
|
||||
*result = std::make_unique<std::istringstream>("");
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_CALL(*filesystem, ResetFileStream(_))
|
||||
.Times(2)
|
||||
.WillOnce([](auto &result) {
|
||||
std::array<acpu_stats, NUM_CPU_CORES> acpuStats{{
|
||||
{.weighted_sum_freq = 100, .total_idle_time_ns = 150},
|
||||
}};
|
||||
char *bytes = reinterpret_cast<char *>(acpuStats.begin());
|
||||
static_cast<std::istringstream &>(*result).str(
|
||||
std::string(bytes, bytes + sizeof(acpuStats)));
|
||||
return true;
|
||||
})
|
||||
.WillOnce([](auto &result) {
|
||||
std::array<acpu_stats, NUM_CPU_CORES> acpuStats{{
|
||||
{.weighted_sum_freq = 200, .total_idle_time_ns = 100},
|
||||
}};
|
||||
char *bytes = reinterpret_cast<char *>(acpuStats.begin());
|
||||
static_cast<std::istringstream &>(*result).str(
|
||||
std::string(bytes, bytes + sizeof(acpuStats)));
|
||||
return true;
|
||||
});
|
||||
|
||||
KernelCpuFeatureReader reader(std::move(filesystem), std::move(timeSource));
|
||||
ASSERT_TRUE(reader.Init());
|
||||
|
||||
std::array<double, NUM_CPU_POLICIES> cpuPolicyAverageFrequencyHz;
|
||||
std::array<double, NUM_CPU_CORES> cpuCoreIdleTimesPercentage;
|
||||
ASSERT_TRUE(
|
||||
reader.GetRecentCpuFeatures(&cpuPolicyAverageFrequencyHz, &cpuCoreIdleTimesPercentage));
|
||||
std::array<double, NUM_CPU_CORES> expectedIdleTimes{{0}};
|
||||
ASSERT_EQ(cpuCoreIdleTimesPercentage, expectedIdleTimes);
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,126 +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 <gtest/gtest.h>
|
||||
|
||||
#include <random>
|
||||
#include <set>
|
||||
|
||||
#include "adaptivecpu/Model.h"
|
||||
#include "mocks.h"
|
||||
|
||||
using std::chrono_literals::operator""ns;
|
||||
using testing::_;
|
||||
using testing::ByMove;
|
||||
using testing::Return;
|
||||
using testing::UnorderedElementsAre;
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
TEST(ModelTest, ModelInput_SetCpuFreqiencies) {
|
||||
const ModelInput expected{
|
||||
.cpuPolicyAverageFrequencyHz = {100, 101, 102},
|
||||
};
|
||||
ModelInput actual;
|
||||
ASSERT_TRUE(actual.SetCpuFreqiencies({
|
||||
{.policyId = 0, .averageFrequencyHz = 100},
|
||||
{.policyId = 4, .averageFrequencyHz = 101},
|
||||
{.policyId = 6, .averageFrequencyHz = 102},
|
||||
}));
|
||||
ASSERT_EQ(actual, expected);
|
||||
}
|
||||
|
||||
TEST(ModelTest, ModelInput_SetCpuFreqiencies_failsWithOutOfOrderFrquencies) {
|
||||
ASSERT_FALSE(ModelInput().SetCpuFreqiencies({
|
||||
{.policyId = 0, .averageFrequencyHz = 100},
|
||||
{.policyId = 6, .averageFrequencyHz = 102},
|
||||
{.policyId = 4, .averageFrequencyHz = 101},
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(ModelTest, Run_randomInputs) {
|
||||
std::default_random_engine generator;
|
||||
std::uniform_real_distribution<double> frequencyDistribution(0, 1e6);
|
||||
std::uniform_real_distribution<double> idleTimesDistribution(0, 1);
|
||||
std::uniform_int_distribution<uint32_t> frameTimeDistribution(1, 100);
|
||||
std::uniform_int_distribution<uint16_t> numRenderedFramesDistribution(1, 20);
|
||||
std::uniform_int_distribution<uint32_t> throttleDecisionDistribution(0, 3);
|
||||
|
||||
const auto randomModelInput = [&]() {
|
||||
return ModelInput{
|
||||
.cpuPolicyAverageFrequencyHz = {frequencyDistribution(generator),
|
||||
frequencyDistribution(generator),
|
||||
frequencyDistribution(generator)},
|
||||
.cpuCoreIdleTimesPercentage =
|
||||
{idleTimesDistribution(generator), idleTimesDistribution(generator),
|
||||
idleTimesDistribution(generator), idleTimesDistribution(generator),
|
||||
idleTimesDistribution(generator), idleTimesDistribution(generator),
|
||||
idleTimesDistribution(generator), idleTimesDistribution(generator)},
|
||||
.workDurationFeatures =
|
||||
{.averageDuration =
|
||||
std::chrono::nanoseconds(frameTimeDistribution(generator)),
|
||||
.maxDuration = std::chrono::nanoseconds(frameTimeDistribution(generator)),
|
||||
.numMissedDeadlines = numRenderedFramesDistribution(generator),
|
||||
.numDurations = numRenderedFramesDistribution(generator)},
|
||||
.previousThrottleDecision =
|
||||
static_cast<ThrottleDecision>(throttleDecisionDistribution(generator)),
|
||||
};
|
||||
};
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
std::deque<ModelInput> modelInputs{randomModelInput(), randomModelInput(),
|
||||
randomModelInput()};
|
||||
Model().Run(modelInputs, AdaptiveCpuConfig::DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ModelTest, Run_randomThrottling) {
|
||||
ModelInput modelInput{
|
||||
.cpuPolicyAverageFrequencyHz = {0, 0, 0},
|
||||
.cpuCoreIdleTimesPercentage = {0, 0, 0, 0, 0, 0, 0, 0},
|
||||
.workDurationFeatures = {.averageDuration = 0ns,
|
||||
.maxDuration = 0ns,
|
||||
.numMissedDeadlines = 0,
|
||||
.numDurations = 0},
|
||||
.previousThrottleDecision = ThrottleDecision::NO_THROTTLE,
|
||||
};
|
||||
std::deque<ModelInput> modelInputs{modelInput, modelInput, modelInput};
|
||||
|
||||
AdaptiveCpuConfig config = AdaptiveCpuConfig::DEFAULT;
|
||||
config.randomThrottleOptions = {ThrottleDecision::THROTTLE_70, ThrottleDecision::THROTTLE_80};
|
||||
config.randomThrottleDecisionProbability = 1;
|
||||
|
||||
std::set<ThrottleDecision> actualThrottleDecisions;
|
||||
Model model;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
ThrottleDecision throttleDecision = model.Run(modelInputs, config);
|
||||
actualThrottleDecisions.insert(throttleDecision);
|
||||
}
|
||||
ASSERT_THAT(actualThrottleDecisions,
|
||||
UnorderedElementsAre(ThrottleDecision::THROTTLE_70, ThrottleDecision::THROTTLE_80));
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,126 +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 <gtest/gtest.h>
|
||||
|
||||
#include "adaptivecpu/WorkDurationProcessor.h"
|
||||
|
||||
using ::aidl::android::hardware::power::WorkDuration;
|
||||
using std::chrono_literals::operator""ns;
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
static const std::chrono::nanoseconds kNormalTargetDuration = 16666666ns;
|
||||
|
||||
TEST(WorkDurationProcessorTest, GetFeatures) {
|
||||
WorkDurationProcessor processor;
|
||||
ASSERT_TRUE(processor.ReportWorkDurations(
|
||||
std::vector<WorkDuration>{
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count()},
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count() * 3}},
|
||||
kNormalTargetDuration));
|
||||
|
||||
const WorkDurationFeatures expected = {.averageDuration = kNormalTargetDuration * 2,
|
||||
.maxDuration = kNormalTargetDuration * 3,
|
||||
.numMissedDeadlines = 1,
|
||||
.numDurations = 2};
|
||||
const WorkDurationFeatures actual = processor.GetFeatures();
|
||||
ASSERT_EQ(actual, expected);
|
||||
}
|
||||
|
||||
TEST(WorkDurationProcessorTest, GetFeatures_multipleBatches) {
|
||||
WorkDurationProcessor processor;
|
||||
ASSERT_TRUE(processor.ReportWorkDurations(
|
||||
std::vector<WorkDuration>{
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count()},
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count() * 3}},
|
||||
kNormalTargetDuration));
|
||||
ASSERT_TRUE(processor.ReportWorkDurations(
|
||||
std::vector<WorkDuration>{
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count() * 6},
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count() * 2}},
|
||||
kNormalTargetDuration));
|
||||
|
||||
const WorkDurationFeatures expected = {.averageDuration = kNormalTargetDuration * 3,
|
||||
.maxDuration = kNormalTargetDuration * 6,
|
||||
.numMissedDeadlines = 3,
|
||||
.numDurations = 4};
|
||||
const WorkDurationFeatures actual = processor.GetFeatures();
|
||||
ASSERT_EQ(actual, expected);
|
||||
}
|
||||
|
||||
TEST(WorkDurationProcessorTest, GetFeatures_scalesDifferentTargetDurations) {
|
||||
WorkDurationProcessor processor;
|
||||
ASSERT_TRUE(processor.ReportWorkDurations(
|
||||
std::vector<WorkDuration>{
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count() * 2},
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count() * 6}},
|
||||
kNormalTargetDuration * 2));
|
||||
|
||||
const WorkDurationFeatures expected = {.averageDuration = kNormalTargetDuration * 2,
|
||||
.maxDuration = kNormalTargetDuration * 3,
|
||||
.numMissedDeadlines = 1,
|
||||
.numDurations = 2};
|
||||
const WorkDurationFeatures actual = processor.GetFeatures();
|
||||
ASSERT_EQ(actual, expected);
|
||||
}
|
||||
|
||||
TEST(WorkDurationProcessorTest, GetFeatures_noFrames) {
|
||||
WorkDurationProcessor processor;
|
||||
const WorkDurationFeatures expected = {
|
||||
.averageDuration = 0ns, .maxDuration = 0ns, .numMissedDeadlines = 0, .numDurations = 0};
|
||||
const WorkDurationFeatures actual = processor.GetFeatures();
|
||||
ASSERT_EQ(actual, expected);
|
||||
}
|
||||
|
||||
TEST(WorkDurationProcessorTest, HasWorkDurations) {
|
||||
WorkDurationProcessor processor;
|
||||
ASSERT_FALSE(processor.HasWorkDurations());
|
||||
ASSERT_TRUE(processor.ReportWorkDurations(
|
||||
std::vector<WorkDuration>{
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count()}},
|
||||
kNormalTargetDuration * 2));
|
||||
ASSERT_TRUE(processor.HasWorkDurations());
|
||||
processor.GetFeatures();
|
||||
ASSERT_FALSE(processor.HasWorkDurations());
|
||||
}
|
||||
|
||||
TEST(WorkDurationProcessorTest, GetFeatures_tooManyUnprocessedThenClears) {
|
||||
WorkDurationProcessor processor;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ASSERT_TRUE(processor.ReportWorkDurations(
|
||||
std::vector<WorkDuration>{
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count()}},
|
||||
kNormalTargetDuration));
|
||||
}
|
||||
ASSERT_FALSE(processor.ReportWorkDurations(
|
||||
std::vector<WorkDuration>{
|
||||
{.timeStampNanos = 0, .durationNanos = kNormalTargetDuration.count()}},
|
||||
kNormalTargetDuration));
|
||||
ASSERT_EQ(processor.GetFeatures().numDurations, 0);
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,53 +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 <gmock/gmock.h>
|
||||
|
||||
#include "adaptivecpu/IFilesystem.h"
|
||||
#include "adaptivecpu/ITimeSource.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
class MockFilesystem : public IFilesystem {
|
||||
public:
|
||||
~MockFilesystem() override {}
|
||||
MOCK_METHOD(bool, ListDirectory, (const std::string &path, std::vector<std::string> *result),
|
||||
(const, override));
|
||||
MOCK_METHOD(bool, ReadFileStream,
|
||||
(const std::string &path, std::unique_ptr<std::istream> *result),
|
||||
(const, override));
|
||||
MOCK_METHOD(bool, ResetFileStream, (const std::unique_ptr<std::istream> &fileStream),
|
||||
(const, override));
|
||||
};
|
||||
|
||||
class MockTimeSource : public ITimeSource {
|
||||
public:
|
||||
~MockTimeSource() override {}
|
||||
MOCK_METHOD(std::chrono::nanoseconds, GetTime, (), (const, override));
|
||||
MOCK_METHOD(std::chrono::nanoseconds, GetKernelTime, (), (const, override));
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,5 +0,0 @@
|
|||
BOARD_SEPOLICY_DIRS += hardware/google/pixel-sepolicy/power-libperfmgr
|
||||
|
||||
# power HAL
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.power-service.pixel-libperfmgr
|
|
@ -1,32 +1,25 @@
|
|||
service vendor.power-hal-aidl /vendor/bin/hw/android.hardware.power-service.lenovo-sdm710-libperfmgr
|
||||
service vendor.power-hal-aidl /vendor/bin/hw/android.hardware.power-service.xiaomi-libperfmgr
|
||||
class hal
|
||||
user root
|
||||
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 ""
|
||||
setprop vendor.powerhal.audio ""
|
||||
setprop vendor.powerhal.rendering ""
|
||||
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}
|
||||
|
||||
# Restart powerHAL when debug property set
|
||||
on property:ro.debuggable=1 && property:vendor.powerhal.config.debug=*
|
||||
restart vendor.power-hal-aidl
|
||||
|
||||
on property:persist.vendor.powerhal.config.debug=*
|
||||
setprop vendor.powerhal.config.debug ${persist.vendor.powerhal.config.debug}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.power</name>
|
||||
<version>3</version>
|
||||
<version>2</version>
|
||||
<fqname>IPower/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
|
@ -1,87 +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 "powerhal-libperfmgr"
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cutils/sockets.h>
|
||||
#include <log/log.h>
|
||||
|
||||
#include "DisplayLowPower.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
DisplayLowPower::DisplayLowPower() : mFossStatus(false) {}
|
||||
|
||||
void DisplayLowPower::Init() {
|
||||
ConnectPpsDaemon();
|
||||
}
|
||||
|
||||
void DisplayLowPower::SetDisplayLowPower(bool enable) {
|
||||
SetFoss(enable);
|
||||
}
|
||||
|
||||
void DisplayLowPower::ConnectPpsDaemon() {
|
||||
constexpr const char kPpsDaemon[] = "pps";
|
||||
|
||||
mPpsSocket.reset(
|
||||
socket_local_client(kPpsDaemon, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM));
|
||||
if (mPpsSocket.get() < 0) {
|
||||
ALOGW("Connecting to PPS daemon failed (%s)", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
int DisplayLowPower::SendPpsCommand(const std::string_view cmd) {
|
||||
if (TEMP_FAILURE_RETRY(write(mPpsSocket.get(), cmd.data(), cmd.size())) < 0) {
|
||||
ALOGE("Failed to send pps command '%s' over socket (%s)", cmd.data(), strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DisplayLowPower::SetFoss(bool enable) {
|
||||
if (mPpsSocket.get() < 0 || mFossStatus == enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALOGI("%s foss", (enable) ? "Enable" : "Disable");
|
||||
|
||||
std::string_view foss_cmd;
|
||||
if (enable) {
|
||||
foss_cmd = "foss:on";
|
||||
} else {
|
||||
foss_cmd = "foss:off";
|
||||
}
|
||||
|
||||
if (!SendPpsCommand(foss_cmd)) {
|
||||
mFossStatus = enable;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -1,51 +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 <string_view>
|
||||
|
||||
#include <android-base/unique_fd.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
class DisplayLowPower {
|
||||
public:
|
||||
DisplayLowPower();
|
||||
~DisplayLowPower() {}
|
||||
void Init();
|
||||
void SetDisplayLowPower(bool enable);
|
||||
|
||||
private:
|
||||
void ConnectPpsDaemon();
|
||||
int SendPpsCommand(const std::string_view cmd);
|
||||
void SetFoss(bool enable);
|
||||
|
||||
::android::base::unique_fd mPpsSocket;
|
||||
bool mFossStatus;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
|
@ -13,80 +13,55 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "powerhal-libperfmgr"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android/binder_ibinder_platform.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "Power.h"
|
||||
#include "PowerExt.h"
|
||||
#include "PowerSessionManager.h"
|
||||
#include "adaptivecpu/AdaptiveCpu.h"
|
||||
#include "disp-power/DisplayLowPower.h"
|
||||
|
||||
using aidl::google::hardware::power::impl::pixel::AdaptiveCpu;
|
||||
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");
|
||||
|
||||
int main() {
|
||||
// Parse config but do not start the looper
|
||||
std::shared_ptr<HintManager> hm = HintManager::GetInstance();
|
||||
std::shared_ptr<HintManager> hm = std::shared_ptr<HintManager>(HintManager::GetInstance());
|
||||
if (!hm) {
|
||||
LOG(FATAL) << "HintManager Init failed";
|
||||
}
|
||||
|
||||
std::shared_ptr<DisplayLowPower> dlpw = std::make_shared<DisplayLowPower>();
|
||||
|
||||
// single thread
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
|
||||
std::shared_ptr<AdaptiveCpu> adaptiveCpu = std::make_shared<AdaptiveCpu>();
|
||||
|
||||
// core service
|
||||
std::shared_ptr<Power> pw = ndk::SharedRefBase::make<Power>(dlpw, adaptiveCpu);
|
||||
std::shared_ptr<Power> pw = ndk::SharedRefBase::make<Power>();
|
||||
ndk::SpAIBinder pwBinder = pw->asBinder();
|
||||
AIBinder_setMinSchedulerPolicy(pwBinder.get(), SCHED_NORMAL, -20);
|
||||
|
||||
// extension service
|
||||
std::shared_ptr<PowerExt> pwExt = ndk::SharedRefBase::make<PowerExt>(dlpw, adaptiveCpu);
|
||||
std::shared_ptr<PowerExt> pwExt = ndk::SharedRefBase::make<PowerExt>();
|
||||
auto pwExtBinder = pwExt->asBinder();
|
||||
AIBinder_setMinSchedulerPolicy(pwExtBinder.get(), SCHED_NORMAL, -20);
|
||||
|
||||
// attach the extension to the same binder we will be registering
|
||||
CHECK(STATUS_OK == AIBinder_setExtension(pwBinder.get(), pwExt->asBinder().get()));
|
||||
|
||||
const std::string instance = std::string() + Power::descriptor + "/default";
|
||||
binder_status_t status = AServiceManager_addService(pw->asBinder().get(), instance.c_str());
|
||||
CHECK(status == STATUS_OK);
|
||||
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is started.";
|
||||
|
||||
LOG(INFO) << "Xiaomi Power HAL AIDL Service with Extension is started.";
|
||||
if (HintManager::GetInstance()->GetAdpfProfile()) {
|
||||
PowerHintMonitor::getInstance()->start();
|
||||
}
|
||||
|
||||
std::thread initThread([&]() {
|
||||
::android::base::WaitForProperty(kPowerHalInitProp.data(), "1");
|
||||
HintManager::GetInstance()->Start();
|
||||
dlpw->Init();
|
||||
});
|
||||
initThread.detach();
|
||||
|
||||
ABinderProcess_joinThreadPool();
|
||||
|
||||
// should not reach
|
||||
LOG(ERROR) << "Pixel Power HAL AIDL Service with Extension just died.";
|
||||
LOG(ERROR) << "Xiaomi Power HAL AIDL Service with Extension just died.";
|
||||
return EXIT_FAILURE;
|
||||
}
|
|
@ -6,7 +6,6 @@ persist.audio.fluence.voicecall=true
|
|||
persist.audio.fluence.voicerec=false
|
||||
persist.audio.fluence.speaker=true
|
||||
persist.audio.fluence.voicecomm=true
|
||||
persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxhd-aac-ldac
|
||||
ro.qc.sdk.audio.ssr=false
|
||||
ro.qc.sdk.audio.fluencetype=none
|
||||
|
||||
|
@ -113,3 +112,6 @@ ro.zram.periodic_wb_delay_hours=24
|
|||
|
||||
# Zygote
|
||||
persist.device_config.runtime_native.usap_pool_enabled=true
|
||||
|
||||
# Radio
|
||||
persist.vendor.qti.telephony.vt_cam_interface=2
|
||||
|
|
|
@ -444,16 +444,16 @@ vendor/lib64/vendor.qti.esepowermanager@1.0.so|a114629809e67015a14e5e367c6fb374a
|
|||
vendor/lib64/vendor.qti.esepowermanager@1.1.so|f111cf42439d28fe88d9ebf6b6a1c44b729a3194
|
||||
|
||||
# FM
|
||||
lib64/fm_helium.so
|
||||
lib64/libfm-hci.so
|
||||
lib/fm_helium.so
|
||||
lib/libfm-hci.so
|
||||
-product/lib64/vendor.qti.hardware.fm@1.0.so
|
||||
-product/lib/vendor.qti.hardware.fm@1.0.so
|
||||
vendor/lib64/hw/vendor.qti.hardware.fm@1.0-impl.so
|
||||
vendor/lib64/vendor.qti.hardware.fm@1.0.so
|
||||
-product/lib/vendor.qti.hardware.fm@1.0.so:system_ext/lib/vendor.qti.hardware.fm@1.0.so
|
||||
-product/lib64/vendor.qti.hardware.fm@1.0.so:system_ext/lib64/vendor.qti.hardware.fm@1.0.so
|
||||
system/lib/fm_helium.so:system_ext/lib/fm_helium.so
|
||||
system/lib/libfm-hci.so:system_ext/lib/libfm-hci.so
|
||||
system/lib64/fm_helium.so:system_ext/lib64/fm_helium.so
|
||||
system/lib64/libfm-hci.so:system_ext/lib64/libfm-hci.so
|
||||
vendor/lib/hw/vendor.qti.hardware.fm@1.0-impl.so
|
||||
vendor/lib/vendor.qti.hardware.fm@1.0.so
|
||||
vendor/lib64/hw/vendor.qti.hardware.fm@1.0-impl.so
|
||||
vendor/lib64/vendor.qti.hardware.fm@1.0.so
|
||||
|
||||
# Gatekeeper
|
||||
vendor/bin/hw/android.hardware.gatekeeper@1.0-service-qti
|
||||
|
@ -1006,67 +1006,53 @@ vendor/lib64/mediadrm/libwvdrmengine.so|f25fe9c6038fb99b0308998e0a8dba3b7c32fa50
|
|||
vendor/lib64/libwvhidl.so|f32257498c35e1336b48a03463f8c8cea7df7b18
|
||||
vendor/lib/mediadrm/libwvdrmengine.so|0363a398d49518d0442df335e8cb7f19741dec9d
|
||||
|
||||
# WiFi Display - from LA.QSSI.13.0.r1-05300-qssi.0
|
||||
-system/framework/WfdCommon.jar|9f431b56d7f38c71089333008695dd5f717e5034
|
||||
system_ext/bin/wfdservice64|3326f77c84ac3b164d3ac4696292ad4ea9f20b72
|
||||
system_ext/bin/wfdservice|cd0638589d1f652d5d40673105dd3ee63856cb88
|
||||
# WiFi Display (system) - from KB2001 14.0.0.81(EX01)
|
||||
system/framework/WfdCommon.jar|a661c494d064b79a3f71579592411fada1ea232f
|
||||
system_ext/bin/wfdservice|400d123df78c1ed2e9643ff3ddf5ee5748f954fe
|
||||
system_ext/etc/init/wfdservice.rc|907def8565d8f91f531ca7dfad880af05d540b0c
|
||||
system_ext/etc/permissions/wfd-system-ext-privapp-permissions-qti.xml|828999946f9dfef98f17f42a1c8daba47c2c442d
|
||||
system_ext/etc/seccomp_policy/wfdservice.policy|37994de64d6bd127898bd556cd614db459fe07ec
|
||||
system_ext/etc/seccomp_policy/wfdservice64.policy|1e331272649395423b11c575892e0bdc9433b820
|
||||
system_ext/etc/seccomp_policy/wfdservice.policy|5b3592c965f16b2d55ac89d56d8d3c49a6b5800b
|
||||
system_ext/etc/wfdconfigsink.xml|cb78df66948314a75080a4161321fb3111a0785a
|
||||
system_ext/lib/com.qualcomm.qti.wifidisplayhal@1.0.so|146073f7288ee95dc5297d397e5199e5bc24e67d
|
||||
system_ext/lib/libmiracastsystem.so|3b1caaa0b5f84e2c986af78a6a48e59d332282c4
|
||||
system_ext/lib/libmmosal.so|fc1359e5c79abf0bb877a652e6b900cef911e9dc
|
||||
system_ext/lib/libmmparser_lite.so|7171defd018c507a2e34784569eb9920a22f15cf
|
||||
system_ext/lib/libmmrtpdecoder.so|e15387b44fd9b3661d763d934663551ca30743d7
|
||||
system_ext/lib/libmmrtpencoder.so|dbf276471b60a706d76e12edde388ef887b27396
|
||||
system_ext/lib/libwfdavenhancements.so|8a2eeeb2185b8b06aadeb11ec32141cea37cac9c
|
||||
system_ext/lib/libwfdclient.so|feead7bcaf6a54b60a511f62fe2822a5ebf3fbee
|
||||
system_ext/lib/libwfdcommonutils.so|4b48d7941df68f7316c464d94d2f31d4e8f026e5
|
||||
system_ext/lib/libwfdconfigutils.so|2f6a16b597f814697d2ca1d92eab618b3e90ac9d
|
||||
system_ext/lib/libwfddisplayconfig.so|ec3383d6c03a21985f4442eae6c7e935867d10c8
|
||||
system_ext/lib/libwfdmminterface.so|610a9dadc4f577a655b9fdfee2411a44b0e39a7d
|
||||
system_ext/lib/libwfdmmsink.so|a045b3dd2b4cad52684e579af2d72554c178e9f6
|
||||
system_ext/lib/libwfdmmsrc_system.so|c3a0c08eaefa1cb59ed3134752b9a6d424c0e1e6
|
||||
system_ext/lib/libwfdrtsp.so|3ace8ddfd6dc3f8aea2d8f489431599e6467de1c
|
||||
system_ext/lib/libwfdservice.so|1512125bbba762f3e5293a24ff13457a69597472
|
||||
system_ext/lib/libwfdsinksm.so|68d32947455c468d12e52a57cd71a2ba50d7fcd2
|
||||
system_ext/lib/libwfduibcinterface.so|7ac5b7fd7ff0b469629548549cf3a907068be174
|
||||
system_ext/lib/libwfduibcsink.so|5630028a8152379a1037d81224b8c031209b93ce
|
||||
system_ext/lib/libwfduibcsinkinterface.so|25e3cd7b8fd106c401597e9d71f47006ca06b31f
|
||||
system_ext/lib/libwfduibcsrc.so|09821648adb3275b2c2619af7581f35a47643ff5
|
||||
system_ext/lib/libwfduibcsrcinterface.so|0c98741c0d65b27acf73a8b1a742e433fbeb86f4
|
||||
system_ext/lib/vendor.qti.hardware.sigma_miracast@1.0-halimpl.so|6b274a507030e3b32c053a0eead50679c540448b
|
||||
system_ext/lib/vendor.qti.hardware.sigma_miracast@1.0.so|c8c3d91a4732bee4c056f3af9bab89ac9622397c
|
||||
system_ext/lib/vendor.qti.hardware.wifidisplaysession@1.0.so|d4e627158da501dd52f8936312f40364f480b1eb
|
||||
system_ext/lib64/com.qualcomm.qti.wifidisplayhal@1.0.so|07a7c1f2f394d64b3683d318aa03bfacbe1e6784
|
||||
system_ext/lib64/libmiracastsystem.so|49385d8087da9b338b8a4ed99e5fa5cc0133c0b1
|
||||
system_ext/lib64/libmmosal.so|d46f10b470ecd829c6f2a424566f1cbbc6ebe234
|
||||
system_ext/lib64/libmmparser_lite.so|1959f64d628f9c7dac476f4e32a4f9cae1443f76
|
||||
system_ext/lib64/libmmrtpdecoder.so|8bb6d0a8f31795ed913acd3e8cb2299ada7cd22c
|
||||
system_ext/lib64/libmmrtpencoder.so|fef79b731d9c2109f23ebc27575b6e057da8310f
|
||||
system_ext/lib64/libwfdavenhancements.so|4906965cc3c3df4f1185cd63ae4f624666216b06
|
||||
system_ext/lib64/libwfdclient.so|09d0f04a6251f14f41e548592a9848af9d70975c
|
||||
system_ext/lib64/libwfdcommonutils.so|4350b11e16553d02fded587feaae5cd82cdfaa0a
|
||||
system_ext/lib64/libwfdconfigutils.so|08e0be434b9c54035c4ead47ebb7f0322e2a23ba
|
||||
system_ext/lib64/libwfddisplayconfig.so|59a5cb17ffe46900c0ae26a8937a5ddab80fe283
|
||||
system_ext/lib64/libwfdmminterface.so|b1e33104bc2231c7f75132757a28c918ee4b3889
|
||||
system_ext/lib64/libwfdmmsink.so|0db18686f52492b89d9feffffd0494371f6a8c18
|
||||
system_ext/lib64/libwfdmmsrc_system.so|d46d868c7047927c7da7cc3f7274177de655de7d
|
||||
system_ext/lib64/libwfdnative.so|bf8b8596431d578f12f9eead38b5afbb4c54a008
|
||||
system_ext/lib64/libwfdrtsp.so|1957934068e8befa237106fbc584457e86ef07da
|
||||
system_ext/lib64/libwfdservice.so|b0e0b2059142168e856d66cc34448704849f14b4
|
||||
system_ext/lib64/libwfdsinksm.so|bd2369a1203a3b24115605ec1d27d288b4b62718
|
||||
system_ext/lib64/libwfduibcinterface.so|d5a578a2159c4681cb9d159b93c1c39b8f3091f7
|
||||
system_ext/lib64/libwfduibcsink.so|d4cc3afb86003f0e26134f82b503b6deac30b6b5
|
||||
system_ext/lib64/libwfduibcsinkinterface.so|a875792e5242870cd9a069cb367a6b5031fce2f0
|
||||
system_ext/lib64/libwfduibcsrc.so|1529ca18c3484b8a3f3d95e9198def564e86fda3
|
||||
system_ext/lib64/libwfduibcsrcinterface.so|69400030817aa8f6994a525b027bb3dd7cabd0d4
|
||||
system_ext/lib64/vendor.qti.hardware.sigma_miracast@1.0-halimpl.so|a2d59542267d94c451b85bc0541388d004adb68e
|
||||
system_ext/lib64/vendor.qti.hardware.sigma_miracast@1.0.so|c2a925b368d2d85a3ed0beebef61fb16209e2303
|
||||
system_ext/lib64/vendor.qti.hardware.wifidisplaysession@1.0.so|10b4472b777e070e51ed81ab371b05cfc5324d18
|
||||
system_ext/priv-app/WfdService/WfdService.apk|556c225c72b346319b0c0615e3ed43e1fcf1384d
|
||||
system_ext/lib/com.qualcomm.qti.wifidisplayhal@1.0.so|cb88bc73bf9f44d7da000a41d38b309ffdf71370
|
||||
system_ext/lib/libmmosal.so|e806f8040b4e59c6e08e437734a2176090a94ae3
|
||||
system_ext/lib/libmmparser_lite.so|873d818fbfa0ce01a1f9cd951c1fba32d4159735
|
||||
system_ext/lib/libmmrtpdecoder.so|4fc76315f11ff5fe416f36b66c9422ef05eae182
|
||||
system_ext/lib/libmmrtpencoder.so|0fa2096eec29eec395f6bd88d7d1049a127e090c
|
||||
system_ext/lib/libwfdavenhancements.so|581db496334d2adb76e6c6af67620f49ca24eabd
|
||||
system_ext/lib/libwfdclient.so|a9639d9f269880700bac6fc06e8302702fb0ab32
|
||||
system_ext/lib/libwfdcommonutils.so|b738182e77f3e7faf72460f09ebdfca7de5e0c23
|
||||
system_ext/lib/libwfdconfigutils.so|df70b2da2b8aff916a1c2f6e7365d87cf1c4ffdf
|
||||
system_ext/lib/libwfddisplayconfig.so|f46fe63fb3d58c143dc92741a962167af3d8b928
|
||||
system_ext/lib/libwfdmminterface.so|5844114d7cc823090a70fe4f44cbda0ddf585ebd
|
||||
system_ext/lib/libwfdmmsink.so|23fb5c836fc06865b229c30b46998e41c0624dac
|
||||
system_ext/lib/libwfdmmsrc_system.so|0adfc69a5560158f3a6803ba720acc795d6d05dc
|
||||
system_ext/lib/libwfdrtsp.so|afd69963c2bd59bdb3ff23e01710c61ed90c5d87
|
||||
system_ext/lib/libwfdservice.so|07e6d0e00393a8c068f75b46531d2e75fdaebde2
|
||||
system_ext/lib/libwfdsinksm.so|875171cc6ae534dd941eec1c87b78d5961e19c06
|
||||
system_ext/lib/libwfduibcinterface.so|e90fa4920b010bd6ef2bd78c2d2644cbd0fcbffa
|
||||
system_ext/lib/libwfduibcsink.so|91af548471c395a958e6155dd9be19cccbe482d3
|
||||
system_ext/lib/libwfduibcsinkinterface.so|bc0e7dca28d1e5cbc6caf5bd5378f3e6db3b460c
|
||||
system_ext/lib/libwfduibcsrc.so|a0b1c73015c449468db0d2776fdfcc56dfeee53b
|
||||
system_ext/lib/libwfduibcsrcinterface.so|2e24ec6a075407664488b4214eef35cb2ca845f4
|
||||
system_ext/lib/vendor.qti.hardware.wifidisplaysession@1.0.so|45a0a8cd9f1aa5cbe69b113192d42bc42e32e9c3
|
||||
system_ext/lib64/libmmosal.so|8488b27e6a9cda05c68181e8bf20afa7ba345222
|
||||
system_ext/lib64/libmmparser_lite.so|afd7b441e1bce732c14f5f8f49821d43bb2ee791
|
||||
system_ext/lib64/libmmrtpdecoder.so|0da526d51135ea58236ab6bcc2d1b7484931df24
|
||||
system_ext/lib64/libmmrtpencoder.so|fafe00d1ed3d691c6d2c2d963144218764cad5ae
|
||||
system_ext/lib64/libwfdclient.so|0070b1e88cee6ebaf17dcb02c2706232cc087071
|
||||
system_ext/lib64/libwfdcommonutils.so|14b3bd86703f2aca0abb1232d2304e626c1af644
|
||||
system_ext/lib64/libwfdconfigutils.so|3b2d91fe7efefd81a0b5cdff59b9918c063fa7a9
|
||||
system_ext/lib64/libwfddisplayconfig.so|5fd7bf7abaedfe890442f88183c49755b25c39aa
|
||||
system_ext/lib64/libwfdmminterface.so|3f16acefbe87741a5841c1c70cf74ff917299c4c
|
||||
system_ext/lib64/libwfdmmsink.so|8150b750357b606475521b491f78d566673f9888
|
||||
system_ext/lib64/libwfdnative.so|6d6dad5e631bc4d63463f608c47f3f9e5493944f
|
||||
system_ext/lib64/libwfdrtsp.so|8181e44d7c1f722218fabd8fe3bf788454a3f586
|
||||
system_ext/lib64/libwfdsinksm.so|c4d68ecbe0accd24296c18444e5a82b6a24be8d8
|
||||
system_ext/lib64/libwfduibcinterface.so|dca32fe063bdba7ce3b131b16cf112b793ae03ad
|
||||
system_ext/lib64/libwfduibcsink.so|63ea93b1a6aec75a294baf50007270807a819e21
|
||||
system_ext/lib64/libwfduibcsinkinterface.so|39c123bd9a4d7a8fa317f8ed4d86972dcfab0423
|
||||
system_ext/lib64/libwfduibcsrc.so|5557f3bd58c37b7e3b28e13f2f86d55930b14ab6
|
||||
system_ext/lib64/libwfduibcsrcinterface.so|77cead9bf7b60384fe1e11dc2b25bd99af0b4608
|
||||
system_ext/priv-app/WfdService/WfdService.apk|7191da7d336f6018ee292af4e69167677b9f5bd1
|
||||
|
||||
# WiFi Display - from OnePlus6 - RKQ1.201217.002/2106301530
|
||||
vendor/bin/wfdhdcphalservice|c459a9dce083f9a2b2d8c7c49903514b87528fda
|
||||
|
@ -1108,93 +1094,3 @@ vendor/lib64/libmmosal.so|c21735de83eecb9f869ab6268c84f4284428cb35
|
|||
vendor/lib64/libwfddisplayconfig_proprietary.so|fb6a6c36346a30662d0f79bb8a8656e32cc2e75d
|
||||
vendor/lib64/libwfdhdcpcp.so|af856708b2ab67e08f76fd5a746028a448991150
|
||||
vendor/lib64/vendor.qti.hardware.wifidisplaysession@1.0.so|86b6ce7b14bcc8f6ab3215962aab694404c27d14
|
||||
|
||||
# CarrierSettings - from coral - R-RPP4.200409.0
|
||||
product/etc/CarrierSettings/airtel_in.pb|ba76d9ecfd74d9e19432adae9b5422ed7f84b747
|
||||
product/etc/CarrierSettings/att5g_us.pb|bb3047e16ef7e5e10df2e558eccd22b4c7e218a8
|
||||
product/etc/CarrierSettings/att_us.pb|3783859071b6c2fadb68bb5e7761a994ad24a1df
|
||||
product/etc/CarrierSettings/bell_ca.pb|08731f06ed601eef96e0f49e10ea102a07611d40
|
||||
product/etc/CarrierSettings/bluegrass_us.pb|a3867c30fde04dd25672879b10e71093e6a1a27d
|
||||
product/etc/CarrierSettings/boost_us.pb|7bc04fe92bec403c75fa775287e2f3f388ade735
|
||||
product/etc/CarrierSettings/bouygues_fr.pb|c6e6485a431ea3bc27970e39bad00f6d1c4829be
|
||||
product/etc/CarrierSettings/btb_gb.pb|8315914b1325c20f9cc7c146640ade7a17db15f5
|
||||
product/etc/CarrierSettings/btc_gb.pb|520e35048aa2dc512f91daef0368078762c1b227
|
||||
product/etc/CarrierSettings/carrier_list.pb|a507ef3823cb112ef8ecf2b4d34a9ec1c2fe0aec
|
||||
product/etc/CarrierSettings/cellcom_us.pb|e0271b45c00558149207e10aa4432b357d7526d5
|
||||
product/etc/CarrierSettings/cht_tw.pb|15d5e721135952f5ca61b16a0308ad79f9a50d14
|
||||
product/etc/CarrierSettings/cricket5g_us.pb|3d08fa78f678a2af8c0e02822ddcea7c3b418978
|
||||
product/etc/CarrierSettings/cricket_us.pb|3d644f7979bc49b2e02ccd5b874889dad30d74ac
|
||||
product/etc/CarrierSettings/cspire_us.pb|79d946f83ab94191c83d328215b5e5ba411bc3c6
|
||||
product/etc/CarrierSettings/default.pb|16a66a14c61179da975b08232d47467822073464
|
||||
product/etc/CarrierSettings/docomo_jp.pb|208821ce29073a4cbfff539e38fd3052d2217d2a
|
||||
product/etc/CarrierSettings/ee_gb.pb|3c0559c8a7c45ce5d02817f06e16a37e0094effc
|
||||
product/etc/CarrierSettings/eplus_de.pb|35270a40cf3e68e038c2325eedf05c1cc9cf7b5f
|
||||
product/etc/CarrierSettings/fet_tw.pb|0cded656dec55574685cddeecf85602b771a297c
|
||||
product/etc/CarrierSettings/fido_ca.pb|4155bd3094920d0646a620ccfcf4971976ceb898
|
||||
product/etc/CarrierSettings/firstnetpacific_us.pb|668a686c4edd7b9da40fb3c034451b23a4f6c3f3
|
||||
product/etc/CarrierSettings/firstnet_us.pb|1bc9ef44d70063522e86c5aa1be721f3636d3d4e
|
||||
product/etc/CarrierSettings/fi_us.pb|e2803619ccf36f63bd105cac4e46f6cfa4035b35
|
||||
product/etc/CarrierSettings/fizz_ca.pb|0d75e2c8b56580c4d4795ee6f1e3b62d2d319b74
|
||||
product/etc/CarrierSettings/freedommobile_ca.pb|e8276ab551a1aac1df8ad965d76e67225a3b34e7
|
||||
product/etc/CarrierSettings/h3_at.pb|89111b9fe76e234235ede8fa6eda67c43b1ba190
|
||||
product/etc/CarrierSettings/h3_gb.pb|2811b99744f9833edca741ad76ad66485e7c844a
|
||||
product/etc/CarrierSettings/idea_in.pb|77ad6d787c3717f3d0ffc36715338341949bdd22
|
||||
product/etc/CarrierSettings/idmobile_gb.pb|ab55b578bf804e817c65f0277132bfb300db89c1
|
||||
product/etc/CarrierSettings/kddi_jp.pb|1e74d06b4c68a19dc928294d851c556a279829dd
|
||||
product/etc/CarrierSettings/kddimvno_jp.pb|771af311f37b54488d08eaa98de94cc205a09000
|
||||
product/etc/CarrierSettings/koodo_ca.pb|343da5aec9403308007d042cb1f19e216f87c9b3
|
||||
product/etc/CarrierSettings/luckymobile_ca.pb|1247e849aae3111c7d92187077cfc505c8b65422
|
||||
product/etc/CarrierSettings/o2_de.pb|f3eb29fff315678e9b6d5bbbc7428aecdc3153f0
|
||||
product/etc/CarrierSettings/o2postpaid_gb.pb|cedebdb968dd2303e347bc0569e4d34d6ab1b0a8
|
||||
product/etc/CarrierSettings/o2prepaid_de.pb|0861eafd2589ca8e50e6d21c109239ba5fd167e1
|
||||
product/etc/CarrierSettings/o2prepaid_gb.pb|bf6ec3e1b82f23550fb9ea7d7def823c9088fadf
|
||||
product/etc/CarrierSettings/optus_au.pb|3cfe56f32eac5df6976a692cfbfb35530e43917a
|
||||
product/etc/CarrierSettings/orange_es.pb|25c474061c6437f713720116c8122d30027845ef
|
||||
product/etc/CarrierSettings/orange_fr.pb|dd3b9bf9151ec965e845e1ea96bd9752816e16f3
|
||||
product/etc/CarrierSettings/others.pb|d2cf5a92634fac82dc4a60e1ada137033db4a130
|
||||
product/etc/CarrierSettings/pcmobilebell_ca.pb|285714983398a4c886f189e380d22babd6968e3b
|
||||
product/etc/CarrierSettings/rakuten_jp.pb|b1204b307bb123183df6611dcf6c5f61a6c5e4df
|
||||
product/etc/CarrierSettings/rjio_in.pb|3ca38e1f8cf522b2b6291ae08649cbfa63ab8b0c
|
||||
product/etc/CarrierSettings/rogers_ca.pb|a9201c7646f6f93aecba7fe854e7ee25917d6605
|
||||
product/etc/CarrierSettings/sfr_fr.pb|ab1e380d2400e1299dd03e97dc7dbe97776ae400
|
||||
product/etc/CarrierSettings/singtel_sg.pb|4ad088f046381921b451e2eddc04355ea4c9b1ce
|
||||
product/etc/CarrierSettings/softbank_jp.pb|c1a200dff0b51a9532b7f00b24ee3f6b9b3ef6b8
|
||||
product/etc/CarrierSettings/solomobile_ca.pb|83288e185294c7d0900364c18714ba6ed2cae657
|
||||
product/etc/CarrierSettings/spectrum_us.pb|2e80bb018fa7248712ff1580236bc32501764f31
|
||||
product/etc/CarrierSettings/sprintprepaid_us.pb|f8bf30e91aedcf3170d3830ebb7e47bde117a899
|
||||
product/etc/CarrierSettings/sprint_us.pb|0c3ee0fa9a8c70b2ec5527bf54948ca899046a28
|
||||
product/etc/CarrierSettings/sprintwholesale_us.pb|3e85bc601be19e9e46cbf00b26fdce4b05cb2973
|
||||
product/etc/CarrierSettings/starhub_sg.pb|49c526eae01a3b15528e0bb405262045997138dd
|
||||
product/etc/CarrierSettings/swisscom_ch.pb|862e3cee34a9d8758319efa3f858869dc2c6bb8e
|
||||
product/etc/CarrierSettings/swisscom_li.pb|b425f07c8c812e1d64c752e6bc7b2c9e96b9666a
|
||||
product/etc/CarrierSettings/tdc_dk.pb|a543c4db47674d4b47c4636e01774746d95e347e
|
||||
product/etc/CarrierSettings/tele2_se.pb|2ad5436b590570b0620962f7460bef2d0d841c75
|
||||
product/etc/CarrierSettings/telekom_de.pb|08d1e88adc534bf1bb991eea143b95e1b8cdcd17
|
||||
product/etc/CarrierSettings/telenor_dk.pb|061a867c381b0579546933de589d4eb01e81561d
|
||||
product/etc/CarrierSettings/telenor_no.pb|edff85791c6dd1001420db3ae204c3bb55b4511f
|
||||
product/etc/CarrierSettings/telia_no.pb|d06154f660f724e5863bf6509a194734f12d6570
|
||||
product/etc/CarrierSettings/telia_se.pb|a45ce80e79b7c9dc6151c650fa12d815f74a5650
|
||||
product/etc/CarrierSettings/telstra_au.pb|837a0575facc19babf8563a447897fe1f286d9fc
|
||||
product/etc/CarrierSettings/telus_ca.pb|269aa3b0325eb97717ff5587e335e90ef08b09bc
|
||||
product/etc/CarrierSettings/tim_it.pb|3e04089cf886f9a75b79f9a78fb441fa8cafb463
|
||||
product/etc/CarrierSettings/tmobile_nl.pb|936f75e2958a4e09b8bd3d278bb562e94b0ccf1d
|
||||
product/etc/CarrierSettings/tmobile_us.pb|08f99051fd8ba5f9d65d80cf2c66d51d8114282a
|
||||
product/etc/CarrierSettings/tracfonetmo_us.pb|b610ce42a979fd34fb1b36fc725a2b35a818accb
|
||||
product/etc/CarrierSettings/tracfoneverizon_us.pb|88dc4c0a3e9363398bf72537e99268f84b193c5d
|
||||
product/etc/CarrierSettings/twm_tw.pb|e88c01147316149150261f51dc31589caa42c429
|
||||
product/etc/CarrierSettings/uscc_us.pb|18521df72bc65b97bb2e013d4e4668456fd1f48e
|
||||
product/etc/CarrierSettings/verizon_us.pb|d7cb3e2a171acc3db56631761d6afa83e55fd288
|
||||
product/etc/CarrierSettings/virgin_us.pb|47fa194634daead004750ee2e9a4d95f6f578ecd
|
||||
product/etc/CarrierSettings/videotron_ca.pb|1e52d7ae3357ff651e35f1ddee430f8ef07366d9
|
||||
product/etc/CarrierSettings/virgin_ca.pb|7ad8d1fd3dce4eaf5955a8911dad5ce294ae1dda
|
||||
product/etc/CarrierSettings/visible_us.pb|a496dcbfe16ab08286d87ba45a988272d51d9241
|
||||
product/etc/CarrierSettings/vodafone_au.pb|a6153c795001011663fe978128ccb846afb2dadc
|
||||
product/etc/CarrierSettings/vodafone_de.pb|595913b107e573077dcac3244fd9cead48993520
|
||||
product/etc/CarrierSettings/vodafone_es.pb|7aeb052cc04916ddc0ea735d80eee1a12565495e
|
||||
product/etc/CarrierSettings/vodafone_gb.pb|97bd59b0ca302e77cd3bfc169ee9dcd1de2c001c
|
||||
product/etc/CarrierSettings/vodafone_in.pb|0b47c74af033e7423e175c3eb834768f487ffef0
|
||||
product/etc/CarrierSettings/vodafone_it.pb|d4c0a66bda9d4d605a413a57227e7247e322193b
|
||||
product/etc/CarrierSettings/vodafone_nl.pb|ddb242406bfa4ec623110c0b448329f2fa2c879f
|
||||
product/etc/CarrierSettings/vodafone_tr.pb|2669f7cb9f3098d265a9c25319c64d1dc630c1ce
|
||||
product/etc/CarrierSettings/xfinity_us.pb|3368bac024d407ee16f4c7b16252c6f9b97dfa24
|
||||
-product/priv-app/CarrierSettings/CarrierSettings.apk|e4ce66de07d6123e14bcef26b3c8e6ecc143934c
|
||||
|
|
|
@ -18,55 +18,28 @@ import common
|
|||
import re
|
||||
|
||||
def FullOTA_InstallEnd(info):
|
||||
input_zip = info.input_zip
|
||||
OTA_UpdateFirmware(info)
|
||||
OTA_InstallEnd(info, input_zip)
|
||||
OTA_InstallEnd(info)
|
||||
return
|
||||
|
||||
def IncrementalOTA_InstallEnd(info):
|
||||
input_zip = info.target_zip
|
||||
OTA_UpdateFirmware(info)
|
||||
OTA_InstallEnd(info, input_zip)
|
||||
OTA_InstallEnd(info)
|
||||
return
|
||||
|
||||
def OTA_UpdateFirmware(info):
|
||||
info.script.AppendExtra('ui_print("Patching firmware images unconditionally...");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/cmnlib64.mbn", "/dev/block/bootdevice/by-name/cmnlib64");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/cmnlib.mbn", "/dev/block/bootdevice/by-name/cmnlib");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/hyp.mbn", "/dev/block/bootdevice/by-name/hyp");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/BTFM.bin", "/dev/block/bootdevice/by-name/bluetooth");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/tz.mbn", "/dev/block/bootdevice/by-name/tz");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/aop.mbn", "/dev/block/bootdevice/by-name/aop");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/xbl_config.elf", "/dev/block/bootdevice/by-name/xbl_config");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/keymaster64.mbn", "/dev/block/bootdevice/by-name/keymaster");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/qupv3fw.elf", "/dev/block/bootdevice/by-name/qupfw");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/abl.elf", "/dev/block/bootdevice/by-name/abl");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/dspso.bin", "/dev/block/bootdevice/by-name/dsp");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/devcfg.mbn", "/dev/block/bootdevice/by-name/devcfg");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/storsec.mbn", "/dev/block/bootdevice/by-name/storsec");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/xbl.elf", "/dev/block/bootdevice/by-name/xbl");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/cmnlib64.mbn", "/dev/block/bootdevice/by-name/cmnlib64bak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/cmnlib.mbn", "/dev/block/bootdevice/by-name/cmnlibbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/hyp.mbn", "/dev/block/bootdevice/by-name/hypbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/tz.mbn", "/dev/block/bootdevice/by-name/tzbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/aop.mbn", "/dev/block/bootdevice/by-name/aopbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/xbl_config.elf", "/dev/block/bootdevice/by-name/xbl_configbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/keymaster64.mbn", "/dev/block/bootdevice/by-name/keymasterbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/qupv3fw.elf", "/dev/block/bootdevice/by-name/qupfwbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/abl.elf", "/dev/block/bootdevice/by-name/ablbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/devcfg.mbn", "/dev/block/bootdevice/by-name/devcfgbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/storsec.mbn", "/dev/block/bootdevice/by-name/storsecbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/xbl.elf", "/dev/block/bootdevice/by-name/xblbak");')
|
||||
info.script.AppendExtra('package_extract_file("install/firmware-update/NON-HLOS.bin", "/dev/block/bootdevice/by-name/modem");')
|
||||
|
||||
def AddImage(info, input_zip, basename, dest):
|
||||
def AddImage(info, dir, basename, dest):
|
||||
name = basename
|
||||
data = input_zip.read("IMAGES/" + basename)
|
||||
data = info.input_zip.read(dir + "/" + basename)
|
||||
common.ZipWriteStr(info.output_zip, name, data)
|
||||
info.script.Print("Patching {} image unconditionally...".format(dest.split('/')[-1]))
|
||||
info.script.AppendExtra('package_extract_file("%s", "%s");' % (name, dest))
|
||||
|
||||
def OTA_InstallEnd(info, input_zip):
|
||||
AddImage(info, input_zip, "vbmeta.img", "/dev/block/bootdevice/by-name/vbmeta")
|
||||
AddImage(info, input_zip, "dtbo.img", "/dev/block/bootdevice/by-name/dtbo")
|
||||
def FullOTA_InstallBegin(info):
|
||||
AddImage(info, "RADIO", "super_dummy.img", "/tmp/super_dummy.img");
|
||||
info.script.AppendExtra('package_extract_file("install/bin/flash_super_dummy.sh", "/tmp/flash_super_dummy.sh");')
|
||||
info.script.AppendExtra('set_metadata("/tmp/flash_super_dummy.sh", "uid", 0, "gid", 0, "mode", 0755);')
|
||||
info.script.AppendExtra('run_program("/tmp/flash_super_dummy.sh");')
|
||||
return
|
||||
|
||||
def OTA_InstallEnd(info):
|
||||
AddImage(info, "IMAGES", "vbmeta.img", "/dev/block/bootdevice/by-name/vbmeta")
|
||||
AddImage(info, "IMAGES", "dtbo.img", "/dev/block/bootdevice/by-name/dtbo")
|
||||
return
|
||||
|
|
|
@ -7,3 +7,12 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)
|
|||
LOCAL_MODULE_STEM := ueventd.rc
|
||||
LOCAL_SRC_FILES := etc/$(LOCAL_MODULE)
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := fstab.qcom_ramdisk
|
||||
LOCAL_MODULE_STEM := fstab.qcom
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_SRC_FILES := etc/fstab.qcom
|
||||
LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)
|
||||
include $(BUILD_PREBUILT)
|
||||
|
|
|
@ -6,11 +6,18 @@
|
|||
# Currently we dont have e2fsck compiled. So fs check would failed.
|
||||
|
||||
#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
|
||||
/dev/block/bootdevice/by-name/system / ext4 ro,barrier=1,discard,i_version wait,avb
|
||||
system /system ext4 ro,barrier=1,discard wait,logical,first_stage_mount
|
||||
system_ext /system_ext ext4 ro,barrier=1,discard wait,logical,first_stage_mount
|
||||
product /product ext4 ro,barrier=1,discard wait,logical,first_stage_mount
|
||||
vendor /vendor ext4 ro,barrier=1,discard wait,logical,first_stage_mount
|
||||
odm /odm ext4 ro,barrier=1,discard wait,logical,first_stage_mount
|
||||
/dev/block/bootdevice/by-name/recovery /recovery emmc defaults defaults
|
||||
/dev/block/bootdevice/by-name/boot /boot emmc defaults defaults
|
||||
/dev/block/by-name/logdump /metadata ext4 nosuid,nodev,noatime,discard,data=journal,commit=1 wait,check,formattable,first_stage_mount
|
||||
/dev/block/bootdevice/by-name/userdata /data ext4 noatime,nosuid,noatime,nodev,barrier=1,noauto_da_alloc,discard,lazytime latemount,wait,check,fileencryption=ice,reservedsize=128M
|
||||
/dev/block/bootdevice/by-name/cache /cache ext4 nosuid,noatime,nodev,barrier=1 wait
|
||||
/devices/platform/soc/8804000.sdhci/mmc_host* /storage/sdcard1 vfat nosuid,nodev wait,voldmanaged=sdcard1:auto,encryptable=footer
|
||||
/devices/platform/soc/1da4000.ufshc_card/host* /storage/sdcard1 vfat nosuid,nodev wait,voldmanaged=sdcard1:auto,encryptable=footer
|
||||
/devices/platform/soc/8804000.sdhci/mmc_host* /storage/sdcard1 vfat nosuid,nodev wait,voldmanaged=sdcard1:auto,encryptable=userdata
|
||||
/devices/platform/soc/1da4000.ufshc_card/host* /storage/sdcard1 vfat nosuid,nodev wait,voldmanaged=sdcard1:auto,encryptable=userdata
|
||||
/dev/block/bootdevice/by-name/modem /vendor/firmware_mnt vfat ro,shortname=lower,uid=1000,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0 wait
|
||||
/dev/block/bootdevice/by-name/dsp /vendor/dsp ext4 ro,nosuid,nodev,barrier=1 wait
|
||||
/dev/block/bootdevice/by-name/persist /mnt/vendor/persist ext4 nosuid,noatime,nodev,barrier=1 wait
|
||||
|
|
|
@ -1379,15 +1379,3 @@ on property:sys.usb.config=midi && property:sys.usb.configfs=1
|
|||
on property:sys.usb.config=midi,adb && property:sys.usb.configfs=1
|
||||
write /config/usb_gadget/g1/idVendor 0x18d1
|
||||
write /config/usb_gadget/g1/idProduct 0x4ee9
|
||||
|
||||
on property:vendor.usb.eud=1
|
||||
write /config/usb_gadget/g1/configs/b.1/MaxPower 1
|
||||
write /sys/module/eud/parameters/enable 1
|
||||
write /sys/kernel/debug/pmic-votable/USB_ICL/force_active 1
|
||||
write /sys/kernel/debug/pmic-votable/USB_ICL/force_val 500
|
||||
|
||||
on property:vendor.usb.eud=0
|
||||
write /sys/kernel/debug/pmic-votable/USB_ICL/force_active 0
|
||||
write /sys/kernel/debug/pmic-votable/USB_ICL/force_val 0
|
||||
write /config/usb_gadget/g1/configs/b.1/MaxPower 0
|
||||
write /sys/module/eud/parameters/enable 0
|
||||
|
|
|
@ -101,7 +101,6 @@ if [ $feature_id == 6 ]; then
|
|||
echo 940800000 > /sys/class/devfreq/soc\:qcom,cpu6-cpu-l3-lat/min_freq
|
||||
echo 1017600000 > /sys/class/devfreq/soc\:qcom,cpu6-cpu-l3-lat/max_freq
|
||||
echo 3 > /sys/class/kgsl/kgsl-3d0/max_pwrlevel
|
||||
echo {class:ddr, res:fixed, val: 1016} > /sys/kernel/debug/aop_send_message
|
||||
setprop vendor.sku_identified 1
|
||||
elif [ $feature_id == 5 ]; then
|
||||
echo "SKU Configured : SA6150"
|
||||
|
@ -126,7 +125,6 @@ elif [ $feature_id == 5 ]; then
|
|||
echo 940800000 > /sys/class/devfreq/soc\:qcom,cpu6-cpu-l3-lat/min_freq
|
||||
echo 1363200000 > /sys/class/devfreq/soc\:qcom,cpu6-cpu-l3-lat/max_freq
|
||||
echo 2 > /sys/class/kgsl/kgsl-3d0/max_pwrlevel
|
||||
echo {class:ddr, res:fixed, val: 1333} > /sys/kernel/debug/aop_send_message
|
||||
setprop vendor.sku_identified 1
|
||||
elif [ $feature_id == 4 || $feature_id == 3 ]; then
|
||||
echo "SKU Configured : SA6155"
|
||||
|
@ -151,7 +149,6 @@ elif [ $feature_id == 4 || $feature_id == 3 ]; then
|
|||
echo 940800000 > /sys/class/devfreq/soc\:qcom,cpu6-cpu-l3-lat/min_freq
|
||||
echo 1363200000 > /sys/class/devfreq/soc\:qcom,cpu6-cpu-l3-lat/max_freq
|
||||
echo 0 > /sys/class/kgsl/kgsl-3d0/max_pwrlevel
|
||||
echo {class:ddr, res:fixed, val: 1555} > /sys/kernel/debug/aop_send_message
|
||||
setprop vendor.sku_identified 1
|
||||
else
|
||||
echo "unknown feature_id value" $feature_id
|
||||
|
@ -176,7 +173,6 @@ else
|
|||
echo 940800000 > /sys/class/devfreq/soc\:qcom,cpu6-cpu-l3-lat/min_freq
|
||||
echo 1363200000 > /sys/class/devfreq/soc\:qcom,cpu6-cpu-l3-lat/max_freq
|
||||
echo 0 > /sys/class/kgsl/kgsl-3d0/max_pwrlevel
|
||||
echo {class:ddr, res:fixed, val: 1555} > /sys/kernel/debug/aop_send_message
|
||||
setprop vendor.sku_identified 1
|
||||
fi
|
||||
}
|
||||
|
@ -345,9 +341,7 @@ function configure_zram_parameters() {
|
|||
# For >4GB Non-Go device, size = 4GB
|
||||
# And enable lz4 zram compression for Go targets.
|
||||
|
||||
if [ "$low_ram" == "true" ]; then
|
||||
echo lz4 > /sys/block/zram0/comp_algorithm
|
||||
fi
|
||||
|
||||
if [ -f /sys/block/zram0/disksize ]; then
|
||||
if [ -f /sys/block/zram0/use_dedup ]; then
|
||||
|
@ -5047,12 +5041,6 @@ case "$target" in
|
|||
;;
|
||||
esac
|
||||
|
||||
case "$target" in
|
||||
"qsd8650a_st1x")
|
||||
mount -t debugfs none /sys/kernel/debug
|
||||
;;
|
||||
esac
|
||||
|
||||
chown -h system /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate
|
||||
chown -h system /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor
|
||||
chown -h system /sys/devices/system/cpu/cpufreq/ondemand/io_is_busy
|
||||
|
@ -5139,20 +5127,6 @@ case "$target" in
|
|||
;;
|
||||
esac
|
||||
|
||||
# Install AdrenoTest.apk if not already installed
|
||||
if [ -f /data/prebuilt/AdrenoTest.apk ]; then
|
||||
if [ ! -d /data/data/com.qualcomm.adrenotest ]; then
|
||||
pm install /data/prebuilt/AdrenoTest.apk
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install SWE_Browser.apk if not already installed
|
||||
if [ -f /data/prebuilt/SWE_AndroidBrowser.apk ]; then
|
||||
if [ ! -d /data/data/com.android.swe.browser ]; then
|
||||
pm install /data/prebuilt/SWE_AndroidBrowser.apk
|
||||
fi
|
||||
fi
|
||||
|
||||
# Change adj level and min_free_kbytes setting for lowmemory killer to kick in
|
||||
case "$target" in
|
||||
"msm8660")
|
||||
|
|
|
@ -35,26 +35,12 @@ on early-init
|
|||
rm /data/resource-cache
|
||||
rm /data/system/package_cache
|
||||
|
||||
mount debugfs debugfs /sys/kernel/debug
|
||||
chmod 0755 /sys/kernel/debug
|
||||
|
||||
# Change ownership of hw_recovery related nodes
|
||||
chown system graphics /sys/kernel/debug/dri/0/debug/dump
|
||||
chown system graphics /sys/kernel/debug/dri/0/debug/recovery_reg
|
||||
chown system graphics /sys/kernel/debug/dri/0/debug/recovery_dbgbus
|
||||
chown system graphics /sys/kernel/debug/dri/0/debug/recovery_vbif_dbgbus
|
||||
|
||||
# Change ownership of sw_sync node
|
||||
chown system graphics /sys/kernel/debug/sync/sw_sync
|
||||
chmod 0666 /sys/kernel/debug/sync/sw_sync
|
||||
|
||||
chown root system /dev/kmsg
|
||||
chmod 0620 /dev/kmsg
|
||||
# Load WIGIG platform driver
|
||||
exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d /vendor/lib/modules msm_11ad_proxy
|
||||
|
||||
on init
|
||||
|
||||
# Support legacy paths
|
||||
symlink /sdcard /mnt/sdcard
|
||||
symlink /sdcard /storage/sdcard0
|
||||
|
@ -79,9 +65,11 @@ on init
|
|||
write /sys/block/mmcblk0/queue/nr_requests 256
|
||||
write /sys/block/mmcblk0/queue/iostats 0
|
||||
|
||||
on post-fs
|
||||
chmod 0755 /sys/kernel/debug/tracing
|
||||
# report max frequency to unity tasks.
|
||||
write /proc/sys/kernel/sched_lib_name "com.miHoYo.,UnityMain,libunity.so"
|
||||
write /proc/sys/kernel/sched_lib_mask_force 255
|
||||
|
||||
on post-fs
|
||||
# Start services for bootanim
|
||||
start surfaceflinger
|
||||
start bootanim
|
||||
|
@ -152,8 +140,6 @@ on boot
|
|||
chown bluetooth bluetooth /sys/module/hci_smd/parameters/hcismd_set
|
||||
chown system system /sys/module/msm_core/parameters/polling_interval
|
||||
chown system system /sys/module/msm_core/parameters/disabled
|
||||
chown system system /sys/kernel/debug/msm_core/enable
|
||||
chown system system /sys/kernel/debug/msm_core/ptable
|
||||
chown system system /sys/kernel/boot_slpi/ssr
|
||||
chown system system /sys/module/radio_iris_transport/parameters/fmsmd_set
|
||||
chmod 0660 /sys/module/bluetooth_power/parameters/power
|
||||
|
@ -214,9 +200,6 @@ on boot
|
|||
|
||||
setprop ro.telephony.call_ring.multiple false
|
||||
|
||||
#enable camera read sensors data
|
||||
setprop persist.camera.gyro.disable 0
|
||||
|
||||
#Remove SUID bit for iproute2 ip tool
|
||||
chmod 0755 /system/bin/ip
|
||||
|
||||
|
@ -1059,16 +1042,6 @@ service vendor.audio-hal /vendor/bin/hw/android.hardware.audio.service
|
|||
socket audio_hw_socket seqpacket 0666 system system
|
||||
onrestart restart audioserver
|
||||
|
||||
service vendor.thermal-hal-2-0 /vendor/bin/hw/android.hardware.thermal@2.0-service.pixel
|
||||
override
|
||||
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
|
||||
|
||||
on property:sys.boot_completed=1
|
||||
# Restrict permissions to socket file
|
||||
# to hide Magisk & co.
|
||||
|
|
50
rootdir/etc/init.recovery.qcom.rc
Normal file
50
rootdir/etc/init.recovery.qcom.rc
Normal file
|
@ -0,0 +1,50 @@
|
|||
# Copyright (c) 2009-2012, 2014-2015, The Linux Foundation. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of The Linux Foundation nor
|
||||
# the names of its contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
#import /init.recovery.qcom_decrypt.rc
|
||||
|
||||
on fs
|
||||
wait /dev/block/platform/soc/${ro.boot.bootdevice}
|
||||
symlink /dev/block/platform/soc/${ro.boot.bootdevice} /dev/block/bootdevice
|
||||
export ANDROID_ROOT /system_root
|
||||
|
||||
on early-init
|
||||
# Enable double-tap to wake
|
||||
write /sys/devices/virtual/touch/tp_dev/gesture_on 1
|
||||
|
||||
on init
|
||||
# Workaround for setting AVB version
|
||||
setprop sys.usb.configfs 1
|
||||
setprop ro.boot.avb_version 1.0
|
||||
setprop ro.boot.vbmeta.avb_version ${ro.boot.avb_version}
|
||||
setprop vendor.gatekeeper.disable_spu true
|
||||
|
||||
#on boot
|
||||
# setprop sys.usb.config adb
|
||||
# start health-hal-2-1
|
||||
# chown system system /sys/class/touch/tp_dev/gesture_on
|
||||
# chown 0660 /sys/class/touch/tp_dev/gesture_on
|
124
rootdir/etc/init.recovery.usb.rc
Normal file
124
rootdir/etc/init.recovery.usb.rc
Normal file
|
@ -0,0 +1,124 @@
|
|||
# Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of The Linux Foundation nor
|
||||
# the names of its contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
on boot
|
||||
write /sys/class/android_usb/android0/iSerial ${ro.serialno}
|
||||
mount configfs none /config
|
||||
mkdir /config/usb_gadget/g1 0770
|
||||
mkdir /config/usb_gadget/g2 0770
|
||||
mkdir /config/usb_gadget/g1/strings/0x409 0770
|
||||
mkdir /config/usb_gadget/g2/strings/0x409 0770
|
||||
write /config/usb_gadget/g1/bcdUSB 0x0200
|
||||
write /config/usb_gadget/g2/bcdUSB 0x0200
|
||||
write /config/usb_gadget/g1/os_desc/use 1
|
||||
write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno}
|
||||
write /config/usb_gadget/g2/strings/0x409/serialnumber ${ro.serialno}
|
||||
write /config/usb_gadget/g1/strings/0x409/manufacturer ${ro.product.manufacturer}
|
||||
write /config/usb_gadget/g2/strings/0x409/manufacturer ${ro.product.manufacturer}
|
||||
write /config/usb_gadget/g1/strings/0x409/product ${ro.product.model}
|
||||
write /config/usb_gadget/g2/strings/0x409/product ${ro.product.model}
|
||||
mkdir /config/usb_gadget/g1/functions/mass_storage.0
|
||||
mkdir /config/usb_gadget/g1/functions/mtp.gs0
|
||||
mkdir /config/usb_gadget/g1/functions/ptp.gs1
|
||||
mkdir /config/usb_gadget/g1/functions/accessory.gs2
|
||||
mkdir /config/usb_gadget/g1/functions/audio_source.gs3
|
||||
mkdir /config/usb_gadget/g1/functions/midi.gs5
|
||||
mkdir /config/usb_gadget/g1/functions/ffs.adb
|
||||
mkdir /config/usb_gadget/g1/functions/diag.diag
|
||||
mkdir /config/usb_gadget/g1/functions/diag.diag_mdm
|
||||
mkdir /config/usb_gadget/g1/functions/cser.dun.0
|
||||
mkdir /config/usb_gadget/g1/functions/cser.nmea.1
|
||||
mkdir /config/usb_gadget/g1/functions/cser.dun.2
|
||||
mkdir /config/usb_gadget/g1/functions/gsi.rmnet
|
||||
mkdir /config/usb_gadget/g1/functions/gsi.rndis
|
||||
mkdir /config/usb_gadget/g1/functions/gsi.dpl
|
||||
mkdir /config/usb_gadget/g1/functions/qdss.qdss
|
||||
mkdir /config/usb_gadget/g1/functions/qdss.qdss_mdm
|
||||
mkdir /config/usb_gadget/g1/functions/rndis_bam.rndis
|
||||
mkdir /config/usb_gadget/g1/functions/rndis.rndis
|
||||
mkdir /config/usb_gadget/g1/functions/rmnet_bam.rmnet
|
||||
mkdir /config/usb_gadget/g1/functions/rmnet_bam.dpl
|
||||
mkdir /config/usb_gadget/g1/functions/rmnet_bam.rmnet_bam_dmux
|
||||
mkdir /config/usb_gadget/g1/functions/rmnet_bam.dpl_bam_dmux
|
||||
mkdir /config/usb_gadget/g1/functions/ncm.0
|
||||
mkdir /config/usb_gadget/g1/functions/ccid.ccid
|
||||
mkdir /config/usb_gadget/g1/functions/uac2.0
|
||||
mkdir /config/usb_gadget/g1/functions/uvc.0
|
||||
mkdir /config/usb_gadget/g1/configs/b.1 0770
|
||||
mkdir /config/usb_gadget/g2/configs/b.1 0770
|
||||
mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770
|
||||
mkdir /config/usb_gadget/g2/configs/b.1/strings/0x409 0770
|
||||
write /config/usb_gadget/g1/os_desc/b_vendor_code 0x1
|
||||
write /config/usb_gadget/g1/os_desc/qw_sign "MSFT100"
|
||||
symlink /config/usb_gadget/g1/configs/b.1 /config/usb_gadget/g1/os_desc/b.1
|
||||
mkdir /dev/usb-ffs 0775 shell system
|
||||
mkdir /dev/usb-ffs/adb 0770 shell system
|
||||
mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=1000,rmode=0770,fmode=0660
|
||||
write /sys/class/android_usb/android0/f_ffs/aliases adb
|
||||
setprop vendor.usb.controller ${sys.usb.controller}
|
||||
|
||||
on property:sys.usb.config=none
|
||||
write /config/usb_gadget/g1/UDC "none"
|
||||
stop adbd
|
||||
setprop sys.usb.ffs.ready 0
|
||||
write /config/usb_gadget/g1/bDeviceClass 0
|
||||
write /config/usb_gadget/g1/bDeviceSubClass 0
|
||||
write /config/usb_gadget/g1/bDeviceProtocol 0
|
||||
setprop sys.usb.state ${sys.usb.config}
|
||||
|
||||
on property:sys.usb.config=mtp,adb
|
||||
start adbd
|
||||
|
||||
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=mtp,adb
|
||||
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp_adb"
|
||||
rm /config/usb_gadget/g1/configs/b.1/f1
|
||||
rm /config/usb_gadget/g1/configs/b.1/f2
|
||||
rm /config/usb_gadget/g1/configs/b.1/f3
|
||||
rm /config/usb_gadget/g1/configs/b.1/f4
|
||||
rm /config/usb_gadget/g1/configs/b.1/f5
|
||||
write /config/usb_gadget/g1/idVendor 0x05C6
|
||||
write /config/usb_gadget/g1/idProduct 0x9039
|
||||
symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1
|
||||
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
|
||||
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
|
||||
setprop sys.usb.state ${sys.usb.config}
|
||||
|
||||
on property:sys.usb.config=sideload
|
||||
start adbd
|
||||
|
||||
on property:sys.usb.ffs.ready=1 && property:sys.usb.config=sideload
|
||||
write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb"
|
||||
rm /config/usb_gadget/g1/configs/b.1/f1
|
||||
rm /config/usb_gadget/g1/configs/b.1/f2
|
||||
rm /config/usb_gadget/g1/configs/b.1/f3
|
||||
rm /config/usb_gadget/g1/configs/b.1/f4
|
||||
rm /config/usb_gadget/g1/configs/b.1/f5
|
||||
write /config/usb_gadget/g1/idVendor 0x18d1
|
||||
write /config/usb_gadget/g1/idProduct 0x4ee7
|
||||
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1
|
||||
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
|
||||
setprop sys.usb.state ${sys.usb.config}
|
|
@ -96,12 +96,6 @@ on boot
|
|||
write /dev/cpuset/background/cpus 0-7
|
||||
write /dev/cpuset/system-background/cpus 0-7
|
||||
|
||||
# Allow system to manipulate KProfiles modes and parameters
|
||||
chown system system /sys/module/kprofiles/parameters/auto_kprofiles
|
||||
chmod 0660 /sys/module/kprofiles/parameters/auto_kprofiles
|
||||
chown system system /sys/module/kprofiles/parameters/kp_mode
|
||||
chmod 0660 /sys/module/kprofiles/parameters/kp_mode
|
||||
|
||||
####Regionalization config and prop files####
|
||||
chmod 0644 /persist/speccfg/spec
|
||||
chmod 0644 /persist/speccfg/devicetype
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
# Android fstab file.
|
||||
# The filesystem that contains the filesystem checker binary (typically /system) cannot
|
||||
# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
|
||||
|
||||
#TODO: Add 'check' as fs_mgr_flags with data partition.
|
||||
# Currently we dont have e2fsck compiled. So fs check would failed.
|
||||
|
||||
#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
|
||||
/dev/block/bootdevice/by-name/system / ext4 ro,barrier=1 wait
|
||||
/dev/block/bootdevice/by-name/vendor /vendor ext4 ro,barrier=1 wait
|
||||
/dev/block/bootdevice/by-name/cache /cache ext4 noatime,nosuid,nodev,barrier=1,data=ordered wait,check
|
||||
/dev/block/bootdevice/by-name/userdata /data ext4 noatime,nosuid,nodev,barrier=1,data=ordered,noauto_da_alloc wait,check,encryptable=footer
|
||||
/dev/block/bootdevice/by-name/boot /boot emmc defaults defaults
|
||||
/dev/block/bootdevice/by-name/recovery /recovery emmc defaults defaults
|
|
@ -370,6 +370,9 @@ firmware_directories /vendor/firmware_mnt/image/
|
|||
#KGSL
|
||||
/sys/class/kgsl/kgsl-3d0 perfcounter 0660 root shell
|
||||
|
||||
# socinfo
|
||||
/sys/devices/soc0 serial_number 0000 root root
|
||||
|
||||
# sys-fs display
|
||||
/sys/class/graphics/fb* hpd 0664 system graphics
|
||||
/sys/class/graphics/fb* res_info 0664 system graphics
|
||||
|
|
128
sdm710.mk
128
sdm710.mk
|
@ -3,8 +3,10 @@ $(call inherit-product, $(SRC_TARGET_DIR)/product/product_launched_with_p.mk)
|
|||
$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
|
||||
$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base_telephony.mk)
|
||||
|
||||
OVERRIDE_PRODUCT_COMPRESSED_APEX := false
|
||||
|
||||
# Get non-open-source specific aspects
|
||||
$(call inherit-product-if-exists, vendor/lenovo/sdm710-common/sdm710-common-vendor.mk)
|
||||
$(call inherit-product, vendor/lenovo/sdm710-common/sdm710-common-vendor.mk)
|
||||
|
||||
# Setup dalvik vm configs
|
||||
$(call inherit-product, frameworks/native/build/phone-xhdpi-4096-dalvik-heap.mk)
|
||||
|
@ -60,6 +62,23 @@ PRODUCT_COPY_FILES += \
|
|||
frameworks/native/data/etc/android.software.midi.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.midi.xml \
|
||||
frameworks/native/data/etc/android.software.sip.voip.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.sip.voip.xml
|
||||
|
||||
# QPR3
|
||||
PRODUCT_PACKAGES += \
|
||||
libaudioroute \
|
||||
libaudioroute.vendor \
|
||||
libstagefrighthw \
|
||||
libstagefright_softomx_plugin.vendor \
|
||||
libprocessgroup.vendor \
|
||||
libsqlite.vendor \
|
||||
liblz4.vendor \
|
||||
libssl.vendor \
|
||||
libcurl.vendor \
|
||||
libjsoncpp.vendor \
|
||||
libsqlite.vendor \
|
||||
libtinyxml \
|
||||
libavservices_minijail.vendor \
|
||||
libpng.vendor
|
||||
|
||||
# AID/fs configs
|
||||
PRODUCT_PACKAGES += \
|
||||
fs_config_files
|
||||
|
@ -68,6 +87,11 @@ PRODUCT_PACKAGES += \
|
|||
PRODUCT_COPY_FILES += \
|
||||
frameworks/native/data/etc/android.software.freeform_window_management.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.freeform_window_management.xml
|
||||
|
||||
# ART
|
||||
PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD := false
|
||||
PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER := everything
|
||||
USE_DEX2OAT_DEBUG := false
|
||||
WITH_DEXPREOPT_DEBUG_INFO := false
|
||||
|
||||
# Audio
|
||||
PRODUCT_PACKAGES += \
|
||||
|
@ -112,7 +136,8 @@ PRODUCT_PACKAGES += \
|
|||
PRODUCT_PACKAGES += \
|
||||
android.hardware.camera.provider@2.4-impl \
|
||||
android.hardware.camera.provider@2.4-service \
|
||||
vendor.qti.hardware.camera.device@1.0.vendor
|
||||
vendor.qti.hardware.camera.device@1.0.vendor \
|
||||
Aperture
|
||||
|
||||
# Charger
|
||||
PRODUCT_PACKAGES += \
|
||||
|
@ -120,6 +145,7 @@ PRODUCT_PACKAGES += \
|
|||
|
||||
# Common init scripts
|
||||
PRODUCT_PACKAGES += \
|
||||
fstab.qcom_ramdisk \
|
||||
fstab.qcom \
|
||||
init.class_main.sh \
|
||||
init.msm.usb.configfs.rc \
|
||||
|
@ -134,6 +160,11 @@ PRODUCT_PACKAGES += \
|
|||
init.target.rc \
|
||||
ueventd.qcom.rc
|
||||
|
||||
# Recovery init
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/rootdir/etc/init.recovery.qcom.rc:$(TARGET_RECOVERY_OUT)/root/init.recovery.qcom.rc \
|
||||
$(LOCAL_PATH)/rootdir/etc/init.recovery.usb.rc:$(TARGET_RECOVERY_OUT)/root/init.recovery.usb.rc
|
||||
|
||||
# Codec2
|
||||
PRODUCT_PACKAGES += \
|
||||
libcodec2_vndk.vendor \
|
||||
|
@ -173,7 +204,8 @@ PRODUCT_PACKAGES += \
|
|||
vendor.display.config@2.0 \
|
||||
vendor.display.config@2.0.vendor \
|
||||
memtrack.sdm710 \
|
||||
vendor.qti.hardware.display.allocator@1.0-service
|
||||
vendor.qti.hardware.display.allocator@1.0-service \
|
||||
vendor.qti.hardware.display.config-V5-ndk
|
||||
|
||||
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
|
||||
ro.surface_flinger.has_HDR_display=true \
|
||||
|
@ -187,6 +219,14 @@ PRODUCT_PACKAGES += \
|
|||
android.hardware.drm@1.3.vendor \
|
||||
android.hardware.drm-service.clearkey
|
||||
|
||||
# CBS_init
|
||||
PRODUCT_PACKAGES += \
|
||||
libcrypto-v33
|
||||
|
||||
# Fastbootd
|
||||
PRODUCT_PACKAGES += \
|
||||
fastbootd
|
||||
|
||||
# Gatekeeper
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.gatekeeper@1.0 \
|
||||
|
@ -218,7 +258,16 @@ PRODUCT_PACKAGES += \
|
|||
|
||||
# Fingerprint
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.biometrics.fingerprint@2.1.vendor
|
||||
android.hardware.biometrics.fingerprint-service.xiaomi \
|
||||
android.hardware.biometrics.fingerprint@2.1.vendor \
|
||||
|
||||
|
||||
# Dynamic Partitions
|
||||
PRODUCT_BUILD_SUPER_PARTITION := false
|
||||
PRODUCT_USE_DYNAMIC_PARTITIONS := true
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/configs/flash_super_dummy.sh:install/bin/flash_super_dummy.sh
|
||||
|
||||
# FM
|
||||
PRODUCT_PACKAGES += \
|
||||
|
@ -231,6 +280,12 @@ PRODUCT_PACKAGES += \
|
|||
ims-ext-common \
|
||||
ims_ext_common.xml
|
||||
|
||||
# HWUI
|
||||
HWUI_COMPILE_FOR_PERF := true
|
||||
|
||||
# Kernel
|
||||
PRODUCT_SET_DEBUGFS_RESTRICTIONS := true
|
||||
|
||||
# Input
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/keylayout/fts_ts.kl:$(TARGET_COPY_OUT_SYSTEM)/usr/keylayout/fts_ts.kl
|
||||
|
@ -255,18 +310,18 @@ PRODUCT_PACKAGES += \
|
|||
PRODUCT_PACKAGES += \
|
||||
android.hardware.light@2.0-service.lenovo_sdm710
|
||||
|
||||
# Livedisplay
|
||||
ifeq ($(findstring Plus, $(CUSTOM_VERSION)),)
|
||||
# Lineage Health
|
||||
PRODUCT_PACKAGES += \
|
||||
vendor.lineage.health-service.default
|
||||
|
||||
# LiveDisplay
|
||||
PRODUCT_PACKAGES += \
|
||||
vendor.lineage.livedisplay@2.0-service-sdm
|
||||
endif
|
||||
|
||||
# KProfiles
|
||||
PRODUCT_PACKAGES += \
|
||||
KProfiles
|
||||
|
||||
# Media
|
||||
PRODUCT_PACKAGES += \
|
||||
#android.hardware.media.omx@1.0-impl \
|
||||
android.hardware.media.omx@1.0-service \
|
||||
libavservices_minijail \
|
||||
libavservices_minijail.vendor \
|
||||
libc2dcolorconvert \
|
||||
|
@ -278,7 +333,8 @@ PRODUCT_PACKAGES += \
|
|||
libOmxQcelp13Enc \
|
||||
libOmxVdec \
|
||||
libOmxVenc \
|
||||
libstagefrighthw
|
||||
libstagefrighthw \
|
||||
libstagefright_omx.vendor
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/configs/media_codecs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs.xml \
|
||||
|
@ -332,15 +388,12 @@ PRODUCT_PACKAGES += \
|
|||
PRODUCT_PACKAGES += \
|
||||
libqti-perfd-client
|
||||
|
||||
# PocketMode
|
||||
PRODUCT_PACKAGES += \
|
||||
LenovoPocketMode
|
||||
|
||||
# Power
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.power@1.2 \
|
||||
android.hardware.power@1.2.vendor \
|
||||
android.hardware.power-service.lenovo-sdm710-libperfmgr
|
||||
android.hardware.power.stats@1.0-service.mock \
|
||||
android.hardware.power-service.xiaomi-libperfmgr
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/configs/powerhint.json:$(TARGET_COPY_OUT_VENDOR)/etc/powerhint.json
|
||||
|
@ -354,7 +407,16 @@ PRODUCT_DEXPREOPT_SPEED_APPS += \
|
|||
# Protobuf
|
||||
PRODUCT_PACKAGES += \
|
||||
libprotobuf-cpp-full-vendorcompat \
|
||||
libprotobuf-cpp-lite-vendorcompat
|
||||
libprotobuf-cpp-full-3.9.1-vendorcompat \
|
||||
libprotobuf-cpp-lite-3.9.1-vendorcompat
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
prebuilts/vndk/v29/arm/arch-arm-armv7-a-neon/shared/vndk-core/libprotobuf-cpp-full.so:$(TARGET_COPY_OUT_VENDOR)/lib/libprotobuf-cpp-full.so \
|
||||
prebuilts/vndk/v29/arm64/arch-arm64-armv8-a/shared/vndk-core/libprotobuf-cpp-full.so:$(TARGET_COPY_OUT_VENDOR)/lib64/libprotobuf-cpp-full.so
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
prebuilts/vndk/v29/arm/arch-arm-armv7-a-neon/shared/vndk-core/libprotobuf-cpp-full.so:$(TARGET_COPY_OUT_VENDOR)/lib/libprotobuf-cpp-full.so \
|
||||
prebuilts/vndk/v29/arm64/arch-arm64-armv8-a/shared/vndk-core/libprotobuf-cpp-full.so:$(TARGET_COPY_OUT_VENDOR)/lib64/libprotobuf-cpp-full.so
|
||||
|
||||
# QTI
|
||||
PRODUCT_PACKAGES += \
|
||||
|
@ -396,11 +458,13 @@ PRODUCT_PACKAGES += \
|
|||
# Sensors
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.sensors@2.0.vendor \
|
||||
libsensorndkbridge
|
||||
libsensorndkbridge \
|
||||
android.frameworks.sensorservice@1.0.vendor
|
||||
|
||||
# Soong namespaces
|
||||
PRODUCT_SOONG_NAMESPACES += \
|
||||
$(LOCAL_PATH) \
|
||||
hardware/xiaomi \
|
||||
hardware/google/interfaces \
|
||||
hardware/google/pixel \
|
||||
vendor/qcom/opensource/commonsys/system/bt/conf \
|
||||
|
@ -410,13 +474,14 @@ PRODUCT_SOONG_NAMESPACES += \
|
|||
PRODUCT_SYSTEM_SERVER_COMPILER_FILTER := speed-profile
|
||||
PRODUCT_USE_PROFILE_FOR_BOOT_IMAGE := true
|
||||
PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION := frameworks/base/config/boot-image-profile.txt
|
||||
PRODUCT_ALWAYS_PREOPT_EXTRACTED_APK := true
|
||||
|
||||
# Telephony
|
||||
PRODUCT_PACKAGES += \
|
||||
telephony-ext
|
||||
|
||||
PRODUCT_BOOT_JARS += \
|
||||
telephony-ext
|
||||
#PRODUCT_BOOT_JARS += \
|
||||
# telephony-ext
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
qti-telephony-hidl-wrapper \
|
||||
|
@ -428,21 +493,20 @@ PRODUCT_PACKAGES += \
|
|||
PRODUCT_PACKAGES += \
|
||||
TetheringConfigOverlay
|
||||
|
||||
# Thermal engine
|
||||
# Thermal
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.thermal@2.0-service.mock
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/configs/thermal-engine.conf:$(TARGET_COPY_OUT_VENDOR)/etc/thermal-engine.conf
|
||||
|
||||
# TinyXML
|
||||
PRODUCT_PACKAGES += \
|
||||
libtinyxml
|
||||
|
||||
# Tracing
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.atrace@1.0-service.pixel
|
||||
|
||||
# USB
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.usb@1.0-service
|
||||
android.hardware.usb@1.3-service.dual_role_usb
|
||||
|
||||
# Vibrator
|
||||
PRODUCT_PACKAGES += \
|
||||
|
@ -453,7 +517,7 @@ PRODUCT_COPY_FILES += \
|
|||
|
||||
# WiFi
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.wifi@1.0-service \
|
||||
android.hardware.wifi-service \
|
||||
hostapd \
|
||||
libwifi-hal-qcom \
|
||||
libwpa_client \
|
||||
|
@ -474,14 +538,8 @@ PRODUCT_PACKAGES += \
|
|||
libnl \
|
||||
libwfdaac_vendor
|
||||
|
||||
# Setting vendor SPL
|
||||
VENDOR_SECURITY_PATCH = $(PLATFORM_SECURITY_PATCH)
|
||||
|
||||
# Set boot SPL
|
||||
BOOT_SECURITY_PATCH = $(PLATFORM_SECURITY_PATCH)
|
||||
|
||||
# App launch prefetching (IORapd)
|
||||
PRODUCT_PROPERTY_OVERRIDES += \
|
||||
PRODUCT_SYSTEM_PROPERTIES += \
|
||||
ro.iorapd.enable=false \
|
||||
iorapd.perfetto.enable=false \
|
||||
iorapd.readahead.enable=false \
|
||||
|
|
2
sepolicy/private/odrefresh.te
Normal file
2
sepolicy/private/odrefresh.te
Normal file
|
@ -0,0 +1,2 @@
|
|||
allow odrefresh self:capability kill;
|
||||
allow odrefresh aac_drc_prop:file { getattr open };
|
3
sepolicy/vendor/device.te
vendored
3
sepolicy/vendor/device.te
vendored
|
@ -1,3 +1,6 @@
|
|||
# Dynamic Partition
|
||||
typeattribute system_block_device super_block_device_type;
|
||||
|
||||
type fingerprint_device, dev_type;
|
||||
|
||||
type gps_device, dev_type;
|
||||
|
|
4
sepolicy/vendor/file.te
vendored
4
sepolicy/vendor/file.te
vendored
|
@ -1,7 +1,6 @@
|
|||
type fingerprint_data_file, data_file_type, file_type;
|
||||
type thermal_data_file, data_file_type, file_type;
|
||||
|
||||
type debugfs_sched_features, debugfs_type, fs_type;
|
||||
type proc_sysctl_schedboost, proc_type, fs_type;
|
||||
|
||||
type sysfs_fingerprint, sysfs_type, fs_type;
|
||||
|
@ -10,6 +9,3 @@ type sysfs_msm_subsys, sysfs_type, fs_type;
|
|||
type sysfs_rpm, sysfs_type, fs_type;
|
||||
type sysfs_system_sleep_stats, sysfs_type, fs_type;
|
||||
type sysfs_tp, fs_type, sysfs_type;
|
||||
|
||||
# KProfiles
|
||||
type sysfs_kprofiles, sysfs_type, fs_type;
|
15
sepolicy/vendor/file_contexts
vendored
15
sepolicy/vendor/file_contexts
vendored
|
@ -13,14 +13,23 @@
|
|||
|
||||
# HALs
|
||||
/vendor/bin/hw/android\.hardware\.light@2\.0-service\.lenovo_sdm710 u:object_r:hal_light_default_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.power@1\.3-service\.lenovo-libperfmgr u:object_r:hal_power_default_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.power-service\.lenovo-sdm710-libperfmgr u:object_r:hal_power_default_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-fpcservice u:object_r:hal_fingerprint_default_exec:s0
|
||||
#/vendor/bin/hw/android\.hardware\.power@1\.3-service\.lenovo-libperfmgr u:object_r:hal_power_default_exec:s0
|
||||
#/vendor/bin/hw/android\.hardware\.power-service\.lenovo-sdm710-libperfmgr u:object_r:hal_power_default_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.power-service\.xiaomi-libperfmgr u:object_r:hal_power_default_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.biometrics\.fingerprint-service\.xiaomi u:object_r:hal_fingerprint_default_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.atrace@1.0-service\.pixel u:object_r:hal_atrace_default_exec:s0
|
||||
/vendor/bin/hw/android\.hardware\.neuralnetworks@1\.2-service-qti u:object_r:hal_neuralnetworks_default_exec:s0
|
||||
/(vendor|system/vendor)/bin/hw/android\.hardware\.thermal@2\.0-service\.mock u:object_r:hal_thermal_default_exec:s0
|
||||
|
||||
# Allystar GPS
|
||||
/sys/ontim_bootinfo/gps_avdd_en u:object_r:sysfs_gps:s0
|
||||
/sys/ontim_bootinfo/gps_lna u:object_r:sysfs_gps:s0
|
||||
/sys/ontim_bootinfo/gps_reset u:object_r:sysfs_gps:s0
|
||||
/dev/ttyHS1 u:object_r:gps_device:s0
|
||||
|
||||
# Power aidl stats
|
||||
/(vendor|system/vendor)/bin/hw/android\.hardware\.power\.stats@1\.0-service\.mock u:object_r:hal_power_stats_default_exec:s0
|
||||
|
||||
# Block devices
|
||||
/dev/block/platform/soc/7c4000\.sdhci/by-name/system u:object_r:system_block_device:s0
|
||||
/dev/block/platform/soc/7c4000\.sdhci/by-name/vendor u:object_r:system_block_device:s0
|
||||
|
|
3
sepolicy/vendor/fsck.te
vendored
Normal file
3
sepolicy/vendor/fsck.te
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
type vendor_persist_block_device, dev_type;
|
||||
|
||||
allow fsck self:capability { sys_admin kill };
|
11
sepolicy/vendor/genfs_contexts
vendored
11
sepolicy/vendor/genfs_contexts
vendored
|
@ -1,17 +1,12 @@
|
|||
genfscon sysfs /power/rpmh_stats/master_stats u:object_r:sysfs_rpm:s0
|
||||
genfscon sysfs /power/system_sleep/stats u:object_r:sysfs_system_sleep_stats:s0
|
||||
|
||||
genfscon debugfs /sched_features u:object_r:debugfs_sched_features:s0
|
||||
genfscon proc /sys/kernel/sched_boost u:object_r:proc_sysctl_schedboost:s0
|
||||
|
||||
# DT2W
|
||||
genfscon sysfs /devices/virtual/touch/tp_dev/gesture_on u:object_r:sysfs_tp:s0
|
||||
|
||||
# KProfiles
|
||||
genfscon sysfs /module/kprofiles/parameters/auto_kprofiles u:object_r:sysfs_kprofiles:s0
|
||||
genfscon sysfs /module/kprofiles/parameters/kp_mode u:object_r:sysfs_kprofiles:s0
|
||||
|
||||
# Graphics
|
||||
genfscon sysfs /devices/platform/soc/soc:qcom,msm-ext-disp/extcon/extcon1/name u:object_r:sysfs_graphics:s0
|
||||
genfscon sysfs /devices/platform/soc/soc:qcom,msm-ext-disp/extcon/extcon2/name u:object_r:sysfs_graphics:s0
|
||||
genfscon sysfs /devices/platform/soc/soc:qcom,msm-ext-disp/extcon/extcon3/name u:object_r:sysfs_graphics:s0
|
||||
genfscon sysfs /sys/devices/platform/soc/soc:qcom,msm-ext-disp/extcon/extcon1/name u:object_r:sysfs_graphics:s0
|
||||
genfscon sysfs /sys/devices/platform/soc/soc:qcom,msm-ext-disp/extcon/extcon2/name u:object_r:sysfs_graphics:s0
|
||||
genfscon sysfs /sys/devices/platform/soc/soc:qcom,msm-ext-disp/extcon/extcon3/name u:object_r:sysfs_graphics:s0
|
||||
|
|
1
sepolicy/vendor/hal_power_default.te
vendored
1
sepolicy/vendor/hal_power_default.te
vendored
|
@ -16,7 +16,6 @@ allow hal_power_default sysfs_devices_system_cpu:file rw_file_perms;
|
|||
allow hal_power_default device_latency:chr_file rw_file_perms;
|
||||
allow hal_power_default cgroup:dir search;
|
||||
allow hal_power_default cgroup:file rw_file_perms;
|
||||
allow hal_power_default debugfs_sched_features:file rw_file_perms;
|
||||
allow hal_power_default proc_sysctl_schedboost:file rw_file_perms;
|
||||
|
||||
# Allow power hal to talk to mm-pp-daemon to control display lpm
|
||||
|
|
6
sepolicy/vendor/init.te
vendored
6
sepolicy/vendor/init.te
vendored
|
@ -1,6 +1,8 @@
|
|||
get_prop(init, exported_default_prop)
|
||||
allow init logdump_partition:lnk_file relabelto;
|
||||
|
||||
allow init self:netlink_route_socket rw_socket_perms_no_ioctl;
|
||||
allow init self:rawip_socket create_socket_perms_no_ioctl;
|
||||
allow init socket_device:sock_file { unlink setattr create };
|
||||
|
||||
# Allow init to set attribute to sysfs_kprofiles
|
||||
allow init sysfs_kprofiles:file { setattr };
|
||||
allow init proc:file write;
|
||||
|
|
1
sepolicy/vendor/mediacodec.te
vendored
Normal file
1
sepolicy/vendor/mediacodec.te
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
allow mediacodec vendor_audio_prop:file { read open getattr map };
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue