4 Commits
bka ... udc

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

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

Change-Id: I2c4f9e00e689a7fa0650d53868b9921d5e8d001c
2024-11-27 19:01:58 +01:00
687 changed files with 4435 additions and 22149 deletions

View File

@@ -1,13 +0,0 @@
BasedOnStyle: Google
Standard: Cpp11
AccessModifierOffset: -2
AllowShortFunctionsOnASingleLine: Inline
ColumnLimit: 100
CommentPragmas: NOLINT:.*
DerivePointerAlignment: false
IncludeBlocks: Preserve
IndentWidth: 4
ContinuationIndentWidth: 8
PointerAlignment: Left
TabWidth: 4
UseTab: Never

View File

@@ -1,13 +0,0 @@
name: build
runs:
using: composite
steps:
- name: Install dependencies
shell: bash
run: pip install pre-commit
- name: Lint
shell: bash
run: pre-commit run --all

View File

@@ -1,38 +0,0 @@
name: gerrit checks
on:
workflow_dispatch:
inputs:
ref:
type: string
gerrit-ref:
type: string
change:
type: string
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: lineageos-infra/fetch-gerrit-change@main
with:
gerrit-ref: ${{ inputs.gerrit-ref }}
ref: ${{ inputs.ref }}
- name: Check if build/action.yml exists
id: check
run: |
if [ -f ./.github/workflows/build/action.yml ]; then
echo "run=1" >> "$GITHUB_OUTPUT"
fi
- name: Build
if: ${{ steps.check.outputs.run }}
uses: ./.github/workflows/build
- uses: lineageos-infra/gerrit-vote@main
if: ${{ steps.check.outputs.run && always() }}
with:
auth: ${{ secrets.GERRIT_VOTE_CREDS }}
change: ${{ inputs.change }}
ref: ${{ inputs.ref }}

View File

@@ -1,20 +0,0 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v21.1.8
hooks:
- id: clang-format
types_or: [c, c++]
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.15.0
hooks:
- id: pretty-format-kotlin
args: [--autofix, --ktfmt, --ktfmt-style=kotlinlang]

View File

@@ -1,5 +1,5 @@
//
// SPDX-FileCopyrightText: 2022-2026 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,17 +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",
],
}
prebuilt_hidl_interfaces {
name: "hidl_zeku_explorer_interface",
interfaces: [
"vendor.zeku.hardware.explorer@1.0::IMmsProvider",
],
}

