4 Commits
vic ... udc

Author SHA1 Message Date
6597137fb2 sepolicy: qti: Allow system server to detect oem charging
Signed-off-by: AnierinB <anierin@evolution-x.org>
2024-12-11 08:28:55 -05:00
patr_
56cc248362 vintf: Add version 1.0 for vendor.oplus.hardware.cameraMDM
Used on avicii.

Change-Id: Ib02fb994f391bd015ec2171cfa13690e847b032a
2024-12-08 00:33:55 +00:00
LineageOS Infra
10cf887bbf Automatic translation import
Change-Id: If3a415dc18218f48561093d1091c9ed687260c1f
2024-12-02 04:47:52 +00:00
LuK1337
387d07577e sepolicy: qti: Allow sensors to read /proc/oplusVersion/*
E sensors-hal: ambient_light:131, fail to open /proc/oplusVersion/prjName
E sensors-hal: is_aging_vesion:59, fail to open /proc/oplusVersion/engVersion

Change-Id: I2c4f9e00e689a7fa0650d53868b9921d5e8d001c
2024-11-27 19:01:58 +01:00
485 changed files with 3749 additions and 17014 deletions

View File

@@ -1 +0,0 @@
../../build/soong/scripts/system-clang-format

View File

@@ -1,5 +1,5 @@
//
// SPDX-FileCopyrightText: 2022-2025 The LineageOS Project
// Copyright (C) 2022-2023 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
@@ -7,6 +7,7 @@ soong_namespace {
imports: [
"hardware/google/interfaces",
"hardware/google/pixel",
"hardware/qcom-caf/bootctrl",
],
}
@@ -16,10 +17,3 @@ prebuilt_hidl_interfaces {
"vendor.oplus.hardware.cameraextension@1.0::ICameraExtensionService",
],
}
prebuilt_hidl_interfaces {
name: "hidl_pixelworks_feature_interface",
interfaces: [
"vendor.pixelworks.hardware.feature@1.0::IIrisFeature",
],
}

5
Android.mk Normal file
View File

@@ -0,0 +1,5 @@
ifneq ($(filter $(call my-dir),$(PRODUCT_SOONG_NAMESPACES)),)
include $(call all-subdir-makefiles)
endif

View File

@@ -1,39 +0,0 @@
//
// Copyright (C) 2024-2025 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
android_app {
name: "DSPVolumeSynchronizer",
certificate: "platform",
srcs: ["src/**/*.java"],
platform_apis: true,
privileged: true,
system_ext_specific: true,
static_libs: [
"androidx.core_core",
"SettingsLib",
],
required: [
"privapp-permissions-dspvolume",
"config-dspvolume",
],
}
prebuilt_etc {
name: "privapp-permissions-dspvolume",
relative_install_path: "permissions",
src: "privapp-permissions-dspvolume.xml",
system_ext_specific: true,
filename_from_src: true,
}
prebuilt_etc {
name: "config-dspvolume",
relative_install_path: "sysconfig",
src: "config-dspvolume.xml",
system_ext_specific: true,
filename_from_src: true,
}

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.lineageos.dspvolume.xiaomi"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="android.uid.system">
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<application
android:label="@string/app_name"
android:persistent="true"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">
<receiver
android:name=".BootReceiver"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter android:priority="999">
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service
android:name=".VolumeListenerService" />
</application>
</manifest>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<config>
<allow-in-power-save package="org.lineageos.dspvolume.xiaomi" />
<hidden-api-whitelisted-app package="org.lineageos.dspvolume.xiaomi" />
</config>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<privapp-permissions package="org.lineageos.dspvolume.xiaomi">
<permission name="android.permission.INTERACT_ACROSS_USERS" />
<permission name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<permission name="android.permission.MODIFY_AUDIO_SETTINGS" />
<permission name="android.permission.RECEIVE_BOOT_COMPLETED" />
</privapp-permissions>
</permissions>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- App Name -->
<string name="app_name">DSP Volume Synchronizer</string>
</resources>

View File

@@ -1,16 +0,0 @@
package org.lineageos.dspvolume.xiaomi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
if (context == null) {
return;
}
context.startService(new Intent(context, VolumeListenerService.class));
}
}

View File

@@ -1,28 +0,0 @@
package org.lineageos.dspvolume.xiaomi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.util.Log;
import android.os.Bundle;
public class VolumeListenerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (context == null) {
return;
}
if(intent.getIntExtra("android.media.EXTRA_VOLUME_STREAM_TYPE", 0) == AudioManager.STREAM_MUSIC) {
AudioManager audioManager = context.getSystemService(AudioManager.class);
int current = intent.getIntExtra(
"android.media.EXTRA_VOLUME_STREAM_VALUE",
0
);
audioManager.setParameters("volume_change=" + current + ";flags=8");
}
}
}

View File

@@ -1,30 +0,0 @@
package org.lineageos.dspvolume.xiaomi;
import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.IBinder;
import androidx.annotation.Nullable;
public class VolumeListenerService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.media.VOLUME_CHANGED_ACTION");
registerReceiver(new VolumeListenerReceiver(), intentFilter);
AudioManager audioManager = getSystemService(AudioManager.class);
int current = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
audioManager.setParameters("volume_change=" + current + ";flags=8");
return super.onStartCommand(intent, flags, startId);
}
}

View File

@@ -8,6 +8,7 @@ android_app {
name: "OplusEuicc",
srcs: ["src/**/*.kt"],
resource_dirs: ["res"],
sdk_version: "current",
product_specific: true,
@@ -24,16 +25,16 @@ android_app {
}
prebuilt_etc {
sub_dir: "permissions",
name: "org.lineageos.euicc.xml",
relative_install_path: "permissions",
filename: "org.lineageos.euicc.xml",
src: "org.lineageos.euicc.xml",
product_specific: true,
}
prebuilt_etc {
sub_dir: "sysconfig",
name: "hidden-api-whitelist-org.lineageos.euicc.xml",
relative_install_path: "sysconfig",
filename: "hidden-api-whitelist-org.lineageos.euicc.xml",
src: "hidden-api-whitelist-org.lineageos.euicc.xml",
product_specific: true,

View File

@@ -4,6 +4,6 @@
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="sim_illustration_lottie_mappings_json">{\"sim_illustration_lottie_mappings\":[{\"devices\":[\"OP591BL1\",\"OP5929L1\",\"OP594DL1\",\"OP595DL1\",\"OP5D0DL1\",\"OP5D55L1\"],\"illustration_lottie\":\"sim_illustration_lottie_bottom\"}]}</string>
<string name="sim_slot_mappings_json">{\"sim-slot-mappings\":[{\"devices\":[\"OP594DL1\",\"OP595DL1\",\"OP5D55L1\"],\"esim-slot-ids\":[1],\"psim-slot-ids\":[0]},{\"devices\":[\"OP591BL1\",\"OP5929L1\",\"OP5D0DL1\"],\"esim-slot-ids\":[],\"psim-slot-ids\":[0,1]}]}</string>
<string name="sim_illustration_lottie_mappings_json">{\"sim_illustration_lottie_mappings\":[{\"devices\":[\"OP594DL1\"],\"illustration_lottie\":\"sim_illustration_lottie_bottom\"}]}</string>
<string name="sim_slot_mappings_json">{\"sim-slot-mappings\":[{\"devices\":[\"OP594DL1\"],\"esim-slot-ids\":[1],\"psim-slot-ids\":[0]}]}</string>
</resources>

View File

@@ -1,24 +0,0 @@
//
// Copyright (C) 2022-2025 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
android_app {
name: "IFAAService",
srcs: [
"src/**/*.kt",
"src/**/*.aidl",
],
aidl: {
local_include_dirs: ["src"],
},
static_libs: [
"vendor.oplus.hardware.biometrics.fingerprintpay-V1-java",
],
certificate: "platform",
platform_apis: true,
system_ext_specific: true,
}

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2022-2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.ifaa.aidl.manager">
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<application
android:label="@string/app_name"
android:persistent="true">
<service
android:name=".IfaaService"
android:exported="true">
<intent-filter>
<action android:name="org.ifaa.aidl.manager.IfaaManagerService" />
</intent-filter>
</service>
</application>
</manifest>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2022-2024 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="app_name">IFAAService</string>
</resources>

View File

@@ -1,19 +0,0 @@
//
// Copyright (C) 2022 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
package org.ifaa.aidl.manager;
interface IfaaManagerService {
int getSupportBIOTypes();
int startBIOManager(int authType);
String getDeviceModel();
byte[] processCmd(inout byte[] param);
int getVersion();
String getExtInfo(int authType, String keyExtInfo);
void setExtInfo(int authType, String keyExtInfo, String valExtInfo);
int getEnabled(int bioType);
int[] getIDList(int bioType);
}

View File

@@ -1,197 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.ifaa.aidl.manager
import android.app.KeyguardManager
import android.app.Service
import android.content.Intent
import android.graphics.Point
import android.hardware.fingerprint.FingerprintManager
import android.os.IBinder
import android.os.ServiceManager
import android.os.SystemProperties
import android.provider.Settings
import android.util.Log
import android.view.WindowManager
import org.json.JSONObject
import vendor.oplus.hardware.biometrics.fingerprintpay.IFingerprintPay
class IfaaService : Service() {
private var _fpPayService: IFingerprintPay? = null
private val fpPayServiceDeathRecipient = IBinder.DeathRecipient {
Log.i(LOG_TAG, "aidl FingerprintPay hal died, reset hal proxy!")
_fpPayService = null
}
private val fingerprintManager by lazy { getSystemService(FingerprintManager::class.java)!! }
private val keyguardManager by lazy { getSystemService(KeyguardManager::class.java)!! }
private val windowManager by lazy { getSystemService(WindowManager::class.java)!! }
override fun onBind(intent: Intent) = object : IfaaManagerService.Stub() {
private val _supportBIOTypes by lazy {
when (SystemProperties.get(FP_TYPE_PROP, "")) {
"back", "side", "front" -> AUTH_TYPE_FINGERPRINT
"ultrasonic", "optical" -> AUTH_TYPE_OPTICAL_FINGERPRINT
else -> AUTH_TYPE_NOT_SUPPORT
}
}
override fun getSupportBIOTypes() = _supportBIOTypes
override fun startBIOManager(authType: Int) = when (authType) {
AUTH_TYPE_FINGERPRINT -> {
applicationContext.startActivity(
Intent(Settings.ACTION_SECURITY_SETTINGS).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
)
COMMAND_OK
}
else -> COMMAND_FAIL
}
private val _deviceModel by lazy { SystemProperties.get(IFAA_MODEL_PROP, "OPLUS-Default") }
override fun getDeviceModel() = _deviceModel
override fun processCmd(param: ByteArray) = try {
getFpPayService()?.ifaa_invoke_command(param)
} catch (e: Exception) {
Log.e(LOG_TAG, "processCmdImpl: ifaa_invoke_command aidl failed", e)
null
}
override fun getVersion() = 4
override fun getExtInfo(authType: Int, keyExtInfo: String) = when (keyExtInfo) {
KEY_GET_SENSOR_LOCATION -> initExtString()
else -> ""
}
override fun setExtInfo(authType: Int, keyExtInfo: String, valExtInfo: String) {
// Do nothing
}
override fun getEnabled(bioType: Int): Int {
if (!keyguardManager.isKeyguardSecure) {
Log.e(LOG_TAG, "No secure keyguard set.")
return BIOMETRIC_NOUSE_NOSET_KEYGUARD
}
return when (bioType) {
AUTH_TYPE_FINGERPRINT -> when {
!fingerprintManager.isHardwareDetected -> {
Log.e(LOG_TAG, "Fingerprint hardware not available!")
BIOMETRIC_NOUSE_SYSTEMLOCKED
}
fingerprintManager.enrolledFingerprints.isNullOrEmpty() -> {
Log.e(LOG_TAG, "Fingerprint not enrolled!")
BIOMETRIC_NOUSE_NOT_ENROLLED
}
else -> BIOMETRIC_USE_READY
}
else -> 0
}
}
override fun getIDList(bioType: Int): IntArray? = when (bioType) {
AUTH_TYPE_FINGERPRINT -> {
val enrolledFingerprintIds = fingerprintManager.enrolledFingerprints?.map {
it.biometricId
}?.toIntArray()
Log.w(LOG_TAG, "getIDList: ${enrolledFingerprintIds}!")
enrolledFingerprintIds
}
else -> null
}
}
private fun getFpPayService() = _fpPayService ?: run {
val binder = ServiceManager.getService("${IFingerprintPay.DESCRIPTOR}/default")
IFingerprintPay.Stub.asInterface(binder)?.also {
binder.linkToDeath(fpPayServiceDeathRecipient, 0)
_fpPayService = it
}
}
private val defaultDisplayDimension by lazy {
val dim1 = displayNoVerify?.supportedModes?.maxByOrNull { it.physicalHeight }
?.run { Point(physicalWidth, physicalHeight) }
val dim2 = windowManager.maximumWindowMetrics.bounds
.run { Point(width(), height()) }
dim1?.let { Point(maxOf(dim1.x, dim2.x), maxOf(dim1.y, dim2.y)) } ?: dim2
}
private val iconDiameter by lazy { SystemProperties.getInt(FP_ICON_SIZE_PROP, 190) }
// Coordinates of the upper left corner
private val iconLocation by lazy {
val iconLocationBottom = SystemProperties.getInt(FP_ICON_LOCATION_PROP, 278)
Point(
(defaultDisplayDimension.x - iconDiameter) / 2,
defaultDisplayDimension.y - iconLocationBottom - iconDiameter / 2
)
}
private fun initExtString() = run {
val displayDimension = windowManager.maximumWindowMetrics.bounds.run {
Point(width(), height())
}
val scale = { pos: Point ->
Point(
pos.x * displayDimension.x / defaultDisplayDimension.x,
pos.y * displayDimension.y / defaultDisplayDimension.y
)
}
val scaledLocation = scale(iconLocation)
val scaledDiameter = scale(Point(iconDiameter, iconDiameter))
JSONObject().apply {
put("type", 0)
put("fullView", JSONObject().apply {
put("startX", scaledLocation.x)
put("startY", scaledLocation.y)
put("width", scaledDiameter.x)
put("height", scaledDiameter.y)
put("navConflict", true)
})
}.toString()
}
companion object {
private val LOG_TAG = IfaaService::class.simpleName!!
private const val AUTH_TYPE_NOT_SUPPORT = 0
private const val AUTH_TYPE_FINGERPRINT = 1
private const val AUTH_TYPE_OPTICAL_FINGERPRINT = 1.shl(4).or(AUTH_TYPE_FINGERPRINT)
private const val BIOMETRIC_USE_READY = 1000
private const val BIOMETRIC_NOUSE_SYSTEMLOCKED = 1001
private const val BIOMETRIC_NOUSE_NOT_ENROLLED = 1002
private const val BIOMETRIC_NOUSE_NOSET_KEYGUARD = 1003
private const val COMMAND_OK = 0
private const val COMMAND_FAIL = -1
// Populated by fingerprint HAL
private const val FP_TYPE_PROP = "persist.vendor.fingerprint.sensor_type"
private const val FP_ICON_SIZE_PROP = "persist.vendor.fingerprint.optical.iconsize"
private const val FP_ICON_LOCATION_PROP = "persist.vendor.fingerprint.optical.iconlocation"
// NOTE: Populate ifaaModel from /my_stock/etc/sys_alipay_model_list.json
private const val IFAA_MODEL_PROP = "sys.oplus.ifaa.model"
private const val KEY_GET_SENSOR_LOCATION = "org.ifaa.ext.key.GET_SENSOR_LOCATION"
}
}

View File

@@ -2,6 +2,7 @@ android_app {
name: "KeyHandler",
srcs: ["src/**/*.kt"],
resource_dirs: ["res"],
certificate: "platform",
platform_apis: true,

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018, 2021-2025 The LineageOS Project
Copyright (C) 2018, 2021-2022 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="android.uid.system"
package="org.lineageos.settings.device">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
@@ -42,19 +41,17 @@
<!-- Additional button settings (Button settings) -->
<activity
android:name=".ButtonSettingsActivity"
android:label="@string/alert_slider_category_title"
android:exported="true">
android:label="@string/button_panel_title"
android:exported="false">
<intent-filter>
<action android:name="com.android.settings.action.IA_SETTINGS" />
<action android:name="org.lineageos.settings.device.ADDITIONAL_BUTTONS_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.sound" />
</activity>
<service
android:name=".KeyHandler"
android:permission="KeyHandlerService"
android:exported="true" />
android:exported="false" />
</application>
</manifest>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2021 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="alert_slider_category_title">Плъзгач за предупреждение</string>
<string name="alert_slider_selection_dialog_title">Действие</string>
<string name="alert_slider_top_position">Горна позиция </string>
<string name="alert_slider_middle_position">Средна позиция</string>
<string name="alert_slider_bottom_position">Долна позиция</string>
<string name="alert_slider_mode_none">Нищо</string>
<string name="alert_slider_mode_silent">Без звук</string>
<string name="alert_slider_mode_normal">Нормален</string>
<string name="alert_slider_mode_vibration">Вибрация</string>
<string name="alert_slider_mode_dnd_priority_only">Само важни</string>
<string name="alert_slider_mode_dnd_total_silence">Тотална тишина</string>
<string name="alert_slider_mode_dnd_alarms_only">Само будилници</string>
<string name="alert_slider_mute_media_title">Заглуши</string>
<string name="alert_slider_mute_media_summary">Заглуши само когато се превключва в тих режим</string>
</resources>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2021 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="alert_slider_category_title">نوار لغزنده هشدار</string>
<string name="alert_slider_selection_dialog_title">عمل</string>
<string name="alert_slider_top_position">موقعیت بالا</string>
<string name="alert_slider_middle_position">موقعیت وسط</string>
<string name="alert_slider_bottom_position">موقعیت پایین</string>
<string name="alert_slider_mode_none">هیچ</string>
<string name="alert_slider_mode_silent">بی‌صدا</string>
<string name="alert_slider_mode_normal">عادی</string>
<string name="alert_slider_mode_vibration">لرزش</string>
<string name="alert_slider_mode_dnd_priority_only">فقط اولویت ها</string>
<string name="alert_slider_mode_dnd_total_silence">سکوت کامل</string>
<string name="alert_slider_mode_dnd_alarms_only">فقط هشدار ها</string>
<string name="alert_slider_mute_media_title">رسانه بی صدا</string>
<string name="alert_slider_mute_media_summary">هنگام جابجایی به بی‌صدا، رسانه را بی‌صدا کنید</string>
</resources>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2021 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="alert_slider_category_title">מתג התראות</string>
<string name="alert_slider_selection_dialog_title">פעולה</string>
<string name="alert_slider_top_position">ממוקם למעלה</string>
<string name="alert_slider_middle_position">ממוקם באמצע</string>
<string name="alert_slider_bottom_position">ממוקם למטה</string>
<string name="alert_slider_mode_none">ללא</string>
<string name="alert_slider_mode_silent">שקט</string>
<string name="alert_slider_mode_normal">רגיל</string>
<string name="alert_slider_mode_vibration">רטט</string>
<string name="alert_slider_mode_dnd_priority_only">עדיפות בלבד</string>
<string name="alert_slider_mode_dnd_total_silence">מושתק לחלוטין</string>
<string name="alert_slider_mode_dnd_alarms_only">שעון מעורר בלבד</string>
<string name="alert_slider_mute_media_title">השתקת מדיה</string>
<string name="alert_slider_mute_media_summary">השתקת מדיה במעבר להשתקה</string>
</resources>

View File

@@ -17,5 +17,5 @@
<string name="alert_slider_mode_dnd_total_silence">Silêncio total</string>
<string name="alert_slider_mode_dnd_alarms_only">Somente alarmes</string>
<string name="alert_slider_mute_media_title">Silenciar mídia</string>
<string name="alert_slider_mute_media_summary">Silenciar mídia ao mudar para o modo silencioso</string>
<string name="alert_slider_mute_media_summary">Silenciar mídia ao mudar para modo silencioso</string>
</resources>

View File

@@ -4,10 +4,5 @@
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="alert_slider_selection_dialog_title">Åtgärd</string>
<string name="alert_slider_mode_none">Inget</string>
<string name="alert_slider_mode_normal">Normal</string>
<string name="alert_slider_mode_vibration">Vibration</string>
<string name="alert_slider_mode_dnd_priority_only">Endast prioritet</string>
<string name="alert_slider_mode_dnd_alarms_only">Endast alarm</string>
</resources>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2021 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="alert_slider_category_title">ئاگاھلاندۇرۇش سىيرىغۇچ</string>
<string name="alert_slider_selection_dialog_title">مەشغۇلات</string>
<string name="alert_slider_top_position">چوققا نۇقتا</string>
<string name="alert_slider_middle_position">ئوتتۇرا نۇقتا</string>
<string name="alert_slider_bottom_position">ئاستى نۇقتا</string>
<string name="alert_slider_mode_none">يوق</string>
<string name="alert_slider_mode_silent">ئۈنسىز</string>
<string name="alert_slider_mode_normal">ئادەتتىكى</string>
<string name="alert_slider_mode_vibration">تىترەت</string>
<string name="alert_slider_mode_dnd_priority_only">ئالدىنلىقلا</string>
<string name="alert_slider_mode_dnd_total_silence">تامامەن ئۈنسىز</string>
<string name="alert_slider_mode_dnd_alarms_only">قوڭغۇراقلا</string>
<string name="alert_slider_mute_media_title">ۋاسىتە ئۈنسىز</string>
<string name="alert_slider_mute_media_summary">ئۈنسىز ھالەتكە ئالماشتۇرغاندا ۋاسىتىنى ئۈنسىزلەيدۇ</string>
</resources>

View File

@@ -5,7 +5,7 @@
-->
<resources>
<!-- Alert slider -->
<string name="alert_slider_category_title">Alert slider settings</string>
<string name="alert_slider_category_title">Alert slider</string>
<string name="alert_slider_selection_dialog_title">Action</string>
<string name="alert_slider_top_position">Top position</string>
<string name="alert_slider_middle_position">Middle position</string>

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2025 The LineageOS Project
* Copyright (C) 2021-2023 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
@@ -41,18 +41,10 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
private var wasMuted = false
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
AudioManager.STREAM_MUTE_CHANGED_ACTION -> {
val stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1)
val state = intent.getBooleanExtra(
AudioManager.EXTRA_STREAM_VOLUME_MUTED, false
)
if (stream == AudioSystem.STREAM_MUSIC && !state) {
wasMuted = false
}
}
Intent.ACTION_BOOT_COMPLETED -> populateKeyState(false)
val stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1)
val state = intent.getBooleanExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, false)
if (stream == AudioSystem.STREAM_MUSIC && !state) {
wasMuted = false
}
}
}
@@ -60,10 +52,7 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
init {
context.registerReceiver(
broadcastReceiver,
IntentFilter().apply {
addAction(AudioManager.STREAM_MUTE_CHANGED_ACTION)
addAction(Intent.ACTION_BOOT_COMPLETED)
}
IntentFilter(AudioManager.STREAM_MUTE_CHANGED_ACTION)
)
}
@@ -78,19 +67,15 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
return event
}
populateKeyState(true)
when (File("/proc/tristatekey/tri_state").readText().trim()) {
"1" -> handleMode(POSITION_TOP)
"2" -> handleMode(POSITION_MIDDLE)
"3" -> handleMode(POSITION_BOTTOM)
}
return null
}
private fun populateKeyState(vibrate: Boolean) {
when (File("/proc/tristatekey/tri_state").readText().trim()) {
"1" -> handleMode(POSITION_TOP, vibrate)
"2" -> handleMode(POSITION_MIDDLE, vibrate)
"3" -> handleMode(POSITION_BOTTOM, vibrate)
}
}
private fun vibrateIfNeeded(mode: Int) {
when (mode) {
AudioManager.RINGER_MODE_VIBRATE -> vibrator.vibrate(
@@ -104,7 +89,7 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
}
}
private fun handleMode(position: Int, vibrate: Boolean) {
private fun handleMode(position: Int) {
val muteMedia = sharedPreferences.getBoolean(MUTE_MEDIA_WITH_SILENT, false)
val mode = when (position) {
@@ -139,10 +124,7 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
}
}
}
if (vibrate) {
vibrateIfNeeded(mode)
}
vibrateIfNeeded(mode)
}
}

