Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6597137fb2 | |||
|
|
56cc248362 | ||
|
|
10cf887bbf | ||
|
|
387d07577e |
@@ -1 +0,0 @@
|
||||
../../build/soong/scripts/system-clang-format
|
||||
10
Android.bp
10
Android.bp
@@ -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
5
Android.mk
Normal file
@@ -0,0 +1,5 @@
|
||||
ifneq ($(filter $(call my-dir),$(PRODUCT_SOONG_NAMESPACES)),)
|
||||
|
||||
include $(call all-subdir-makefiles)
|
||||
|
||||
endif
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">DSP Volume Synchronizer</string>
|
||||
</resources>
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ android_app {
|
||||
name: "KeyHandler",
|
||||
|
||||
srcs: ["src/**/*.kt"],
|
||||
resource_dirs: ["res"],
|
||||
|
||||
certificate: "platform",
|
||||
platform_apis: true,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -1,3 +0,0 @@
|
||||
-keep class org.lineageos.pen.* {
|
||||
*;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
19
README.md
19
README.md
@@ -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 |
|
||||
@@ -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",
|
||||
],
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
service vendor.commondcs /vendor/bin/hw/vendor.oplus.hardware.commondcs-service
|
||||
class hal
|
||||
user system
|
||||
group system
|
||||
@@ -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>
|
||||
@@ -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",
|
||||
],
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -1,4 +0,0 @@
|
||||
service vendor.livedisplay-hal /vendor/bin/hw/vendor.lineage.livedisplay-service.oplus
|
||||
class late_start
|
||||
user system
|
||||
group system
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
service oplus.performance.hal.service /vendor/bin/hw/vendor.oplus.hardware.performance-service
|
||||
class hal
|
||||
user system
|
||||
group system
|
||||
@@ -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>
|
||||
@@ -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",
|
||||
],
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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",
|
||||
],
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"],
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
76
aidl/vibrator/Android.bp
Normal 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",
|
||||
],
|
||||
}
|
||||
@@ -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 {
|
||||
12
aidl/vibrator/effect/Android.bp
Normal file
12
aidl/vibrator/effect/Android.bp
Normal 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",
|
||||
],
|
||||
}
|
||||
@@ -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[] = {
|
||||
@@ -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
Reference in New Issue
Block a user