├── .clang-format
├── Android.bp
├── BesLoudness
├── Android.bp
├── AndroidManifest.xml
├── proguard.flags
├── res
│ ├── drawable
│ │ └── besloudness_qs_tile_icon.xml
│ ├── values-ast-rES
│ │ └── strings.xml
│ ├── values-az
│ │ └── strings.xml
│ ├── values-ca
│ │ └── strings.xml
│ ├── values-da
│ │ └── strings.xml
│ ├── values-de
│ │ └── strings.xml
│ ├── values-el
│ │ └── strings.xml
│ ├── values-en-rAU
│ │ └── strings.xml
│ ├── values-en-rCA
│ │ └── strings.xml
│ ├── values-en-rGB
│ │ └── strings.xml
│ ├── values-en-rIN
│ │ └── strings.xml
│ ├── values-fr
│ │ └── strings.xml
│ ├── values-fur-rIT
│ │ └── strings.xml
│ ├── values-it
│ │ └── strings.xml
│ ├── values-ja
│ │ └── strings.xml
│ ├── values-ka
│ │ └── strings.xml
│ ├── values-ko
│ │ └── strings.xml
│ ├── values-nl
│ │ └── strings.xml
│ ├── values-pl
│ │ └── strings.xml
│ ├── values-pt-rBR
│ │ └── strings.xml
│ ├── values-pt-rPT
│ │ └── strings.xml
│ ├── values-ro
│ │ └── strings.xml
│ ├── values-ru
│ │ └── strings.xml
│ ├── values-sl
│ │ └── strings.xml
│ ├── values-sq
│ │ └── strings.xml
│ ├── values-tr
│ │ └── strings.xml
│ ├── values-vi
│ │ └── strings.xml
│ ├── values-zh-rCN
│ │ └── strings.xml
│ ├── values-zh-rTW
│ │ └── strings.xml
│ ├── values
│ │ ├── config.xml
│ │ └── strings.xml
│ └── xml
│ │ └── besloudness_panel.xml
└── src
│ └── org
│ └── lineageos
│ └── settings
│ └── device
│ ├── BesLoudnessManager.java
│ ├── BesLoudnessTileService.java
│ ├── BootCompletedReceiver.java
│ └── PreferenceActivity.java
├── InCallService
├── Android.bp
├── AndroidManifest.xml
├── res
│ └── values
│ │ └── strings.xml
└── src
│ └── org
│ └── lineageos
│ └── mediatek
│ └── incallservice
│ ├── CallStateListener.java
│ ├── GainUtils.java
│ ├── OnLockedBootCompleteReceiver.java
│ ├── VolumeChangeReceiver.java
│ └── VolumeChangeService.java
├── PowerOffAlarm
├── Android.bp
├── AndroidManifest.xml
├── com.qualcomm.qti.poweroffalarm_whitelist.xml
├── java
│ ├── com
│ │ └── qualcomm
│ │ │ └── qti
│ │ │ └── poweroffalarm
│ │ │ └── PowerOffAlarmBroadcastReceiver.java
│ └── org
│ │ └── lineageos
│ │ └── poweroffalarm
│ │ ├── AlarmDriver.java
│ │ ├── Driver.java
│ │ ├── PowerOffAlarm.java
│ │ ├── RtcDriver.java
│ │ └── TimerFdDriver.java
├── jni
│ ├── AlarmDriver.cpp
│ ├── RtcDriver.cpp
│ └── TimerFdDriver.cpp
├── proguard.flags
└── res
│ ├── drawable
│ └── permic_power_off_alarm.xml
│ └── values
│ ├── config.xml
│ └── strings.xml
├── README.md
├── aidl
├── gadget
│ ├── Android.bp
│ ├── UsbGadget.cpp
│ ├── UsbGadget.h
│ ├── android.hardware.usb.gadget-service.rc
│ ├── android.hardware.usb.gadget-service.xml
│ └── service_gadget.cpp
├── health
│ ├── Android.bp
│ ├── Health.cpp
│ ├── android.hardware.health-service.mediatek-recovery.rc
│ ├── android.hardware.health-service.mediatek.rc
│ └── android.hardware.health-service.mediatek.xml
├── memtrack
│ ├── Android.bp
│ ├── GpuSysfsReader.cpp
│ ├── GpuSysfsReader.h
│ ├── Memtrack.cpp
│ ├── Memtrack.h
│ ├── filesystem.cpp
│ ├── filesystem.h
│ ├── main.cpp
│ ├── memtrack_default.rc
│ └── memtrack_default.xml
├── power-mediatek
│ ├── Android.bp
│ ├── Power.cpp
│ ├── Power.h
│ ├── power-mtk.xml
│ └── types.h
├── thermal
│ ├── Android.bp
│ ├── OWNERS
│ ├── Thermal.cpp
│ ├── Thermal.h
│ ├── android.hardware.thermal-service.mediatek.rc
│ ├── android.hardware.thermal-service.mediatek.xml
│ ├── init.thermal.symlinks.sh
│ ├── mediatek-thermal-symlinks.rc
│ ├── service.cpp
│ ├── thermal-helper.cpp
│ ├── thermal-helper.h
│ ├── utils
│ │ ├── config_schema.json
│ │ ├── power_files.cpp
│ │ ├── power_files.h
│ │ ├── powerhal_helper.cpp
│ │ ├── powerhal_helper.h
│ │ ├── thermal_files.cpp
│ │ ├── thermal_files.h
│ │ ├── thermal_info.cpp
│ │ ├── thermal_info.h
│ │ ├── thermal_predictions_helper.cpp
│ │ ├── thermal_predictions_helper.h
│ │ ├── thermal_stats_helper.cpp
│ │ ├── thermal_stats_helper.h
│ │ ├── thermal_throttling.cpp
│ │ ├── thermal_throttling.h
│ │ ├── thermal_watcher.cpp
│ │ └── thermal_watcher.h
│ └── virtualtemp_estimator
│ │ ├── virtualtemp_estimator.cpp
│ │ ├── virtualtemp_estimator.h
│ │ └── virtualtemp_estimator_data.h
├── usb-legacy
│ ├── Android.bp
│ ├── Usb.cpp
│ ├── Usb.h
│ ├── android.hardware.usb-service.mediatek-legacy.rc
│ ├── android.hardware.usb-service.mediatek-legacy.xml
│ └── service.cpp
├── usb
│ ├── Android.bp
│ ├── Usb.cpp
│ ├── Usb.h
│ ├── android.hardware.usb-service.mediatek.rc
│ ├── android.hardware.usb-service.mediatek.xml
│ └── service.cpp
└── vibrator
│ ├── Android.bp
│ ├── Vibrator.cpp
│ ├── Vibrator.h
│ ├── VibratorUtils.cpp
│ ├── android.hardware.vibrator.mediatek.xml
│ ├── main.cpp
│ └── vibrator-mediatek.rc
├── create_pl_dev
├── Android.bp
├── create_pl_dev.cpp
└── create_pl_dev.rc
├── hidl
└── mtkpower
│ └── 1.2
│ └── default
│ ├── Android.bp
│ ├── MtkPerf.cpp
│ ├── MtkPerf.h
│ ├── MtkPower.cpp
│ ├── MtkPower.h
│ ├── MtkPowerCallback.cpp
│ ├── MtkPowerCallback.h
│ ├── service.cpp
│ └── vendor.mediatek.hardware.mtkpower@1.2-service.stub.rc
├── interfaces
├── Android.bp
├── mtkpower
│ ├── 1.0
│ │ ├── .hidl-autogen
│ │ ├── Android.bp
│ │ ├── IMtkPerf.hal
│ │ └── IMtkPower.hal
│ ├── 1.1
│ │ ├── .hidl-autogen
│ │ ├── Android.bp
│ │ ├── IMtkPerf.hal
│ │ ├── IMtkPower.hal
│ │ └── IMtkPowerCallback.hal
│ └── 1.2
│ │ ├── .hidl-autogen
│ │ ├── Android.bp
│ │ ├── IMtkPerf.hal
│ │ ├── IMtkPower.hal
│ │ └── IMtkPowerCallback.hal
└── vendor_hal_makefile_generator.sh
├── libmtkperf_client
├── Android.bp
├── mtkperf_client.c
└── powerhalwrap_vendor.c
├── libwifi-hal-wrapper
├── Android.bp
├── libwifi-hal-wrapper.xml
├── libwifi-hal.cpp
└── wifi_hal_legacy.h
├── sensors
├── Android.bp
├── SensorsSubHal.cpp
└── SensorsSubHal.h
└── vintf
└── mediatek_framework_compatibility_matrix.xml
/.clang-format:
--------------------------------------------------------------------------------
1 | ../../build/soong/scripts/system-clang-format
--------------------------------------------------------------------------------
/Android.bp:
--------------------------------------------------------------------------------
1 | soong_namespace {
2 | imports: [
3 | "hardware/google/interfaces",
4 | "hardware/google/pixel",
5 | ],
6 | }
7 |
--------------------------------------------------------------------------------
/BesLoudness/Android.bp:
--------------------------------------------------------------------------------
1 | android_app {
2 | name: "BesLoudness",
3 | defaults: ["SettingsLibDefaults"],
4 |
5 | srcs: ["src/**/*.java"],
6 |
7 | certificate: "platform",
8 | platform_apis: true,
9 | system_ext_specific: true,
10 |
11 | static_libs: [
12 | "androidx.core_core",
13 | "androidx.preference_preference",
14 | ],
15 |
16 | optimize: {
17 | proguard_flags_files: ["proguard.flags"],
18 | },
19 | }
20 |
--------------------------------------------------------------------------------
/BesLoudness/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
31 |
34 |
35 |
36 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/BesLoudness/proguard.flags:
--------------------------------------------------------------------------------
1 | -keep class org.lineageos.settings.device.* {
2 | *;
3 | }
4 |
5 | -keepclasseswithmembers class * {
6 | public (android.content.Context, android.util.AttributeSet);
7 | }
8 |
9 | -keep class ** extends androidx.preference.PreferenceFragment
10 |
--------------------------------------------------------------------------------
/BesLoudness/res/drawable/besloudness_qs_tile_icon.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-ast-rES/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness potencia\'l volume de los altavoces ya ameyora la calidá del audiu del preséu automáticamente.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-az/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness, dinamikin səs səviyyəsini artırır və cihazın səs keyfiyyətini avtomatik olaraq yüksəldir.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-ca/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness augmenta el volum de l\'altaveu i millora automàticament la qualitat d\'àudio del dispositiu.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-da/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness øger højttalerens lydstyrke og forbedrer automatisk din enheds lydkvalitet.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness erhöht die Lautstärke des Lautsprechers und verbessert die Tonqualität deines Geräts automatisch.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-el/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | Το BesLoudness ενισχύει την ένταση του ηχείου και βελτιώνει αυτόματα την ποιότητα ήχου της συσκευής σας.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-en-rAU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness boosts the speaker volume and enhances the audio quality of your device automatically.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-en-rCA/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness boosts the speaker volume and enhances the audio quality of your device automatically.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-en-rGB/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness boosts the speaker volume and enhances the audio quality of your device automatically.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-en-rIN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness boosts the speaker volume and enhances the audio quality of your device automatically.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness augmente le volume du haut-parleur et améliore automatiquement la qualité sonore de votre appareil.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-fur-rIT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness al aumente il volum de casse e al miore la cualiât dal audio dal dispositîf in automatic.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness aumenta il volume dell\'altoparlante e migliora la qualità dell\'audio del dispositivo automaticamente.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-ja/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness はスピーカーの音量を強化し、オーディオ品質を自動的に向上させます。
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-ka/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness აძლიერებს გამოცემული ხმის დონეს და ამასთანავე აუმჯობესებს მის ხარისხს.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-ko/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness는 자동으로 스피커의 볼륨을 키우고 기기의 오디오 품질을 높입니다.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-nl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudheid verhoogt het luidsprekervolume en verbetert automatisch de audiokwaliteit van uw apparaat.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-pl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness zwiększa głośność głośnika i automatycznie podnosi jakość dźwięku urządzenia.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness aumenta o volume do alto-falante e melhora automaticamente a qualidade de áudio de seu dispositivo.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-pt-rPT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 |
10 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-ro/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness mărește volumul difuzorului și sporește calitatea audio a dispozitivului dvs. automat.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness автоматически увеличивает громкость динамика и улучшает качество звука вашего устройства.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-sl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness ojača glasnost zvočnika in samodejno izboljša kakovost zvoka vaše naprave.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-sq/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesZëri
9 | BesZëri rrit volumin e altoparlantit dhe përmirëson cilësinë e audios së pajisjes suaj automatikisht.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-tr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | İyileştirilmiş Yüksek Ses
9 | İyileştirilmiş Yüksek Ses, hoparlör sesini artırır ve cihazınızın ses kalitesini otomatik olarak iyileştirir.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-vi/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness tự động tăng âm lượng loa và nâng cao chất lượng âm thanh của thiết bị.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness 会自动提高扬声器音量并增强您设备的音频质量。
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values-zh-rTW/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness 可以提高喇叭音量並自動增強裝置音訊品質。
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/values/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | true
9 |
10 |
--------------------------------------------------------------------------------
/BesLoudness/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | BesLoudness
9 | BesLoudness boosts the speaker volume and enhances the audio quality of your device automatically.
10 |
11 |
--------------------------------------------------------------------------------
/BesLoudness/res/xml/besloudness_panel.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
11 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/BesLoudness/src/org/lineageos/settings/device/BesLoudnessManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | package org.lineageos.settings.device;
8 |
9 | import android.content.SharedPreferences;
10 | import android.content.BroadcastReceiver;
11 | import android.content.Context;
12 | import android.content.Intent;
13 | import android.media.AudioManager;
14 | import android.util.Log;
15 |
16 | import org.lineageos.settings.besloudness.R;
17 |
18 | public class BesLoudnessManager {
19 | public static final String TAG = "BesLoudness";
20 | public static final String SHARED_PREFS_NAME = "besloudness";
21 | public static final String KEY_BESLOUDNESS = "besloudness";
22 |
23 | public static void set(final Context context, Boolean value) {
24 | final boolean defaultValue = context.getResources().getBoolean(
25 | R.bool.besloudness_default_value);
26 | final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFS_NAME, 0);
27 | if (value != null) {
28 | prefs.edit().putBoolean(KEY_BESLOUDNESS, value).apply();
29 | }
30 | boolean newValue = prefs.getBoolean(KEY_BESLOUDNESS, defaultValue);
31 | final AudioManager amgr = (AudioManager) context.getSystemService("audio");
32 | amgr.setParameters("SetBesLoudnessStatus=" + (newValue ? "1" : "0"));
33 | }
34 |
35 | public static boolean get(final Context context) {
36 | final boolean defaultValue = context.getResources().getBoolean(
37 | R.bool.besloudness_default_value);
38 | final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFS_NAME, 0);
39 | boolean expectedValue = prefs.getBoolean(KEY_BESLOUDNESS, defaultValue);
40 | final AudioManager amgr = (AudioManager) context.getSystemService("audio");
41 | boolean actualValue = !("GetBesLoudnessStatus=0".equals(
42 | amgr.getParameters("GetBesLoudnessStatus")));
43 | if (actualValue != expectedValue) {
44 | Log.e(TAG, "value mismatch, expected " + expectedValue + ", got " + actualValue);
45 | }
46 | return actualValue;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/BesLoudness/src/org/lineageos/settings/device/BesLoudnessTileService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 The LineageOS Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.lineageos.settings.device;
18 |
19 | import android.service.quicksettings.Tile;
20 | import android.service.quicksettings.TileService;
21 |
22 | public class BesLoudnessTileService extends TileService {
23 |
24 | @Override
25 | public void onStartListening() {
26 | updateQsState();
27 | super.onStartListening();
28 | }
29 |
30 | @Override
31 | public void onClick() {
32 | Tile tile = getQsTile();
33 | BesLoudnessManager.set(this, !BesLoudnessManager.get(this));
34 | updateQsState();
35 | super.onClick();
36 | }
37 |
38 | private void updateQsState() {
39 | Tile tile = getQsTile();
40 | if (BesLoudnessManager.get(this)) {
41 | tile.setState(Tile.STATE_ACTIVE);
42 | } else {
43 | tile.setState(Tile.STATE_INACTIVE);
44 | }
45 | tile.updateTile();
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/BesLoudness/src/org/lineageos/settings/device/BootCompletedReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | package org.lineageos.settings.device;
8 |
9 | import android.content.BroadcastReceiver;
10 | import android.content.Context;
11 | import android.content.Intent;
12 | import android.util.Log;
13 |
14 | public class BootCompletedReceiver extends BroadcastReceiver {
15 | @Override
16 | public void onReceive(final Context context, Intent intent) {
17 | Log.i(BesLoudnessManager.TAG, "Booting");
18 | BesLoudnessManager.set(context, null); // Apply saved preference
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/BesLoudness/src/org/lineageos/settings/device/PreferenceActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | package org.lineageos.settings.device;
8 |
9 | import android.os.Bundle;
10 | import android.widget.CompoundButton;
11 | import android.widget.CompoundButton.OnCheckedChangeListener;
12 |
13 | import androidx.preference.PreferenceFragment;
14 |
15 | import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
16 | import com.android.settingslib.widget.MainSwitchPreference;
17 |
18 | public class PreferenceActivity extends CollapsingToolbarBaseActivity {
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | getFragmentManager()
24 | .beginTransaction()
25 | .replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
26 | new SoundPreferenceFragment())
27 | .commit();
28 | }
29 |
30 | public static class SoundPreferenceFragment extends PreferenceFragment
31 | implements OnCheckedChangeListener {
32 |
33 | @Override
34 | public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
35 | addPreferencesFromResource(org.lineageos.settings.besloudness.R.xml.besloudness_panel);
36 | MainSwitchPreference toggle = (MainSwitchPreference)
37 | findPreference(BesLoudnessManager.KEY_BESLOUDNESS);
38 | assert toggle != null;
39 | toggle.updateStatus(BesLoudnessManager.get(getContext()));
40 | toggle.addOnSwitchChangeListener(this);
41 | }
42 |
43 | @Override
44 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
45 | BesLoudnessManager.set(getContext(), isChecked);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/InCallService/Android.bp:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2023 The LineageOS Project
3 | //
4 | // SPDX-License-Identifier: Apache-2.0
5 | //
6 |
7 | android_app {
8 | name: "MtkInCallService",
9 |
10 | srcs: ["src/**/*.java"],
11 |
12 | certificate: "platform",
13 | platform_apis: true,
14 | privileged: true,
15 |
16 | optimize: {
17 | enabled: false,
18 | },
19 | }
20 |
--------------------------------------------------------------------------------
/InCallService/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
16 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/InCallService/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 | Mediatek In-Call Service
9 |
10 |
--------------------------------------------------------------------------------
/InCallService/src/org/lineageos/mediatek/incallservice/CallStateListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | package org.lineageos.mediatek.incallservice;
8 |
9 | import android.media.AudioManager;
10 |
11 | import android.telephony.TelephonyManager;
12 | import android.telephony.TelephonyCallback;
13 |
14 | import android.util.Log;
15 |
16 | public class CallStateListener extends TelephonyCallback implements TelephonyCallback.CallStateListener {
17 | private static final String LOG_TAG = "MtkInCallService";
18 | private AudioManager mAudioManager;
19 |
20 | public CallStateListener(AudioManager audioManager) {
21 | mAudioManager = audioManager;
22 | }
23 |
24 | @Override
25 | public void onCallStateChanged(int state) {
26 | if (state == TelephonyManager.CALL_STATE_OFFHOOK || state == TelephonyManager.CALL_STATE_RINGING) {
27 | Log.d(LOG_TAG, "CallStateListener: CALL_STATE_OFFHOOK, setting gain.");
28 | GainUtils.setGainLevel(mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL));
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/InCallService/src/org/lineageos/mediatek/incallservice/GainUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | package org.lineageos.mediatek.incallservice;
8 |
9 | import android.media.AudioSystem;
10 | import android.media.AudioDeviceInfo;
11 | import android.os.SystemProperties;
12 | import android.util.Log;
13 |
14 | public class GainUtils {
15 | public static final String LOG_TAG = "MtkInCallService";
16 | public static final int volSteps = SystemProperties.getInt("ro.config.vc_call_vol_steps", 7);
17 |
18 | /**
19 | * Sets the gain level for a given audio device.
20 | * @param audioDevice The audio device to set the gain level for.
21 | * @param gainIndex The gain level to set.
22 | * @param streamType The stream type to set the gain level for.
23 | */
24 | public static void setGainLevel(int audioDevice, int gainIndex, int streamType) {
25 | String parameters = String.format("volumeDevice=%d;volumeIndex=%d;volumeStreamType=%d",
26 | audioDevice, Math.min(volSteps, gainIndex), streamType);
27 | Log.d(LOG_TAG, "Setting audio parameters to: " + parameters);
28 | AudioSystem.setParameters(parameters);
29 | }
30 |
31 | /**
32 | * Sets the gain level for built-in earpiece and bluetooth SCO devices.
33 | * @param gainIndex The gain level to set.
34 | */
35 | public static void setGainLevel(int gainIndex) {
36 | GainUtils.setGainLevel(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE, gainIndex, AudioSystem.STREAM_VOICE_CALL);
37 | GainUtils.setGainLevel(AudioDeviceInfo.TYPE_BLUETOOTH_SCO, gainIndex, AudioSystem.STREAM_VOICE_CALL);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/InCallService/src/org/lineageos/mediatek/incallservice/OnLockedBootCompleteReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | package org.lineageos.mediatek.incallservice;
8 |
9 | import android.content.BroadcastReceiver;
10 | import android.content.Intent;
11 | import android.content.Context;
12 |
13 | import android.util.Log;
14 |
15 | public class OnLockedBootCompleteReceiver extends BroadcastReceiver {
16 | private static final String LOG_TAG = "MediatekInCallService";
17 |
18 | @Override
19 | public void onReceive(final Context context, Intent intent) {
20 | Log.i(LOG_TAG, "onBoot");
21 |
22 | Intent sIntent = new Intent(context, VolumeChangeService.class);
23 | context.startService(sIntent);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/InCallService/src/org/lineageos/mediatek/incallservice/VolumeChangeReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | package org.lineageos.mediatek.incallservice;
8 |
9 | import android.content.Intent;
10 | import android.content.Context;
11 | import android.content.BroadcastReceiver;
12 |
13 | import android.media.AudioManager;
14 | import android.media.AudioSystem;
15 | import android.media.AudioDeviceInfo;
16 |
17 | import android.util.Log;
18 |
19 | public class VolumeChangeReceiver extends BroadcastReceiver {
20 | public static final String LOG_TAG = "MediatekInCallService";
21 |
22 | private AudioManager mAudioManager;
23 |
24 | public VolumeChangeReceiver(AudioManager audioManager) {
25 | mAudioManager = audioManager;
26 | }
27 |
28 | private void handleVolumeStateChange(Intent intent) {
29 | if (intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1) == AudioManager.STREAM_VOICE_CALL) {
30 | AudioDeviceInfo callDevice = mAudioManager.getCommunicationDevice();
31 |
32 | int volumeIndex = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
33 | if (volumeIndex == -1)
34 | volumeIndex = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
35 |
36 | GainUtils.setGainLevel(callDevice.getPort().type(), volumeIndex, AudioSystem.STREAM_VOICE_CALL);
37 | }
38 | }
39 |
40 | @Override
41 | public void onReceive(Context context, Intent intent) {
42 | handleVolumeStateChange(intent);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/InCallService/src/org/lineageos/mediatek/incallservice/VolumeChangeService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | package org.lineageos.mediatek.incallservice;
8 |
9 | import android.media.AudioManager;
10 |
11 | import android.telephony.TelephonyManager;
12 | import android.telephony.TelephonyCallback;
13 |
14 | import android.content.Intent;
15 | import android.content.IntentFilter;
16 | import android.content.Context;
17 | import android.app.Service;
18 | import android.os.IBinder;
19 |
20 | import android.util.Log;
21 |
22 | public class VolumeChangeService extends Service {
23 | public static final String LOG_TAG = "MediatekInCallService";
24 |
25 | private Context mContext;
26 | private VolumeChangeReceiver mVolumeChangeReceiver;
27 | private CallStateListener mCallStateListener;
28 |
29 | @Override
30 | public IBinder onBind(Intent intent) {
31 | return null;
32 | }
33 |
34 | @Override
35 | public void onDestroy() {
36 | super.onDestroy();
37 | }
38 |
39 | @Override
40 | public int onStartCommand(Intent intent, int flags, int startid) {
41 | mContext = this;
42 |
43 | AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
44 | TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
45 | mVolumeChangeReceiver = new VolumeChangeReceiver(audioManager);
46 | mCallStateListener = new CallStateListener(audioManager);
47 |
48 | Log.i(LOG_TAG, "Service is starting...");
49 |
50 | this.registerReceiver(mVolumeChangeReceiver,
51 | new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
52 |
53 | telephonyManager.registerTelephonyCallback(getMainExecutor(), mCallStateListener);
54 |
55 | return START_STICKY;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/PowerOffAlarm/Android.bp:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | android_app {
7 | name: "PowerOffAlarm",
8 |
9 | srcs: ["java/**/*.java"],
10 |
11 | system_ext_specific: true,
12 | certificate: "platform",
13 | privileged: true,
14 | platform_apis: true,
15 |
16 | optimize: {
17 | proguard_flags_files: ["proguard.flags"],
18 | },
19 | jni_libs: ["libjni_poweroffalarm"],
20 | required: [
21 | "com.qualcomm.qti.poweroffalarm_whitelist",
22 | "libjni_poweroffalarm",
23 | ],
24 | }
25 |
26 | cc_library {
27 | name: "libjni_poweroffalarm",
28 | srcs: [
29 | "jni/AlarmDriver.cpp",
30 | "jni/RtcDriver.cpp",
31 | "jni/TimerFdDriver.cpp",
32 | ],
33 | cflags: [
34 | "-Werror",
35 | "-Wall",
36 | "-Wextra",
37 | ],
38 | header_libs: [
39 | "jni_headers",
40 | "libbase_headers",
41 | "generated_kernel_headers",
42 | ],
43 | shared_libs: [
44 | "liblog",
45 | ],
46 | system_ext_specific: true,
47 | }
48 |
49 | prebuilt_etc {
50 | name: "com.qualcomm.qti.poweroffalarm_whitelist",
51 | system_ext_specific: true,
52 | relative_install_path: "sysconfig",
53 | src: "com.qualcomm.qti.poweroffalarm_whitelist.xml",
54 | filename_from_src: true,
55 | }
56 |
--------------------------------------------------------------------------------
/PowerOffAlarm/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
11 |
12 |
13 |
20 |
21 |
22 |
23 |
27 |
28 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/PowerOffAlarm/com.qualcomm.qti.poweroffalarm_whitelist.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PowerOffAlarm/java/com/qualcomm/qti/poweroffalarm/PowerOffAlarmBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | package com.qualcomm.qti.poweroffalarm;
7 |
8 | import android.content.BroadcastReceiver;
9 | import android.content.Context;
10 | import android.content.Intent;
11 | import android.util.Log;
12 |
13 | import org.lineageos.poweroffalarm.PowerOffAlarm;
14 |
15 | public class PowerOffAlarmBroadcastReceiver extends BroadcastReceiver {
16 | private static final String ACTION_CANCEL_POWEROFF_ALARM = "org.codeaurora.poweroffalarm.action.CANCEL_ALARM";
17 | private static final String ACTION_SET_POWEROFF_ALARM = "org.codeaurora.poweroffalarm.action.SET_ALARM";
18 | private static final String TAG = "PowerOffAlarmBroadcastReceiver";
19 | private static final String TIME = "time";
20 |
21 | @Override
22 | public void onReceive(Context context, Intent intent) {
23 | if (intent == null) {
24 | Log.w(TAG, "Dropping null intent.");
25 | return;
26 | }
27 | String action = intent.getAction();
28 | boolean isSetAlarm = ACTION_SET_POWEROFF_ALARM.equals(action);
29 | boolean isCancelAlarm = ACTION_CANCEL_POWEROFF_ALARM.equals(action);
30 | final long alarmTime = intent.getLongExtra(TIME, -1L);
31 | if (!(isSetAlarm || isCancelAlarm) || alarmTime <= 0) {
32 | Log.w(TAG, "Dropping malformed intent with action " + action + ". "
33 | + "alarmTime=" + alarmTime);
34 | return;
35 | }
36 | Log.d(TAG, "Receive " + (isSetAlarm ? "set" : "cancel") + " intent.");
37 | final PowerOffAlarm powerOffAlarm = new PowerOffAlarm(context);
38 | final long alarmInPref = powerOffAlarm.getAlarmFromPreference();
39 | Log.d(TAG, "alarmTime=" + alarmTime + " alarmInPref=" + alarmInPref);
40 | if (isSetAlarm) {
41 | powerOffAlarm.saveAlarmToPreference(alarmTime);
42 | powerOffAlarm.setAlarmToRtc(alarmTime);
43 | } else if (isCancelAlarm && alarmTime == alarmInPref) {
44 | powerOffAlarm.saveAlarmToPreference(0L);
45 | powerOffAlarm.cancelAlarmInRtc();
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/PowerOffAlarm/java/org/lineageos/poweroffalarm/AlarmDriver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | package org.lineageos.poweroffalarm;
7 |
8 | public class AlarmDriver implements Driver {
9 |
10 | static {
11 | System.loadLibrary("jni_poweroffalarm");
12 | }
13 |
14 | public native void set(long time);
15 | public native void cancel();
16 | public native long getRtcTimeOptional();
17 | public native boolean isSupported();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/PowerOffAlarm/java/org/lineageos/poweroffalarm/Driver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | package org.lineageos.poweroffalarm;
7 |
8 | /**
9 | * Driver interface
10 | * guranteed to be called on single thread
11 | */
12 | public interface Driver {
13 |
14 | /**
15 | * Set auto boot to RTC time
16 | * @param time the unix time (as per RTC) when to wake up
17 | */
18 | public void set(long time);
19 |
20 | /**
21 | * cancel RTC auto boot
22 | */
23 | public void cancel();
24 |
25 | /**
26 | * get current unix time as per RTC if supported
27 | * used to account for differences between RTC and AP time
28 | * @return value if supported, or -1L
29 | */
30 | public long getRtcTimeOptional();
31 |
32 | /**
33 | * indicate if this driver backend is supported for RTC wakeup
34 | * if this method returns false, it is guranteed that no other methods will be called
35 | * @return true if this driver is supported
36 | */
37 | public boolean isSupported();
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/PowerOffAlarm/java/org/lineageos/poweroffalarm/PowerOffAlarm.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | package org.lineageos.poweroffalarm;
7 |
8 | import android.content.Context;
9 | import android.content.SharedPreferences;
10 | import android.preference.PreferenceManager;
11 | import android.util.Log;
12 |
13 | import com.qualcomm.qti.poweroffalarm.R;
14 |
15 | public class PowerOffAlarm {
16 | private static final String TAG = "PowerOffAlarm";
17 | private static final String PREF_KEY_ALARM_TIME = "alarm_time";
18 | private static final boolean DEBUG = false;
19 |
20 | private final Context mContext;
21 | private final long mPreBootMillisec;
22 | private final Driver mDriver;
23 | private final SharedPreferences mPrefs;
24 |
25 | public PowerOffAlarm(Context context) {
26 | mContext = context;
27 | mPreBootMillisec = mContext.getResources().getInteger(R.integer.config_preBootMillis);
28 | final String driverConfig = mContext.getString(R.string.config_powerOffAlarmDrivers);
29 | Log.d(TAG, "trying driver config " + driverConfig);
30 | final String[] drivers = driverConfig != null ? driverConfig.split(",") : new String[0];
31 | Driver driver = null;
32 | for (String driverName : drivers) {
33 | Log.d(TAG, "trying driver " + driverName);
34 | switch (driverName) {
35 | case "alarm":
36 | driver = new AlarmDriver();
37 | break;
38 | case "rtc":
39 | driver = new RtcDriver();
40 | break;
41 | case "timerfd":
42 | driver = new TimerFdDriver();
43 | break;
44 | default:
45 | Log.w(TAG, "driver " + driverName + " does not exist");
46 | break;
47 | }
48 | boolean isSupported = false;
49 | if (driver != null) {
50 | try {
51 | isSupported = driver.isSupported();
52 | } catch (Exception e) {
53 | Log.e(TAG, Log.getStackTraceString(e));
54 | }
55 | }
56 | if (isSupported) {
57 | Log.d(TAG, "selected driver " + driverName);
58 | break;
59 | }
60 | Log.d(TAG, "driver " + driverName + " is not supported");
61 | driver = null;
62 | }
63 | mDriver = driver;
64 | if (mDriver == null) {
65 | Log.w(TAG, "no driver found, disabling PowerOffAlarm");
66 | }
67 | mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
68 | }
69 |
70 | public void saveAlarmToPreference(long time) {
71 | mPrefs.edit().putLong(PREF_KEY_ALARM_TIME, time).apply();
72 | }
73 |
74 | public long getAlarmFromPreference() {
75 | return mPrefs.getLong(PREF_KEY_ALARM_TIME, 0L);
76 | }
77 |
78 | public void cancelAlarmInRtc() {
79 | if (mDriver != null) {
80 | try {
81 | mDriver.cancel();
82 | } catch (Exception e) {
83 | Log.e(TAG, Log.getStackTraceString(e));
84 | }
85 | }
86 | }
87 |
88 | public void setAlarmToRtc(long time) {
89 | if (mDriver != null) {
90 | long currentTime = System.currentTimeMillis();
91 | if (time <= currentTime + mPreBootMillisec) {
92 | Log.w(TAG, time + " is too early, current time is " + currentTime + "!");
93 | return;
94 | }
95 | long rtcTime = -1;
96 | try {
97 | rtcTime = mDriver.getRtcTimeOptional();
98 | if (DEBUG) Log.v(TAG, "read rtcTime " + rtcTime + " current " + currentTime);
99 | } catch (Exception e) {
100 | Log.e(TAG, Log.getStackTraceString(e));
101 | }
102 | if (rtcTime > 0) {
103 | // Account for differences in counting between RTC and AP clock, if needed
104 | long timeDiff = time - currentTime;
105 | time = (rtcTime + timeDiff) - mPreBootMillisec;
106 | } else {
107 | time -= mPreBootMillisec;
108 | }
109 | try {
110 | mDriver.set(time);
111 | } catch (Exception e) {
112 | Log.e(TAG, Log.getStackTraceString(e));
113 | }
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/PowerOffAlarm/java/org/lineageos/poweroffalarm/RtcDriver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | package org.lineageos.poweroffalarm;
7 |
8 | public class RtcDriver implements Driver {
9 |
10 | static {
11 | System.loadLibrary("jni_poweroffalarm");
12 | }
13 |
14 | public native void set(long time);
15 | public native void cancel();
16 | public native long getRtcTimeOptional();
17 | public native boolean isSupported();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/PowerOffAlarm/java/org/lineageos/poweroffalarm/TimerFdDriver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | package org.lineageos.poweroffalarm;
7 |
8 | public class TimerFdDriver implements Driver {
9 |
10 | static {
11 | System.loadLibrary("jni_poweroffalarm");
12 | }
13 |
14 | public native void set(long time);
15 | public native void cancel();
16 | public native long getRtcTimeOptional();
17 | public native boolean isSupported();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/PowerOffAlarm/jni/AlarmDriver.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size)
17 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2,type,struct timespec)
18 | #define ANDROID_ALARM_POWER_ON_LOGO 7
19 |
20 | static std::string alarm_dev = "/dev/alarm";
21 |
22 | extern "C" jboolean Java_org_lineageos_poweroffalarm_AlarmDriver_isSupported(
23 | JNIEnv*, jobject) {
24 | return access(alarm_dev.c_str(), F_OK) == 0;
25 | }
26 |
27 | extern "C" void Java_org_lineageos_poweroffalarm_AlarmDriver_set(
28 | JNIEnv*, jobject, jlong time) {
29 | android::base::unique_fd fd{open(alarm_dev.c_str(), O_WRONLY)};
30 | if (!fd.ok()) {
31 | ALOGE("Unable to open %s: %s", alarm_dev.c_str(), strerror(errno));
32 | return;
33 | }
34 |
35 | struct timespec ts = {};
36 | ts.tv_sec = time / 1000;
37 | ts.tv_nsec = (time % 1000) * 1000000;
38 |
39 | if (ioctl(fd, ANDROID_ALARM_SET(ANDROID_ALARM_POWER_ON_LOGO), &ts) == -1) {
40 | ALOGV("ANDROID_ALARM_SET ioctl failed: %s", strerror(errno));
41 | return;
42 | }
43 | }
44 |
45 | extern "C" void Java_org_lineageos_poweroffalarm_AlarmDriver_cancel(
46 | JNIEnv* env, jobject thiz) {
47 | Java_org_lineageos_poweroffalarm_AlarmDriver_set(env, thiz, 0);
48 | }
49 |
50 | extern "C" jlong Java_org_lineageos_poweroffalarm_AlarmDriver_getRtcTimeOptional(
51 | JNIEnv*, jobject) {
52 | return -1L;
53 | }
54 |
--------------------------------------------------------------------------------
/PowerOffAlarm/jni/RtcDriver.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #define RTC_POFF_ALM_SET _IOW('p', 0x15, struct rtc_time)
18 |
19 | static std::string rtc_dev = "/dev/rtc0";
20 |
21 | extern "C" jboolean Java_org_lineageos_poweroffalarm_RtcDriver_isSupported(
22 | JNIEnv*, jobject) {
23 | return access(rtc_dev.c_str(), F_OK) == 0;
24 | }
25 |
26 | extern "C" void Java_org_lineageos_poweroffalarm_RtcDriver_set(
27 | JNIEnv*, jobject, jlong time) {
28 | android::base::unique_fd fd{open(rtc_dev.c_str(), O_WRONLY)};
29 | if (!fd.ok()) {
30 | ALOGE("Unable to open %s: %s", rtc_dev.c_str(), strerror(errno));
31 | return;
32 | }
33 |
34 | struct tm tm = {};
35 | long ctime = time / 1000;
36 | if (!gmtime_r(&ctime, &tm)) {
37 | ALOGV("gmtime_r() failed: %s", strerror(errno));
38 | return;
39 | }
40 |
41 | struct rtc_time rtc = {};
42 | rtc.tm_sec = tm.tm_sec;
43 | rtc.tm_min = tm.tm_min;
44 | rtc.tm_hour = tm.tm_hour;
45 | rtc.tm_mday = tm.tm_mday;
46 | rtc.tm_mon = tm.tm_mon;
47 | rtc.tm_year = tm.tm_year;
48 | rtc.tm_wday = tm.tm_wday;
49 | rtc.tm_yday = tm.tm_yday;
50 | rtc.tm_isdst = tm.tm_isdst;
51 | if (ioctl(fd, RTC_POFF_ALM_SET, &rtc) == -1) {
52 | ALOGV("RTC_POFF_ALM_SET ioctl failed: %s", strerror(errno));
53 | return;
54 | }
55 | }
56 |
57 | extern "C" void Java_org_lineageos_poweroffalarm_RtcDriver_cancel(
58 | JNIEnv* env, jobject thiz) {
59 | Java_org_lineageos_poweroffalarm_RtcDriver_set(env, thiz, 0);
60 | }
61 |
62 | extern "C" jlong Java_org_lineageos_poweroffalarm_RtcDriver_getRtcTimeOptional(
63 | JNIEnv*, jobject) {
64 | android::base::unique_fd fd{open(rtc_dev.c_str(), O_RDWR)};
65 | if (!fd.ok()) {
66 | ALOGE("Unable to open %s: %s", rtc_dev.c_str(), strerror(errno));
67 | return -1;
68 | }
69 |
70 | struct rtc_time rtc = {};
71 | if (ioctl(fd, RTC_RD_TIME, &rtc) == -1) {
72 | ALOGV("RTC_RD_TIME ioctl failed: %s", strerror(errno));
73 | return -1;
74 | }
75 |
76 | struct tm tm = {};
77 | tm.tm_sec = rtc.tm_sec;
78 | tm.tm_min = rtc.tm_min;
79 | tm.tm_hour = rtc.tm_hour;
80 | tm.tm_mday = rtc.tm_mday;
81 | tm.tm_mon = rtc.tm_mon;
82 | tm.tm_year = rtc.tm_year;
83 | tm.tm_wday = rtc.tm_wday;
84 | tm.tm_yday = rtc.tm_yday;
85 | tm.tm_isdst = rtc.tm_isdst;
86 | long time = timegm(&tm);
87 | if (time < 0) {
88 | ALOGV("timegm() failed: %s", strerror(errno));
89 | return -1;
90 | }
91 |
92 | return time * 1000;
93 | }
94 |
--------------------------------------------------------------------------------
/PowerOffAlarm/jni/TimerFdDriver.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | * SPDX-License-Identifier: Apache-2.0
4 | */
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | extern "C" jboolean Java_org_lineageos_poweroffalarm_TimerFdDriver_isSupported(
18 | JNIEnv*, jobject) {
19 | #ifdef CLOCK_POWER_OFF_ALARM
20 | return true;
21 | #else
22 | return false;
23 | #endif
24 | }
25 |
26 | extern "C" void Java_org_lineageos_poweroffalarm_TimerFdDriver_set(
27 | JNIEnv*, jobject, [[maybe_unused]] jlong time) {
28 | #ifdef CLOCK_POWER_OFF_ALARM
29 | android::base::unique_fd fd{timerfd_create(CLOCK_POWER_OFF_ALARM, TFD_NONBLOCK)};
30 | if (!fd.ok()) {
31 | ALOGE("Unable to open CLOCK_POWER_OFF_ALARM: %s", strerror(errno));
32 | return;
33 | }
34 |
35 | struct timespec ts = {};
36 | ts.tv_sec = time / 1000;
37 | ts.tv_nsec = (time % 1000) * 1000000;
38 |
39 | struct itimerspec spec = {};
40 | memcpy(&spec.it_value, &ts, sizeof(spec.it_value));
41 |
42 | timerfd_settime(fd, TFD_TIMER_ABSTIME, &spec, NULL);
43 | #endif
44 | }
45 |
46 | extern "C" void Java_org_lineageos_poweroffalarm_TimerFdDriver_cancel(
47 | JNIEnv*, jobject) {
48 | #ifdef CLOCK_POWER_OFF_ALARM
49 | android::base::unique_fd fd{timerfd_create(CLOCK_POWER_OFF_ALARM, TFD_NONBLOCK)};
50 | if (!fd.ok()) {
51 | ALOGE("Unable to open CLOCK_POWER_OFF_ALARM: %s", strerror(errno));
52 | return;
53 | }
54 |
55 | struct itimerspec spec = {};
56 | timerfd_settime(fd, TFD_TIMER_ABSTIME, &spec, NULL);
57 | #endif
58 | }
59 |
60 | extern "C" jlong Java_org_lineageos_poweroffalarm_TimerFdDriver_getRtcTimeOptional(
61 | JNIEnv*, jobject) {
62 | return -1L;
63 | }
64 |
--------------------------------------------------------------------------------
/PowerOffAlarm/proguard.flags:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LineageOS/android_hardware_mediatek/6e579f65d78b86a5aea5c03fa742a5a7b852765c/PowerOffAlarm/proguard.flags
--------------------------------------------------------------------------------
/PowerOffAlarm/res/drawable/permic_power_off_alarm.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PowerOffAlarm/res/values/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
20 | timerfd,alarm,rtc
21 |
22 |
27 | 150000
28 |
29 |
30 |
--------------------------------------------------------------------------------
/PowerOffAlarm/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | Power off alarm
8 | set and clear the alarm which will wake up device from the power off state
9 | Power off alarm
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Common hardware components for MediaTek devices
2 |
--------------------------------------------------------------------------------
/aidl/gadget/Android.bp:
--------------------------------------------------------------------------------
1 | //
2 | // SPDX-FileCopyrightText: 2021 The Android Open Source Project
3 | // SPDX-FileCopyrightText: 2024 The LineageOS Project
4 | // SPDX-License-Identifier: Apache-2.0
5 | //
6 |
7 | cc_binary {
8 | name: "android.hardware.usb.gadget-service.mediatek",
9 | relative_install_path: "hw",
10 | init_rc: ["android.hardware.usb.gadget-service.rc"],
11 | vintf_fragments: [
12 | "android.hardware.usb.gadget-service.xml",
13 | ],
14 | vendor: true,
15 | srcs: [
16 | "service_gadget.cpp",
17 | "UsbGadget.cpp",
18 | ],
19 | cflags: [
20 | "-Wall",
21 | "-Werror",
22 | ],
23 | shared_libs: [
24 | "libbase",
25 | "liblog",
26 | "libutils",
27 | "android.frameworks.stats-V1-ndk",
28 | "android.hardware.usb.gadget-V1-ndk",
29 | "libcutils",
30 | "libbinder_ndk",
31 | ],
32 | static_libs: [
33 | "libpixelusb-aidl",
34 | ],
35 | proprietary: true,
36 | export_shared_lib_headers: [
37 | "android.frameworks.stats-V1-ndk",
38 | ],
39 | }
40 |
--------------------------------------------------------------------------------
/aidl/gadget/UsbGadget.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2020 The Android Open Source Project
3 | * SPDX-FileCopyrightText: 2024 The LineageOS Project
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | namespace aidl {
30 | namespace android {
31 | namespace hardware {
32 | namespace usb {
33 | namespace gadget {
34 |
35 | using ::aidl::android::hardware::usb::gadget::GadgetFunction;
36 | using ::aidl::android::hardware::usb::gadget::IUsbGadget;
37 | using ::aidl::android::hardware::usb::gadget::IUsbGadgetCallback;
38 | using ::aidl::android::hardware::usb::gadget::Status;
39 | using ::aidl::android::hardware::usb::gadget::UsbSpeed;
40 | using ::android::base::GetProperty;
41 | using ::android::base::ReadFileToString;
42 | using ::android::base::SetProperty;
43 | using ::android::base::Trim;
44 | using ::android::base::unique_fd;
45 | using ::android::base::WriteStringToFile;
46 | using ::android::hardware::google::pixel::usb::addAdb;
47 | using ::android::hardware::google::pixel::usb::addEpollFd;
48 | using ::android::hardware::google::pixel::usb::kDebug;
49 | using ::android::hardware::google::pixel::usb::kDisconnectWaitUs;
50 | using ::android::hardware::google::pixel::usb::linkFunction;
51 | using ::android::hardware::google::pixel::usb::MonitorFfs;
52 | using ::android::hardware::google::pixel::usb::resetGadget;
53 | using ::android::hardware::google::pixel::usb::setVidPid;
54 | using ::android::hardware::google::pixel::usb::unlinkFunctions;
55 | using ::ndk::ScopedAStatus;
56 | using ::std::shared_ptr;
57 | using ::std::string;
58 |
59 | const std::string kGadgetName = GetProperty("sys.usb.controller", "");
60 |
61 | #define UDC_PATH "/sys/class/udc/"
62 | #define DEVICE "device/"
63 | #define SPEED_PATH "current_speed"
64 | #define SAVING_PATH DEVICE "saving"
65 |
66 | struct UsbGadget : public BnUsbGadget {
67 | UsbGadget();
68 |
69 | // Makes sure that only one request is processed at a time.
70 | std::mutex mLockSetCurrentFunction;
71 | long mCurrentUsbFunctions;
72 | bool mCurrentUsbFunctionsApplied;
73 | UsbSpeed mUsbSpeed;
74 | MonitorFfs* mMonitorFfs;
75 |
76 | ScopedAStatus setCurrentUsbFunctions(long functions,
77 | const shared_ptr& callback,
78 | int64_t timeout, int64_t in_transactionId) override;
79 |
80 | ScopedAStatus getCurrentUsbFunctions(const shared_ptr& callback,
81 | int64_t in_transactionId) override;
82 |
83 | ScopedAStatus reset(const shared_ptr& callback,
84 | int64_t in_transactionId) override;
85 |
86 | ScopedAStatus getUsbSpeed(const shared_ptr& callback,
87 | int64_t in_transactionId) override;
88 |
89 | ScopedAStatus setVidPid(const char* vid, const char* pid);
90 |
91 | private:
92 | Status tearDownGadget();
93 | Status setupFunctions(long functions, const shared_ptr& callback,
94 | uint64_t timeout, int64_t in_transactionId);
95 | };
96 |
97 | } // namespace gadget
98 | } // namespace usb
99 | } // namespace hardware
100 | } // namespace android
101 | } // namespace aidl
102 |
--------------------------------------------------------------------------------
/aidl/gadget/android.hardware.usb.gadget-service.rc:
--------------------------------------------------------------------------------
1 | service vendor.usb-gadget-hal /vendor/bin/hw/android.hardware.usb.gadget-service.mediatek
2 | class hal
3 | user system
4 | group system shell mtp
5 | disabled
6 |
7 | on property:sys.usb.configfs=2
8 | enable vendor.usb-gadget-hal
9 |
--------------------------------------------------------------------------------
/aidl/gadget/android.hardware.usb.gadget-service.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | android.hardware.usb.gadget
4 | 1
5 |
6 | IUsbGadget
7 | default
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/aidl/gadget/service_gadget.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2021 The Android Open Source Project
3 | * SPDX-FileCopyrightText: 2024 The LineageOS Project
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #define LOG_TAG "android.hardware.usb.gadget-service.mediatek"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include "UsbGadget.h"
14 |
15 | using android::OK;
16 | using android::sp;
17 | using android::status_t;
18 |
19 | using aidl::android::hardware::usb::gadget::UsbGadget;
20 |
21 | int main() {
22 | ABinderProcess_setThreadPoolMaxThreadCount(0);
23 | std::shared_ptr usbgadget = ndk::SharedRefBase::make();
24 |
25 | const std::string instance = std::string() + UsbGadget::descriptor + "/default";
26 | binder_status_t status =
27 | AServiceManager_addService(usbgadget->asBinder().get(), instance.c_str());
28 | CHECK(status == STATUS_OK);
29 |
30 | ALOGV("AIDL USB Gadget HAL about to start");
31 | ABinderProcess_joinThreadPool();
32 | return -1; // Should never be reached
33 | }
34 |
--------------------------------------------------------------------------------
/aidl/health/Android.bp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | cc_defaults {
8 | name: "android.hardware.health-service.mediatek-defaults",
9 | defaults: [
10 | "libhealth_aidl_impl_user",
11 | "libhealth_aidl_charger_defaults",
12 | ],
13 | relative_install_path: "hw",
14 | vintf_fragments: ["android.hardware.health-service.mediatek.xml"],
15 | srcs: [
16 | "Health.cpp",
17 | ],
18 | static_libs: [
19 | "libhealth_aidl_impl",
20 | ],
21 | }
22 |
23 | cc_binary {
24 | name: "android.hardware.health-service.mediatek",
25 | defaults: ["android.hardware.health-service.mediatek-defaults"],
26 | vendor: true,
27 | init_rc: ["android.hardware.health-service.mediatek.rc"],
28 | overrides: ["charger"],
29 | }
30 |
31 | cc_binary {
32 | name: "android.hardware.health-service.mediatek-recovery",
33 | defaults: ["android.hardware.health-service.mediatek-defaults"],
34 | recovery: true,
35 | init_rc: ["android.hardware.health-service.mediatek-recovery.rc"],
36 | overrides: ["charger.recovery"],
37 | }
38 |
--------------------------------------------------------------------------------
/aidl/health/Health.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 The Android Open Source Project
3 | * Copyright (C) 2022 The LineageOS Project
4 | *
5 | * SPDX-License-Identifier: Apache-2.0
6 | */
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #ifndef CHARGER_FORCE_NO_UI
14 | #define CHARGER_FORCE_NO_UI 0
15 | #endif
16 |
17 | #if !CHARGER_FORCE_NO_UI
18 | #include
19 | #endif
20 |
21 | using aidl::android::hardware::health::HalHealthLoop;
22 | using aidl::android::hardware::health::Health;
23 |
24 | #if !CHARGER_FORCE_NO_UI
25 | using aidl::android::hardware::health::charger::ChargerCallback;
26 | using aidl::android::hardware::health::charger::ChargerModeMain;
27 | #endif
28 |
29 | static constexpr const char* gInstanceName = "default";
30 | static constexpr std::string_view gChargerArg{"--charger"};
31 |
32 | #if !CHARGER_FORCE_NO_UI
33 | namespace aidl::android::hardware::health {
34 | class ChargerCallbackImpl : public ChargerCallback {
35 | public:
36 | using ChargerCallback::ChargerCallback;
37 | bool ChargerEnableSuspend() override { return true; }
38 | };
39 | } // namespace aidl::android::hardware::health
40 | #endif
41 |
42 | int main(int argc, char** argv) {
43 | #ifdef __ANDROID_RECOVERY__
44 | android::base::InitLogging(argv, android::base::KernelLogger);
45 | #endif
46 |
47 | // make a default health service
48 | auto config = std::make_unique();
49 | ::android::hardware::health::InitHealthdConfig(config.get());
50 | auto binder = ndk::SharedRefBase::make(gInstanceName, std::move(config));
51 |
52 | if (argc >= 2 && argv[1] == gChargerArg) {
53 | #if !CHARGER_FORCE_NO_UI
54 | // If charger shouldn't have UI for your device, simply drop the line below
55 | // for your service implementation. This corresponds to
56 | // ro.charger.no_ui=true
57 | return ChargerModeMain(binder, std::make_shared(binder));
58 | #endif
59 |
60 | LOG(INFO) << "Starting charger mode without UI.";
61 | } else {
62 | LOG(INFO) << "Starting health HAL.";
63 | }
64 |
65 | auto hal_health_loop = std::make_shared(binder, binder);
66 | return hal_health_loop->StartLoop();
67 | }
68 |
--------------------------------------------------------------------------------
/aidl/health/android.hardware.health-service.mediatek-recovery.rc:
--------------------------------------------------------------------------------
1 | service vendor.health-mediatek /system/bin/hw/android.hardware.health-service.mediatek-recovery
2 | class hal
3 | seclabel u:r:hal_health_default:s0
4 | user system
5 | group system
6 | capabilities WAKE_ALARM BLOCK_SUSPEND
7 | file /dev/kmsg w
8 |
--------------------------------------------------------------------------------
/aidl/health/android.hardware.health-service.mediatek.rc:
--------------------------------------------------------------------------------
1 | service vendor.health-mediatek /vendor/bin/hw/android.hardware.health-service.mediatek
2 | class hal
3 | user system
4 | group system
5 | capabilities WAKE_ALARM BLOCK_SUSPEND
6 | file /dev/kmsg w
7 |
8 | service vendor.charger /vendor/bin/hw/android.hardware.health-service.mediatek --charger
9 | class charger
10 | seclabel u:r:charger_vendor:s0
11 | user system
12 | group system wakelock input
13 | capabilities SYS_BOOT
14 | file /dev/kmsg w
15 | file /sys/fs/pstore/console-ramoops-0 r
16 | file /sys/fs/pstore/console-ramoops r
17 | file /proc/last_kmsg r
18 |
19 | on charger
20 | chown system system /dev/graphics/fb0
21 | chown system system /dev/dri/card0
22 |
--------------------------------------------------------------------------------
/aidl/health/android.hardware.health-service.mediatek.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | android.hardware.health
4 | 3
5 | IHealth/default
6 |
7 |
8 |
--------------------------------------------------------------------------------
/aidl/memtrack/Android.bp:
--------------------------------------------------------------------------------
1 | cc_binary {
2 | name: "android.hardware.memtrack-service.mediatek-mali",
3 | relative_install_path: "hw",
4 | init_rc: ["memtrack_default.rc"],
5 | vintf_fragments: ["memtrack_default.xml"],
6 | vendor: true,
7 | shared_libs: [
8 | "android.hardware.memtrack-V1-ndk",
9 | "libbase",
10 | "libbinder_ndk",
11 | "liblog",
12 | ],
13 | srcs: [
14 | "Memtrack.cpp",
15 | "GpuSysfsReader.cpp",
16 | "filesystem.cpp",
17 | "main.cpp",
18 | ],
19 | }
20 |
--------------------------------------------------------------------------------
/aidl/memtrack/GpuSysfsReader.cpp:
--------------------------------------------------------------------------------
1 | #include "GpuSysfsReader.h"
2 |
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | #include "filesystem.h"
9 |
10 | #undef LOG_TAG
11 | #define LOG_TAG "memtrack-gpusysfsreader"
12 |
13 | using namespace GpuSysfsReader;
14 |
15 | namespace {
16 | uint64_t readNode(const std::string node, pid_t pid) {
17 | std::stringstream ss;
18 | if (pid)
19 | ss << kSysfsDevicePath << "/" << kProcessDir << "/" << pid << "/" << node;
20 | else
21 | ss << kSysfsDevicePath << "/" << node;
22 | const std::string path = ss.str();
23 |
24 | if (!filesystem::exists(filesystem::path(path))) {
25 | ALOGV("File not found: %s", path.c_str());
26 | return 0;
27 | }
28 |
29 | std::ifstream file(path.c_str());
30 | if (!file.is_open()) {
31 | ALOGW("Failed to open %s path", path.c_str());
32 | return 0;
33 | }
34 |
35 | uint64_t out;
36 | file >> out;
37 | file.close();
38 |
39 | return out;
40 | }
41 | } // namespace
42 |
43 | uint64_t GpuSysfsReader::getDmaBufGpuMem(pid_t pid) { return readNode(kDmaBufGpuMemNode, pid); }
44 |
45 | uint64_t GpuSysfsReader::getGpuMemTotal(pid_t pid) { return readNode(kTotalGpuMemNode, pid); }
46 |
47 | uint64_t GpuSysfsReader::getPrivateGpuMem(pid_t pid) {
48 | auto dma_buf_size = getDmaBufGpuMem(pid);
49 | auto gpu_total_size = getGpuMemTotal(pid);
50 |
51 | if (dma_buf_size > gpu_total_size) {
52 | ALOGE("Bug in reader, dma-buf size (%" PRIu64 ") is higher than total gpu size (%" PRIu64
53 | ")",
54 | dma_buf_size, gpu_total_size);
55 | return 0;
56 | }
57 |
58 | return gpu_total_size - dma_buf_size;
59 | }
60 |
--------------------------------------------------------------------------------
/aidl/memtrack/GpuSysfsReader.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #include
5 | #include
6 |
7 | namespace GpuSysfsReader {
8 | uint64_t getDmaBufGpuMem(pid_t pid = 0);
9 | uint64_t getGpuMemTotal(pid_t pid = 0);
10 | uint64_t getPrivateGpuMem(pid_t pid = 0);
11 |
12 | constexpr char kSysfsDevicePath[] = "/sys/class/misc/mali0/device";
13 | constexpr char kProcessDir[] = "kprcs";
14 | constexpr char kMappedDmaBufsDir[] = "dma_bufs";
15 | constexpr char kTotalGpuMemNode[] = "total_gpu_mem";
16 | constexpr char kDmaBufGpuMemNode[] = "dma_buf_gpu_mem";
17 | } // namespace GpuSysfsReader
18 |
--------------------------------------------------------------------------------
/aidl/memtrack/Memtrack.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include "GpuSysfsReader.h"
9 | #include "filesystem.h"
10 |
11 | #undef LOG_TAG
12 | #define LOG_TAG "memtrack-core"
13 |
14 | namespace aidl {
15 | namespace android {
16 | namespace hardware {
17 | namespace memtrack {
18 |
19 | ndk::ScopedAStatus Memtrack::getMemory(int pid, MemtrackType type,
20 | std::vector* _aidl_return) {
21 | if (pid < 0)
22 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
23 |
24 | if (type != MemtrackType::OTHER && type != MemtrackType::GL && type != MemtrackType::GRAPHICS &&
25 | type != MemtrackType::MULTIMEDIA && type != MemtrackType::CAMERA)
26 | return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
27 |
28 | _aidl_return->clear();
29 |
30 | // Other types are retained only for backward compatibility
31 | if (type != MemtrackType::GL && type != MemtrackType::GRAPHICS)
32 | return ndk::ScopedAStatus::ok();
33 |
34 | // pid 0 is only supported for GL type to report total private memory
35 | if (pid == 0 && type != MemtrackType::GL)
36 | return ndk::ScopedAStatus::ok();
37 |
38 | uint64_t size = 0;
39 | switch (type) {
40 | case MemtrackType::GL:
41 | size = GpuSysfsReader::getPrivateGpuMem(pid);
42 | break;
43 | case MemtrackType::GRAPHICS:
44 | // TODO(b/194483693): This is not PSS as required by memtrack HAL
45 | // but complete dmabuf allocations. Reporting PSS requires reading
46 | // procfs. This HAL does not have that permission yet.
47 | size = GpuSysfsReader::getDmaBufGpuMem(pid);
48 | break;
49 | default:
50 | break;
51 | }
52 |
53 | MemtrackRecord record = {
54 | .flags = MemtrackRecord::FLAG_SMAPS_UNACCOUNTED,
55 | .sizeInBytes = static_cast(size),
56 | };
57 | _aidl_return->emplace_back(record);
58 |
59 | return ndk::ScopedAStatus::ok();
60 | }
61 |
62 | ndk::ScopedAStatus Memtrack::getGpuDeviceInfo(std::vector* _aidl_return) {
63 | auto devPath = filesystem::path(GpuSysfsReader::kSysfsDevicePath);
64 | std::string devName = "default-gpu";
65 | if (filesystem::exists(devPath) && filesystem::is_symlink(devPath)) {
66 | devName = filesystem::read_symlink(devPath).filename().string();
67 | }
68 |
69 | DeviceInfo dev_info = {.id = 0, .name = devName};
70 |
71 | _aidl_return->clear();
72 | _aidl_return->emplace_back(dev_info);
73 | return ndk::ScopedAStatus::ok();
74 | }
75 |
76 | } // namespace memtrack
77 | } // namespace hardware
78 | } // namespace android
79 | } // namespace aidl
80 |
--------------------------------------------------------------------------------
/aidl/memtrack/Memtrack.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | namespace aidl {
10 | namespace android {
11 | namespace hardware {
12 | namespace memtrack {
13 |
14 | class Memtrack : public BnMemtrack {
15 | public:
16 | ndk::ScopedAStatus getMemory(int pid, MemtrackType type,
17 | std::vector* _aidl_return) override;
18 |
19 | ndk::ScopedAStatus getGpuDeviceInfo(std::vector* _aidl_return) override;
20 | };
21 |
22 | } // namespace memtrack
23 | } // namespace hardware
24 | } // namespace android
25 | } // namespace aidl
26 |
--------------------------------------------------------------------------------
/aidl/memtrack/filesystem.cpp:
--------------------------------------------------------------------------------
1 | #include "filesystem.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | namespace filesystem {
14 |
15 | bool exists(const path& p) {
16 | struct stat s;
17 | return stat(p.string().c_str(), &s) == 0;
18 | }
19 |
20 | bool is_directory(const path& p) {
21 | struct stat s;
22 | if (stat(p.string().c_str(), &s))
23 | return false;
24 |
25 | return S_ISDIR(s.st_mode);
26 | }
27 |
28 | bool is_symlink(const path& p) {
29 | struct stat s;
30 | if (lstat(p.string().c_str(), &s))
31 | return false;
32 |
33 | return S_ISLNK(s.st_mode);
34 | }
35 |
36 | path read_symlink(const path& p) {
37 | char* actualPath = realpath(p.string().c_str(), NULL);
38 | if (!actualPath) {
39 | return path(p.string());
40 | }
41 |
42 | path out(actualPath);
43 | free(actualPath);
44 | return out;
45 | }
46 |
47 | std::vector directory_iterator(const path& p) {
48 | if (!exists(p) || !is_directory(p))
49 | return {};
50 |
51 | std::unique_ptr dir(opendir(p.string().c_str()), &closedir);
52 | if (!dir) {
53 | ALOGE("Failed to open %s directory", p.string().c_str());
54 | }
55 |
56 | std::vector out;
57 | struct dirent* dent;
58 | while ((dent = readdir(dir.get()))) {
59 | if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
60 | continue;
61 |
62 | std::stringstream ss(p.string());
63 | ss << "/" << dent->d_name;
64 | out.emplace_back(ss.str());
65 | }
66 |
67 | return out;
68 | }
69 |
70 | } // namespace filesystem
71 |
--------------------------------------------------------------------------------
/aidl/memtrack/filesystem.h:
--------------------------------------------------------------------------------
1 | // TODO(b/147469372): filesystem library in Android's libcxx is not available
2 | // for vendors. It had an unstable ABI and libcxx isn't updated ever since.
3 |
4 | // This simply implements some of the required functions in not-so-safe fashion.
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #include
15 | #include
16 |
17 | namespace filesystem {
18 | class path {
19 | public:
20 | path(const std::string _path) : strPath(_path) {}
21 |
22 | path filename() const {
23 | auto pos = strPath.rfind('/');
24 | if (pos == std::string::npos)
25 | return path(strPath);
26 |
27 | pos++;
28 | auto l = strPath.size();
29 | return path(strPath.substr(pos, l - pos));
30 | }
31 |
32 | std::string string() const { return strPath; }
33 |
34 | private:
35 | std::string strPath;
36 | };
37 |
38 | class directory_entry {
39 | public:
40 | directory_entry(const std::string _path) : p(_path) {}
41 |
42 | class path path() {
43 | return p;
44 | }
45 |
46 | private:
47 | class path p;
48 | };
49 |
50 | bool exists(const path& p);
51 |
52 | bool is_directory(const path& p);
53 |
54 | bool is_symlink(const path& p);
55 |
56 | path read_symlink(const path& p);
57 |
58 | // Vector is easier to create than an iterator and serves our purposes well
59 | std::vector directory_iterator(const path& p);
60 | } // namespace filesystem
61 |
--------------------------------------------------------------------------------
/aidl/memtrack/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "Memtrack.h"
6 |
7 | #undef LOG_TAG
8 | #define LOG_TAG "memtrack-service"
9 |
10 | using aidl::android::hardware::memtrack::Memtrack;
11 |
12 | int main() {
13 | ABinderProcess_setThreadPoolMaxThreadCount(0);
14 | std::shared_ptr memtrack = ndk::SharedRefBase::make();
15 |
16 | const std::string instance = std::string() + Memtrack::descriptor + "/default";
17 | binder_status_t status =
18 | AServiceManager_addService(memtrack->asBinder().get(), instance.c_str());
19 | CHECK(status == STATUS_OK);
20 |
21 | ABinderProcess_joinThreadPool();
22 | return EXIT_FAILURE; // Unreachable
23 | }
24 |
--------------------------------------------------------------------------------
/aidl/memtrack/memtrack_default.rc:
--------------------------------------------------------------------------------
1 | service vendor.memtrack-default /vendor/bin/hw/android.hardware.memtrack-service.mediatek-mali
2 | class hal
3 | user graphics
4 | group system
5 |
--------------------------------------------------------------------------------
/aidl/memtrack/memtrack_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | android.hardware.memtrack
4 | IMemtrack/default
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/aidl/power-mediatek/Android.bp:
--------------------------------------------------------------------------------
1 | //
2 | // SPDX-FileCopyrightText: 2024 The LineageOS Project
3 | // SPDX-License-Identifier: Apache-2.0
4 | //
5 |
6 | soong_config_module_type {
7 | name: "mediatek_power_defaults",
8 | module_type: "cc_defaults",
9 | config_namespace: "mediatek_power",
10 | value_variables: [
11 | "double_tap_to_wake_node",
12 | "powerhal_ext",
13 | ],
14 | properties: [
15 | "cflags",
16 | "whole_static_libs",
17 | ],
18 | }
19 |
20 | mediatek_power_defaults {
21 | name: "mediatek_power_defaults",
22 | soong_config_variables: {
23 | double_tap_to_wake_node: {
24 | cflags: ["-DTAP_TO_WAKE_NODE=\"%s\""],
25 | },
26 | powerhal_ext: {
27 | cflags: ["-DMODE_EXT"],
28 | whole_static_libs: ["%s"],
29 | },
30 | },
31 | }
32 |
33 | cc_library_shared {
34 | name: "android.hardware.power-service-mediatek",
35 | defaults: ["mediatek_power_defaults"],
36 | vendor: true,
37 | compile_multilib: "64",
38 | vintf_fragments: ["power-mtk.xml"],
39 | srcs: ["Power.cpp"],
40 |
41 | shared_libs: [
42 | "libbase",
43 | "libbinder_ndk",
44 | "android.hardware.power-V2-ndk",
45 | ],
46 | }
47 |
--------------------------------------------------------------------------------
/aidl/power-mediatek/Power.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2020 The Android Open Source Project
3 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
4 | *
5 | * SPDX-License-Identifier: Apache-2.0
6 | */
7 |
8 | #pragma once
9 |
10 | #include "types.h"
11 |
12 | #include
13 |
14 | namespace aidl {
15 | namespace android {
16 | namespace hardware {
17 | namespace power {
18 | namespace impl {
19 | namespace mediatek {
20 |
21 | const std::string kTouchBoostDurationProperty = "persist.vendor.powerhal.touchboost_duration";
22 | const int32_t kDefaultTouchBoostDuration = 1; /* ms */
23 | const int32_t kLaunchBoostDuration = 30000; /* ms */
24 | const int32_t kMaxInteractiveDuration = 5000; /* ms */
25 | const int32_t kMinInteractiveDuration = 400; /* ms */
26 | const int32_t kMaxTouchBoostDuration = 1000; /* ms */
27 |
28 | class Power : public BnPower {
29 | public:
30 | Power();
31 | ~Power();
32 | ndk::ScopedAStatus setMode(Mode type, bool enabled) override;
33 | ndk::ScopedAStatus isModeSupported(Mode type, bool* _aidl_return) override;
34 | ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override;
35 | ndk::ScopedAStatus isBoostSupported(Boost type, bool* _aidl_return) override;
36 | ndk::ScopedAStatus createHintSession(int32_t tgid, int32_t uid,
37 | const std::vector& threadIds,
38 | int64_t durationNanos,
39 | std::shared_ptr* _aidl_return) override;
40 | ndk::ScopedAStatus getHintSessionPreferredRate(int64_t* outNanoseconds) override;
41 |
42 | private:
43 | static long long calcTimespanUs(struct timespec start, struct timespec end);
44 | void handleInteractionHint(int32_t targetDuration);
45 |
46 | libpowerhal_t* mPerf;
47 |
48 | struct timespec mPreviousInteractionTime;
49 | int32_t mTouchBoostDuration;
50 | int32_t mPreviousInteractionDuration;
51 | int32_t mPreviousInteractionHandle;
52 | int32_t mLaunchHandle;
53 | };
54 |
55 | } // namespace mediatek
56 | } // namespace impl
57 | } // namespace power
58 | } // namespace hardware
59 | } // namespace android
60 | } // namespace aidl
61 |
--------------------------------------------------------------------------------
/aidl/power-mediatek/power-mtk.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | android.hardware.power
4 | 2
5 | IPower/default
6 |
7 |
8 |
--------------------------------------------------------------------------------
/aidl/power-mediatek/types.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: 2023 The LineageOS Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #pragma once
8 |
9 | #define POWERHAL_LIB_NAME "libpowerhal.so"
10 |
11 | #define MTKPOWER_HINT_LAUNCH 11
12 | #define MTKPOWER_HINT_APP_TOUCH 25
13 | #define MTKPOWER_HINT_UX_SCROLLING 43
14 |
15 | #define USINSEC 1000000L
16 | #define NSINUS 1000L
17 |
18 | typedef struct libpowerhal_t {
19 | void* perfLib;
20 | void (*Init)(int32_t);
21 | void (*LockRel)(int32_t);
22 | void (*UserScnDisableAll)(void);
23 | void (*UserScnRestoreAll)(void);
24 | int32_t (*CusLockHint)(int32_t, int32_t, __pid_t);
25 | } libpowerhal_t;
26 |
--------------------------------------------------------------------------------
/aidl/thermal/Android.bp:
--------------------------------------------------------------------------------
1 | cc_binary {
2 | name: "android.hardware.thermal-service.mediatek",
3 | srcs: [
4 | "service.cpp",
5 | "Thermal.cpp",
6 | "thermal-helper.cpp",
7 | "utils/thermal_throttling.cpp",
8 | "utils/thermal_info.cpp",
9 | "utils/thermal_files.cpp",
10 | "utils/power_files.cpp",
11 | "utils/powerhal_helper.cpp",
12 | "utils/thermal_stats_helper.cpp",
13 | "utils/thermal_predictions_helper.cpp",
14 | "utils/thermal_watcher.cpp",
15 | "virtualtemp_estimator/virtualtemp_estimator.cpp",
16 | ],
17 | vendor: true,
18 | relative_install_path: "hw",
19 | vintf_fragments: [
20 | "android.hardware.thermal-service.mediatek.xml",
21 | ],
22 | init_rc: [
23 | "android.hardware.thermal-service.mediatek.rc",
24 | ],
25 | required: [
26 | "thermal_symlinks_mediatek",
27 | ],
28 | shared_libs: [
29 | "libbase",
30 | "libcutils",
31 | "libjsoncpp",
32 | "libutils",
33 | "libnl",
34 | "libbinder_ndk",
35 | "android.frameworks.stats-V2-ndk",
36 | "android.hardware.power-V1-ndk",
37 | "android.hardware.thermal-V3-ndk",
38 | "pixel-power-ext-V1-ndk",
39 | "pixelatoms-cpp",
40 | ],
41 | static_libs: [
42 | "libpixelstats",
43 | ],
44 | export_shared_lib_headers: [
45 | "android.frameworks.stats-V2-ndk",
46 | "pixelatoms-cpp",
47 | ],
48 | cflags: [
49 | "-Wall",
50 | "-Werror",
51 | "-Wextra",
52 | "-Wunused",
53 | ],
54 | tidy: true,
55 | tidy_checks: [
56 | "android-*",
57 | "cert-*",
58 | "clang-analyzer-security*",
59 | ],
60 | tidy_checks_as_errors: [
61 | "android-*",
62 | "clang-analyzer-security*",
63 | "cert-*",
64 | ],
65 | }
66 |
67 | sh_binary {
68 | name: "thermal_symlinks_mediatek",
69 | src: "init.thermal.symlinks.sh",
70 | vendor: true,
71 | init_rc: [
72 | "mediatek-thermal-symlinks.rc",
73 | ],
74 | }
75 |
--------------------------------------------------------------------------------
/aidl/thermal/OWNERS:
--------------------------------------------------------------------------------
1 | wvw@google.com
2 | paillon@google.com
3 | jenhaochen@google.com
4 | liumartin@google.com
5 | sayanna@google.com
6 | kamewang@google.com
7 |
--------------------------------------------------------------------------------
/aidl/thermal/Thermal.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The Android Open Source Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 | #include
13 |
14 | #include "thermal-helper.h"
15 |
16 | namespace aidl {
17 | namespace android {
18 | namespace hardware {
19 | namespace thermal {
20 | namespace implementation {
21 |
22 | struct CallbackSetting {
23 | CallbackSetting(std::shared_ptr callback, bool is_filter_type,
24 | TemperatureType type)
25 | : callback(std::move(callback)), is_filter_type(is_filter_type), type(type) {}
26 | std::shared_ptr callback;
27 | bool is_filter_type;
28 | TemperatureType type;
29 | };
30 |
31 | struct CoolingDeviceCallbackSetting {
32 | CoolingDeviceCallbackSetting(std::shared_ptr callback,
33 | bool is_filter_type, CoolingType type)
34 | : callback(std::move(callback)), is_filter_type(is_filter_type), type(type) {}
35 | std::shared_ptr callback;
36 | bool is_filter_type;
37 | CoolingType type;
38 | };
39 |
40 | class Thermal : public BnThermal {
41 | public:
42 | Thermal();
43 | explicit Thermal(const std::shared_ptr &helper);
44 | ~Thermal() = default;
45 | ndk::ScopedAStatus getTemperatures(std::vector *_aidl_return) override;
46 | ndk::ScopedAStatus getTemperaturesWithType(TemperatureType type,
47 | std::vector *_aidl_return) override;
48 |
49 | ndk::ScopedAStatus getTemperatureThresholds(
50 | std::vector *_aidl_return) override;
51 | ndk::ScopedAStatus getTemperatureThresholdsWithType(
52 | TemperatureType type, std::vector *_aidl_return) override;
53 |
54 | ndk::ScopedAStatus registerThermalChangedCallback(
55 | const std::shared_ptr &callback) override;
56 | ndk::ScopedAStatus registerThermalChangedCallbackWithType(
57 | const std::shared_ptr &callback,
58 | TemperatureType type) override;
59 | ndk::ScopedAStatus unregisterThermalChangedCallback(
60 | const std::shared_ptr &callback) override;
61 |
62 | ndk::ScopedAStatus getCoolingDevices(std::vector *_aidl_return) override;
63 | ndk::ScopedAStatus getCoolingDevicesWithType(CoolingType type,
64 | std::vector *_aidl_return) override;
65 |
66 | ndk::ScopedAStatus registerCoolingDeviceChangedCallbackWithType(
67 | const std::shared_ptr &callback,
68 | CoolingType type) override;
69 | ndk::ScopedAStatus unregisterCoolingDeviceChangedCallback(
70 | const std::shared_ptr &callback) override;
71 | ndk::ScopedAStatus forecastSkinTemperature(int32_t forecastSeconds,
72 | float *_aidl_return) override;
73 |
74 | binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
75 |
76 | // Helper function for calling callbacks
77 | void sendThermalChangedCallback(const Temperature &t);
78 |
79 | private:
80 | class Looper {
81 | public:
82 | struct Event {
83 | std::function handler;
84 | };
85 |
86 | Looper() {
87 | thread_ = std::thread([&] { loop(); });
88 | }
89 | ~Looper();
90 |
91 | void addEvent(const Event &e);
92 |
93 | private:
94 | std::condition_variable cv_;
95 | std::queue events_;
96 | std::mutex mutex_;
97 | std::thread thread_;
98 | bool aborted_;
99 |
100 | void loop();
101 | };
102 |
103 | std::shared_ptr thermal_helper_;
104 | std::mutex thermal_callback_mutex_;
105 | std::vector callbacks_;
106 | std::mutex cdev_callback_mutex_;
107 | std::vector cdev_callbacks_;
108 |
109 | Looper looper_;
110 |
111 | ndk::ScopedAStatus getFilteredTemperatures(bool filterType, TemperatureType type,
112 | std::vector *_aidl_return);
113 | ndk::ScopedAStatus getFilteredCoolingDevices(bool filterType, CoolingType type,
114 | std::vector *_aidl_return);
115 | ndk::ScopedAStatus getFilteredTemperatureThresholds(
116 | bool filterType, TemperatureType type, std::vector *_aidl_return);
117 | ndk::ScopedAStatus registerThermalChangedCallback(
118 | const std::shared_ptr &callback, bool filterType,
119 | TemperatureType type);
120 |
121 | void dumpVirtualSensorInfo(std::ostringstream *dump_buf);
122 | void dumpVtEstimatorInfo(std::ostringstream *dump_buf);
123 | void dumpThrottlingInfo(std::ostringstream *dump_buf);
124 | void dumpThrottlingRequestStatus(std::ostringstream *dump_buf);
125 | void dumpPowerRailInfo(std::ostringstream *dump_buf);
126 | void dumpStatsRecord(std::ostringstream *dump_buf, const StatsRecord &stats_record,
127 | std::string_view line_prefix);
128 | void dumpThermalStats(std::ostringstream *dump_buf);
129 | void dumpThermalData(int fd, const char **args, uint32_t numArgs);
130 | };
131 |
132 | } // namespace implementation
133 | } // namespace thermal
134 | } // namespace hardware
135 | } // namespace android
136 | } // namespace aidl
137 |
--------------------------------------------------------------------------------
/aidl/thermal/android.hardware.thermal-service.mediatek.rc:
--------------------------------------------------------------------------------
1 | on property:vendor.thermal.link_ready=1
2 | # queue the trigger to start thermal-hal and continue execute
3 | # per-device thermal setup "on property:vendor.thermal.link_ready=1"
4 | trigger enable-thermal-hal
5 |
6 | on enable-thermal-hal
7 | restart vendor.thermal-hal
8 |
9 | service vendor.thermal-hal /vendor/bin/hw/android.hardware.thermal-service.mediatek
10 | class hal
11 | user system
12 | group system
13 | priority -10
14 | disabled
15 |
--------------------------------------------------------------------------------
/aidl/thermal/android.hardware.thermal-service.mediatek.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | android.hardware.thermal
4 | 3
5 | IThermal/default
6 |
7 |
8 |
--------------------------------------------------------------------------------
/aidl/thermal/init.thermal.symlinks.sh:
--------------------------------------------------------------------------------
1 | #!/vendor/bin/sh
2 |
3 | for f in /sys/class/thermal/thermal_zone*
4 | do
5 | tz_name=`cat $f/type`
6 | ln -s $f /dev/thermal/tz-by-name/$tz_name
7 | done
8 | for f in /sys/class/thermal/cooling_device*
9 | do
10 | cdev_name=`cat $f/type`
11 | ln -s $f /dev/thermal/cdev-by-name/$cdev_name
12 | done
13 | setprop vendor.thermal.link_ready 1
14 |
--------------------------------------------------------------------------------
/aidl/thermal/mediatek-thermal-symlinks.rc:
--------------------------------------------------------------------------------
1 | on boot
2 | mkdir /dev/thermal 0750 system system
3 | mkdir /dev/thermal/tz-by-name 0750 system system
4 | mkdir /dev/thermal/cdev-by-name 0750 system system
5 | start vendor.thermal.symlinks
6 |
7 | service vendor.thermal.symlinks /vendor/bin/thermal_symlinks_mediatek
8 | user system
9 | group system
10 | oneshot
11 | disabled
12 |
--------------------------------------------------------------------------------
/aidl/thermal/service.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The Android Open Source Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 | #include
7 | #include
8 | #include
9 |
10 | #include "Thermal.h"
11 |
12 | constexpr std::string_view kThermalLogTag("pixel-thermal");
13 |
14 | using ::android::OK;
15 | using ::android::status_t;
16 |
17 | // Generated AIDL files:
18 | using Thermal = ::aidl::android::hardware::thermal::implementation::Thermal;
19 |
20 | #if !defined(THERMAL_INSTANCE_NAME)
21 | #define THERMAL_INSTANCE_NAME "default"
22 | #endif
23 |
24 | int main(int /* argc */, char ** /* argv */) {
25 | // ignore broken pipe signal to avoid Thermal HAL being killed when dumpsys timeout
26 | signal(SIGPIPE, SIG_IGN);
27 | android::base::SetDefaultTag(kThermalLogTag.data());
28 |
29 | auto svc = ndk::SharedRefBase::make();
30 | const auto svcName = std::string() + svc->descriptor + "/" + THERMAL_INSTANCE_NAME;
31 | LOG(INFO) << "Pixel Thermal AIDL Service starting..." + svcName;
32 | ABinderProcess_setThreadPoolMaxThreadCount(0);
33 |
34 | auto svcBinder = svc->asBinder();
35 | binder_status_t status = AServiceManager_addService(svcBinder.get(), svcName.c_str());
36 | if (status != STATUS_OK) {
37 | LOG(ERROR) << "Pixel Thermal AIDL Service failed to start: " << status << ".";
38 | return EXIT_FAILURE;
39 | }
40 | LOG(INFO) << "Pixel Thermal HAL AIDL Service started.";
41 | ABinderProcess_joinThreadPool();
42 | return EXIT_FAILURE; // should not reach
43 | }
44 |
--------------------------------------------------------------------------------
/aidl/thermal/utils/config_schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "definitions":{
3 |
4 | },
5 | "$schema":"http://json-schema.org/draft-07/schema#",
6 | "$id":"http://example.com/root.json",
7 | "type":"object",
8 | "title":"The Root Schema",
9 | "required":[
10 | "Sensors"
11 | ],
12 | "properties":{
13 | "Sensors":{
14 | "$id":"#/properties/Sensors",
15 | "type":"array",
16 | "title":"The Sensors Schema",
17 | "items":{
18 | "$id":"#/properties/Sensors/items",
19 | "type":"object",
20 | "title":"The Items Schema",
21 | "required":[
22 | "Name",
23 | "Type",
24 | "HotThreshold",
25 | "VrThreshold",
26 | "Multiplier"
27 | ],
28 | "properties":{
29 | "Name":{
30 | "$id":"#/properties/Sensors/items/properties/Name",
31 | "type":"string",
32 | "title":"The Name Schema",
33 | "default":"",
34 | "examples":[
35 | "cpu0-silver-usr"
36 | ],
37 | "pattern":"^(.+)$"
38 | },
39 | "Type":{
40 | "$id":"#/properties/Sensors/items/properties/Type",
41 | "type":"string",
42 | "title":"The Type Schema",
43 | "default":"",
44 | "examples":[
45 | "CPU"
46 | ],
47 | "pattern":"^(.+)$"
48 | },
49 | "HotThreshold":{
50 | "$id":"#/properties/Sensors/items/properties/HotThreshold",
51 | "type":"array",
52 | "title":"The hot threshold Schema, values are thresholds from ThrottlingSeverity::NONE to ThrottlingSeverity::SHUTDOWN",
53 | "default":"NAN",
54 | "maxItems":7,
55 | "minItems":7,
56 | "items":{
57 | "$id":"#/properties/Sensors/items/properties/HotThreshold/items",
58 | "type":[
59 | "string",
60 | "number"
61 | ],
62 | "title":"The Items Schema",
63 | "default":"",
64 | "examples":[
65 | "NAN",
66 | "NAN",
67 | "NAN",
68 | 95,
69 | "NAN",
70 | "NAN",
71 | 125
72 | ],
73 | "pattern":"^([-+]?[0-9]*\\.?[0-9]+|NAN)$"
74 | }
75 | },
76 | "HotHysteresis":{
77 | "$id":"#/properties/Sensors/items/properties/HotHysteresis",
78 | "type":"array",
79 | "title":"The hot hysteresis Schema, values are thresholds from ThrottlingSeverity::NONE to ThrottlingSeverity::SHUTDOWN. Throttling status will be cleared HotThreshold - HotHysteresis.",
80 | "default":null,
81 | "maxItems":7,
82 | "minItems":7,
83 | "items":{
84 | "$id":"#/properties/Sensors/items/properties/HotHysteresis/items",
85 | "type":[
86 | "number"
87 | ],
88 | "title":"The Items Schema",
89 | "default":0.0,
90 | "examples":[
91 | 0.0,
92 | 0.0,
93 | 0.0,
94 | 1.0,
95 | 1.5,
96 | 1.0,
97 | 2.0
98 | ]
99 | }
100 | },
101 | "ColdThreshold":{
102 | "$id":"#/properties/Sensors/items/properties/ColdThreshold",
103 | "type":"array",
104 | "title":"The cold threshold Schema, values are thresholds from ThrottlingSeverity::NONE to ThrottlingSeverity::SHUTDOWN, default to NAN",
105 | "default":null,
106 | "maxItems":7,
107 | "minItems":7,
108 | "items":{
109 | "$id":"#/properties/Sensors/items/properties/ColdThreshold/items",
110 | "type":"string",
111 | "title":"The Items Schema",
112 | "default":"NAN",
113 | "examples":[
114 | "NAN",
115 | "NAN",
116 | "NAN",
117 | "NAN",
118 | "NAN",
119 | "NAN",
120 | "NAN"
121 | ],
122 | "pattern":"^([-+]?[0-9]*\\.?[0-9]+|NAN)$"
123 | }
124 | },
125 | "ColdHysteresis":{
126 | "$id":"#/properties/Sensors/items/properties/ColdHysteresis",
127 | "type":"array",
128 | "title":"The cold hysteresis Schema, values are thresholds from ThrottlingSeverity::NONE to ThrottlingSeverity::SHUTDOWN. Throttling status will be cleared ColdThreshold + ColdHysteresis.",
129 | "default":null,
130 | "maxItems":7,
131 | "minItems":7,
132 | "items":{
133 | "$id":"#/properties/Sensors/items/properties/ColdHysteresis/items",
134 | "type":[
135 | "number"
136 | ],
137 | "title":"The Items Schema",
138 | "default":0.0,
139 | "examples":[
140 | 0.0,
141 | 0.0,
142 | 0.0,
143 | 1.0,
144 | 1.5,
145 | 1.0,
146 | 2.0
147 | ]
148 | }
149 | },
150 | "VrThreshold":{
151 | "$id":"#/properties/Sensors/items/properties/VrThreshold",
152 | "type":"string",
153 | "title":"The Vrthreshold Schema",
154 | "default":"",
155 | "examples":[
156 | "NAN"
157 | ],
158 | "pattern":"^(.*)$"
159 | },
160 | "Multiplier":{
161 | "$id":"#/properties/Sensors/items/properties/Multiplier",
162 | "type":"number",
163 | "title":"The Multiplier Schema",
164 | "default":0.001,
165 | "examples":[
166 | 0.001
167 | ],
168 | "exclusiveMinimum":0.0
169 | },
170 | "Monitor":{
171 | "$id":"#/properties/Sensors/items/properties/Monitor",
172 | "type":"boolean",
173 | "title":"The Monitor Schema, if the sensor will be monitored and used to trigger throttling event",
174 | "default":false,
175 | "examples":[
176 | true
177 | ]
178 | }
179 | }
180 | }
181 | },
182 | "CoolingDevices":{
183 | "$id":"#/properties/CoolingDevices",
184 | "type":"array",
185 | "title":"The Coolingdevices Schema",
186 | "items":{
187 | "$id":"#/properties/CoolingDevices/items",
188 | "type":"object",
189 | "title":"The Items Schema",
190 | "required":[
191 | "Name",
192 | "Type"
193 | ],
194 | "properties":{
195 | "Name":{
196 | "$id":"#/properties/CoolingDevices/items/properties/Name",
197 | "type":"string",
198 | "title":"The Name Schema",
199 | "default":"",
200 | "examples":[
201 | "thermal-cpufreq-0"
202 | ],
203 | "pattern":"^(.+)$"
204 | },
205 | "Type":{
206 | "$id":"#/properties/CoolingDevices/items/properties/Type",
207 | "type":"string",
208 | "title":"The Type Schema",
209 | "default":"",
210 | "examples":[
211 | "CPU"
212 | ],
213 | "pattern":"^(.+)$"
214 | }
215 | }
216 | }
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/aidl/thermal/utils/power_files.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The Android Open Source Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | #include "thermal_info.h"
19 |
20 | namespace aidl {
21 | namespace android {
22 | namespace hardware {
23 | namespace thermal {
24 | namespace implementation {
25 |
26 | using ::android::base::boot_clock;
27 |
28 | struct PowerSample {
29 | uint64_t energy_counter;
30 | uint64_t duration;
31 | };
32 |
33 | struct PowerStatus {
34 | boot_clock::time_point last_update_time;
35 | // A vector to record the queues of power sample history.
36 | std::vector> power_history;
37 | float last_updated_avg_power;
38 | };
39 |
40 | struct PowerStatusLog {
41 | boot_clock::time_point prev_log_time;
42 | // energy sample at last logging
43 | std::unordered_map prev_energy_info_map;
44 | };
45 |
46 | // A helper class for monitoring power rails.
47 | class PowerFiles {
48 | public:
49 | PowerFiles() = default;
50 | ~PowerFiles() = default;
51 | // Disallow copy and assign.
52 | PowerFiles(const PowerFiles &) = delete;
53 | void operator=(const PowerFiles &) = delete;
54 | bool registerPowerRailsToWatch(const Json::Value &config);
55 | // Update the power data from ODPM sysfs
56 | bool refreshPowerStatus(void);
57 | // Log the power data for the duration
58 | void logPowerStatus(const boot_clock::time_point &now);
59 | // Get previous power log time_point
60 | const boot_clock::time_point &GetPrevPowerLogTime() const {
61 | return power_status_log_.prev_log_time;
62 | }
63 | // Get power status map
64 | const std::unordered_map &GetPowerStatusMap() const {
65 | std::shared_lock _lock(power_status_map_mutex_);
66 | return power_status_map_;
67 | }
68 | // Get power rail info map
69 | const std::unordered_map &GetPowerRailInfoMap() const {
70 | return power_rail_info_map_;
71 | }
72 |
73 | private:
74 | // Update energy value to energy_info_map_, return false if the value is failed to update.
75 | bool updateEnergyValues(void);
76 | // Compute the average power for physical power rail.
77 | float updateAveragePower(std::string_view power_rail, std::queue *power_history);
78 | // Update the power data for the target power rail.
79 | float updatePowerRail(std::string_view power_rail);
80 | // Find the energy source path, return false if no energy source found.
81 | bool findEnergySourceToWatch(void);
82 | // The map to record the energy counter for each power rail.
83 | std::unordered_map energy_info_map_;
84 | // The map to record the power data for each thermal sensor.
85 | std::unordered_map power_status_map_;
86 | mutable std::shared_mutex power_status_map_mutex_;
87 | // The map to record the power rail information from thermal config
88 | std::unordered_map power_rail_info_map_;
89 | // The set to store the energy source paths
90 | std::unordered_set energy_path_set_;
91 | PowerStatusLog power_status_log_;
92 | };
93 |
94 | } // namespace implementation
95 | } // namespace thermal
96 | } // namespace hardware
97 | } // namespace android
98 | } // namespace aidl
99 |
--------------------------------------------------------------------------------
/aidl/thermal/utils/powerhal_helper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The Android Open Source Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include "thermal_info.h"
22 |
23 | namespace aidl {
24 | namespace android {
25 | namespace hardware {
26 | namespace thermal {
27 | namespace implementation {
28 |
29 | using ::aidl::android::hardware::power::IPower;
30 | using ::aidl::google::hardware::power::extension::pixel::IPowerExt;
31 |
32 | using CdevRequestStatus = std::unordered_map;
33 |
34 | struct PowerHintstatus {
35 | std::unordered_map hint_severity_map;
36 | ThrottlingSeverity prev_hint_severity;
37 | };
38 |
39 | class PowerHalService {
40 | public:
41 | PowerHalService();
42 | ~PowerHalService() = default;
43 | bool connect();
44 | void reconnect();
45 | bool isAidlPowerHalExist() { return power_hal_aidl_exist_; }
46 | bool isModeSupported(const std::string &type, const ThrottlingSeverity &t);
47 | bool isPowerHalConnected() { return power_hal_aidl_ != nullptr; }
48 | bool isPowerHalExtConnected() { return power_hal_ext_aidl_ != nullptr; }
49 | void setMode(const std::string &type, const ThrottlingSeverity &t, const bool &enable,
50 | const bool error_on_exit = false);
51 | void updateSupportedPowerHints(
52 | const std::unordered_map &sensor_info_map_);
53 | void sendPowerExtHint(const Temperature &t);
54 |
55 | private:
56 | ndk::ScopedAIBinder_DeathRecipient power_hal_ext_aidl_death_recipient_;
57 | static void onPowerHalExtAidlBinderDied(void *cookie) {
58 | if (cookie) {
59 | auto *e = static_cast(cookie);
60 | {
61 | std::lock_guard lock(e->lock_);
62 | e->power_hal_aidl_ = nullptr;
63 | e->power_hal_ext_aidl_ = nullptr;
64 | }
65 | e->reconnect();
66 | }
67 | }
68 |
69 | bool power_hal_aidl_exist_;
70 | std::shared_ptr power_hal_aidl_;
71 | std::shared_ptr power_hal_ext_aidl_;
72 | std::mutex lock_;
73 | std::unordered_map supported_powerhint_map_;
74 | mutable std::shared_mutex powerhint_status_mutex_;
75 | };
76 |
77 | } // namespace implementation
78 | } // namespace thermal
79 | } // namespace hardware
80 | } // namespace android
81 | } // namespace aidl
82 |
--------------------------------------------------------------------------------
/aidl/thermal/utils/thermal_files.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The Android Open Source Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #define ATRACE_TAG (ATRACE_TAG_THERMAL | ATRACE_TAG_HAL)
8 |
9 | #include "thermal_files.h"
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include
18 | #include
19 |
20 | namespace aidl {
21 | namespace android {
22 | namespace hardware {
23 | namespace thermal {
24 | namespace implementation {
25 |
26 | using ::android::base::StringPrintf;
27 |
28 | std::string ThermalFiles::getThermalFilePath(std::string_view thermal_name) const {
29 | auto sensor_itr = thermal_name_to_path_map_.find(thermal_name.data());
30 | if (sensor_itr == thermal_name_to_path_map_.end()) {
31 | return "";
32 | }
33 | return sensor_itr->second;
34 | }
35 |
36 | bool ThermalFiles::addThermalFile(std::string_view thermal_name, std::string_view path) {
37 | return thermal_name_to_path_map_.emplace(thermal_name, path).second;
38 | }
39 |
40 | bool ThermalFiles::readThermalFile(std::string_view thermal_name, std::string *data) const {
41 | std::string sensor_reading;
42 | std::string file_path = getThermalFilePath(std::string_view(thermal_name));
43 | *data = "";
44 |
45 | ATRACE_NAME(StringPrintf("ThermalFiles::readThermalFile - %s", thermal_name.data()).c_str());
46 | if (file_path.empty()) {
47 | PLOG(WARNING) << "Failed to find " << thermal_name << "'s path";
48 | return false;
49 | }
50 |
51 | if (!::android::base::ReadFileToString(file_path, &sensor_reading)) {
52 | PLOG(WARNING) << "Failed to read sensor: " << thermal_name;
53 | return false;
54 | }
55 |
56 | if (sensor_reading.size() <= 1) {
57 | LOG(ERROR) << thermal_name << "'s return size:" << sensor_reading.size() << " is invalid";
58 | return false;
59 | }
60 |
61 | // Strip the newline.
62 | *data = ::android::base::Trim(sensor_reading);
63 | return true;
64 | }
65 |
66 | bool ThermalFiles::writeCdevFile(std::string_view cdev_name, std::string_view data) {
67 | std::string file_path =
68 | getThermalFilePath(::android::base::StringPrintf("%s_%s", cdev_name.data(), "w"));
69 |
70 | ATRACE_NAME(StringPrintf("ThermalFiles::writeCdevFile - %s", cdev_name.data()).c_str());
71 | if (!::android::base::WriteStringToFile(data.data(), file_path)) {
72 | PLOG(WARNING) << "Failed to write cdev: " << cdev_name << " to " << data.data();
73 | return false;
74 | }
75 |
76 | return true;
77 | }
78 |
79 | } // namespace implementation
80 | } // namespace thermal
81 | } // namespace hardware
82 | } // namespace android
83 | } // namespace aidl
84 |
--------------------------------------------------------------------------------
/aidl/thermal/utils/thermal_files.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The Android Open Source Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | namespace aidl {
13 | namespace android {
14 | namespace hardware {
15 | namespace thermal {
16 | namespace implementation {
17 |
18 | class ThermalFiles {
19 | public:
20 | ThermalFiles() = default;
21 | ~ThermalFiles() = default;
22 | ThermalFiles(const ThermalFiles &) = delete;
23 | void operator=(const ThermalFiles &) = delete;
24 |
25 | std::string getThermalFilePath(std::string_view thermal_name) const;
26 | // Returns true if add was successful, false otherwise.
27 | bool addThermalFile(std::string_view thermal_name, std::string_view path);
28 | // If thermal_name is not found in the thermal names to path map, this will set
29 | // data to empty and return false. If the thermal_name is found and its content
30 | // is read, this function will fill in data accordingly then return true.
31 | bool readThermalFile(std::string_view thermal_name, std::string *data) const;
32 | bool writeCdevFile(std::string_view thermal_name, std::string_view data);
33 | size_t getNumThermalFiles() const { return thermal_name_to_path_map_.size(); }
34 |
35 | private:
36 | std::unordered_map thermal_name_to_path_map_;
37 | };
38 |
39 | } // namespace implementation
40 | } // namespace thermal
41 | } // namespace hardware
42 | } // namespace android
43 | } // namespace aidl
44 |
--------------------------------------------------------------------------------
/aidl/thermal/utils/thermal_predictions_helper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The Android Open Source Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | #include "thermal_info.h"
19 |
20 | namespace aidl {
21 | namespace android {
22 | namespace hardware {
23 | namespace thermal {
24 | namespace implementation {
25 |
26 | using ::android::base::boot_clock;
27 | constexpr int kToleranceIntervalMs = 1000;
28 |
29 | struct PredictionSample {
30 | PredictionSample(int num_out_samples) {
31 | timestamp = boot_clock::time_point::min();
32 | values = std::vector(num_out_samples, NAN);
33 | }
34 | boot_clock::time_point timestamp;
35 | std::vector values;
36 | };
37 |
38 | struct PredictorSensorInfo {
39 | std::string sensor_name;
40 | int sample_duration;
41 | int num_out_samples;
42 | std::vector samples;
43 | int cur_index;
44 | };
45 |
46 | struct PredictedSensorInfo {
47 | std::string sensor_name;
48 | std::string linked_sensor;
49 | int duration;
50 | int prediction_index;
51 | };
52 |
53 | class ThermalPredictionsHelper {
54 | public:
55 | ThermalPredictionsHelper() = default;
56 | ~ThermalPredictionsHelper() = default;
57 | // Disallow copy and assign
58 | ThermalPredictionsHelper(const ThermalPredictionsHelper &) = delete;
59 | void operator=(const ThermalPredictionsHelper &) = delete;
60 |
61 | bool initializePredictionSensors(
62 | const std::unordered_map &sensor_info_map);
63 | bool updateSensor(std::string_view sensor_name, std::vector &values);
64 | SensorReadStatus readSensor(std::string_view sensor_name, float *temp);
65 |
66 | private:
67 | std::unordered_map predictor_sensors_;
68 | std::unordered_map predicted_sensors_;
69 | mutable std::shared_mutex sensor_predictions_mutex_;
70 |
71 | bool registerPredictedSensor(std::string_view sensor_name, std::string_view linked_sensor,
72 | int duration);
73 | bool registerPredictorSensor(std::string_view sensor_name, int sample_duration,
74 | int num_out_samples);
75 | };
76 |
77 | } // namespace implementation
78 | } // namespace thermal
79 | } // namespace hardware
80 | } // namespace android
81 | } // namespace aidl
82 |
--------------------------------------------------------------------------------
/aidl/thermal/utils/thermal_throttling.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The Android Open Source Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #include "power_files.h"
20 | #include "thermal_info.h"
21 | #include "thermal_stats_helper.h"
22 |
23 | namespace aidl {
24 | namespace android {
25 | namespace hardware {
26 | namespace thermal {
27 | namespace implementation {
28 |
29 | struct ThermalThrottlingStatus {
30 | std::unordered_map pid_power_budget_map;
31 | std::unordered_map pid_cdev_request_map;
32 | std::unordered_map hardlimit_cdev_request_map;
33 | std::unordered_map throttling_release_map;
34 | std::unordered_map cdev_status_map;
35 | float prev_err;
36 | float i_budget;
37 | float prev_target;
38 | float prev_power_budget;
39 | float budget_transient;
40 | int tran_cycle;
41 | std::string profile;
42 | };
43 |
44 | // Return the control temp target of PID algorithm
45 | size_t getTargetStateOfPID(const SensorInfo &sensor_info, const ThrottlingSeverity curr_severity);
46 |
47 | // A helper class for conducting thermal throttling
48 | class ThermalThrottling {
49 | public:
50 | ThermalThrottling() = default;
51 | ~ThermalThrottling() = default;
52 | // Disallow copy and assign.
53 | ThermalThrottling(const ThermalThrottling &) = delete;
54 | void operator=(const ThermalThrottling &) = delete;
55 |
56 | // Clear throttling data
57 | void clearThrottlingData(std::string_view sensor_name);
58 | // Register map for throttling algo
59 | bool registerThermalThrottling(
60 | std::string_view sensor_name, const std::shared_ptr &throttling_info,
61 | const std::unordered_map &cooling_device_info_map);
62 | // Get throttling status map
63 | const std::unordered_map &GetThermalThrottlingStatusMap()
64 | const {
65 | std::shared_lock _lock(thermal_throttling_status_map_mutex_);
66 | return thermal_throttling_status_map_;
67 | }
68 | // Update thermal throttling request for the specific sensor
69 | void thermalThrottlingUpdate(
70 | const Temperature &temp, const SensorInfo &sensor_info,
71 | const ThrottlingSeverity curr_severity, const std::chrono::milliseconds time_elapsed_ms,
72 | const std::unordered_map &power_status_map,
73 | const std::unordered_map &cooling_device_info_map,
74 | const bool max_throttling = false,
75 | const std::vector &sensor_predictions = std::vector{});
76 |
77 | // Compute the throttling target from all the sensors' request
78 | void computeCoolingDevicesRequest(std::string_view sensor_name, const SensorInfo &sensor_info,
79 | const ThrottlingSeverity curr_severity,
80 | std::vector *cooling_devices_to_update,
81 | ThermalStatsHelper *thermal_stats_helper);
82 | // Get the aggregated (from all sensor) max request for a cooling device
83 | bool getCdevMaxRequest(std::string_view cdev_name, int *max_state);
84 |
85 | private:
86 | // Check if the thermal throttling profile need to be switched
87 | void parseProfileProperty(std::string_view sensor_name, const SensorInfo &sensor_info);
88 | // PID algo - get the total power budget
89 | float updatePowerBudget(
90 | const Temperature &temp, const SensorInfo &sensor_info,
91 | const std::unordered_map &cooling_device_info_map,
92 | std::chrono::milliseconds time_elapsed_ms, ThrottlingSeverity curr_severity,
93 | const bool max_throttling,
94 | const std::vector &sensor_predictions = std::vector{});
95 |
96 | // PID algo - return the power number from excluded power rail list
97 | float computeExcludedPower(const SensorInfo &sensor_info,
98 | const ThrottlingSeverity curr_severity,
99 | const std::unordered_map &power_status_map,
100 | std::string *log_buf, std::string_view sensor_name);
101 |
102 | // PID algo - allocate the power to target CDEV according to the ODPM
103 | bool allocatePowerToCdev(
104 | const Temperature &temp, const SensorInfo &sensor_info,
105 | const ThrottlingSeverity curr_severity, const std::chrono::milliseconds time_elapsed_ms,
106 | const std::unordered_map &power_status_map,
107 | const std::unordered_map &cooling_device_info_map,
108 | const bool max_throttling, const std::vector &sensor_predictions);
109 | // PID algo - map the target throttling state according to the power budget
110 | void updateCdevRequestByPower(
111 | std::string sensor_name,
112 | const std::unordered_map &cooling_device_info_map);
113 | // Hard limit algo - assign the throttling state according to the severity
114 | void updateCdevRequestBySeverity(std::string_view sensor_name, const SensorInfo &sensor_info,
115 | ThrottlingSeverity curr_severity);
116 | // Throttling release algo - decide release step according to the predefined power threshold,
117 | // return false if the throttling release is not registered in thermal config
118 | bool throttlingReleaseUpdate(
119 | std::string_view sensor_name,
120 | const std::unordered_map &cooling_device_info_map,
121 | const std::unordered_map &power_status_map,
122 | const ThrottlingSeverity severity, const SensorInfo &sensor_info);
123 | // Update the cooling device request set for new request and notify the caller if there is
124 | // change in max_request for the cooling device.
125 | bool updateCdevMaxRequestAndNotifyIfChange(std::string_view cdev_name, int cur_request,
126 | int new_request);
127 | mutable std::shared_mutex thermal_throttling_status_map_mutex_;
128 | // Thermal throttling status from each sensor
129 | std::unordered_map thermal_throttling_status_map_;
130 | std::shared_mutex cdev_all_request_map_mutex_;
131 | // Set of all request for a cooling device from each sensor
132 | std::unordered_map>> cdev_all_request_map_;
133 | };
134 |
135 | } // namespace implementation
136 | } // namespace thermal
137 | } // namespace hardware
138 | } // namespace android
139 | } // namespace aidl
140 |
--------------------------------------------------------------------------------
/aidl/thermal/utils/thermal_watcher.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 The Android Open Source Project
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | namespace aidl {
29 | namespace android {
30 | namespace hardware {
31 | namespace thermal {
32 | namespace implementation {
33 |
34 | using ::android::base::boot_clock;
35 | using ::android::base::unique_fd;
36 | using WatcherCallback = std::function