View File

@@ -1,29 +0,0 @@
//
// SPDX-FileCopyrightText: 2025 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
android_app {
name: "OplusPen",
srcs: ["src/**/*.kt"],
certificate: "platform",
platform_apis: true,
system_ext_specific: true,
optimize: {
proguard_flags_files: ["proguard.flags"],
},
required: [
"default-permissions_org.lineageos.pen",
],
}
prebuilt_etc {
name: "default-permissions_org.lineageos.pen",
system_ext_specific: true,
src: "default-permissions_org.lineageos.pen.xml",
sub_dir: "default-permissions",
filename_from_src: true,
}

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.lineageos.pen">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:label="@string/app_name"
android:persistent="true"
android:usesNonSdkApi="true">
<receiver
android:exported="true"
android:name=".BootCompletedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service
android:exported="false"
android:name=".PenService" />
</application>
</manifest>

View File

@@ -1,13 +0,0 @@
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<exceptions>
<exception package="org.lineageos.pen">
<permission name="android.permission.ACCESS_FINE_LOCATION" fixed="false" />
<permission name="android.permission.BLUETOOTH_CONNECT" fixed="false" />
<permission name="android.permission.BLUETOOTH_SCAN" fixed="false" />
<permission name="android.permission.POST_NOTIFICATIONS" fixed="false" />
</exception>
</exceptions>

View File

@@ -1,3 +0,0 @@
-keep class org.lineageos.pen.* {
*;
}

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: Material Design Authors / Google LLC
SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:pathData="M167,840Q146,845 130.5,829.5Q115,814 120,793L160,602L358,800L167,840ZM358,800L160,602L618,144Q641,121 675,121Q709,121 732,144L816,228Q839,251 839,285Q839,319 816,342L358,800ZM675,200L261,614L346,699L760,285Q760,285 760,285Q760,285 760,285L675,200Q675,200 675,200Q675,200 675,200Z" />
</vector>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="app_name" translatable="false">OplusPen</string>
<string name="pen_attached">Pen attached</string>
<string name="tap_to_connect">Tap to connect</string>
</resources>

View File

@@ -1,22 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.pen
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
class BootCompletedReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "Received boot completed intent")
context.startService(Intent(context, PenService::class.java))
}
companion object {
private const val TAG = "OplusPenBootReceiver"
}
}

View File

@@ -1,145 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.pen
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.bluetooth.BluetoothManager
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanFilter
import android.bluetooth.le.ScanResult
import android.bluetooth.le.ScanSettings
import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.os.UEventObserver
import android.util.Log
class PenService : Service() {
private val bluetoothManager by lazy { getSystemService(BluetoothManager::class.java) }
private val notificationManager by lazy { getSystemService(NotificationManager::class.java) }
private val observer = object : UEventObserver() {
private val lock = Any()
override fun onUEvent(event: UEvent) {
synchronized(lock) {
val pencilStatus = event.get("pencil_status") ?: return
val pencilAddr = event.get("pencil_addr")?.chunked(2)?.joinToString(":") {
it.uppercase()
} ?: return
when (pencilStatus) {
"0" -> notificationManager.cancel(NOTIFICATION_ID)
"1" -> postNotification(pencilAddr)
}
}
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
intent?.getStringExtra(EXTRA_PENCIL_ADDR)?.let {
bondBtDevice(it)
}
return START_STICKY
}
override fun onBind(intent: Intent?): IBinder? = null
override fun onCreate() {
super.onCreate()
observer.startObserving("DEVPATH=/devices/virtual/oplus_wireless/pencil")
}
override fun onDestroy() {
super.onDestroy()
observer.stopObserving()
}
private fun bondBtDevice(pencilAddr: String) {
val adapter = bluetoothManager.adapter
@Suppress("DEPRECATION") adapter.enable()
val scanner = adapter.bluetoothLeScanner
scanner.startScan(
listOf(ScanFilter.Builder().setDeviceAddress(pencilAddr).build()),
ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setReportDelay(0L)
.build(),
object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult) {
super.onScanResult(callbackType, result)
scanner.stopScan(this)
result.device.createBond()
}
override fun onBatchScanResults(results: MutableList<ScanResult>) {
super.onBatchScanResults(results)
scanner.stopScan(this)
}
override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
scanner.stopScan(this)
}
}
)
}
private fun postNotification(pencilAddr: String) {
val adapter = bluetoothManager.adapter
if (adapter.bondedDevices.contains(adapter.getRemoteDevice(pencilAddr))) {
Log.e(TAG, "$pencilAddr already bonded, bailing out")
return
}
if (notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null) {
notificationManager.createNotificationChannel(
NotificationChannel(
NOTIFICATION_CHANNEL_ID,
NOTIFICATION_CHANNEL_ID,
NotificationManager.IMPORTANCE_HIGH
)
)
}
val contentIntent = PendingIntent.getService(
this,
0,
Intent(this, PenService::class.java).apply {
putExtra(EXTRA_PENCIL_ADDR, pencilAddr)
},
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val notification = Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stylus)
.setContentTitle(getString(R.string.pen_attached))
.setContentText(getString(R.string.tap_to_connect))
.setContentIntent(contentIntent)
.setAutoCancel(true)
.build()
notificationManager.notify(NOTIFICATION_ID, notification)
}
companion object {
private const val TAG = "OplusPenService"
private const val EXTRA_PENCIL_ADDR = "pencil_addr"
private const val NOTIFICATION_CHANNEL_ID = "OplusPen"
private const val NOTIFICATION_ID = 1000
}
}

View File

@@ -1,19 +0,0 @@
# hardware/oplus
## Soong options
| Namespace | Variable | Description | Default |
| --------- | -------- | ----------- | ------- |
| OPLUS_LINEAGE_LIVEDISPLAY_HAL | ENABLE_AB | Enable AdaptiveBacklight feature | false |
| OPLUS_LINEAGE_LIVEDISPLAY_HAL | ENABLE_AF | Enable AntiFlicker feature | false |
| OPLUS_LINEAGE_LIVEDISPLAY_HAL | ENABLE_DM | Enable DisplayModes feature | false |
| OPLUS_LINEAGE_LIVEDISPLAY_HAL | ENABLE_PA | Enable PictureAdjustment feature | true |
| OPLUS_LINEAGE_LIVEDISPLAY_HAL | ENABLE_SE | Enable SunlightEnhancement feature | true |
| OPLUS_LINEAGE_TOUCH_HAL | ENABLE_GM | Enable GloveMode feature | false |
| OPLUS_LINEAGE_TOUCH_HAL | ENABLE_HTPR | Enable HighTouchPollingRate feature | true |
| OPLUS_LINEAGE_TOUCH_HAL | ENABLE_TG | Enable TouchscreenGesture feature | true |
| OPLUS_LINEAGE_TOUCH_HAL | INCLUDE_DIR | Device specific include dir path | |
| OPLUS_LINEAGE_TOUCH_HAL | USE_OPLUSTOUCH | Use and interface with stock OplusTouch | false |
| OPLUS_LINEAGE_VIBRATOR_HAL | INCLUDE_DIR | Device specific include dir path | |
| OPLUS_LINEAGE_VIBRATOR_HAL | USE_EFFECT_STREAM | Enable effect stream feature | false |
| QTI_GPT_UTILS | USE_BSG_FRAMEWORK | Enable BSG framework feature | true |

View File

@@ -1,22 +0,0 @@
//
// Copyright (C) 2025 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
cc_binary {
name: "vendor.oplus.hardware.commondcs-service",
vendor: true,
relative_install_path: "hw",
init_rc: ["vendor.oplus.hardware.commondcs-service.rc"],
vintf_fragments: ["vendor.oplus.hardware.commondcs-service.xml"],
srcs: [
"CommonDcsAidlHalService.cpp",
"service.cpp",
],
shared_libs: [
"libbase",
"libbinder_ndk",
"vendor.oplus.hardware.commondcs-V1-ndk",
],
}

View File