5
Android.mk Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,17 +1,41 @@
//
// SPDX-FileCopyrightText: 2023-2025 The LineageOS Project
// Copyright (C) 2023 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
phony {
android_app {
name: "OplusEuicc",
srcs: ["src/**/*.kt"],
resource_dirs: ["res"],
sdk_version: "current",
product_specific: true,
certificate: "platform",
privileged: true,
optimize: {
proguard_flags_files: ["proguard.flags"],
},
required: [
"EuiccPolicy",
"EuiccPolicyOplus",
"org.lineageos.euicc.xml",
"hidden-api-whitelist-org.lineageos.euicc.xml",
],
}
runtime_resource_overlay {
name: "EuiccPolicyOplus",
prebuilt_etc {
sub_dir: "permissions",
name: "org.lineageos.euicc.xml",
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",
filename: "hidden-api-whitelist-org.lineageos.euicc.xml",
src: "hidden-api-whitelist-org.lineageos.euicc.xml",
product_specific: true,
}

View File

@@ -1,10 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2023-2025 The LineageOS Project
Copyright (C) 2023-2024 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.lineageos.euicc.overlay.oplus">
<overlay android:targetPackage="org.lineageos.euicc"
android:isStatic="true" />
package="org.lineageos.euicc">
<queries>
<package android:name="com.google.android.gms" />
<package android:name="com.google.android.gsf" />
<package android:name="com.google.android.euicc" />
<package android:name="com.google.android.ims" />
</queries>
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
<application
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>
<receiver
android:directBootAware="true"
android:exported="true"
android:name=".EuiccReceiver"
android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS">
<intent-filter>
<action android:name="com.google.android.euicc.action.PARTNER_CUSTOMIZATION"/>
</intent-filter>
</receiver>
</application>
</manifest>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<config>
<hidden-api-whitelisted-app package="org.lineageos.euicc" />
</config>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<privapp-permissions package="org.lineageos.euicc">
<permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
<permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
</privapp-permissions>
</permissions>

3
Euicc/proguard.flags Normal file
View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,63 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2023-2025 The LineageOS Project
Copyright (C) 2023 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="sim_illustration_lottie_mappings_json" translatable="false">
{
\"sim_illustration_lottie_mappings\": [
{
\"devices\": [
\"OP591BL1\",
\"OP5929L1\",
\"OP594DL1\",
\"OP595DL1\",
\"OP5CF9L1\",
\"OP5D0DL1\",
\"OP5D2BL1\",
\"OP5D35L1\",
\"OP5D3BL1\",
\"OP5D55L1\"
],
\"illustration_lottie\": \"sim_illustration_lottie_bottom\"
}
]
}
</string>
<string name="sim_slot_mappings_json" translatable="false">
{
\"sim-slot-mappings\": [
{
\"devices\": [
\"OP594DL1\",
\"OP595DL1\",
\"OP5D35L1\",
\"OP5D3BL1\",
\"OP5D55L1\"
],
\"esim-slot-ids\": [
1
],
\"psim-slot-ids\": [
0
]
},
{
\"devices\": [
\"OP591BL1\",
\"OP5929L1\",
\"OP5CF9L1\",
\"OP5D0DL1\",
\"OP5D2BL1\"
],
\"esim-slot-ids\": [],
\"psim-slot-ids\": [
0,
1
]
}
]
}
</string>
<string name="sim_illustration_lottie_mappings_json">{\"sim_illustration_lottie_mappings\":[{\"devices\":[\"OP594DL1\"],\"illustration_lottie\":\"sim_illustration_lottie_bottom\"}]}</string>
<string name="sim_slot_mappings_json">{\"sim-slot-mappings\":[{\"devices\":[\"OP594DL1\"],\"esim-slot-ids\":[1],\"psim-slot-ids\":[0]}]}</string>
</resources>

View File

@@ -1,9 +1,9 @@
/*
* SPDX-FileCopyrightText: 2025 The LineageOS Project
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.pen
package org.lineageos.euicc
import android.content.BroadcastReceiver
import android.content.Context
@@ -13,10 +13,10 @@ 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))
EuiccDisabler.enableOrDisableEuicc(context)
}
companion object {
private const val TAG = "OplusPenBootReceiver"
private const val TAG = "OplusEuiccBootReceiver"
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2021-2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.euicc
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.ApplicationInfoFlags
import android.util.Log
object EuiccDisabler {
private const val TAG = "OplusEuiccDisabler"
private val EUICC_DEPENDENCIES = listOf(
"com.google.android.gms",
"com.google.android.gsf",
)
private val EUICC_PACKAGES = listOf(
"com.google.android.euicc",
"com.google.android.ims",
)
private fun isInstalled(pm: PackageManager, pkgName: String) = runCatching {
val info = pm.getApplicationInfo(pkgName, ApplicationInfoFlags.of(0))
info.flags and ApplicationInfo.FLAG_INSTALLED != 0
}.getOrDefault(false)
private fun isInstalledAndEnabled(pm: PackageManager, pkgName: String) = runCatching {
val info = pm.getApplicationInfo(pkgName, ApplicationInfoFlags.of(0))
Log.d(TAG, "package $pkgName installed, enabled = ${info.enabled}")
info.enabled
}.getOrDefault(false)
fun enableOrDisableEuicc(context: Context) {
val pm = context.packageManager
val disable = EUICC_DEPENDENCIES.any { !isInstalledAndEnabled(pm, it) }
val flag = if (disable) {
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
} else {
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
}
for (pkg in EUICC_PACKAGES) {
if (isInstalled(pm, pkg)) {
pm.setApplicationEnabledSetting(pkg, flag, 0)
}
}
}
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright (C) 2023 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.euicc
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
class EuiccReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "Received PARTNER_CUSTOMIZATION intent")
}
companion object {
private const val TAG = "OplusEuiccReceiver"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,6 +2,7 @@ android_app {
name: "KeyHandler",
srcs: ["src/**/*.kt"],
resource_dirs: ["res"],
certificate: "platform",
platform_apis: true,
@@ -12,9 +13,7 @@ android_app {
],
optimize: {
optimize: true,
proguard_flags_files: ["proguard.flags"],
shrink_resources: true,
},
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,19 +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_selection_dialog_title">Atzione</string>
<string name="alert_slider_top_position">Positzione superiore</string>
<string name="alert_slider_middle_position">Positzione tzentrale</string>
<string name="alert_slider_bottom_position">Positzione inferiore</string>
<string name="alert_slider_mode_silent">A sa muda</string>
<string name="alert_slider_mode_normal">Normale</string>
<string name="alert_slider_mode_vibration">Vibratzione</string>
<string name="alert_slider_mode_dnd_priority_only">Prioridade isceti</string>
<string name="alert_slider_mode_dnd_total_silence">Silèntziu totale</string>
<string name="alert_slider_mode_dnd_alarms_only">Isvèllias isceti</string>
<string name="alert_slider_mute_media_title">Pone is cuntenutos multimediales a sa muda</string>
<string name="alert_slider_mute_media_summary">Pone is cuntenutos multimediales a sa muda cando passas a silèntziu</string>
</resources>

View File

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

View File

@@ -1,12 +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_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>
</resources>

View File

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

View File

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

View File

@@ -1,16 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2021-2025 The LineageOS Project
Copyright (C) 2021 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/alert_slider_category_title">
<SwitchPreferenceCompat
<SwitchPreference
android:key="config_mute_media"
android:title="@string/alert_slider_mute_media_title"
android:summary="@string/alert_slider_mute_media_summary"
@@ -19,29 +16,29 @@
<ListPreference
android:key="config_top_position"
android:dialogTitle="@string/alert_slider_selection_dialog_title"
android:title="@string/alert_slider_top_position"
android:summary="%s"
android:entries="@array/alert_slider_action_entries"
android:entryValues="@array/alert_slider_action_entry_values"
android:defaultValue="0"
android:title="@string/alert_slider_top_position"
app:useSimpleSummaryProvider="true" />
android:defaultValue="0" />
<ListPreference
android:key="config_middle_position"
android:dialogTitle="@string/alert_slider_selection_dialog_title"
android:title="@string/alert_slider_middle_position"
android:summary="%s"
android:entries="@array/alert_slider_action_entries"
android:entryValues="@array/alert_slider_action_entry_values"
android:defaultValue="1"
android:title="@string/alert_slider_middle_position"
app:useSimpleSummaryProvider="true" />
android:defaultValue="1" />
<ListPreference
android:key="config_bottom_position"
android:dialogTitle="@string/alert_slider_selection_dialog_title"
android:title="@string/alert_slider_bottom_position"
android:summary="%s"
android:entries="@array/alert_slider_action_entries"
android:entryValues="@array/alert_slider_action_entry_values"
android:defaultValue="2"
android:title="@string/alert_slider_bottom_position"
app:useSimpleSummaryProvider="true" />
android:defaultValue="2" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,27 +1,20 @@
/*
* SPDX-FileCopyrightText: 2021-2025 The LineageOS Project
* Copyright (C) 2021-2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.settings.device
import android.os.Bundle
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity
class ButtonSettingsActivity : CollapsingToolbarBaseActivity() {
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager
.beginTransaction()
.replace(
com.android.settingslib.collapsingtoolbar.R.id.content_frame,
ButtonSettingsFragment(),
TAG,
)
.commit()
}
companion object {
private const val TAG = "ButtonSettingsActivity"
fragmentManager.beginTransaction().replace(
com.android.settingslib.collapsingtoolbar.R.id.content_frame,
ButtonSettingsFragment()
).commit()
}
}

View File

@@ -1,15 +1,31 @@
/*
* SPDX-FileCopyrightText: 2021-2025 The LineageOS Project
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.settings.device
import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
import android.view.MenuItem
import androidx.preference.PreferenceFragment
class ButtonSettingsFragment : PreferenceFragmentCompat() {
class ButtonSettingsFragment : PreferenceFragment() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.button_panel, rootKey)
addPreferencesFromResource(R.xml.button_panel)
activity.actionBar!!.setDisplayHomeAsUpEnabled(true)
}
override fun addPreferencesFromResource(preferencesResId: Int) {
super.addPreferencesFromResource(preferencesResId)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.home -> {
activity.finish()
return true
}
}
return super.onOptionsItemSelected(item)
}
}

View File

@@ -8,6 +8,7 @@ package org.lineageos.settings.device
import android.database.Cursor
import android.database.MatrixCursor
import android.provider.SearchIndexableResource
import android.provider.SearchIndexablesProvider
import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME
import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID
import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION
@@ -18,14 +19,15 @@ import android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID
import android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS
import android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS
import android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS
import android.provider.SearchIndexablesProvider
class ConfigPanelSearchIndexablesProvider : SearchIndexablesProvider() {
override fun onCreate(): Boolean = true
override fun queryXmlResources(projection: Array<String?>?): Cursor {
val cursor = MatrixCursor(INDEXABLES_XML_RES_COLUMNS)
INDEXABLE_RES.forEach { cursor.addRow(generateResourceRef(it)) }
INDEXABLE_RES.forEach {
cursor.addRow(generateResourceRef(it))
}
return cursor
}
@@ -52,14 +54,10 @@ class ConfigPanelSearchIndexablesProvider : SearchIndexablesProvider() {
companion object {
private const val TAG = "ConfigPanelSearchIndexablesProvider"
private val INDEXABLE_RES =
arrayOf<SearchIndexableResource>(
SearchIndexableResource(
1,
R.xml.button_panel,
ButtonSettingsActivity::class.java.name,
0,
)
private val INDEXABLE_RES = arrayOf<SearchIndexableResource>(
SearchIndexableResource(
1, R.xml.button_panel, ButtonSettingsActivity::class.java.name, 0
)
)
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2025 The LineageOS Project
* Copyright (C) 2021-2023 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
@@ -18,6 +18,7 @@ import android.os.Vibrator
import android.provider.Settings
import android.view.KeyEvent
import com.android.internal.os.DeviceKeyHandler
import java.io.File
import java.util.concurrent.Executors
@@ -26,43 +27,32 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
private val notificationManager = context.getSystemService(NotificationManager::class.java)!!
private val vibrator = context.getSystemService(Vibrator::class.java)!!
private val packageContext =
context.createPackageContext(KeyHandler::class.java.getPackage()!!.name, 0)
private val packageContext = context.createPackageContext(
KeyHandler::class.java.getPackage()!!.name, 0
)
private val sharedPreferences
get() =
packageContext.getSharedPreferences(
packageContext.packageName + "_preferences",
Context.MODE_PRIVATE or Context.MODE_MULTI_PROCESS,
)
get() = packageContext.getSharedPreferences(
packageContext.packageName + "_preferences",
Context.MODE_PRIVATE or Context.MODE_MULTI_PROCESS
)
private val executorService = Executors.newSingleThreadExecutor()
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)
}
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
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
}
}
}
init {
context.registerReceiver(
broadcastReceiver,
IntentFilter().apply {
addAction(AudioManager.STREAM_MUTE_CHANGED_ACTION)
addAction(Intent.ACTION_BOOT_COMPLETED)
},
IntentFilter(AudioManager.STREAM_MUTE_CHANGED_ACTION)
)
}
@@ -77,40 +67,37 @@ 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(MODE_VIBRATION_EFFECT, HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES)
AudioManager.RINGER_MODE_NORMAL ->
vibrator.vibrate(MODE_NORMAL_EFFECT, HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES)
AudioManager.RINGER_MODE_VIBRATE -> vibrator.vibrate(
MODE_VIBRATION_EFFECT,
HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES
)
AudioManager.RINGER_MODE_NORMAL -> vibrator.vibrate(
MODE_NORMAL_EFFECT,
HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES
)
}
}
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) {
POSITION_TOP -> sharedPreferences.getString(ALERT_SLIDER_TOP_KEY, "0")!!.toInt()
POSITION_MIDDLE ->
sharedPreferences.getString(ALERT_SLIDER_MIDDLE_KEY, "1")!!.toInt()
POSITION_BOTTOM ->
sharedPreferences.getString(ALERT_SLIDER_BOTTOM_KEY, "2")!!.toInt()
else -> return
}
val mode = when (position) {
POSITION_TOP -> sharedPreferences.getString(ALERT_SLIDER_TOP_KEY, "0")!!.toInt()
POSITION_MIDDLE -> sharedPreferences.getString(ALERT_SLIDER_MIDDLE_KEY, "1")!!.toInt()
POSITION_BOTTOM -> sharedPreferences.getString(ALERT_SLIDER_BOTTOM_KEY, "2")!!.toInt()
else -> return
}
executorService.submit {
when (mode) {
@@ -122,17 +109,14 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
wasMuted = true
}
}
AudioManager.RINGER_MODE_VIBRATE,
AudioManager.RINGER_MODE_NORMAL -> {
AudioManager.RINGER_MODE_VIBRATE, AudioManager.RINGER_MODE_NORMAL -> {
setZenMode(Settings.Global.ZEN_MODE_OFF)
audioManager.ringerModeInternal = mode
if (muteMedia && wasMuted) {
audioManager.adjustVolume(AudioManager.ADJUST_UNMUTE, 0)
}
}
ZEN_PRIORITY_ONLY,
ZEN_TOTAL_SILENCE,
ZEN_ALARMS_ONLY -> {
ZEN_PRIORITY_ONLY, ZEN_TOTAL_SILENCE, ZEN_ALARMS_ONLY -> {
audioManager.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL
setZenMode(mode - ZEN_OFFSET)
if (muteMedia && wasMuted) {
@@ -140,10 +124,7 @@ class KeyHandler(context: Context) : DeviceKeyHandler {
}
}
}
if (vibrate) {
vibrateIfNeeded(mode)
}
vibrateIfNeeded(mode)
}
}

View File

@@ -1,30 +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,
privileged: true,
system_ext_specific: true,
optimize: {
proguard_flags_files: ["proguard.flags"],
},
required: [
"default-permissions_org.lineageos.pen",
],
}
prebuilt_etc {
name: "default-permissions_org.lineageos.pen",
system_ext_specific: true,
src: "default-permissions_org.lineageos.pen.xml",
sub_dir: "default-permissions",
filename_from_src: true,
}

View File

@@ -1,33 +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.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<application
android:label="@string/app_name"
android:persistent="true"
android:usesNonSdkApi="true">
<receiver
android:exported="true"
android:name=".BootCompletedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service
android:exported="false"
android:name=".PenService" />
</application>
</manifest>

View File

@@ -1,12 +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.BLUETOOTH_CONNECT" fixed="false" />
<permission name="android.permission.BLUETOOTH_SCAN" fixed="false" />
<permission name="android.permission.POST_NOTIFICATIONS" fixed="false" />
</exception>
</exceptions>

View File

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

View File

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

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Qələm taxılıb</string>
<string name="tap_to_connect">Bağlanmaq üçün toxunun</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Дигитална писалка е сдвоена</string>
<string name="tap_to_connect">Натисни за сдвояване</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Bolígraf adjunt</string>
<string name="tap_to_connect">Toqueu per connectar</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Pero připojeno</string>
<string name="tap_to_connect">Klepnutím připojit</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Η γραφίδα προσαρτήθηκε</string>
<string name="tap_to_connect">Πατήστε για σύνδεση</string>
</resources>

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Bolígrafo adjunto</string>
<string name="tap_to_connect">Toca para conectar</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">قلم متصل شد</string>
<string name="tap_to_connect">برای اتصال ضربه بزنید</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Stylo attaché</string>
<string name="tap_to_connect">Appuyer pour connecter</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Peann ceangailte</string>
<string name="tap_to_connect">Tapáil chun ceangal</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Toll mellékelve</string>
<string name="tap_to_connect">A csatlakoztatáshoz érintse meg</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Penna attaccata</string>
<string name="tap_to_connect">Tocca per connettere</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">עט מצורף</string>
<string name="tap_to_connect">נגיעה להתחברות</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">ペンを装着しました</string>
<string name="tap_to_connect">タップして接続</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">კალამი მიუერთდა</string>
<string name="tap_to_connect">შეეხეთ მიერთებისთვის</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Dołączone pióro</string>
<string name="tap_to_connect">Dotknij, aby połączyć</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Caneta anexada</string>
<string name="tap_to_connect">Toque para conectar</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Caneta anexada</string>
<string name="tap_to_connect">Toque para conectar</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Stilou atașat</string>
<string name="tap_to_connect">Atingeți pentru a conecta</string>
</resources>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="tap_to_connect">Нажмите, чтобы подключить</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Pinna alligongiada</string>
<string name="tap_to_connect">Toca pro connètere</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Pisalo priključeno</string>
<string name="tap_to_connect">Tapnite za povezavo</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">எழுத்தாணி இணைக்கப்பட்டது</string>
<string name="tap_to_connect">இணைக்கத் தட்டுக</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">قەلەم ئۇلاندى</string>
<string name="tap_to_connect">چېكىلسە باغلىنىدۇ</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">Đã gắn bút</string>
<string name="tap_to_connect">Chạm để kết nối</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string name="pen_attached">笔已连接</string>
<string name="tap_to_connect">轻触以连接</string>
</resources>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2025 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<!-- Max supported refresh rate when using pen. -->
<string name="config_penSupportedRefreshRate" translatable="false"></string>
</resources>

View File

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

View File

@@ -1,232 +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.Intent
import android.database.ContentObserver
import android.hardware.input.InputManager
import android.os.Handler
import android.os.IBinder
import android.os.UEventObserver
import android.provider.Settings
import android.provider.Settings.System.PEAK_REFRESH_RATE
import android.util.Log
class PenService : Service() {
private val bluetoothManager by lazy { getSystemService(BluetoothManager::class.java) }
private val inputManager by lazy { getSystemService(InputManager::class.java) }
private val notificationManager by lazy { getSystemService(NotificationManager::class.java) }
private val penSupportedRefreshRate by lazy {
getString(R.string.config_penSupportedRefreshRate)
}
private val handler by lazy { Handler(mainLooper) }
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)
}
}
}
}
private val inputObserver =
object : InputManager.InputDeviceListener {
override fun onInputDeviceAdded(deviceId: Int) {
overridePeakRefreshRateIfNeeded()
}
override fun onInputDeviceRemoved(deviceId: Int) {
overridePeakRefreshRateIfNeeded()
}
override fun onInputDeviceChanged(deviceId: Int) {
// Do nothing
}
}
private val peakRefreshRateSettingsObserver by lazy {
object : ContentObserver(handler) {
override fun onChange(selfChange: Boolean) {
super.onChange(selfChange)
overridePeakRefreshRateIfNeeded()
}
}
}
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()
if (!penSupportedRefreshRate.isEmpty()) {
contentResolver.registerContentObserver(
Settings.System.getUriFor(PEAK_REFRESH_RATE),
false,
peakRefreshRateSettingsObserver,
)
peakRefreshRateSettingsObserver.onChange(true)
inputManager.registerInputDeviceListener(inputObserver, handler)
}
observer.startObserving("DEVPATH=/devices/virtual/oplus_wireless/pencil")
}
override fun onDestroy() {
super.onDestroy()
if (!penSupportedRefreshRate.isEmpty()) {
contentResolver.unregisterContentObserver(peakRefreshRateSettingsObserver)
inputManager.unregisterInputDeviceListener(inputObserver)
}
observer.stopObserving()
}
private fun bondBtDevice(pencilAddr: String) {
val adapter = bluetoothManager.adapter
@Suppress("DEPRECATION") adapter.enable()
val scanner = run {
repeat(50) {
adapter.bluetoothLeScanner?.let {
return@run it
}
Thread.sleep(100)
}
return@run null
}
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 overridePeakRefreshRateIfNeeded() {
val isPenConnected =
inputManager.inputDeviceIds.firstOrNull {
val device = inputManager.getInputDevice(it) ?: return@firstOrNull false
if (device.vendorId != 0x22D9 && device.vendorId != 0x330A) {
// Not an OPPO/Maxeye vendor ID
return@firstOrNull false
}
if (
device.bluetoothAddress?.startsWith("C0:87:06") == false &&
device.bluetoothAddress?.startsWith("F8:6F:DE") == false
) {
// Not a Maxeye/Goodix MAC prefix
return@firstOrNull false
}
return@firstOrNull true
} != null
val peakRefreshRate = Settings.System.getString(contentResolver, PEAK_REFRESH_RATE)
if (isPenConnected && peakRefreshRate == "Infinity") {
Settings.System.putString(contentResolver, PEAK_REFRESH_RATE, penSupportedRefreshRate)
} else if (!isPenConnected && peakRefreshRate == penSupportedRefreshRate) {
Settings.System.putString(contentResolver, PEAK_REFRESH_RATE, "Infinity")
}
}
private fun postNotification(pencilAddr: String) {
val adapter = bluetoothManager.adapter
if (adapter.bondedDevices.contains(adapter.getRemoteDevice(pencilAddr))) {
Log.e(TAG, "$pencilAddr already bonded, bailing out")
return
}
if (notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null) {
notificationManager.createNotificationChannel(
NotificationChannel(
NOTIFICATION_CHANNEL_ID,
NOTIFICATION_CHANNEL_ID,
NotificationManager.IMPORTANCE_HIGH,
)
)
}
val contentIntent =
PendingIntent.getService(
this,
0,
Intent(this, PenService::class.java).apply {
putExtra(EXTRA_PENCIL_ADDR, pencilAddr)
},
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
)
val notification =
Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stylus)
.setContentTitle(getString(R.string.pen_attached))
.setContentText(getString(R.string.tap_to_connect))
.setContentIntent(contentIntent)
.setAutoCancel(true)
.build()
notificationManager.notify(NOTIFICATION_ID, notification)
}
companion object {
private const val TAG = "OplusPenService"
private const val EXTRA_PENCIL_ADDR = "pencil_addr"
private const val NOTIFICATION_CHANNEL_ID = "OplusPen"
private const val NOTIFICATION_ID = 1000
}
}

View File

@@ -1,18 +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 |

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,50 +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_PULSE, &value) != 0 &&
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_PULSE, &value) != 0 &&
ioctl(mOplusDisplayFd, PANEL_IOCTL_SET_PWM_TURBO, &value) != 0 &&
ioctl(mOplusDisplayFd, PANEL_IOCTL_SET_DIMLAYER_BL_EN, &value) != 0) {
LOG(ERROR) << "Failed to set AntiFlicker state";
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
return ndk::ScopedAStatus::ok();
}
} // namespace livedisplay
} // namespace lineage
} // namespace vendor
} // namespace aidl

View File

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

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