@@ -1,26 +0,0 @@
/*
* Copyright (C) 2025 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "CommonDcsAidlHalService.h"
namespace aidl {
namespace vendor {
namespace oplus {
namespace hardware {
namespace commondcs {
ndk::ScopedAStatus CommonDcsAidlHalService::notifyMsgToCommonDcs(
const std::vector<StringPair>& data, const std::string& logTag, const std::string& eventId,
int32_t* _aidl_return) {
*_aidl_return = 0;
return ndk::ScopedAStatus::ok();
}
} // namespace commondcs
} // namespace hardware
} // namespace oplus
} // namespace vendor
} // namespace aidl

View File

@@ -1,27 +0,0 @@
/*
* Copyright (C) 2025 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/oplus/hardware/commondcs/BnCommonDcsAidlHalService.h>
namespace aidl {
namespace vendor {
namespace oplus {
namespace hardware {
namespace commondcs {
struct CommonDcsAidlHalService : public BnCommonDcsAidlHalService {
ndk::ScopedAStatus notifyMsgToCommonDcs(const std::vector<StringPair>& data,
const std::string& logTag, const std::string& eventId,
int32_t* _aidl_return) final;
};
} // namespace commondcs
} // namespace hardware
} // namespace oplus
} // namespace vendor
} // namespace aidl

View File

@@ -1,27 +0,0 @@
/*
* Copyright (C) 2025 The LineageOS Project
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "CommonDcsAidlHalService.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using ::aidl::vendor::oplus::hardware::commondcs::CommonDcsAidlHalService;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<CommonDcsAidlHalService> service =
ndk::SharedRefBase::make<CommonDcsAidlHalService>();
const std::string instance = std::string() + CommonDcsAidlHalService::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(service->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,4 +0,0 @@
service vendor.commondcs /vendor/bin/hw/vendor.oplus.hardware.commondcs-service
class hal
user system
group system

View File

@@ -1,7 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.oplus.hardware.commondcs</name>
<version>1</version>
<fqname>ICommonDcsAidlHalService/default</fqname>
</hal>
</manifest>

View File

@@ -1,19 +0,0 @@
cc_binary {
name: "android.hardware.ir-service.oplus",
vendor: true,
relative_install_path: "hw",
init_rc: ["android.hardware.ir-service.oplus.rc"],
vintf_fragments: ["android.hardware.ir-service.xml"],
srcs: [
"ConsumerIr.cpp",
"service.cpp",
],
shared_libs: [
"android.hardware.ir-V1-ndk",
"libbase",
"libbinder_ndk",
],
header_libs: [
"kernel_headers.oplus",
],
}

View File

@@ -1,77 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#include "ConsumerIr.h"
#include <aidl/android/hardware/ir/ConsumerIrFreqRange.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <oplus/oplus_ir_core.h>
namespace aidl {
namespace android {
namespace hardware {
namespace ir {
static constexpr int32_t MAX_PATTERN_TIME = 2000000;
static constexpr int32_t MIN_FREQ = 20000;
static constexpr int32_t MAX_FREQ = 60000;
ConsumerIr::ConsumerIr() : supportedFreqs({{MIN_FREQ, MAX_FREQ}}) {}
::ndk::ScopedAStatus ConsumerIr::getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) {
*_aidl_return = supportedFreqs;
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus ConsumerIr::transmit(int32_t carrierFreqHz,
const std::vector<int32_t>& pattern) {
if (carrierFreqHz < MIN_FREQ || carrierFreqHz > MAX_FREQ) {
LOG(ERROR) << "Invalid carrier frequency: " << carrierFreqHz;
return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
int32_t totalTime = 0;
for (int32_t value : pattern) {
if (value < 0) {
LOG(ERROR) << "Invalid pattern value: " << value;
return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
totalTime += value;
}
if (totalTime > MAX_PATTERN_TIME) {
LOG(ERROR) << "Pattern is too long: " << totalTime << " us";
return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
::android::base::unique_fd fd(open("/dev/oplus_consumer_ir", O_WRONLY));
if (!fd.ok()) {
LOG(ERROR) << "Failed to open /dev/oplus_consumer_ir: " << strerror(errno);
return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
size_t paramsSize = sizeof(struct pattern_params) + pattern.size() * sizeof(int32_t);
auto params = std::unique_ptr<struct pattern_params, decltype(&free)>(
static_cast<pattern_params*>(malloc(paramsSize)), free);
if (!params) {
LOG(ERROR) << "Failed to allocate memory for IR params";
return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
params->carrier_freq = carrierFreqHz;
params->size = pattern.size();
memcpy(params->pattern, pattern.data(), pattern.size() * sizeof(int32_t));
int result = ioctl(fd, IR_SEND_PATTERN, params.get());
return result < 0 ? ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)
: ::ndk::ScopedAStatus::ok();
}
} // namespace ir
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@@ -1,30 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/android/hardware/ir/BnConsumerIr.h>
namespace aidl {
namespace android {
namespace hardware {
namespace ir {
class ConsumerIr : public BnConsumerIr {
public:
ConsumerIr();
private:
::ndk::ScopedAStatus getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) override;
::ndk::ScopedAStatus transmit(int32_t carrierFreqHz,
const std::vector<int32_t>& pattern) override;
std::vector<ConsumerIrFreqRange> supportedFreqs;
};
} // namespace ir
} // namespace hardware
} // namespace android
} // namespace aidl

View File

@@ -1,9 +0,0 @@
on boot
chown system system /dev/oplus_consumer_ir
chmod 0644 /dev/oplus_consumer_ir
service vendor.ir-default /vendor/bin/hw/android.hardware.ir-service.oplus
class hal
user system
group system
interface aidl android.hardware.ir.IConsumerIr/default

View File

@@ -1,7 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.ir</name>
<version>1</version>
<fqname>IConsumerIr/default</fqname>
</hal>
</manifest>

View File

@@ -1,25 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#include "ConsumerIr.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using ::aidl::android::hardware::ir::ConsumerIr;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<ConsumerIr> consumerIr = ndk::SharedRefBase::make<ConsumerIr>();
const std::string instance = std::string() + ConsumerIr::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(consumerIr->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,46 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "AdaptiveBacklightService"
#include <android-base/logging.h>
#include <fcntl.h>
#include <livedisplay/oplus/AdaptiveBacklight.h>
#include <oplus/oplus_display_panel.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace livedisplay {
AdaptiveBacklight::AdaptiveBacklight() : mOplusDisplayFd(open("/dev/oplus_display", O_RDWR)) {}
ndk::ScopedAStatus AdaptiveBacklight::getEnabled(bool* _aidl_return) {
unsigned int value;
if (ioctl(mOplusDisplayFd, PANEL_IOCTL_GET_CABC_STATUS, &value) != 0) {
LOG(ERROR) << "Failed to read current AdaptiveBacklight state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = value > 0;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus AdaptiveBacklight::setEnabled(bool enabled) {
bool isEnabled;
if (auto status = getEnabled(&isEnabled); !status.isOk()) {
return status;
}
unsigned int value = enabled;
if (isEnabled != enabled && ioctl(mOplusDisplayFd, PANEL_IOCTL_SET_CABC_STATUS, &value) != 0) {
LOG(ERROR) << "Failed to set AdaptiveBacklight state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
return ndk::ScopedAStatus::ok();
}
} // namespace livedisplay
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,90 +0,0 @@
//
// SPDX-FileCopyrightText: 2019-2025 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
filegroup {
name: "vendor.lineage.livedisplay-oplus-ab",
srcs: ["AdaptiveBacklight.cpp"],
}
filegroup {
name: "vendor.lineage.livedisplay-oplus-af",
srcs: ["AntiFlicker.cpp"],
}
filegroup {
name: "vendor.lineage.livedisplay-oplus-dm",
srcs: ["DisplayModes.cpp"],
}
filegroup {
name: "vendor.lineage.livedisplay-oplus-se",
srcs: ["SunlightEnhancement.cpp"],
}
cc_library_headers {
name: "vendor.lineage.livedisplay-oplus-headers",
vendor_available: true,
export_include_dirs: ["include"],
}
cc_binary {
name: "vendor.lineage.livedisplay-service.oplus",
init_rc: ["vendor.lineage.livedisplay-service.oplus.rc"],
vintf_fragments: select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_AB"), {
"true": ["vendor.lineage.livedisplay-service.oplus-ab.xml"],
default: [],
}) + select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_AF"), {
"true": ["vendor.lineage.livedisplay-service.oplus-af.xml"],
default: [],
}) + select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_DM"), {
"true": ["vendor.lineage.livedisplay-service.oplus-dm.xml"],
default: [],
}) + select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_PA"), {
"false": [],
default: ["vendor.lineage.livedisplay-service.oplus-pa.xml"],
}) + select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_SE"), {
"false": [],
default: ["vendor.lineage.livedisplay-service.oplus-se.xml"],
}),
relative_install_path: "hw",
srcs: [
":vendor.lineage.livedisplay-sdm-pa",
":vendor.lineage.livedisplay-sdm-utils",
":vendor.lineage.livedisplay-oplus-ab",
":vendor.lineage.livedisplay-oplus-af",
":vendor.lineage.livedisplay-oplus-dm",
":vendor.lineage.livedisplay-oplus-se",
"service.cpp",
],
shared_libs: [
"libbase",
"libbinder_ndk",
"libbinder",
"libutils",
"vendor.lineage.livedisplay-V1-ndk",
],
header_libs: [
"kernel_headers.oplus",
"vendor.lineage.livedisplay-sdm-headers",
"vendor.lineage.livedisplay-oplus-headers",
],
cflags: select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_AB"), {
"true": ["-DENABLE_AB=true"],
default: ["-DENABLE_AB=false"],
}) + select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_AF"), {
"true": ["-DENABLE_AF=true"],
default: ["-DENABLE_AF=false"],
}) + select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_DM"), {
"true": ["-DENABLE_DM=true"],
default: ["-DENABLE_DM=false"],
}) + select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_PA"), {
"false": ["-DENABLE_PA=false"],
default: ["-DENABLE_PA=true"],
}) + select(soong_config_variable("OPLUS_LINEAGE_LIVEDISPLAY_HAL", "ENABLE_SE"), {
"false": ["-DENABLE_SE=false"],
default: ["-DENABLE_SE=true"],
}),
proprietary: true,
}

View File

@@ -1,48 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "AntiFlickerService"
#include <android-base/logging.h>
#include <fcntl.h>
#include <livedisplay/oplus/AntiFlicker.h>
#include <oplus/oplus_display_panel.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace livedisplay {
AntiFlicker::AntiFlicker() : mOplusDisplayFd(open("/dev/oplus_display", O_RDWR)) {}
ndk::ScopedAStatus AntiFlicker::getEnabled(bool* _aidl_return) {
unsigned int value;
if (ioctl(mOplusDisplayFd, PANEL_IOCTL_GET_PWM_TURBO, &value) != 0 &&
ioctl(mOplusDisplayFd, PANEL_IOCTL_GET_DIMLAYER_BL_EN, &value) != 0) {
LOG(ERROR) << "Failed to read current AntiFlicker state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = value > 0;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus AntiFlicker::setEnabled(bool enabled) {
bool isEnabled;
if (auto status = getEnabled(&isEnabled); !status.isOk()) {
return status;
}
unsigned int value = enabled;
if (isEnabled != enabled && ioctl(mOplusDisplayFd, PANEL_IOCTL_SET_PWM_TURBO, &value) != 0 &&
ioctl(mOplusDisplayFd, PANEL_IOCTL_SET_DIMLAYER_BL_EN, &value) != 0) {
LOG(ERROR) << "Failed to set AntiFlicker state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
return ndk::ScopedAStatus::ok();
}
} // namespace livedisplay
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,46 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "SunlightEnhancementService"
#include <android-base/logging.h>
#include <fcntl.h>
#include <livedisplay/oplus/SunlightEnhancement.h>
#include <oplus/oplus_display_panel.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace livedisplay {
SunlightEnhancement::SunlightEnhancement() : mOplusDisplayFd(open("/dev/oplus_display", O_RDWR)) {}
ndk::ScopedAStatus SunlightEnhancement::getEnabled(bool* _aidl_return) {
unsigned int value;
if (ioctl(mOplusDisplayFd, PANEL_IOCTL_GET_HBM, &value) != 0) {
LOG(ERROR) << "Failed to read current SunlightEnhancement state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = value > 0;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus SunlightEnhancement::setEnabled(bool enabled) {
bool isEnabled;
if (auto status = getEnabled(&isEnabled); !status.isOk()) {
return status;
}
unsigned int value = enabled;
if (isEnabled != enabled && ioctl(mOplusDisplayFd, PANEL_IOCTL_SET_HBM, &value) != 0) {
LOG(ERROR) << "Failed to set SunlightEnhancement state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
return ndk::ScopedAStatus::ok();
}
} // namespace livedisplay
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,30 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/livedisplay/BnAdaptiveBacklight.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace livedisplay {
class AdaptiveBacklight : public BnAdaptiveBacklight {
public:
AdaptiveBacklight();
// Methods from ::aidl::vendor::lineage::livedisplay::BnAdaptiveBacklight follow.
ndk::ScopedAStatus getEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enabled) override;
private:
int mOplusDisplayFd;
};
} // namespace livedisplay
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,30 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/livedisplay/BnAntiFlicker.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace livedisplay {
class AntiFlicker : public BnAntiFlicker {
public:
AntiFlicker();
// Methods from ::aidl::vendor::lineage::livedisplay::BnAntiFlicker follow.
ndk::ScopedAStatus getEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enabled) override;
private:
int mOplusDisplayFd;
};
} // namespace livedisplay
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,49 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/livedisplay/BnDisplayModes.h>
#include <livedisplay/sdm/SDMController.h>
#include <map>
namespace aidl {
namespace vendor {
namespace lineage {
namespace livedisplay {
class DisplayModes : public BnDisplayModes {
public:
DisplayModes(std::shared_ptr<sdm::SDMController> controller);
using DisplayModeSetCallback = std::function<void()>;
inline void registerDisplayModeSetCallback(DisplayModeSetCallback callback) {
mOnDisplayModeSet = callback;
}
// Methods from ::aidl::vendor::lineage::livedisplay::BnDisplayModes follow.
ndk::ScopedAStatus getDisplayModes(std::vector<DisplayMode>* _aidl_return) override;
ndk::ScopedAStatus getCurrentDisplayMode(DisplayMode* _aidl_return) override;
ndk::ScopedAStatus getDefaultDisplayMode(DisplayMode* _aidl_return) override;
ndk::ScopedAStatus setDisplayMode(int32_t modeID, bool makeDefault) override;
private:
struct ModeInfo {
std::string name;
int32_t displayModeId;
uint32_t seedMode;
};
static const std::map<int32_t, ModeInfo> kModeMap;
std::shared_ptr<sdm::SDMController> mController;
int32_t mOplusDisplayFd;
int32_t mCurrentModeId;
int32_t mDefaultModeId;
DisplayModeSetCallback mOnDisplayModeSet;
};
} // namespace livedisplay
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,30 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/livedisplay/BnSunlightEnhancement.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace livedisplay {
class SunlightEnhancement : public BnSunlightEnhancement {
public:
SunlightEnhancement();
// Methods from ::aidl::vendor::lineage::livedisplay::BnSunlightEnhancement follow.
ndk::ScopedAStatus getEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enabled) override;
private:
int mOplusDisplayFd;
};
} // namespace livedisplay
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,76 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "vendor.lineage.livedisplay-service-oplus"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <binder/ProcessState.h>
#include <livedisplay/oplus/AdaptiveBacklight.h>
#include <livedisplay/oplus/AntiFlicker.h>
#include <livedisplay/oplus/DisplayModes.h>
#include <livedisplay/oplus/SunlightEnhancement.h>
#include <livedisplay/sdm/PictureAdjustment.h>
using ::aidl::vendor::lineage::livedisplay::AdaptiveBacklight;
using ::aidl::vendor::lineage::livedisplay::AntiFlicker;
using ::aidl::vendor::lineage::livedisplay::DisplayModes;
using ::aidl::vendor::lineage::livedisplay::SunlightEnhancement;
using ::aidl::vendor::lineage::livedisplay::sdm::PictureAdjustment;
using ::aidl::vendor::lineage::livedisplay::sdm::SDMController;
int main() {
android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
android::ProcessState::self()->startThreadPool();
LOG(INFO) << "LiveDisplay HAL service is starting.";
std::shared_ptr<SDMController> controller =
ENABLE_DM || ENABLE_PA ? std::make_shared<SDMController>() : nullptr;
std::shared_ptr<AdaptiveBacklight> ab =
ENABLE_AB ? ndk::SharedRefBase::make<AdaptiveBacklight>() : nullptr;
std::shared_ptr<AntiFlicker> af = ENABLE_AF ? ndk::SharedRefBase::make<AntiFlicker>() : nullptr;
std::shared_ptr<DisplayModes> dm =
ENABLE_DM ? ndk::SharedRefBase::make<DisplayModes>(controller) : nullptr;
std::shared_ptr<PictureAdjustment> pa =
ENABLE_PA ? ndk::SharedRefBase::make<PictureAdjustment>(controller) : nullptr;
std::shared_ptr<SunlightEnhancement> se =
ENABLE_SE ? ndk::SharedRefBase::make<SunlightEnhancement>() : nullptr;
if (ab) {
std::string instance = std::string() + AdaptiveBacklight::descriptor + "/default";
binder_status_t status = AServiceManager_addService(ab->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
}
if (af) {
std::string instance = std::string() + AntiFlicker::descriptor + "/default";
binder_status_t status = AServiceManager_addService(af->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
}
if (dm) {
std::string instance = std::string() + DisplayModes::descriptor + "/default";
binder_status_t status = AServiceManager_addService(dm->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
}
if (pa) {
std::string instance = std::string() + PictureAdjustment::descriptor + "/default";
binder_status_t status = AServiceManager_addService(pa->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
}
if (se) {
std::string instance = std::string() + SunlightEnhancement::descriptor + "/default";
binder_status_t status = AServiceManager_addService(se->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
}
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,10 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.lineage.livedisplay</name>
<version>1</version>
<interface>
<name>IAdaptiveBacklight</name>
<instance>default</instance>
</interface>
</hal>
</manifest>

View File

@@ -1,10 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.lineage.livedisplay</name>
<version>1</version>
<interface>
<name>IPictureAdjustment</name>
<instance>default</instance>
</interface>
</hal>
</manifest>

View File

@@ -1,4 +0,0 @@
service vendor.livedisplay-hal /vendor/bin/hw/vendor.lineage.livedisplay-service.oplus
class late_start
user system
group system

View File

@@ -1,7 +1,6 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.oplus.hardware.osense.client</name>
<version>1</version>
<fqname>IOsenseAidlHalReporter/default</fqname>
</hal>
</manifest>

View File

@@ -1,21 +0,0 @@
//
// SPDX-FileCopyrightText: 2025 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
cc_binary {
name: "vendor.oplus.hardware.performance-service",
vendor: true,
relative_install_path: "hw",
init_rc: ["vendor.oplus.hardware.performance-service.rc"],
vintf_fragments: ["vendor.oplus.hardware.performance-service.xml"],
srcs: [
"Performance.cpp",
"service.cpp",
],
shared_libs: [
"libbase",
"libbinder_ndk",
"vendor.oplus.hardware.performance-V1-ndk",
],
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,234 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/oplus/hardware/performance/BnPerformance.h>
namespace aidl {
namespace vendor {
namespace oplus {
namespace hardware {
namespace performance {
class Performance : public BnPerformance {
ndk::ScopedAStatus addAcmDirName(const std::string& dirname, int64_t flag,
int32_t* _aidl_return) override;
ndk::ScopedAStatus addAcmNomediaDirName(const std::string& dirname,
int32_t* _aidl_return) override;
ndk::ScopedAStatus addAcmPkgName(const std::string& pkgname, int64_t flag,
int32_t* _aidl_return) override;
ndk::ScopedAStatus addTaskTrackPid(int32_t group, int32_t pid, bool clear,
int32_t* _aidl_return) override;
ndk::ScopedAStatus clearTaskTrackGroup(int32_t group) override;
ndk::ScopedAStatus delAcmDirName(const std::string& dirname, int32_t* _aidl_return) override;
ndk::ScopedAStatus delAcmNomediaDirName(const std::string& dirname,
int32_t* _aidl_return) override;
ndk::ScopedAStatus delAcmPkgName(const std::string& pkgname, int32_t* _aidl_return) override;
ndk::ScopedAStatus disableDamonReclaim(int32_t* _aidl_return) override;
ndk::ScopedAStatus disableKmallocDebug(int32_t* _aidl_return) override;
ndk::ScopedAStatus disableMultiThreadOptimize(int32_t* _aidl_return) override;
ndk::ScopedAStatus disableProcessReclaim(int32_t* _aidl_return) override;
ndk::ScopedAStatus disableTaskCpustats(int32_t* _aidl_return) override;
ndk::ScopedAStatus disableTaskPlacementDecision(int32_t* _aidl_return) override;
ndk::ScopedAStatus disableVmallocDebug(int32_t* _aidl_return) override;
ndk::ScopedAStatus enableAudioPerf(const std::string& value, int32_t* _aidl_return) override;
ndk::ScopedAStatus enableDamonReclaim(int32_t* _aidl_return) override;
ndk::ScopedAStatus enableKmallocDebug(int32_t* _aidl_return) override;
ndk::ScopedAStatus enableMultiThreadOptimize(int32_t* _aidl_return) override;
ndk::ScopedAStatus enableProcessReclaim(int32_t* _aidl_return) override;
ndk::ScopedAStatus enableTaskCpustats(int32_t* _aidl_return) override;
ndk::ScopedAStatus enableTaskPlacementDecision(int32_t* _aidl_return) override;
ndk::ScopedAStatus enableVmallocDebug(int32_t* _aidl_return) override;
ndk::ScopedAStatus existMemMonitor(int32_t* _aidl_return) override;
ndk::ScopedAStatus getAcmDirFlag(const std::string& dirname, int64_t* _aidl_return) override;
ndk::ScopedAStatus getAcmOpstat(int32_t* _aidl_return) override;
ndk::ScopedAStatus getAcmPkgFlag(const std::string& pkgname, int64_t* _aidl_return) override;
ndk::ScopedAStatus getClmMuxSwitch(std::string* _aidl_return) override;
ndk::ScopedAStatus getClmThreshold(int32_t threshold_id, std::string* _aidl_return) override;
ndk::ScopedAStatus getDdrResidency(std::string* _aidl_return) override;
ndk::ScopedAStatus getDevinfoDDRInfo(std::string* _aidl_return) override;
ndk::ScopedAStatus getDevinfoUfsInfo(std::string* _aidl_return) override;
ndk::ScopedAStatus getDevinfoUfsVersionInfo(std::string* _aidl_return) override;
ndk::ScopedAStatus getExt4FragScore(const std::string& devpath,
std::string* _aidl_return) override;
ndk::ScopedAStatus getExt4FreefragInfo(const std::string& devpath,
std::string* _aidl_return) override;
ndk::ScopedAStatus getF2fsMovedBlks(std::string* _aidl_return) override;
ndk::ScopedAStatus getHIAllocWait(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHICpuInfo(std::string* _aidl_return) override;
ndk::ScopedAStatus getHICpuLoading(std::string* _aidl_return) override;
ndk::ScopedAStatus getHIDState(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHIEmcdrvIowait(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHIFsyncWait(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHIIonWait(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHIIowait(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHIIowaitHung(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHIKswapdLoading(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHISchedLatency(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHIScmCall(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getHIUfsFeature(ProcReqHal* _aidl_return) override;
ndk::ScopedAStatus getKernelVersion(int32_t* _aidl_return) override;
ndk::ScopedAStatus getKmallocDebug(std::string* _aidl_return) override;
ndk::ScopedAStatus getKmallocOrigin(std::string* _aidl_return) override;
ndk::ScopedAStatus getKmallocUsed(std::string* _aidl_return) override;
ndk::ScopedAStatus getMemMonitor(std::string* _aidl_return) override;
ndk::ScopedAStatus getOswapVersion(int32_t* _aidl_return) override;
ndk::ScopedAStatus getUfsSignalRecordUpload(std::string* _aidl_return) override;
ndk::ScopedAStatus getUfsplusHpbStatus(int32_t* _aidl_return) override;
ndk::ScopedAStatus getUfsplusTwStatus(int32_t* _aidl_return) override;
ndk::ScopedAStatus getVmallocDebug(std::string* _aidl_return) override;
ndk::ScopedAStatus getVmallocHashCal(std::string* _aidl_return) override;
ndk::ScopedAStatus getVmallocUsed(std::string* _aidl_return) override;
ndk::ScopedAStatus getWakeThreadsAffinityOrdered(const std::string& handle, int32_t size,
TaskWakeInfo* _aidl_return) override;
ndk::ScopedAStatus getallocwait(std::string* _aidl_return) override;
ndk::ScopedAStatus getdstate(std::string* _aidl_return) override;
ndk::ScopedAStatus getfsyncwait(std::string* _aidl_return) override;
ndk::ScopedAStatus getionwait(std::string* _aidl_return) override;
ndk::ScopedAStatus getiowait(std::string* _aidl_return) override;
ndk::ScopedAStatus getschedlatency(std::string* _aidl_return) override;
ndk::ScopedAStatus hybridswap_memcg_para_read(int32_t action, const std::string& cgroup,
std::string* _aidl_return) override;
ndk::ScopedAStatus hybridswap_memcg_para_write(int32_t action, const std::string& cgroup,
const std::string& str,
int32_t* _aidl_return) override;
ndk::ScopedAStatus hybridswap_zram_para_read(int32_t action,
std::string* _aidl_return) override;
ndk::ScopedAStatus hybridswap_zram_para_write(int32_t action, const std::string& str,
int32_t* _aidl_return) override;
ndk::ScopedAStatus isJankTaskTrackEnable(bool* _aidl_return) override;
ndk::ScopedAStatus perProcessMemReadahead(int32_t uid, int32_t pid, int32_t type,
int32_t* _aidl_return) override;
ndk::ScopedAStatus perProcessMemReclaim(int32_t uid, int32_t pid, int32_t type,
int32_t* _aidl_return) override;
ndk::ScopedAStatus readCallStack(std::string* _aidl_return) override;
ndk::ScopedAStatus readClmEnable(std::string* _aidl_return) override;
ndk::ScopedAStatus readClmHighLoadAll(std::string* _aidl_return) override;
ndk::ScopedAStatus readClmHighLoadGrp(std::string* _aidl_return) override;
ndk::ScopedAStatus readClmLowLoadGrp(std::string* _aidl_return) override;
ndk::ScopedAStatus readCpuTaskstats(std::string* _aidl_return) override;
ndk::ScopedAStatus readDBacktrace(std::string* _aidl_return) override;
ndk::ScopedAStatus readDConvert(std::string* _aidl_return) override;
ndk::ScopedAStatus readFgFreqsThreshold(std::string* _aidl_return) override;
ndk::ScopedAStatus readIOBacktrace(std::string* _aidl_return) override;
ndk::ScopedAStatus readIomonitorInfo(const std::string& procname,
std::string* _aidl_return) override;
ndk::ScopedAStatus readJankCpuIndicator(std::string* _aidl_return) override;
ndk::ScopedAStatus readJankCpuInfo(std::string* _aidl_return) override;
ndk::ScopedAStatus readJankCpuInfoSig(std::string* _aidl_return) override;
ndk::ScopedAStatus readJankCpuLoad(std::string* _aidl_return) override;
ndk::ScopedAStatus readJankCpuLoad32(std::string* _aidl_return) override;
ndk::ScopedAStatus readJankCpuLoad32Scale(std::string* _aidl_return) override;
ndk::ScopedAStatus readJankTaskTrack(std::string* _aidl_return) override;
ndk::ScopedAStatus readJankTaskTrackByPid(int32_t pid, std::string* _aidl_return) override;
ndk::ScopedAStatus readJankVersion(std::string* _aidl_return) override;
ndk::ScopedAStatus readKmallocDebugCreate(std::string* _aidl_return) override;
ndk::ScopedAStatus readLimitTable(std::string* _aidl_return) override;
ndk::ScopedAStatus readMemleakDetectThread(std::string* _aidl_return) override;
ndk::ScopedAStatus readMemoryByPids(const std::vector<int32_t>& pids, int32_t flags,
ProcMemStatRet* _aidl_return) override;
ndk::ScopedAStatus readMemoryByUids(const std::vector<int32_t>& uids, int32_t flags,
ProcMemStatRet* _aidl_return) override;
ndk::ScopedAStatus readNandswapProc(const std::string& inProc,
std::string* _aidl_return) override;
ndk::ScopedAStatus readNormalizeRealTime(std::string* _aidl_return) override;
ndk::ScopedAStatus readNormalizeRunningTime(std::string* _aidl_return) override;
ndk::ScopedAStatus readOplusReserve3(int32_t offset, int32_t len,
std::string* _aidl_return) override;
ndk::ScopedAStatus readOsvelteVersion(OsvelteVersionRet* _aidl_return) override;
ndk::ScopedAStatus readPidsSet(std::string* _aidl_return) override;
ndk::ScopedAStatus readRealTime(std::string* _aidl_return) override;
ndk::ScopedAStatus readRunningTime(std::string* _aidl_return) override;
ndk::ScopedAStatus readSchedInfoThreshold(std::string* _aidl_return) override;
ndk::ScopedAStatus readSgeFreqInfo(std::string* _aidl_return) override;
ndk::ScopedAStatus readSgeInfo(std::string* _aidl_return) override;
ndk::ScopedAStatus readStorageFeature(const std::string& name, const std::string& addr,
const std::string& isMulti,
std::string* _aidl_return) override;
ndk::ScopedAStatus readTargetProcess(const std::string& buffer,
std::string* _aidl_return) override;
ndk::ScopedAStatus readTaskCpustatsEnable(std::string* _aidl_return) override;
ndk::ScopedAStatus readTaskSchedInfo(std::string* _aidl_return) override;
ndk::ScopedAStatus readTidsSet(std::string* _aidl_return) override;
ndk::ScopedAStatus readTmemoryDirtypages(std::string* _aidl_return) override;
ndk::ScopedAStatus readTmemoryErrorStat(std::string* _aidl_return) override;
ndk::ScopedAStatus readTmemoryIoLatency(std::string* _aidl_return) override;
ndk::ScopedAStatus readTmemorySysdirtypages(std::string* _aidl_return) override;
ndk::ScopedAStatus readUxTaskTrack(int32_t uPid, int32_t rPid,
std::string* _aidl_return) override;
ndk::ScopedAStatus readVaFeature(std::string* _aidl_return) override;
ndk::ScopedAStatus readVersion(std::string* _aidl_return) override;
ndk::ScopedAStatus removeTaskTrackPid(int32_t group, int32_t pid) override;
ndk::ScopedAStatus searchAcmNomediaDirName(const std::string& dirname,
int32_t* _aidl_return) override;
ndk::ScopedAStatus setAcmOpstat(int32_t flag, int32_t* _aidl_return) override;
ndk::ScopedAStatus setClmMuxSwitch(const std::string& buffer) override;
ndk::ScopedAStatus setClmThreshold(const std::string& buffer, int32_t threshold_id) override;
ndk::ScopedAStatus setDamonReclaimColdTime(int32_t cold_time, int32_t* _aidl_return) override;
ndk::ScopedAStatus setDamonReclaimMonitoring(int32_t sample, int32_t aggr,
int32_t* _aidl_return) override;
ndk::ScopedAStatus setDamonReclaimQuota(int32_t quota_ms, int32_t quota_sz,
int32_t reset_interval, int32_t* _aidl_return) override;
ndk::ScopedAStatus setDamonReclaimWmarks(int32_t metric, int32_t high, int32_t mid, int32_t low,
int32_t* _aidl_return) override;
ndk::ScopedAStatus setExtSchedProp(const std::string& pid, const std::string& prop) override;
ndk::ScopedAStatus setFgUids(const std::string& fg_uid) override;
ndk::ScopedAStatus setFrameRate(const std::string& frame_rate) override;
ndk::ScopedAStatus setFreqGoverner(const std::string& gov_name,
const std::vector<int32_t>& clusters,
int32_t* _aidl_return) override;
ndk::ScopedAStatus setImFlag(const std::string& pid, const std::string& im_flag) override;
ndk::ScopedAStatus setProcessReclaim(const std::string& info, int32_t* _aidl_return) override;
ndk::ScopedAStatus setSchedAssistImptTask(const std::string& impt_info) override;
ndk::ScopedAStatus setSchedAssistScene(const std::string& scene_id) override;
ndk::ScopedAStatus setSlideboost(const std::string& boost) override;
ndk::ScopedAStatus setTpdID(const std::string& param, int32_t* _aidl_return) override;
ndk::ScopedAStatus setTpdSerialParams(const std::string& params,
int32_t* _aidl_return) override;
ndk::ScopedAStatus setWakeSeedThread(const std::string& tid, bool identify_type, bool inUid,
int32_t* _aidl_return) override;
ndk::ScopedAStatus writeClmEnable(const std::string& buffer) override;
ndk::ScopedAStatus writeClmHighLoadAll(const std::string& buffer) override;
ndk::ScopedAStatus writeClmHighLoadGrp(const std::string& buffer) override;
ndk::ScopedAStatus writeClmLowLoadGrp(const std::string& buffer) override;
ndk::ScopedAStatus writeDBacktrace(const std::string& buffer) override;
ndk::ScopedAStatus writeFgFreqsThreshold(const std::string& buffer) override;
ndk::ScopedAStatus writeIOBacktrace(const std::string& buffer) override;
ndk::ScopedAStatus writeJankTaskTrackEnable(bool enable) override;
ndk::ScopedAStatus writeKmallocDebugCreate(int32_t kcreate, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeKmallocDebugCreateWithType(const std::string& type,
int32_t* _aidl_return) override;
ndk::ScopedAStatus writeMemMonitor(const std::string& buffer, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeMemleakDetectThread(int32_t memdect, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeMonitorStatus(const std::string& buffer,
int32_t* _aidl_return) override;
ndk::ScopedAStatus writeNandswapProc(const std::string& inProc, const std::string& cmd,
int32_t* _aidl_return) override;
ndk::ScopedAStatus writeOplusReserve3(int32_t offset, int32_t len, const std::string& info,
int32_t* _aidl_return) override;
ndk::ScopedAStatus writePidsSet(const std::string& buffer) override;
ndk::ScopedAStatus writeSchedInfoThreshold(const std::string& buffer) override;
ndk::ScopedAStatus writeStorageFeature(const std::string& name, const std::string& addr,
const std::string& isMulti, const std::string& cmd,
int32_t* _aidl_return) override;
ndk::ScopedAStatus writeTaskSchedInfo(const std::string& buffer) override;
ndk::ScopedAStatus writeTidsSet(const std::string& buffer) override;
ndk::ScopedAStatus writeTmemoryCapacity(int32_t param, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeTmemoryFlushBusy(int32_t param, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeTmemoryFlushIdle(int32_t param, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeTmemoryHighWaterRatio(int32_t param, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeTmemoryMemory(const std::string& str, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeTmemorySwitch(int32_t param, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeUxState(const std::string& ux_state, const std::string& pid,
const std::string& tid, int32_t* _aidl_return) override;
ndk::ScopedAStatus writeVaFeature(int32_t vafeature, int32_t* _aidl_return) override;
};
} // namespace performance
} // namespace hardware
} // namespace oplus
} // namespace vendor
} // namespace aidl

View File

@@ -1,25 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#include "Performance.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using ::aidl::vendor::oplus::hardware::performance::Performance;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<Performance> performance = ndk::SharedRefBase::make<Performance>();
const std::string instance = std::string() + Performance::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(performance->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,4 +0,0 @@
service oplus.performance.hal.service /vendor/bin/hw/vendor.oplus.hardware.performance-service
class hal
user system
group system

View File

@@ -1,7 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.oplus.hardware.performance</name>
<version>1</version>
<fqname>IPerformance/default</fqname>
</hal>
</manifest>

View File

@@ -1,23 +0,0 @@
//
// SPDX-FileCopyrightText: 2025 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
cc_binary {
name: "vendor.lineage.powershare-service.oplus",
vintf_fragments: ["vendor.lineage.powershare-service.oplus.xml"],
init_rc: ["vendor.lineage.powershare-service.oplus.rc"],
vendor: true,
relative_install_path: "hw",
srcs: [
"PowerShare.cpp",
"service.cpp",
],
shared_libs: [
"libbase",
"liblog",
"libbinder_ndk",
"libutils",
"vendor.lineage.powershare-V1-ndk",
],
}

View File

@@ -1,59 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "vendor.lineage.powershare-service.oplus"
#include "PowerShare.h"
#include <android-base/file.h>
#include <android-base/logging.h>
using ::android::base::ReadFileToString;
using ::android::base::WriteStringToFile;
namespace {
constexpr const char* kWirelessTxEnablePath = "/proc/wireless/enable_tx";
} // anonymous namespace
namespace aidl {
namespace vendor {
namespace lineage {
namespace powershare {
ndk::ScopedAStatus PowerShare::getMinBattery(int32_t* _aidl_return) {
*_aidl_return = 0;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus PowerShare::isEnabled(bool* _aidl_return) {
std::string value;
if (!ReadFileToString(kWirelessTxEnablePath, &value)) {
LOG(ERROR) << "Failed to read current PowerShare state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = value != "disable\n";
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus PowerShare::setEnabled(bool enable) {
if (!WriteStringToFile(enable ? "1" : "0", kWirelessTxEnablePath, true)) {
LOG(ERROR) << "Failed to write PowerShare state";
return ndk::ScopedAStatus::fromExceptionCode(EX_SERVICE_SPECIFIC);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus PowerShare::setMinBattery(int32_t minBattery) {
return ndk::ScopedAStatus::ok();
}
} // namespace powershare
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,26 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/powershare/BnPowerShare.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace powershare {
class PowerShare : public BnPowerShare {
public:
ndk::ScopedAStatus getMinBattery(int32_t* _aidl_return) override;
ndk::ScopedAStatus isEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enable) override;
ndk::ScopedAStatus setMinBattery(int32_t minBattery) override;
};
} // namespace powershare
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,25 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#include "PowerShare.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using aidl::vendor::lineage::powershare::PowerShare;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<PowerShare> powershare = ndk::SharedRefBase::make<PowerShare>();
const std::string instance = std::string(PowerShare::descriptor) + "/default";
binder_status_t status =
AServiceManager_addService(powershare->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,7 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.lineage.powershare</name>
<version>1</version>
<fqname>IPowerShare/default</fqname>
</hal>
</manifest>

View File

@@ -1,57 +0,0 @@
//
// Copyright (C) 2021 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package {
// See: http://go/android-license-faq
default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_binary {
name: "android.hardware.sensors-service.oplus-multihal",
vendor: true,
relative_install_path: "hw",
srcs: [
"service.cpp",
"HalProxy.cpp",
"HalProxyCallback.cpp",
],
header_libs: [
"android.hardware.sensors@2.X-multihal.header",
"android.hardware.sensors@2.X-shared-utils",
],
init_rc: ["android.hardware.sensors-service.oplus-multihal.rc"],
vintf_fragments: ["android.hardware.sensors.oplus-multihal.xml"],
shared_libs: [
"android.hardware.sensors@2.0-ScopedWakelock",
"android.hardware.sensors@2.0",
"android.hardware.sensors@2.1",
"android.hardware.sensors-V3-ndk",
"libbase",
"libcutils",
"libfmq",
"liblog",
"libpower",
"libutils",
"libbinder_ndk",
"libhidlbase",
],
static_libs: [
"libaidlcommonsupport",
"android.hardware.sensors@1.0-convert",
"android.hardware.sensors@2.X-multihal",
"android.hardware.sensors@aidl-multihal",
],
}

View File

@@ -1,810 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "HalProxy.h"
#include <android/hardware/sensors/2.0/types.h>
#include <android-base/file.h>
#include "hardware_legacy/power.h"
#include <dlfcn.h>
#include <cinttypes>
#include <cmath>
#include <fstream>
#include <functional>
#include <thread>
namespace android {
namespace hardware {
namespace sensors {
namespace V2_1 {
namespace implementation {
using ::android::hardware::sensors::V1_0::Result;
using ::android::hardware::sensors::V2_0::EventQueueFlagBits;
using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits;
using ::android::hardware::sensors::V2_0::implementation::getTimeNow;
using ::android::hardware::sensors::V2_0::implementation::kWakelockTimeoutNs;
typedef V2_0::implementation::ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*);
typedef V2_1::implementation::ISensorsSubHal*(SensorsHalGetSubHalV2_1Func)(uint32_t*);
static constexpr int32_t kBitsAfterSubHalIndex = 24;
/**
* Set the subhal index as first byte of sensor handle and return this modified version.
*
* @param sensorHandle The sensor handle to modify.
* @param subHalIndex The index in the hal proxy of the sub hal this sensor belongs to.
*
* @return The modified sensor handle.
*/
int32_t setSubHalIndex(int32_t sensorHandle, size_t subHalIndex) {
return sensorHandle | (static_cast<int32_t>(subHalIndex) << kBitsAfterSubHalIndex);
}
/**
* Extract the subHalIndex from sensorHandle.
*
* @param sensorHandle The sensorHandle to extract from.
*
* @return The subhal index.
*/
size_t extractSubHalIndex(int32_t sensorHandle) {
return static_cast<size_t>(sensorHandle >> kBitsAfterSubHalIndex);
}
/**
* Convert nanoseconds to milliseconds.
*
* @param nanos The nanoseconds input.
*
* @return The milliseconds count.
*/
int64_t msFromNs(int64_t nanos) {
constexpr int64_t nanosecondsInAMillsecond = 1000000;
return nanos / nanosecondsInAMillsecond;
}
bool patchOplusGlanceSensor(V2_1::SensorInfo& sensor) {
if (sensor.typeAsString != "qti.sensor.amd") {
return true;
}
/*
* Implement only the wake-up version of this sensor.
*/
if (!(sensor.flags & V1_0::SensorFlagBits::WAKE_UP)) {
return false;
}
sensor.type = V2_1::SensorType::GLANCE_GESTURE;
sensor.typeAsString = SENSOR_STRING_TYPE_GLANCE_GESTURE;
sensor.maxRange = 2;
return true;
}
bool patchOplusPickupSensor(V2_1::SensorInfo& sensor) {
if (sensor.typeAsString != "android.sensor.tilt_detector") {
return true;
}
/*
* Implement only the wake-up version of this sensor.
*/
if (!(sensor.flags & V1_0::SensorFlagBits::WAKE_UP)) {
return false;
}
sensor.type = V2_1::SensorType::PICK_UP_GESTURE;
sensor.typeAsString = SENSOR_STRING_TYPE_PICK_UP_GESTURE;
sensor.maxRange = 1;
return true;
}
HalProxy::HalProxy() {
static const std::string kMultiHalConfigFiles[] = {"/vendor/etc/sensors/hals.conf",
"/odm/etc/sensors/hals.conf"};
for (const std::string& configFile : kMultiHalConfigFiles) {
initializeSubHalListFromConfigFile(configFile.c_str());
}
init();
}
HalProxy::HalProxy(std::vector<ISensorsSubHalV2_0*>& subHalList) {
for (ISensorsSubHalV2_0* subHal : subHalList) {
mSubHalList.push_back(std::make_unique<SubHalWrapperV2_0>(subHal));
}
init();
}
HalProxy::HalProxy(std::vector<ISensorsSubHalV2_0*>& subHalList,
std::vector<ISensorsSubHalV2_1*>& subHalListV2_1) {
for (ISensorsSubHalV2_0* subHal : subHalList) {
mSubHalList.push_back(std::make_unique<SubHalWrapperV2_0>(subHal));
}
for (ISensorsSubHalV2_1* subHal : subHalListV2_1) {
mSubHalList.push_back(std::make_unique<SubHalWrapperV2_1>(subHal));
}
init();
}
HalProxy::~HalProxy() {
stopThreads();
}
Return<void> HalProxy::getSensorsList_2_1(ISensorsV2_1::getSensorsList_2_1_cb _hidl_cb) {
std::vector<V2_1::SensorInfo> sensors;
for (const auto& iter : mSensors) {
sensors.push_back(iter.second);
}
_hidl_cb(sensors);
return Void();
}
Return<void> HalProxy::getSensorsList(ISensorsV2_0::getSensorsList_cb _hidl_cb) {
std::vector<V1_0::SensorInfo> sensors;
for (const auto& iter : mSensors) {
if (iter.second.type != SensorType::HINGE_ANGLE) {
sensors.push_back(convertToOldSensorInfo(iter.second));
}
}
_hidl_cb(sensors);
return Void();
}
Return<Result> HalProxy::setOperationMode(OperationMode mode) {
Result result = Result::OK;
size_t subHalIndex;
for (subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
result = mSubHalList[subHalIndex]->setOperationMode(mode);
if (result != Result::OK) {
ALOGE("setOperationMode failed for SubHal: %s",
mSubHalList[subHalIndex]->getName().c_str());
break;
}
}
if (result != Result::OK) {
// Reset the subhal operation modes that have been flipped
for (size_t i = 0; i < subHalIndex; i++) {
mSubHalList[i]->setOperationMode(mCurrentOperationMode);
}
} else {
mCurrentOperationMode = mode;
}
return result;
}
Return<Result> HalProxy::activate(int32_t sensorHandle, bool enabled) {
if (!isSubHalIndexValid(sensorHandle)) {
return Result::BAD_VALUE;
}
return getSubHalForSensorHandle(sensorHandle)
->activate(clearSubHalIndex(sensorHandle), enabled);
}
Return<Result> HalProxy::initialize_2_1(
const ::android::hardware::MQDescriptorSync<V2_1::Event>& eventQueueDescriptor,
const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
const sp<V2_1::ISensorsCallback>& sensorsCallback) {
sp<ISensorsCallbackWrapperBase> dynamicCallback =
new ISensorsCallbackWrapperV2_1(sensorsCallback);
// Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
auto eventQueue =
std::make_unique<EventMessageQueueV2_1>(eventQueueDescriptor, true /* resetPointers */);
std::unique_ptr<EventMessageQueueWrapperBase> queue =
std::make_unique<EventMessageQueueWrapperV2_1>(eventQueue);
// Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions.
auto hidlWakeLockQueue =
std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
std::unique_ptr<WakeLockMessageQueueWrapperBase> wakeLockQueue =
std::make_unique<WakeLockMessageQueueWrapperHidl>(hidlWakeLockQueue);
return initializeCommon(queue, wakeLockQueue, dynamicCallback);
}
Return<Result> HalProxy::initialize(
const ::android::hardware::MQDescriptorSync<V1_0::Event>& eventQueueDescriptor,
const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
const sp<V2_0::ISensorsCallback>& sensorsCallback) {
sp<ISensorsCallbackWrapperBase> dynamicCallback =
new ISensorsCallbackWrapperV2_0(sensorsCallback);
// Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
auto eventQueue =
std::make_unique<EventMessageQueueV2_0>(eventQueueDescriptor, true /* resetPointers */);
std::unique_ptr<EventMessageQueueWrapperBase> queue =
std::make_unique<EventMessageQueueWrapperV1_0>(eventQueue);
// Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions.
auto hidlWakeLockQueue =
std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
std::unique_ptr<WakeLockMessageQueueWrapperBase> wakeLockQueue =
std::make_unique<WakeLockMessageQueueWrapperHidl>(hidlWakeLockQueue);
return initializeCommon(queue, wakeLockQueue, dynamicCallback);
}
Return<Result> HalProxy::initializeCommon(
std::unique_ptr<EventMessageQueueWrapperBase>& eventQueue,
std::unique_ptr<WakeLockMessageQueueWrapperBase>& wakeLockQueue,
const sp<ISensorsCallbackWrapperBase>& sensorsCallback) {
Result result = Result::OK;
stopThreads();
resetSharedWakelock();
// So that the pending write events queue can be cleared safely and when we start threads
// again we do not get new events until after initialize resets the subhals.
disableAllSensors();
// Clears the queue if any events were pending write before.
mPendingWriteEventsQueue = std::queue<std::pair<std::vector<V2_1::Event>, size_t>>();
mSizePendingWriteEventsQueue = 0;
// Clears previously connected dynamic sensors
mDynamicSensors.clear();
mDynamicSensorsCallback = sensorsCallback;
// Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
mEventQueue = std::move(eventQueue);
// Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
// events have been successfully read and handled by the framework.
mWakeLockQueue = std::move(wakeLockQueue);
if (mEventQueueFlag != nullptr) {
EventFlag::deleteEventFlag(&mEventQueueFlag);
}
if (mWakelockQueueFlag != nullptr) {
EventFlag::deleteEventFlag(&mWakelockQueueFlag);
}
if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
result = Result::BAD_VALUE;
}
if (EventFlag::createEventFlag(mWakeLockQueue->getEventFlagWord(), &mWakelockQueueFlag) != OK) {
result = Result::BAD_VALUE;
}
if (!mDynamicSensorsCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
result = Result::BAD_VALUE;
}
mThreadsRun.store(true);
mPendingWritesThread = std::thread(startPendingWritesThread, this);
mWakelockThread = std::thread(startWakelockThread, this);
for (size_t i = 0; i < mSubHalList.size(); i++) {
Result currRes = mSubHalList[i]->initialize(this, this, i);
if (currRes != Result::OK) {
result = currRes;
ALOGE("Subhal '%s' failed to initialize with reason %" PRId32 ".",
mSubHalList[i]->getName().c_str(), static_cast<int32_t>(currRes));
}
}
mCurrentOperationMode = OperationMode::NORMAL;
return result;
}
Return<Result> HalProxy::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
int64_t maxReportLatencyNs) {
if (!isSubHalIndexValid(sensorHandle)) {
return Result::BAD_VALUE;
}
return getSubHalForSensorHandle(sensorHandle)
->batch(clearSubHalIndex(sensorHandle), samplingPeriodNs, maxReportLatencyNs);
}
Return<Result> HalProxy::flush(int32_t sensorHandle) {
if (!isSubHalIndexValid(sensorHandle)) {
return Result::BAD_VALUE;
}
return getSubHalForSensorHandle(sensorHandle)->flush(clearSubHalIndex(sensorHandle));
}
Return<Result> HalProxy::injectSensorData_2_1(const V2_1::Event& event) {
return injectSensorData(convertToOldEvent(event));
}
Return<Result> HalProxy::injectSensorData(const V1_0::Event& event) {
Result result = Result::OK;
if (mCurrentOperationMode == OperationMode::NORMAL &&
event.sensorType != V1_0::SensorType::ADDITIONAL_INFO) {
ALOGE("An event with type != ADDITIONAL_INFO passed to injectSensorData while operation"
" mode was NORMAL.");
result = Result::BAD_VALUE;
}
if (result == Result::OK) {
V1_0::Event subHalEvent = event;
if (!isSubHalIndexValid(event.sensorHandle)) {
return Result::BAD_VALUE;
}
subHalEvent.sensorHandle = clearSubHalIndex(event.sensorHandle);
result = getSubHalForSensorHandle(event.sensorHandle)
->injectSensorData(convertToNewEvent(subHalEvent));
}
return result;
}
Return<void> HalProxy::registerDirectChannel(const SharedMemInfo& mem,
ISensorsV2_0::registerDirectChannel_cb _hidl_cb) {
if (mDirectChannelSubHal == nullptr) {
_hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
} else {
mDirectChannelSubHal->registerDirectChannel(mem, _hidl_cb);
}
return Return<void>();
}
Return<Result> HalProxy::unregisterDirectChannel(int32_t channelHandle) {
Result result;
if (mDirectChannelSubHal == nullptr) {
result = Result::INVALID_OPERATION;
} else {
result = mDirectChannelSubHal->unregisterDirectChannel(channelHandle);
}
return result;
}
Return<void> HalProxy::configDirectReport(int32_t sensorHandle, int32_t channelHandle,
RateLevel rate,
ISensorsV2_0::configDirectReport_cb _hidl_cb) {
if (mDirectChannelSubHal == nullptr) {
_hidl_cb(Result::INVALID_OPERATION, -1 /* reportToken */);
} else if (sensorHandle == -1 && rate != RateLevel::STOP) {
_hidl_cb(Result::BAD_VALUE, -1 /* reportToken */);
} else {
// -1 denotes all sensors should be disabled
if (sensorHandle != -1) {
sensorHandle = clearSubHalIndex(sensorHandle);
}
mDirectChannelSubHal->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
}
return Return<void>();
}
Return<void> HalProxy::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
ALOGE("%s: missing fd for writing", __FUNCTION__);
return Void();
}
int writeFd = fd->data[0];
std::ostringstream stream;
stream << "===HalProxy===" << std::endl;
stream << "Internal values:" << std::endl;
stream << " Threads are running: " << (mThreadsRun.load() ? "true" : "false") << std::endl;
int64_t now = getTimeNow();
stream << " Wakelock timeout start time: " << msFromNs(now - mWakelockTimeoutStartTime)
<< " ms ago" << std::endl;
stream << " Wakelock timeout reset time: " << msFromNs(now - mWakelockTimeoutResetTime)
<< " ms ago" << std::endl;
// TODO(b/142969448): Add logging for history of wakelock acquisition per subhal.
stream << " Wakelock ref count: " << mWakelockRefCount << std::endl;
stream << " # of events on pending write writes queue: " << mSizePendingWriteEventsQueue
<< std::endl;
stream << " Most events seen on pending write events queue: "
<< mMostEventsObservedPendingWriteEventsQueue << std::endl;
if (!mPendingWriteEventsQueue.empty()) {
stream << " Size of events list on front of pending writes queue: "
<< mPendingWriteEventsQueue.front().first.size() << std::endl;
}
stream << " # of non-dynamic sensors across all subhals: " << mSensors.size() << std::endl;
stream << " # of dynamic sensors across all subhals: " << mDynamicSensors.size() << std::endl;
stream << "SubHals (" << mSubHalList.size() << "):" << std::endl;
for (auto& subHal : mSubHalList) {
stream << " Name: " << subHal->getName() << std::endl;
stream << " Debug dump: " << std::endl;
android::base::WriteStringToFd(stream.str(), writeFd);
subHal->debug(fd, args);
stream.str("");
stream << std::endl;
}
android::base::WriteStringToFd(stream.str(), writeFd);
return Return<void>();
}
Return<void> HalProxy::onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dynamicSensorsAdded,
int32_t subHalIndex) {
std::vector<SensorInfo> sensors;
{
std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
for (SensorInfo sensor : dynamicSensorsAdded) {
if (!subHalIndexIsClear(sensor.sensorHandle)) {
ALOGE("Dynamic sensor added %s had sensorHandle with first byte not 0.",
sensor.name.c_str());
} else {
sensor.sensorHandle = setSubHalIndex(sensor.sensorHandle, subHalIndex);
mDynamicSensors[sensor.sensorHandle] = sensor;
sensors.push_back(sensor);
}
}
}
mDynamicSensorsCallback->onDynamicSensorsConnected(sensors);
return Return<void>();
}
Return<void> HalProxy::onDynamicSensorsDisconnected(
const hidl_vec<int32_t>& dynamicSensorHandlesRemoved, int32_t subHalIndex) {
// TODO(b/143302327): Block this call until all pending events are flushed from queue
std::vector<int32_t> sensorHandles;
{
std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
for (int32_t sensorHandle : dynamicSensorHandlesRemoved) {
if (!subHalIndexIsClear(sensorHandle)) {
ALOGE("Dynamic sensorHandle removed had first byte not 0.");
} else {
sensorHandle = setSubHalIndex(sensorHandle, subHalIndex);
if (mDynamicSensors.find(sensorHandle) != mDynamicSensors.end()) {
mDynamicSensors.erase(sensorHandle);
sensorHandles.push_back(sensorHandle);
}
}
}
}
mDynamicSensorsCallback->onDynamicSensorsDisconnected(sensorHandles);
return Return<void>();
}
void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
std::ifstream subHalConfigStream(configFileName);
if (!subHalConfigStream) {
ALOGE("Failed to load subHal config file: %s", configFileName);
} else {
std::string subHalLibraryFile;
while (subHalConfigStream >> subHalLibraryFile) {
void* handle = getHandleForSubHalSharedObject(subHalLibraryFile);
if (handle == nullptr) {
ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str());
} else {
SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
(SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
if (sensorsHalGetSubHalPtr != nullptr) {
std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
*sensorsHalGetSubHalPtr;
uint32_t version;
ISensorsSubHalV2_0* subHal = sensorsHalGetSubHal(&version);
if (version != SUB_HAL_2_0_VERSION) {
ALOGE("SubHal version was not 2.0 for library: %s",
subHalLibraryFile.c_str());
} else {
ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
mSubHalList.push_back(std::make_unique<SubHalWrapperV2_0>(subHal));
}
} else {
SensorsHalGetSubHalV2_1Func* getSubHalV2_1Ptr =
(SensorsHalGetSubHalV2_1Func*)dlsym(handle, "sensorsHalGetSubHal_2_1");
if (getSubHalV2_1Ptr == nullptr) {
ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s",
subHalLibraryFile.c_str());
} else {
std::function<SensorsHalGetSubHalV2_1Func> sensorsHalGetSubHal_2_1 =
*getSubHalV2_1Ptr;
uint32_t version;
ISensorsSubHalV2_1* subHal = sensorsHalGetSubHal_2_1(&version);
if (version != SUB_HAL_2_1_VERSION) {
ALOGE("SubHal version was not 2.1 for library: %s",
subHalLibraryFile.c_str());
} else {
ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
mSubHalList.push_back(std::make_unique<SubHalWrapperV2_1>(subHal));
}
}
}
}
}
}
}
void HalProxy::initializeSensorList() {
for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
auto result = mSubHalList[subHalIndex]->getSensorsList([&](const auto& list) {
for (SensorInfo sensor : list) {
if (!subHalIndexIsClear(sensor.sensorHandle)) {
ALOGE("SubHal sensorHandle's first byte was not 0");
} else {
ALOGV("Loaded sensor: %s", sensor.name.c_str());
sensor.sensorHandle = setSubHalIndex(sensor.sensorHandle, subHalIndex);
setDirectChannelFlags(&sensor, mSubHalList[subHalIndex]);
bool keep = patchOplusPickupSensor(sensor) && patchOplusGlanceSensor(sensor);
if (!keep) {
continue;
}
mSensors[sensor.sensorHandle] = sensor;
}
}
});
if (!result.isOk()) {
ALOGE("getSensorsList call failed for SubHal: %s",
mSubHalList[subHalIndex]->getName().c_str());
}
}
}
void* HalProxy::getHandleForSubHalSharedObject(const std::string& filename) {
static const std::string kSubHalShareObjectLocations[] = {
"", // Default locations will be searched
#ifdef __LP64__
"/vendor/lib64/hw/", "/odm/lib64/hw/"
#else
"/vendor/lib/hw/", "/odm/lib/hw/"
#endif
};
for (const std::string& dir : kSubHalShareObjectLocations) {
void* handle = dlopen((dir + filename).c_str(), RTLD_NOW);
if (handle != nullptr) {
return handle;
}
}
return nullptr;
}
void HalProxy::init() {
initializeSensorList();
}
void HalProxy::stopThreads() {
mThreadsRun.store(false);
if (mEventQueueFlag != nullptr && mEventQueue != nullptr) {
size_t numToRead = mEventQueue->availableToRead();
std::vector<Event> events(numToRead);
mEventQueue->read(events.data(), numToRead);
mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::EVENTS_READ));
}
if (mWakelockQueueFlag != nullptr && mWakeLockQueue != nullptr) {
uint32_t kZero = 0;
mWakeLockQueue->write(&kZero);
mWakelockQueueFlag->wake(static_cast<uint32_t>(WakeLockQueueFlagBits::DATA_WRITTEN));
}
mWakelockCV.notify_one();
mEventQueueWriteCV.notify_one();
if (mPendingWritesThread.joinable()) {
mPendingWritesThread.join();
}
if (mWakelockThread.joinable()) {
mWakelockThread.join();
}
}
void HalProxy::disableAllSensors() {
for (const auto& sensorEntry : mSensors) {
int32_t sensorHandle = sensorEntry.first;
activate(sensorHandle, false /* enabled */);
}
std::lock_guard<std::mutex> dynamicSensorsLock(mDynamicSensorsMutex);
for (const auto& sensorEntry : mDynamicSensors) {
int32_t sensorHandle = sensorEntry.first;
activate(sensorHandle, false /* enabled */);
}
}
void HalProxy::startPendingWritesThread(HalProxy* halProxy) {
halProxy->handlePendingWrites();
}
void HalProxy::handlePendingWrites() {
// TODO(b/143302327): Find a way to optimize locking strategy maybe using two mutexes instead of
// one.
std::unique_lock<std::mutex> lock(mEventQueueWriteMutex);
while (mThreadsRun.load()) {
mEventQueueWriteCV.wait(
lock, [&] { return !mPendingWriteEventsQueue.empty() || !mThreadsRun.load(); });
if (mThreadsRun.load()) {
std::vector<Event>& pendingWriteEvents = mPendingWriteEventsQueue.front().first;
size_t numWakeupEvents = mPendingWriteEventsQueue.front().second;
size_t eventQueueSize = mEventQueue->getQuantumCount();
size_t numToWrite = std::min(pendingWriteEvents.size(), eventQueueSize);
lock.unlock();
if (!mEventQueue->writeBlocking(
pendingWriteEvents.data(), numToWrite,
static_cast<uint32_t>(EventQueueFlagBits::EVENTS_READ),
static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS),
kPendingWriteTimeoutNs, mEventQueueFlag)) {
ALOGE("Dropping %zu events after blockingWrite failed.", numToWrite);
if (numWakeupEvents > 0) {
if (pendingWriteEvents.size() > eventQueueSize) {
decrementRefCountAndMaybeReleaseWakelock(
countNumWakeupEvents(pendingWriteEvents, eventQueueSize));
} else {
decrementRefCountAndMaybeReleaseWakelock(numWakeupEvents);
}
}
}
lock.lock();
mSizePendingWriteEventsQueue -= numToWrite;
if (pendingWriteEvents.size() > eventQueueSize) {
// TODO(b/143302327): Check if this erase operation is too inefficient. It will copy
// all the events ahead of it down to fill gap off array at front after the erase.
pendingWriteEvents.erase(pendingWriteEvents.begin(),
pendingWriteEvents.begin() + eventQueueSize);
} else {
mPendingWriteEventsQueue.pop();
}
}
}
}
void HalProxy::startWakelockThread(HalProxy* halProxy) {
halProxy->handleWakelocks();
}
void HalProxy::handleWakelocks() {
std::unique_lock<std::recursive_mutex> lock(mWakelockMutex);
while (mThreadsRun.load()) {
mWakelockCV.wait(lock, [&] { return mWakelockRefCount > 0 || !mThreadsRun.load(); });
if (mThreadsRun.load()) {
int64_t timeLeft;
if (sharedWakelockDidTimeout(&timeLeft)) {
resetSharedWakelock();
} else {
uint32_t numWakeLocksProcessed;
lock.unlock();
bool success = mWakeLockQueue->readBlocking(
&numWakeLocksProcessed, 1, 0,
static_cast<uint32_t>(WakeLockQueueFlagBits::DATA_WRITTEN), timeLeft);
lock.lock();
if (success) {
decrementRefCountAndMaybeReleaseWakelock(
static_cast<size_t>(numWakeLocksProcessed));
}
}
}
}
resetSharedWakelock();
}
bool HalProxy::sharedWakelockDidTimeout(int64_t* timeLeft) {
bool didTimeout;
int64_t duration = getTimeNow() - mWakelockTimeoutStartTime;
if (duration > kWakelockTimeoutNs) {
didTimeout = true;
} else {
didTimeout = false;
*timeLeft = kWakelockTimeoutNs - duration;
}
return didTimeout;
}
void HalProxy::resetSharedWakelock() {
std::lock_guard<std::recursive_mutex> lockGuard(mWakelockMutex);
decrementRefCountAndMaybeReleaseWakelock(mWakelockRefCount);
mWakelockTimeoutResetTime = getTimeNow();
}
void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events, size_t numWakeupEvents,
V2_0::implementation::ScopedWakelock wakelock) {
size_t numToWrite = 0;
std::lock_guard<std::mutex> lock(mEventQueueWriteMutex);
if (wakelock.isLocked()) {
incrementRefCountAndMaybeAcquireWakelock(numWakeupEvents);
}
if (mPendingWriteEventsQueue.empty()) {
numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
if (numToWrite > 0) {
if (mEventQueue->write(events.data(), numToWrite)) {
// TODO(b/143302327): While loop if mEventQueue->avaiableToWrite > 0 to possibly fit
// in more writes immediately
mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
} else {
numToWrite = 0;
}
}
}
size_t numLeft = events.size() - numToWrite;
if (numToWrite < events.size() &&
mSizePendingWriteEventsQueue + numLeft <= kMaxSizePendingWriteEventsQueue) {
std::vector<Event> eventsLeft(events.begin() + numToWrite, events.end());
mPendingWriteEventsQueue.push({eventsLeft, numWakeupEvents});
mSizePendingWriteEventsQueue += numLeft;
mMostEventsObservedPendingWriteEventsQueue =
std::max(mMostEventsObservedPendingWriteEventsQueue, mSizePendingWriteEventsQueue);
mEventQueueWriteCV.notify_one();
}
}
bool HalProxy::incrementRefCountAndMaybeAcquireWakelock(size_t delta,
int64_t* timeoutStart /* = nullptr */) {
if (!mThreadsRun.load()) return false;
std::lock_guard<std::recursive_mutex> lockGuard(mWakelockMutex);
if (mWakelockRefCount == 0) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakelockName);
mWakelockCV.notify_one();
}
mWakelockTimeoutStartTime = getTimeNow();
mWakelockRefCount += delta;
if (timeoutStart != nullptr) {
*timeoutStart = mWakelockTimeoutStartTime;
}
return true;
}
void HalProxy::decrementRefCountAndMaybeReleaseWakelock(size_t delta,
int64_t timeoutStart /* = -1 */) {
if (!mThreadsRun.load()) return;
std::lock_guard<std::recursive_mutex> lockGuard(mWakelockMutex);
if (delta > mWakelockRefCount) {
ALOGE("Decrementing wakelock ref count by %zu when count is %zu",
delta, mWakelockRefCount);
}
if (timeoutStart == -1) timeoutStart = mWakelockTimeoutResetTime;
if (mWakelockRefCount == 0 || timeoutStart < mWakelockTimeoutResetTime) return;
mWakelockRefCount -= std::min(mWakelockRefCount, delta);
if (mWakelockRefCount == 0) {
release_wake_lock(kWakelockName);
}
}
void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo,
std::shared_ptr<ISubHalWrapperBase> subHal) {
bool sensorSupportsDirectChannel =
(sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0;
if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) {
mDirectChannelSubHal = subHal;
} else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) {
// disable direct channel capability for sensors in subHals that are not
// the only one we will enable
sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
}
}
std::shared_ptr<ISubHalWrapperBase> HalProxy::getSubHalForSensorHandle(int32_t sensorHandle) {
return mSubHalList[extractSubHalIndex(sensorHandle)];
}
bool HalProxy::isSubHalIndexValid(int32_t sensorHandle) {
return extractSubHalIndex(sensorHandle) < mSubHalList.size();
}
size_t HalProxy::countNumWakeupEvents(const std::vector<Event>& events, size_t n) {
size_t numWakeupEvents = 0;
for (size_t i = 0; i < n; i++) {
int32_t sensorHandle = events[i].sensorHandle;
if (mSensors[sensorHandle].flags & static_cast<uint32_t>(V1_0::SensorFlagBits::WAKE_UP)) {
numWakeupEvents++;
}
}
return numWakeupEvents;
}
int32_t HalProxy::clearSubHalIndex(int32_t sensorHandle) {
return sensorHandle & (~kSensorHandleSubHalIndexMask);
}
bool HalProxy::subHalIndexIsClear(int32_t sensorHandle) {
return (sensorHandle & kSensorHandleSubHalIndexMask) == 0;
}
} // namespace implementation
} // namespace V2_1
} // namespace sensors
} // namespace hardware
} // namespace android

View File

@@ -1,109 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "HalProxyCallback.h"
#include <cinttypes>
#include <fstream>
namespace android {
namespace hardware {
namespace sensors {
namespace V2_0 {
namespace implementation {
static constexpr int32_t kBitsAfterSubHalIndex = 24;
/**
* Set the subhal index as first byte of sensor handle and return this modified version.
*
* @param sensorHandle The sensor handle to modify.
* @param subHalIndex The index in the hal proxy of the sub hal this sensor belongs to.
*
* @return The modified sensor handle.
*/
int32_t setSubHalIndex(int32_t sensorHandle, size_t subHalIndex) {
return sensorHandle | (static_cast<int32_t>(subHalIndex) << kBitsAfterSubHalIndex);
}
void HalProxyCallbackBase::postEvents(const std::vector<V2_1::Event>& events,
ScopedWakelock wakelock) {
if (events.empty() || !mCallback->areThreadsRunning()) return;
size_t numWakeupEvents;
std::vector<V2_1::Event> processedEvents = processEvents(events, &numWakeupEvents);
if (numWakeupEvents > 0) {
ALOG_ASSERT(wakelock.isLocked(),
"Wakeup events posted while wakelock unlocked for subhal"
" w/ index %" PRId32 ".",
mSubHalIndex);
} else {
ALOG_ASSERT(!wakelock.isLocked(),
"No Wakeup events posted but wakelock locked for subhal"
" w/ index %" PRId32 ".",
mSubHalIndex);
}
mCallback->postEventsToMessageQueue(processedEvents, numWakeupEvents, std::move(wakelock));
}
ScopedWakelock HalProxyCallbackBase::createScopedWakelock(bool lock) {
ScopedWakelock wakelock(mRefCounter, lock);
return wakelock;
}
std::vector<V2_1::Event> HalProxyCallbackBase::processEvents(const std::vector<V2_1::Event>& events,
size_t* numWakeupEvents) const {
*numWakeupEvents = 0;
std::vector<V2_1::Event> eventsOut;
const char* aodLightModeNode = "/sys/kernel/oplus_display/aod_light_mode_set";
for (V2_1::Event event : events) {
event.sensorHandle = setSubHalIndex(event.sensorHandle, mSubHalIndex);
if (event.sensorType == V2_1::SensorType::DYNAMIC_SENSOR_META) {
event.u.dynamic.sensorHandle =
setSubHalIndex(event.u.dynamic.sensorHandle, mSubHalIndex);
}
const V2_1::SensorInfo& sensor = mCallback->getSensorInfo(event.sensorHandle);
if (sensor.type == V2_1::SensorType::GLANCE_GESTURE
&& event.u.scalar != 2) {
continue;
}
if (sensor.type == V2_1::SensorType::PICK_UP_GESTURE
&& event.u.scalar != 0) {
continue;
}
if (sensor.typeAsString == "qti.sensor.lux_aod") {
std::ofstream nodeFile(aodLightModeNode);
if (nodeFile.is_open()) {
nodeFile << !event.u.scalar;
nodeFile.close();
}
}
if ((sensor.flags & V1_0::SensorFlagBits::WAKE_UP) != 0) {
(*numWakeupEvents)++;
}
eventsOut.push_back(event);
}
return eventsOut;
}
} // namespace implementation
} // namespace V2_0
} // namespace sensors
} // namespace hardware
} // namespace android

View File

@@ -1,10 +0,0 @@
on boot
chmod 666 /sys/kernel/oplus_display/aod_light_mode_set
service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.oplus-multihal
class hal
user system
group system wakelock context_hub input uhid
task_profiles ServiceCapacityLow
capabilities BLOCK_SUSPEND
rlimit rtprio 10 10

View File

@@ -1,23 +0,0 @@
<!--
~ Copyright (C) 2021 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.sensors</name>
<version>2</version>
<fqname>ISensors/default</fqname>
</hal>
</manifest>

View File

@@ -1,36 +0,0 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include "HalProxyAidl.h"
using ::aidl::android::hardware::sensors::implementation::HalProxyAidl;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
// Make a default multihal sensors service
auto halProxy = ndk::SharedRefBase::make<HalProxyAidl>();
const std::string halProxyName = std::string() + HalProxyAidl::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(halProxy->asBinder().get(), halProxyName.c_str());
CHECK_EQ(status, STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,61 +0,0 @@
//
// SPDX-FileCopyrightText: 2025 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
cc_binary {
name: "vendor.lineage.touch-service.oplus",
init_rc: ["vendor.lineage.touch-service.oplus.rc"],
vintf_fragments: select(soong_config_variable("OPLUS_LINEAGE_TOUCH_HAL", "ENABLE_GM"), {
"true": ["vendor.lineage.touch-service.oplus-gm.xml"],
default: [],
}) + select(soong_config_variable("OPLUS_LINEAGE_TOUCH_HAL", "ENABLE_HTPR"), {
"false": [],
default: ["vendor.lineage.touch-service.oplus-htpr.xml"],
}) + select(soong_config_variable("OPLUS_LINEAGE_TOUCH_HAL", "ENABLE_TG"), {
"false": [],
default: ["vendor.lineage.touch-service.oplus-tg.xml"],
}),
vendor: true,
relative_install_path: "hw",
srcs: [
"GloveMode.cpp",
"HighTouchPollingRate.cpp",
"TouchscreenGesture.cpp",
"service.cpp",
],
header_libs: [
"vendor.oplus.hardware.touch-headers",
],
shared_libs: [
"libbase",
"liblog",
"libbinder_ndk",
"libutils",
"vendor.lineage.touch-V1-ndk",
"vendor.oplus.hardware.touch-V2-ndk",
],
include_dirs: select(soong_config_variable("OPLUS_LINEAGE_TOUCH_HAL", "INCLUDE_DIR"), {
any @ flag_val: [flag_val],
default: [],
}),
cflags: select(soong_config_variable("OPLUS_LINEAGE_TOUCH_HAL", "ENABLE_GM"), {
"true": ["-DENABLE_GM=true"],
default: ["-DENABLE_GM=false"],
}) + select(soong_config_variable("OPLUS_LINEAGE_TOUCH_HAL", "ENABLE_HTPR"), {
"false": ["-DENABLE_HTPR=false"],
default: ["-DENABLE_HTPR=true"],
}) + select(soong_config_variable("OPLUS_LINEAGE_TOUCH_HAL", "ENABLE_TG"), {
"false": ["-DENABLE_TG=false"],
default: ["-DENABLE_TG=true"],
}) + select(soong_config_variable("OPLUS_LINEAGE_TOUCH_HAL", "USE_OPLUSTOUCH"), {
"true": ["-DUSE_OPLUSTOUCH=true"],
default: ["-DUSE_OPLUSTOUCH=false"],
}),
}
cc_library_headers {
name: "vendor.oplus.hardware.touch-headers",
vendor_available: true,
export_include_dirs: ["touch-headers"],
}

View File

@@ -1,63 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "vendor.lineage.touch-service.oplus"
#include "GloveMode.h"
#include <android-base/file.h>
#include <android-base/logging.h>
#include <OplusTouchConstants.h>
using ::android::base::ReadFileToString;
using ::android::base::WriteStringToFile;
namespace {
constexpr const char* kGloveModeEnablePath = "/proc/touchpanel/glove_mode_enable";
} // anonymous namespace
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
GloveMode::GloveMode(std::shared_ptr<IOplusTouch> oplusTouch)
: mOplusTouch(std::move(oplusTouch)) {}
ndk::ScopedAStatus GloveMode::getEnabled(bool* _aidl_return) {
std::string value;
if (mOplusTouch) {
mOplusTouch->touchReadNodeFile(OplusTouchConstants::DEFAULT_TP_IC_ID,
OplusTouchConstants::GLOVE_MODE_ENABLE_NODE, &value);
} else if (!ReadFileToString(kGloveModeEnablePath, &value)) {
LOG(ERROR) << "Failed to read current GloveMode state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = value[0] != '0';
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus GloveMode::setEnabled(bool enable) {
if (mOplusTouch) {
mOplusTouch->touchWriteNodeFileOneWay(OplusTouchConstants::DEFAULT_TP_IC_ID,
OplusTouchConstants::GLOVE_MODE_ENABLE_NODE,
enable ? "1" : "0");
} else if (!WriteStringToFile(enable ? "1" : "0", kGloveModeEnablePath, true)) {
LOG(ERROR) << "Failed to write GloveMode state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
return ndk::ScopedAStatus::ok();
}
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,32 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/touch/BnGloveMode.h>
#include <aidl/vendor/oplus/hardware/touch/IOplusTouch.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
using aidl::vendor::oplus::hardware::touch::IOplusTouch;
class GloveMode : public BnGloveMode {
public:
explicit GloveMode(std::shared_ptr<IOplusTouch> oplusTouch);
ndk::ScopedAStatus getEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enabled) override;
private:
std::shared_ptr<IOplusTouch> mOplusTouch;
};
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,63 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "vendor.lineage.touch-service.oplus"
#include "HighTouchPollingRate.h"
#include <android-base/file.h>
#include <android-base/logging.h>
#include <OplusTouchConstants.h>
using ::android::base::ReadFileToString;
using ::android::base::WriteStringToFile;
namespace {
constexpr const char* kGameSwitchEnablePath = "/proc/touchpanel/game_switch_enable";
} // anonymous namespace
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
HighTouchPollingRate::HighTouchPollingRate(std::shared_ptr<IOplusTouch> oplusTouch)
: mOplusTouch(std::move(oplusTouch)) {}
ndk::ScopedAStatus HighTouchPollingRate::getEnabled(bool* _aidl_return) {
std::string value;
if (mOplusTouch) {
mOplusTouch->touchReadNodeFile(OplusTouchConstants::DEFAULT_TP_IC_ID,
OplusTouchConstants::GAME_SWITCH_ENABLE_NODE, &value);
} else if (!ReadFileToString(kGameSwitchEnablePath, &value)) {
LOG(ERROR) << "Failed to read current HighTouchPollingRate state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
*_aidl_return = value[0] != '0';
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus HighTouchPollingRate::setEnabled(bool enable) {
if (mOplusTouch) {
mOplusTouch->touchWriteNodeFileOneWay(OplusTouchConstants::DEFAULT_TP_IC_ID,
OplusTouchConstants::GAME_SWITCH_ENABLE_NODE,
enable ? "1" : "0");
} else if (!WriteStringToFile(enable ? "1" : "0", kGameSwitchEnablePath, true)) {
LOG(ERROR) << "Failed to write HighTouchPollingRate state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
return ndk::ScopedAStatus::ok();
}
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,32 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <aidl/vendor/lineage/touch/BnHighTouchPollingRate.h>
#include <aidl/vendor/oplus/hardware/touch/IOplusTouch.h>
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
using aidl::vendor::oplus::hardware::touch::IOplusTouch;
class HighTouchPollingRate : public BnHighTouchPollingRate {
public:
explicit HighTouchPollingRate(std::shared_ptr<IOplusTouch> oplusTouch);
ndk::ScopedAStatus getEnabled(bool* _aidl_return) override;
ndk::ScopedAStatus setEnabled(bool enabled) override;
private:
std::shared_ptr<IOplusTouch> mOplusTouch;
};
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,80 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "vendor.lineage.touch-service.oplus"
#include <android-base/file.h>
#include <android-base/strings.h>
#include <OplusTouchConstants.h>
#include <TouchscreenGestureConfig.h>
using ::android::base::ReadFileToString;
using ::android::base::Trim;
using ::android::base::WriteStringToFile;
namespace {
constexpr const char* kGestureEnableIndepPath = "/proc/touchpanel/double_tap_enable_indep";
} // anonymous namespace
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
TouchscreenGesture::TouchscreenGesture(std::shared_ptr<IOplusTouch> oplusTouch)
: mOplusTouch(std::move(oplusTouch)) {}
ndk::ScopedAStatus TouchscreenGesture::getSupportedGestures(std::vector<Gesture>* _aidl_return) {
std::vector<Gesture> gestures;
for (const auto& [id, name] : kGestureNames) {
if (kSupportedGestures & (1 << id)) {
gestures.push_back({static_cast<int>(gestures.size()), name, kGestureStartKey + id});
}
}
*_aidl_return = gestures;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus TouchscreenGesture::setGestureEnabled(const Gesture& gesture, bool enabled) {
int contents = 0;
if (std::string tmp; mOplusTouch) {
mOplusTouch->touchReadNodeFile(OplusTouchConstants::DEFAULT_TP_IC_ID,
OplusTouchConstants::DOUBLE_TAP_INDEP_NODE, &tmp);
contents = std::stoi(tmp, nullptr, 16);
} else if (ReadFileToString(kGestureEnableIndepPath, &tmp)) {
contents = std::stoi(Trim(tmp), nullptr, 16);
} else {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
if (enabled) {
contents |= (1 << (gesture.keycode - kGestureStartKey));
} else {
contents &= ~(1 << (gesture.keycode - kGestureStartKey));
}
if (mOplusTouch) {
mOplusTouch->touchWriteNodeFileOneWay(OplusTouchConstants::DEFAULT_TP_IC_ID,
OplusTouchConstants::DOUBLE_TAP_ENABLE_NODE, "1");
mOplusTouch->touchWriteNodeFileOneWay(OplusTouchConstants::DEFAULT_TP_IC_ID,
OplusTouchConstants::DOUBLE_TAP_INDEP_NODE,
std::to_string(contents));
} else if (!WriteStringToFile(std::to_string(contents), kGestureEnableIndepPath, true)) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
return ndk::ScopedAStatus::ok();
}
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,23 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "TouchscreenGesture.h"
namespace aidl {
namespace vendor {
namespace lineage {
namespace touch {
const int TouchscreenGesture::kSupportedGestures = makeBitField(
kGestureUpVee, kGestureDownVee, kGestureLeftVee, kGestureRightVee, kGestureCircle,
kGestureDoubleSwipe, kGestureLeftToRight, kGestureRightToLeft, kGestureUpToDown,
kGestureDownToUp, kGestureM, kGestureW, kGestureSingleTap, kGestureS);
} // namespace touch
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

@@ -1,60 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_TAG "vendor.lineage.touch-service.oplus"
#include "GloveMode.h"
#include "HighTouchPollingRate.h"
#include "TouchscreenGesture.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using aidl::vendor::lineage::touch::GloveMode;
using aidl::vendor::lineage::touch::HighTouchPollingRate;
using aidl::vendor::lineage::touch::TouchscreenGesture;
using aidl::vendor::oplus::hardware::touch::IOplusTouch;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
const std::string instance = std::string() + IOplusTouch::descriptor + "/default";
std::shared_ptr<IOplusTouch> oplusTouch =
USE_OPLUSTOUCH ? IOplusTouch::fromBinder(ndk::SpAIBinder(
AServiceManager_waitForService(instance.c_str())))
: nullptr;
std::shared_ptr<GloveMode> gm =
ENABLE_GM ? ndk::SharedRefBase::make<GloveMode>(oplusTouch) : nullptr;
std::shared_ptr<HighTouchPollingRate> htpr =
ENABLE_HTPR ? ndk::SharedRefBase::make<HighTouchPollingRate>(oplusTouch) : nullptr;
std::shared_ptr<TouchscreenGesture> tg =
ENABLE_TG ? ndk::SharedRefBase::make<TouchscreenGesture>(oplusTouch) : nullptr;
if (gm) {
const std::string instance = std::string(GloveMode::descriptor) + "/default";
const binder_status_t status =
AServiceManager_addService(gm->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status;
}
if (htpr) {
const std::string instance = std::string(HighTouchPollingRate::descriptor) + "/default";
const binder_status_t status =
AServiceManager_addService(htpr->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status;
}
if (tg) {
const std::string instance = std::string(TouchscreenGesture::descriptor) + "/default";
const binder_status_t status =
AServiceManager_addService(tg->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status;
}
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

View File

@@ -1,23 +0,0 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
namespace OplusTouchConstants {
// Device IDs
constexpr int DEFAULT_TP_IC_ID = 0;
constexpr int SUB_DISPLAY_TP_IC_ID = 1;
// Features
constexpr int DOUBLE_TAP_GESTURE = 1 << 1;
// Node IDs
constexpr int DOUBLE_TAP_ENABLE_NODE = 1;
constexpr int DOUBLE_TAP_INDEP_NODE = 21;
constexpr int GAME_SWITCH_ENABLE_NODE = 26;
constexpr int GLOVE_MODE_ENABLE_NODE = 192;
} // namespace OplusTouchConstants

View File

@@ -1,7 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.lineage.touch</name>
<version>1</version>
<fqname>IGloveMode/default</fqname>
</hal>
</manifest>

View File

@@ -1,7 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.lineage.touch</name>
<version>1</version>
<fqname>IHighTouchPollingRate/default</fqname>
</hal>
</manifest>

View File

@@ -1,7 +0,0 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>vendor.lineage.touch</name>
<version>1</version>
<fqname>ITouchscreenGesture/default</fqname>
</hal>
</manifest>

View File

@@ -1,4 +0,0 @@
service vendor.touch-hal /vendor/bin/hw/vendor.lineage.touch-service.oplus
class hal
user system
group system

76
aidl/vibrator/Android.bp Normal file
View File

@@ -0,0 +1,76 @@
Common_CFlags = ["-Wall"]
Common_CFlags += ["-Werror"]
soong_config_module_type {
name: "oplus_lineage_vibrator_hal_cc_defaults",
module_type: "cc_defaults",
config_namespace: "OPLUS_LINEAGE_VIBRATOR_HAL",
value_variables: ["INCLUDE_DIR"],
bool_variables: ["USE_EFFECT_STREAM"],
properties: [
"cflags",
"include_dirs",
"shared_libs",
],
}
oplus_lineage_vibrator_hal_cc_defaults {
name: "vibrator_effect_stream_defaults",
soong_config_variables: {
USE_EFFECT_STREAM: {
cflags: ["-DUSE_EFFECT_STREAM"],
shared_libs: ["liboplusvibratoreffect"],
},
},
}
oplus_lineage_vibrator_hal_cc_defaults {
name: "oplus_lineage_vibrator_effect_defaults",
soong_config_variables: {
INCLUDE_DIR: {
include_dirs: ["%s"],
},
},
}
cc_library_shared {
name: "vendor.qti.hardware.vibrator.impl.oplus",
defaults: [
"vibrator_effect_stream_defaults",
],
vendor: true,
cflags: Common_CFlags,
srcs: [
"Vibrator.cpp",
],
shared_libs: [
"libcutils",
"libutils",
"liblog",
"libbinder_ndk",
"android.hardware.vibrator-V1-ndk",
],
export_include_dirs: ["include"]
}
cc_binary {
name: "vendor.qti.hardware.vibrator.service.oplus",
vendor: true,
relative_install_path: "hw",
init_rc: ["vendor.qti.hardware.vibrator.service.oplus.rc"],
vintf_fragments: [
"vendor.qti.hardware.vibrator.service.oplus.xml",
],
cflags: Common_CFlags,
srcs: [
"service.cpp",
],
shared_libs: [
"libcutils",
"libutils",
"libbase",
"libbinder_ndk",
"android.hardware.vibrator-V1-ndk",
"vendor.qti.hardware.vibrator.impl.oplus",
],
}

View File

@@ -67,8 +67,6 @@ namespace vibrator {
#define MSM_CPU_CAPE 530
#define APQ_CPU_CAPE 531
#define MSM_CPU_KALAMA 519
#define MSM_CPU_PINEAPPLE 557
#define MSM_CPU_SUN 618
#define test_bit(bit, array) ((array)[(bit)/8] & (1<<((bit)%8)))
@@ -156,8 +154,6 @@ InputFFDevice::InputFFDevice()
case MSM_CPU_TARO:
case MSM_CPU_YUPIK:
case MSM_CPU_KALAMA:
case MSM_CPU_PINEAPPLE:
case MSM_CPU_SUN:
mSupportExternalControl = true;
break;
default:
@@ -396,7 +392,6 @@ int LedVibratorDevice::on(int32_t timeoutMs) {
ret |= write_value(LED_DEVICE "/duration", timeoutMs);
ret |= write_value(LED_DEVICE "/state", "1");
ret |= write_value(LED_DEVICE "/activate", "1");
usleep(100 * 1000);
ret |= write_value(LED_DEVICE "/activate", "0");
return ret;
@@ -404,9 +399,11 @@ int LedVibratorDevice::on(int32_t timeoutMs) {
int LedVibratorDevice::onWaveform(int waveformIndex) {
int ret = 0;
ret |= write_value(LED_DEVICE "/rtp", "0");
ret |= write_value(LED_DEVICE "/vmax", "1600");
ret |= write_value(LED_DEVICE "/waveform_index", waveformIndex);
ret |= write_value(LED_DEVICE "/brightness", "1");
ret |= write_value(LED_DEVICE "/rtp", "0");
return ret;
}
@@ -490,37 +487,50 @@ ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength es, const std
if (ledVib.mDetected) {
switch (effect) {
case Effect::CLICK:
ledVib.write_value(LED_DEVICE "/rtp", "0");
ledVib.write_value(LED_DEVICE "/vmax", "2500");
ledVib.write_value(LED_DEVICE "/waveform_index", "1");
ledVib.write_value(LED_DEVICE "/brightness", "1");
ledVib.write_value(LED_DEVICE "/rtp", "0");
break;
case Effect::DOUBLE_CLICK:
ledVib.write_value(LED_DEVICE "/rtp", "0");
ledVib.write_value(LED_DEVICE "/vmax", "2500");
ledVib.write_value(LED_DEVICE "/waveform_index", "1");
ledVib.write_value(LED_DEVICE "/brightness", "1");
ledVib.write_value(LED_DEVICE "/rtp", "0");
usleep(100 * 1000);
ledVib.write_value(LED_DEVICE "/rtp", "0");
ledVib.write_value(LED_DEVICE "/vmax", "2500");
ledVib.write_value(LED_DEVICE "/waveform_index", "1");
ledVib.write_value(LED_DEVICE "/brightness", "1");
ledVib.write_value(LED_DEVICE "/rtp", "0");
break;
case Effect::TICK:
ledVib.write_value(LED_DEVICE "/rtp", "0");
ledVib.write_value(LED_DEVICE "/vmax", "1400");
ledVib.write_value(LED_DEVICE "/waveform_index", "1");
ledVib.write_value(LED_DEVICE "/brightness", "1");
ledVib.write_value(LED_DEVICE "/rtp", "0");
break;
case Effect::HEAVY_CLICK:
ledVib.write_value(LED_DEVICE "/rtp", "0");
ledVib.write_value(LED_DEVICE "/vmax", "2500");
ledVib.write_value(LED_DEVICE "/waveform_index", "4");
ledVib.write_value(LED_DEVICE "/brightness", "1");
ledVib.write_value(LED_DEVICE "/rtp", "0");
break;
case Effect::TEXTURE_TICK:
ledVib.write_value(LED_DEVICE "/rtp", "0");
ledVib.write_value(LED_DEVICE "/vmax", "60");
ledVib.write_value(LED_DEVICE "/waveform_index", "2");
ledVib.write_value(LED_DEVICE "/brightness", "1");
ledVib.write_value(LED_DEVICE "/rtp", "0");
break;
default:
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
}
if (effect == Effect::DOUBLE_CLICK) {
ledVib.write_value(LED_DEVICE "/brightness", "1");
usleep(100 * 1000);
ledVib.write_value(LED_DEVICE "/brightness", "1");
} else {
ledVib.write_value(LED_DEVICE "/brightness", "1");
}
// Return magic value for play length so that we won't end up calling on() / off()
playLengthMs = 150;
} else {

View File

@@ -0,0 +1,12 @@
cc_library_shared {
name: "liboplusvibratoreffect",
defaults: ["oplus_lineage_vibrator_effect_defaults"],
vendor: true,
srcs: [
"effect.cpp",
],
shared_libs: [
"libcutils",
"libutils",
],
}

View File

@@ -27,107 +27,28 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Wly THUD as DOUBLE_CLICK */
static const int8_t effect_1[] = {
0, 5, 10, 15, 20, 25, 29, 34, 38, 43, 47, 51, 55, 58, 62,
65, 68, 70, 73, 75, 77, 78, 79, 80, 81, 81, 81, 81, 80, 79,
78, 77, 75, 73, 70, 68, 65, 62, 59, 55, 51, 47, 43, 39, 34,
30, 25, 20, 15, 10, 5, 0, -5, -10, -15, -19, -24, -29, -34, -38,
-42, -47, -51, -54, -58, -61, -65, -68, -70, -73, -75, -77, -78, -79, -80,
-81, -81, -81, -81, -80, -79, -78, -77, -75, -73, -71, -68, -65, -62, -59,
-55, -51, -47, -43, -39, -35, -30, -25, -20, -16, -11, -6, -1, 4, 9,
14, 19, 24, 29, 33, 38, 42, 46, 50, 54, 58, 61, 64, 67, 70,
72, 75, 76, 78, 79, 80, 81, 81, 81, 81, 80, 80, 78, 77, 75,
73, 71, 68, 65, 62, 59, 55, 52, 48, 44, 39, 35, 30, 26, 21,
16, 11, 6, 1, -4, -9, -14, -19, -24, -28, -33, -38, -42, -46, -50,
-54, -58, -61, -64, -67, -70, -72, -74, -76, -78, -79, -80, -81, -81, -81,
-81, -80, -80, -78, -77, -75, -73, -71, -68, -66, -62, -59, -56, -52, -48,
-44, -40, -35, -31, -26, -21, -16, -11, -6, -1, 4, 9, 14, 19, 23,
28, 33, 37, 42, 46, 50, 54, 57, 61, 64, 67, 70, 72, 74, 76,
78, 79, 80, 81, 81, 81, 81, 81, 80, 79, 77, 75, 73, 71, 69,
66, 63, 59, 56, 52, 48, 44, 40, 35, 31, 26, 21, 16, 12, 7,
2, -3, -8, -13, -18, -23, -28, -32, -37, -41, -46, -50, -54, -57, -61,
-64, -67, -70, -72, -74, -76, -78, -79, -80, -81, -81, -81, -81, -81, -80,
-79, -77, -76, -74, -71, -69, -66, -63, -60, -56, -52, -48, -44, -40, -36,
-31, -26, -22, -17, -12, -7, 0, 2, 3, 5, 7, 8, 10, 12, 13,
15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 27, 28,
28, 28, 28, 28, 28, 27, 27, 26, 26, 25, 24, 23, 22, 21, 20,
19, 18, 16, 15, 13, 12, 10, 9, 7, 5, 4, 2, 0, -2, -3,
-5, -7, -8, -10, -12, -13, -15, -16, -17, -19, -20, -21, -22, -23, -24,
-25, -26, -26, -27, -27, -28, -28, -28, -28, -28, -28, -27, -27, -26, -26,
-25, -24, -23, -22, -21, -20, -19, -18, -16, -15, -13, -12, -10, -9, -7,
-5, -4, -2, 0, 1, 3, 5, 7, 8, 10, 11, 13, 15, 16, 17,
19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 27, 28, 28, 28, 28,
28, 28, 27, 27, 26, 26, 25, 24, 23, 22, 21, 20, 19, 18, 16,
15, 13, 12, 10, 9, 7, 5, 4, 2, 0, -1, -3, -5, -6, -8,
-10, -11, -13, -14, -16, -17, -19, -20, -21, -22, -23, -24, -25, -26, -26,
-27, -27, -28, -28, -28, -28, -28, -28, -27, -27, -26, -26, -25, -24, -24,
-23, -21, -20, -19, -18, -16, -15, -14, -12, -10, -9, -7, -6, -4, -2,
0, 1, 3, 5, 6, 8, 10, 11, 13, 14, 16, 17, 18, 20, 21,
22, 23, 24, 25, 26, 26, 27, 27, 28, 28, 28, 28, 28, 28, 27,
27, 27, 26, 25, 24, 24, 23, 22, 20, 19, 18, 17, 15, 14, 12,
11, 9, 7, 6, 4, 2, 1, -1, -3, -5, -6, -8, -10, -11, -13,
-14, -16, -17, -18, -20, -21, -22, -23, -24, -25, -25, -26, -27, -27, -28,
-28, -28, -28, -28, -28, -27, -27, -27, -26, -25, -24, -24, -23, -22, -20,
-19, -18, -17, -15, -14, -12, -11, -9, -7, -6, -4, -2, -1, 1, 3,
4, 6, 8, 9, 11, 13, 14, 16, 17, 18, 20, 21, 22, 23, 24,
25, 25, 26, 27, 27, 27, 28, 28, 28, 28, 28, 27, 27, 27, 26,
25, 25, 24, 23, 22, 21, 19, 18, 17, 15, 14, 12, 11, 9, 8,
6, 4, 2, 1, -1, -3, -4, -6, -8, -9, -11, -13, -14, -15, -17,
-18, -19, -21, -22, -23, -24, -25, -25, -26, -27, -27, -27, -28, -28, -28,
-28, -28, -27, -27, -27, -26, -25, -25, -24, -23, -22, -21, -19, -18, -17,
-15, -14, -12, -11, -9, -8, -6, -4, -3, -1, 1, 3, 4, 6, 8,
9, 11, 12, 14, 15, 17, 18, 19, 21, 22, 23, 24, 25, 25, 26,
27, 27, 27, 28, 28, 28, 28, 28, 27, 27, 27, 26, 25, 25, 24,
23, 22, 21, 20, 18, 17, 16, 14, 13, 11, 9, 8, 6, 4, 3,
1, -1, -2, -4, -6, -8, -9, -11, -12, -14, -15, -17, -18, -19, -21,
-22, -23, -24, -25, -25, -26, -27, -27, -27, -28, -28, -28, -28, -28, -27,
-27, -27, -26, -25, -25, -24, -23, -22, -21, -20, -18, -17, -16, -14, -13,
-11, -9, -8, -6, -5, -3, -1, 1, 2, 4, 6, 7, 9, 11, 12,
14, 15, 17, 18, 19, 20, 22, 23, 24, 24, 25, 26, 27, 27, 27,
28, 28, 28, 28, 28, 28, 27, 27, 26, 26, 25, 24, 23, 22, 21,
20, 18, 17, 16, 14, 13, 11, 10, 8, 6, 5, 3, 1, -1, -2,
-4, -6, -7, -9, -11, -12, -14, -15, -17, -18, -19, -20, -22, -23, -24,
-24, -25, -26, -27, -27, -27, -28, -28, -28, -28, -28, -28, -27, -27, -26,
-26, -25, -24, -23, -22, -21, -20, -19, -17, -16, -14, -13, -11, -10, -8,
-6, -5, -3, -1, 0, 2, 4, 6, 7, 9, 10, 12, 14, 15, 16,
18, 19, 20, 21, 23, 23, 24, 25, 26, 26, 27, 27, 28, 28, 28,
28, 28, 28, 27, 27, 26, 26, 25, 24, 23, 22, 21, 20, 19, 17,
16, 14, 13, 11, 10, 8, 7, 5, 3, 1, 0, -2, -4, -5, -7,
-9, -10, -12, -13, -15, -16, -18, -19, -20, -21, -22, -23, -24, -25, -26,
-26, -27, -27, -28, -28, -28, -28, -28, -28, -27, -27, -26, -26, -25, -24,
-23, -22, -21, -20, -19, -17, -16, -15, -13, -11, -10, -8, -7, -5, -3,
-2, 0, 2, 4, 5, 7, 9, 10, 12, 13, 15, 16, 18, 19, 20,
21, 22, 23, 24, 25, 26, 26, 27, 27, 28, 28, 28, 28, 28, 28,
27, 27, 26, 26, 25, 24, 23, 22, 21, 20, 19, 17, 16, 15, 13,
12, 10, 8, 7, 5, 3, 2, 0, -2, -3, -5, -7, -9, -10, -12,
-13, -15, -16, -18, -19, -20, -21, -22, -23, -24, -25, -26, -26, -27, -27,
-28, -28, -28, -28, -28, -28, -27, -27, -26, -26, -25, -24, -23, -22, -21,
-20, -19, -18, -16, -15, -13, -12, -10, -8, -7, -5, -3, -2, 0, 2,
3, 5, 7, 8, 10, 12, 13, 15, 16, 17, 19, 20, 21, 22, 23,
24, 25, 26, 26, 27, 27, 28, 28, 28, 28, 28, 28, 27, 27, 26,
26, 25, 24, 23, 22, 21, 20, 19, 18, 16, 15, 13, 12, 10, 9,
7, 5, 4, 2, 0, -2, -3, -5, -7, -8, -10, -12, -13, -15, -16,
-17, -19, -20, -21, -22, -23, -24, -25, -26, -26, -27, -27, -28, -28, -28,
-28, -28, -28, -27, -27, -26, -26, -25, -24, -23, -22, -21, -20, -19, -18,
-16, -15, -13, -12, -10, -9, -7, -5, -4, -2, 0, -6, -12, -18, -24,
-30, -35, -41, -46, -51, -56, -61, -66, -70, -74, -78, -81, -85, -87, -90,
-92, -94, -95, -97, -97, -98, -98, -97, -97, -96, -94, -92, -90, -88, -85,
-82, -78, -74, -70, -66, -62, -57, -52, -47, -41, -36, -30, -24, -18, -12,
-6, 0, 6, 12, 18, 23, 29, 35, 40, 46, 51, 56, 61, 66, 70,
74, 78, 81, 84, 87, 90, 92, 94, 95, 97, 97, 98, 98, 97, 97,
96, 94, 92, 90, 88, 85, 82, 78, 75, 71, 66, 62, 57, 52, 47,
42, 36, 30, 25, 19, 13, 7, 1, -5, -11, -17, -23, -29, -35, -40,
-46, -51, -56, -61, -65, -70, -74, -77, -81, -84, -87, -90, -92, -94, -95,
-96, -97, -98, -98, -97, -97, -96, -94, -93, -90, -88, -85, -82, -79, -75,
-71, -67, -62, -57, -52, -47, -42, -36, -31, -25, -19, -13, -7, -1, 5,
11, 17, 23, 29, 34, 40, 45, 50, 55, 60, 65, 69, 73, 77, 81,
84, 87, 90, 92, 94, 95, 96, 97, 98, 98, 97, 97, 96, 94, 93,
91, 88, 85, 82, 79, 75, 71, 67, 62, 58, 53, 48, 42, 37, 31,
25, 19, 14, 8, 2, -4, -10, -16, -22, -28, -34, -39, -45, -50, -55,
-60, -65, -69, -73, -77, -81, -84, -87, -89, -92, -94, -95, -96, -97, -98,
-98, -98, -97, -96, -95, -93, -91, -88, -86, -82, -79, -75, -71, -67, -63,
-58, -53, -48, -43, -37, -31, -26, -20, -14, -8, 0
1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4,
4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 20,
22, 26, 29, 33, 38, 43, 49, 56, 64, 71, 76, 81,
85, 88, 90, 92, 93, 93, 93, 92, 91, 90, 88, 86,
84, 81, 78, 75, 72, 68, 65, 61, 57, 53, 49, 44,
40, 36, 31, 27, 22, 17, 12, 7, 2, -3, -9, -15,
-21, -28, -35, -43, -51, -60, -71, -82, -94, -103, -112, -118,
-123, -126, -127, -127, -127, -127, -124, -121, -117, -112, -107, -101,
-94, -87, -80, -72, -64, -55, -47, -38, -30, -21, -12, -4,
5, 13, 21, 29, 37, 44, 51, 57, 63, 68, 73, 77,
81, 84, 86, 88, 89, 89, 88, 86, 84, 81, 78, 75,
72, 68, 64, 59, 54, 49, 44, 38, 32, 25, 19, 12,
5, -2, -9, -17, -24, -32, -40, -47, -55, -62, -69, -76,
-83, -89, -95, -101, -106, -111, -115, -119, -122, -124, -125, -125,
-125, -123, -120, -116, -111, -104, -95, -85, -74, -65, -56, -49,
-42, -35, -30, -24, -19, -15, -10, -6, -3, 1, 5, 8,
11, 15, 18, 21, 24, 26, 29, 32, 34, 37, 39, 41,
43, 45, 47, 49, 50, 51, 52, 53, 54, 54, 54, 54,
53, 52, 50, 48, 45, 42, 38, 33, 29, 25, 22, 19,
17, 14, 12, 11, 9, 8, 7, 6, 5, 4, 4, 3,
3, 2, 2, 2, 1, 1, 1, 1, 1, 0
};
static const int8_t effect_2[] = {

View File

@@ -33,17 +33,14 @@
#include <VibrationEffectConfig.h>
#include "VibrationEffectLoader.h"
const struct effect_stream *get_effect_stream(uint32_t effect_id)
{
int i;
namespace {
VibrationEffectLoader loader;
}; // anonymous namespace
for (i = 0; i < ARRAY_SIZE(effects); i++) {
if (effect_id == effects[i].effect_id)
return &effects[i];
}
const struct effect_stream* get_effect_stream(uint32_t effect_id) {
auto ret = loader.getEffectStream(effect_id);
if (ret) return ret;
auto it = std::find_if(std::begin(effects), std::end(effects),
[&](auto&& v) { return v.effect_id == effect_id; });
return it != std::end(effects) ? &*it : nullptr;
return NULL;
}

Some files were not shown because too many files have changed in this diff Show More